ソースを参照

fix(dashboard): Handle list relation custom fields properly

David Höck 6 ヶ月 前
コミット
622ed04937

+ 18 - 1
packages/dashboard/src/lib/components/shared/custom-fields-form.tsx

@@ -41,7 +41,12 @@ export function CustomFieldsForm({ entityType, control, formPathPrefix }: Custom
     const customFields = useCustomFieldConfig(entityType);
 
     const getFieldName = (fieldDef: CustomFieldConfig) => {
-        const name = fieldDef.type === 'relation' ? fieldDef.name + 'Id' : fieldDef.name;
+        const name =
+            fieldDef.type === 'relation'
+                ? fieldDef.list
+                    ? fieldDef.name + 'Ids'
+                    : fieldDef.name + 'Id'
+                : fieldDef.name;
         return formPathPrefix ? `${formPathPrefix}.customFields.${name}` : `customFields.${name}`;
     };
 
@@ -266,6 +271,18 @@ function FormInputForType({
             );
         case 'boolean':
             return <Switch checked={field.value} onCheckedChange={field.onChange} disabled={isReadonly} />;
+        case 'relation':
+            if (fieldDef.list) {
+                return (
+                    <Input
+                        {...field}
+                        onChange={e => field.onChange(e.target.value.split(','))}
+                        disabled={isReadonly}
+                    />
+                );
+            } else {
+                return <Input {...field} disabled={isReadonly} />;
+            }
         default:
             return <Input {...field} disabled={isReadonly} />;
     }

+ 43 - 15
packages/dashboard/src/lib/framework/form-engine/utils.ts

@@ -1,24 +1,52 @@
 import { FieldInfo } from '../document-introspection/get-document-structure.js';
 
-export function transformRelationFields<E extends Record<string, any>>(fields: FieldInfo[], entity: E) {
-    const processedEntity = { ...entity } as any;
+/**
+ * Transforms relation fields in an entity, extracting IDs from relation objects.
+ * This is primarily used for custom fields of type "ID".
+ *
+ * @param fields - Array of field information
+ * @param entity - The entity to transform
+ * @returns A new entity with transformed relation fields
+ */
+export function transformRelationFields<E extends Record<string, any>>(fields: FieldInfo[], entity: E): E {
+    // Create a shallow copy to avoid mutating the original entity
+    const processedEntity = { ...entity };
 
-    for (const field of fields) {
-        if (field.name !== 'customFields' || !field.typeInfo) {
-            continue;
-        }
+    // Skip processing if there are no custom fields
+    if (!entity.customFields || !processedEntity.customFields) {
+        return processedEntity;
+    }
 
-        if (!entity.customFields || !processedEntity.customFields) {
-            continue;
-        }
+    // Find the customFields field info
+    const customFieldsInfo = fields.find(field => field.name === 'customFields' && field.typeInfo);
+    if (!customFieldsInfo?.typeInfo) {
+        return processedEntity;
+    }
+
+    // Process only ID type custom fields
+    const idTypeCustomFields = customFieldsInfo.typeInfo.filter(field => field.type === 'ID');
 
-        for (const customField of field.typeInfo) {
-            if (customField.type === 'ID') {
-                const relationField = customField.name;
-                const propertyAccessorKey = customField.name.replace(/Id$/, '');
-                const relationValue = entity.customFields[propertyAccessorKey];
-                const relationIdValue = relationValue?.id;
+    for (const customField of idTypeCustomFields) {
+        const relationField = customField.name;
+
+        if (customField.list) {
+            // For list fields, the accessor is the field name without the "Ids" suffix
+            const propertyAccessorKey = customField.name.replace(/Ids$/, '');
+            const relationValue = entity.customFields[propertyAccessorKey];
+
+            if (relationValue) {
+                const relationIdValue = relationValue.map((v: { id: string }) => v.id);
+                if (relationIdValue && relationIdValue.length > 0) {
+                    processedEntity.customFields[relationField] = relationIdValue;
+                }
+            }
+        } else {
+            // For single fields, the accessor is the field name without the "Id" suffix
+            const propertyAccessorKey = customField.name.replace(/Id$/, '');
+            const relationValue = entity.customFields[propertyAccessorKey];
 
+            if (relationValue) {
+                const relationIdValue = relationValue.id;
                 if (relationIdValue) {
                     processedEntity.customFields[relationField] = relationIdValue;
                 }

ファイルの差分が大きいため隠しています
+ 1 - 1
packages/dashboard/src/lib/graphql/graphql-env.d.ts


ファイルの差分が大きいため隠しています
+ 1 - 1
packages/dev-server/graphql/graphql-env.d.ts


+ 9 - 0
packages/dev-server/test-plugins/reviews/reviews-plugin.ts

@@ -57,6 +57,15 @@ import { ProductReview } from './entities/product-review.entity';
             ui: { tab: 'Reviews', fullWidth: true },
             inverseSide: undefined,
         });
+        config.customFields.Product.push({
+            name: 'promotedReviews',
+            label: [{ languageCode: LanguageCode.en, value: 'Promoted Reviews' }],
+            public: true,
+            type: 'relation',
+            list: true,
+            entity: ProductReview,
+            ui: { tab: 'Reviews', fullWidth: true },
+        });
         config.customFields.Product.push({
             name: 'translatableText',
             label: [{ languageCode: LanguageCode.en, value: 'Translatable text' }],

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません