From 80ff7ffbcfee1f0e84a57f411c0c46e3bd928e7d Mon Sep 17 00:00:00 2001 From: rijkvanzanten Date: Fri, 27 Nov 2020 14:16:55 -0500 Subject: [PATCH 1/2] Organize relational settings --- .../routes/data-model/field-detail/store.ts | 21 ++++++------------- 1 file changed, 6 insertions(+), 15 deletions(-) diff --git a/app/src/modules/settings/routes/data-model/field-detail/store.ts b/app/src/modules/settings/routes/data-model/field-detail/store.ts index 0f39ab39ab..6c11f41710 100644 --- a/app/src/modules/settings/routes/data-model/field-detail/store.ts +++ b/app/src/modules/settings/routes/data-model/field-detail/store.ts @@ -67,22 +67,9 @@ function initLocalStore(collection: string, field: string, type: typeof localTyp if (inter.system === true) return false; const matchesType = inter.types.includes(state.fieldData?.type || 'alias'); - const matchesLocalType = inter.localTypes?.includes(type); - let matchesRelation = false; + const matchesLocalType = inter.localTypes?.includes(type) || true; - if (type === 'standard' || type === 'presentation') { - matchesRelation = inter.relationship === null || inter.relationship === undefined; - } else if (type === 'file') { - matchesRelation = inter.relationship === 'm2o'; - } else if (type === 'files') { - matchesRelation = inter.relationship === 'm2m'; - } else if (type === 'translations') { - matchesRelation = inter.relationship === 'translations'; - } else { - matchesRelation = inter.relationship === type; - } - - return matchesType && matchesRelation && (matchesLocalType === undefined || matchesLocalType); + return matchesType && matchesLocalType; }) .sort((a, b) => (a.name > b.name ? 1 : -1)); }); @@ -127,6 +114,10 @@ function initLocalStore(collection: string, field: string, type: typeof localTyp } if (type === 'file') { + useFile(); + } + + function useFile() { if (!isExisting) { state.fieldData.type = 'uuid'; From 1b3aa5a059175d6a9417b5d7ffe0cffc47a4a956 Mon Sep 17 00:00:00 2001 From: rijkvanzanten Date: Fri, 27 Nov 2020 17:31:00 -0500 Subject: [PATCH 2/2] Finish m2a setup --- api/src/services/collections.ts | 4 +- app/src/components/v-select/v-select.vue | 6 +- .../interfaces/m2a-builder/m2a-builder.vue | 4 +- app/src/lang/en-US/index.json | 6 + .../components/relationship-m2a.vue | 362 ++++++++++++++++++ .../field-detail/components/relationship.vue | 6 +- .../field-detail/components/schema.vue | 2 +- .../data-model/field-detail/field-detail.vue | 19 +- .../routes/data-model/field-detail/store.ts | 190 ++++++++- .../fields/components/fields-management.vue | 5 + .../routes/data-model/get-local-type.ts | 5 +- 11 files changed, 589 insertions(+), 20 deletions(-) create mode 100644 app/src/modules/settings/routes/data-model/field-detail/components/relationship-m2a.vue diff --git a/api/src/services/collections.ts b/api/src/services/collections.ts index 2de4231c7d..5daa26ced8 100644 --- a/api/src/services/collections.ts +++ b/api/src/services/collections.ts @@ -311,15 +311,13 @@ export class CollectionsService { for (const relation of relations) { const isM2O = relation.many_collection === collection; - /** @TODO M2A — Handle m2a case here */ - if (isM2O) { await this.knex('directus_relations') .delete() .where({ many_collection: collection, many_field: relation.many_field }); await fieldsService.deleteField(relation.one_collection!, relation.one_field!); - } else { + } else if (!!relation.one_collection) { await this.knex('directus_relations') .update({ one_field: null }) .where({ one_collection: collection, one_field: relation.one_field }); diff --git a/app/src/components/v-select/v-select.vue b/app/src/components/v-select/v-select.vue index d397e80e8d..986577ee8d 100644 --- a/app/src/components/v-select/v-select.vue +++ b/app/src/components/v-select/v-select.vue @@ -187,6 +187,10 @@ export default defineComponent({ type: Boolean, default: false, }, + multiplePreviewThreshold: { + type: Number, + default: 3, + }, }, setup(props, { emit }) { const { _items } = useItems(); @@ -238,7 +242,7 @@ export default defineComponent({ function useDisplayValue() { const displayValue = computed(() => { if (Array.isArray(props.value)) { - if (props.value.length < 3) { + if (props.value.length < props.multiplePreviewThreshold) { return props.value .map((value) => { return getTextForValue(value) || value; diff --git a/app/src/interfaces/m2a-builder/m2a-builder.vue b/app/src/interfaces/m2a-builder/m2a-builder.vue index c05ada0b9f..b370a2f56a 100644 --- a/app/src/interfaces/m2a-builder/m2a-builder.vue +++ b/app/src/interfaces/m2a-builder/m2a-builder.vue @@ -294,7 +294,7 @@ export default defineComponent({ ? val[anyRelation.value.many_field][primaryKeys.value[collection]] : val[anyRelation.value.many_field]; - const item = relatedItemValues.value[collection].find( + const item = relatedItemValues.value[collection]?.find( (item) => item[primaryKeys.value[collection]] == key ); @@ -317,6 +317,8 @@ export default defineComponent({ return { fetchValues, previewValues, loading, junctionRowMap, relatedItemValues }; async function fetchValues() { + if (props.value === null) return; + loading.value = true; try { diff --git a/app/src/lang/en-US/index.json b/app/src/lang/en-US/index.json index 37c3aef072..775fd73a79 100644 --- a/app/src/lang/en-US/index.json +++ b/app/src/lang/en-US/index.json @@ -180,6 +180,7 @@ "field_m2o": "M2O Relationship", "field_o2m": "O2M Relationship", "field_m2m": "M2M Relationship", + "field_m2a": "M2A Relationship", "field_translations": "Translations", "languages": "Languages", @@ -229,6 +230,7 @@ "configure_m2o": "Configure your Many-to-One Relationship...", "configure_o2m": "Configure your One-to-Many Relationship...", "configure_m2m": "Configure your Many-to-Many Relationship...", + "configure_m2a": "Configure your Many-to-Any Relationship...", "configure_translations": "Configure your Translations...", "configure_languages": "Configure your Languages...", @@ -264,6 +266,7 @@ "m2o_relationship": "Many to One Relationship", "o2m_relationship": "One to Many Relationship", "m2m_relationship": "Many to Many Relationship", + "m2a_relationship": "Many to Any Relationship", "next": "Next", "previous": "Previous", @@ -346,6 +349,7 @@ "item_in": "Item {primaryKey} in {collection} | Items {primaryKey} in {collection}", "this_collection": "This Collection", "related_collection": "Related Collection", + "related_collections": "Related Collections", "translations_collection": "Translations Collection", "languages_collection": "Languages Collection", @@ -469,6 +473,8 @@ "replace_from_library": "Replace File from Library", "replace_from_url": "Replace File from URL", + "collection_key": "Collection Key", + "name": "Name", "primary_key_field": "Primary Key Field", "type": "Type", diff --git a/app/src/modules/settings/routes/data-model/field-detail/components/relationship-m2a.vue b/app/src/modules/settings/routes/data-model/field-detail/components/relationship-m2a.vue new file mode 100644 index 0000000000..2be8caced8 --- /dev/null +++ b/app/src/modules/settings/routes/data-model/field-detail/components/relationship-m2a.vue @@ -0,0 +1,362 @@ + + + + + diff --git a/app/src/modules/settings/routes/data-model/field-detail/components/relationship.vue b/app/src/modules/settings/routes/data-model/field-detail/components/relationship.vue index f7424b4e20..e91e29b59a 100644 --- a/app/src/modules/settings/routes/data-model/field-detail/components/relationship.vue +++ b/app/src/modules/settings/routes/data-model/field-detail/components/relationship.vue @@ -12,22 +12,24 @@ :type="type" v-else-if="type === 'm2m' || type === 'files'" /> +