diff --git a/packages/react/src/auto/AutoForm.ts b/packages/react/src/auto/AutoForm.ts index f0fbe8064..ae61a4ce5 100644 --- a/packages/react/src/auto/AutoForm.ts +++ b/packages/react/src/auto/AutoForm.ts @@ -20,7 +20,15 @@ import type { UseActionFormSubmit, } from "../use-action-form/types.js"; import { isPlainObject, processDefaultValues, toDefaultValues } from "../use-action-form/utils.js"; -import { getRelatedModelFields, isHasManyOrHasManyThroughField, isRelationshipField, pathListToSelection } from "../use-table/helpers.js"; +import { + fileSelection, + getRelatedModelFields, + isHasManyOrHasManyThroughField, + isRelationshipField, + pathListToSelection, + richTextSelection, + roleAssignmentsSelection, +} from "../use-table/helpers.js"; import type { FieldErrors, FieldValues, UseFormReturn } from "../useActionForm.js"; import { useActionForm } from "../useActionForm.js"; import { get, getFlattenedObjectKeys, set, type ErrorWrapper, type OptionsType } from "../utils.js"; @@ -219,7 +227,7 @@ const useFormSelection = (props: { if (!select || !modelApiIdentifier) { return; } - return forceIdsIntoSelect({ select, rootFieldsMetadata }); + return forceRequiredFieldsIntoSelect({ select, rootFieldsMetadata }); }, [select, modelApiIdentifier, rootFieldsMetadata]); if (!modelApiIdentifier || !fields.length) { @@ -236,38 +244,56 @@ const useFormSelection = (props: { return pathListToSelection(modelApiIdentifier, paths, fieldMetaData); }; -const forceIdsIntoSelect = (props: { select: FieldSelection; rootFieldsMetadata: FieldMetadata[] }) => { +const forceRequiredFieldsIntoSelect = (props: { select: FieldSelection; rootFieldsMetadata: FieldMetadata[] }) => { const { select: originalSelect, rootFieldsMetadata } = props; const select = structuredClone(originalSelect); select.id = true; // Always select the ID for the root model - const addIdToSelection = (selectPath: string, fieldMetadata: FieldMetadata) => { - if (!isRelationshipField(fieldMetadata)) { - return; // Non relationships do not need additional selection - } + const addRequiredFieldsToSelection = (selectPath: string, fieldMetadata: FieldMetadata) => { + const isRichTextField = fieldMetadata.fieldType === FieldType.RichText; + const isFileField = fieldMetadata.fieldType === FieldType.File; + const isRolesField = fieldMetadata.fieldType === FieldType.RoleAssignments; + const isRelationship = isRelationshipField(fieldMetadata); const existingSelection = get(select, selectPath); - if (!existingSelection || typeof existingSelection !== "object") { - // Do not go deeper than what is defined in the select object - return; + if (!existingSelection) { + return; // Do not select at all } - const isManyRelation = isHasManyOrHasManyThroughField(fieldMetadata); - const currentFieldSelectPathPrefix = isManyRelation ? `${selectPath}.edges.node` : `${selectPath}`; - const idPath = `${currentFieldSelectPathPrefix}.id`; + if (isRichTextField) { + return set(select, selectPath, richTextSelection); // Assume that the whole rich text is expected to be selected + } - set(select, idPath, true); + if (isFileField) { + return set(select, selectPath, fileSelection); // Assume whole file is expected to be selected + } + if (isRolesField) { + return set(select, selectPath, roleAssignmentsSelection); // Assume whole role assignments are expected to be selected + } - const relatedModelFields = getRelatedModelFields(fieldMetadata); + if (isRelationship) { + if (typeof existingSelection !== "object") { + // Do not go deeper than what is defined in the select object + return; + } + + const isManyRelation = isHasManyOrHasManyThroughField(fieldMetadata); + const currentFieldSelectPathPrefix = isManyRelation ? `${selectPath}.edges.node` : `${selectPath}`; + const idPath = `${currentFieldSelectPathPrefix}.id`; + + set(select, idPath, true); - for (const relatedModelField of relatedModelFields) { - addIdToSelection(`${currentFieldSelectPathPrefix}.${relatedModelField.apiIdentifier}`, relatedModelField); + const relatedModelFields = getRelatedModelFields(fieldMetadata); + + for (const relatedModelField of relatedModelFields) { + addRequiredFieldsToSelection(`${currentFieldSelectPathPrefix}.${relatedModelField.apiIdentifier}`, relatedModelField); + } } }; for (const field of rootFieldsMetadata) { - addIdToSelection(field.apiIdentifier, field); + addRequiredFieldsToSelection(field.apiIdentifier, field); } return select; diff --git a/packages/react/src/use-table/helpers.tsx b/packages/react/src/use-table/helpers.tsx index c4eefdc22..b71713e6b 100644 --- a/packages/react/src/use-table/helpers.tsx +++ b/packages/react/src/use-table/helpers.tsx @@ -331,18 +331,18 @@ export const isRelationshipField = (field: { fieldType: GadgetFieldType }) => { return isHasOneOrBelongsToField(field) || isHasManyOrHasManyThroughField(field); }; -const richTextSelection = { +export const richTextSelection = { markdown: true, truncatedHTML: true, }; -const fileSelection = { +export const fileSelection = { url: true, mimeType: true, fileName: true, }; -const roleAssignmentsSelection = { +export const roleAssignmentsSelection = { key: true, name: true, };