Fix m2m links in related values to target related collection (#9422) (#9451)

Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
This commit is contained in:
Rémi Alvergnat
2021-11-11 22:00:45 +01:00
committed by GitHub
parent 95720bb3f7
commit ce9efb42fa
3 changed files with 44 additions and 20 deletions

View File

@@ -35,18 +35,22 @@ export default defineDisplay({
types: ['alias', 'string', 'uuid', 'integer', 'bigInteger', 'json'],
localTypes: ['m2m', 'm2o', 'o2m', 'translations', 'm2a'],
fields: (options: Options | null, { field, collection }) => {
const relatedCollection = getRelatedCollection(collection, field);
const { relatedCollection, path } = getRelatedCollection(collection, field);
const fieldsStore = useFieldsStore();
const primaryKeyField = fieldsStore.getPrimaryKeyFieldForCollection(relatedCollection);
if (!relatedCollection) return [];
const fields = options?.template
? adjustFieldsForDisplays(getFieldsFromTemplate(options.template), relatedCollection as unknown as string)
? adjustFieldsForDisplays(getFieldsFromTemplate(options.template), relatedCollection)
: [];
if (primaryKeyField && !fields.includes(primaryKeyField.field)) {
fields.push(primaryKeyField.field);
if (primaryKeyField) {
const primaryKeyFieldValue = path ? [...path, primaryKeyField.field].join('.') : primaryKeyField.field;
if (!fields.includes(primaryKeyFieldValue)) {
fields.push(primaryKeyFieldValue);
}
}
return fields;

View File

@@ -16,7 +16,7 @@
</template>
<v-list class="links">
<v-list-item v-for="item in value" :key="item[primaryKeyField]">
<v-list-item v-for="item in value" :key="item[primaryKeyFieldPath]">
<v-list-item-content>
<render-template :template="internalTemplate" :item="item" :collection="relatedCollection" />
</v-list-item-content>
@@ -36,6 +36,7 @@ import getRelatedCollection from '@/utils/get-related-collection';
import { useCollection } from '@directus/shared/composables';
import ValueNull from '@/views/private/components/value-null';
import { getLocalTypeForField } from '../../modules/settings/routes/data-model/get-local-type';
import { get } from 'lodash';
export default defineComponent({
components: { ValueNull },
@@ -60,18 +61,28 @@ export default defineComponent({
setup(props) {
const { t, te } = useI18n();
const relatedCollection = computed(() => {
const relatedCollectionData = computed(() => {
return getRelatedCollection(props.collection, props.field);
});
const relatedCollection = computed(() => {
return relatedCollectionData.value.relatedCollection;
});
const localType = computed(() => {
return getLocalTypeForField(props.collection, props.field);
});
const { primaryKeyField } = useCollection(relatedCollection);
const primaryKeyFieldPath = computed(() => {
return relatedCollectionData.value.path
? [...relatedCollectionData.value.path, primaryKeyField.value?.field].join('.')
: primaryKeyField.value?.field;
});
const internalTemplate = computed(() => {
return props.template || `{{ ${primaryKeyField.value!.field} }}`;
return props.template || `{{ ${primaryKeyFieldPath.value!} }}`;
});
const unit = computed(() => {
@@ -94,11 +105,11 @@ export default defineComponent({
return null;
});
return { relatedCollection, primaryKeyField, getLinkForItem, internalTemplate, unit, localType };
return { relatedCollection, primaryKeyFieldPath, getLinkForItem, internalTemplate, unit, localType };
function getLinkForItem(item: any) {
if (!relatedCollection.value || !primaryKeyField.value) return null;
const primaryKey = item[primaryKeyField.value.field];
if (!relatedCollectionData.value || !primaryKeyFieldPath.value) return null;
const primaryKey = get(item, primaryKeyFieldPath.value);
return `/content/${relatedCollection.value}/${encodeURIComponent(primaryKey)}`;
}

View File

@@ -1,20 +1,29 @@
import { useFieldsStore, useRelationsStore } from '@/stores/';
import { useRelationsStore } from '@/stores/';
import { Relation } from '@directus/shared/types';
import { getLocalTypeForField } from '../../modules/settings/routes/data-model/get-local-type';
export default function getRelatedCollection(collection: string, field: string): string {
export interface RelatedCollectionData {
relatedCollection: string;
path?: string[];
}
export default function getRelatedCollection(collection: string, field: string): RelatedCollectionData {
const relationsStore = useRelationsStore();
const fieldsStore = useFieldsStore();
const relations: Relation[] = relationsStore.getRelationsForField(collection, field);
const localType = getLocalTypeForField(collection, field);
const fieldInfo = fieldsStore.getField(collection, field);
const o2mTypes = ['o2m', 'm2m', 'm2a', 'translations', 'files'];
if (localType && o2mTypes.includes(localType)) {
if (localType == 'm2m' && relations.length > 1) {
return {
relatedCollection: relations[1].related_collection!,
path: [relations[1].field],
};
}
const type = fieldInfo.type.toLowerCase();
const o2mTypes = ['o2m', 'm2m', 'm2a', 'alias', 'translations', 'files'];
if (o2mTypes.includes(type)) {
return relations[0].collection;
return { relatedCollection: relations[0].collection };
}
return relations[0].related_collection!;
return { relatedCollection: relations[0].related_collection! };
}