({
readonly,
project,
databaseGroup,
className,
onDismiss,
onCreated,
}: DatabaseGroupFormProps)
| 50 | } |
| 51 | |
| 52 | export function DatabaseGroupForm({ |
| 53 | readonly, |
| 54 | project, |
| 55 | databaseGroup, |
| 56 | className, |
| 57 | onDismiss, |
| 58 | onCreated, |
| 59 | }: DatabaseGroupFormProps) { |
| 60 | const { t } = useTranslation(); |
| 61 | |
| 62 | const [title, setTitle] = useState(""); |
| 63 | const [resourceId, setResourceId] = useState(""); |
| 64 | const [resourceIdValid, setResourceIdValid] = useState(false); |
| 65 | const [expr, setExpr] = useState<ConditionGroupExpr>( |
| 66 | wrapAsGroup(emptySimpleExpr()) |
| 67 | ); |
| 68 | |
| 69 | const isCreating = databaseGroup === undefined; |
| 70 | |
| 71 | const matchedDatabaseNames = useMemo( |
| 72 | () => databaseGroup?.matchedDatabases.map((db) => db.name) ?? [], |
| 73 | [databaseGroup] |
| 74 | ); |
| 75 | |
| 76 | // Initialize state from databaseGroup in editing mode |
| 77 | useEffect(() => { |
| 78 | if (!databaseGroup || !isValidDatabaseGroupName(databaseGroup.name)) { |
| 79 | return; |
| 80 | } |
| 81 | |
| 82 | const [, groupName] = getProjectNameAndDatabaseGroupName( |
| 83 | databaseGroup.name |
| 84 | ); |
| 85 | setResourceId(groupName); |
| 86 | setTitle(databaseGroup.title); |
| 87 | |
| 88 | if (databaseGroup.databaseExpr?.expression) { |
| 89 | batchConvertCELStringToParsedExpr([ |
| 90 | databaseGroup.databaseExpr.expression, |
| 91 | ]).then((exprList) => { |
| 92 | if (exprList.length > 0) { |
| 93 | const simpleExpr = resolveCELExpr(exprList[0]); |
| 94 | setExpr(cloneDeep(wrapAsGroup(simpleExpr))); |
| 95 | } |
| 96 | }); |
| 97 | } |
| 98 | }, [databaseGroup]); |
| 99 | |
| 100 | // In edit mode, ResourceIdField is readonly and never fires onValidationChange, |
| 101 | // so skip the resourceIdValid gate when editing. |
| 102 | const allowConfirm = useMemo(() => { |
| 103 | const idOk = isCreating ? resourceIdValid : true; |
| 104 | return idOk && title.trim() !== "" && validateSimpleExpr(expr); |
| 105 | }, [isCreating, resourceIdValid, title, expr]); |
| 106 | |
| 107 | // Duplicate-ID validation for creation: try to fetch the group and fail if it exists. |
| 108 | const validateResourceId = useCallback( |
| 109 | async (id: string): Promise<ValidatedMessage[]> => { |
nothing calls this directly
no test coverage detected