app: fix sort creating items (#5484)

* app: fix sort creating items
Problem: When sorting, the relations were assigned to
another fresh created items on the related collection

Why: It was missing the primary key on nested relation.
When the primary key is missing, new item is created.

How to fix: Iterate over all fields to request and when nested field
is found, append the nested primary key.

* Make function name more descriptive, add comment, fix linter warning

Co-authored-by: rijkvanzanten <rijkvanzanten@me.com>
This commit is contained in:
José Varela
2021-05-14 17:51:09 +01:00
committed by GitHub
parent 4d242ab5bf
commit 1a60d0036f
3 changed files with 48 additions and 2 deletions

View File

@@ -2,6 +2,7 @@ import api from '@/api';
import { Header } from '@/components/v-table/types';
import { useFieldsStore } from '@/stores/';
import { Field } from '@/types';
import { addRelatedPrimaryKeyToFields } from '@/utils/add-related-primary-key-to-fields';
import { Ref, ref, watch } from '@vue/composition-api';
import { cloneDeep, get } from 'lodash';
import { RelationInfo } from './use-relation';
@@ -185,9 +186,11 @@ export default function usePreview(
const endpoint = collection.startsWith('directus_') ? `/${collection.substring(9)}` : `/items/${collection}`;
const fieldsToFetch = addRelatedPrimaryKeyToFields(collection, fields);
const response = await api.get(endpoint, {
params: {
fields: fields,
fields: fieldsToFetch,
[`filter[${filteredField}][_in]`]: primaryKeys.join(','),
},
});

View File

@@ -83,6 +83,7 @@ import { isEqual, sortBy } from 'lodash';
import { get } from 'lodash';
import { unexpectedError } from '@/utils/unexpected-error';
import { getFieldsFromTemplate } from '@/utils/get-fields-from-template';
import { addRelatedPrimaryKeyToFields } from '@/utils/add-related-primary-key-to-fields';
import Draggable from 'vuedraggable';
import adjustFieldsForDisplays from '@/utils/adjust-fields-for-displays';
@@ -294,6 +295,8 @@ export default defineComponent({
if (relation.value.sort_field !== null && fieldsList.includes(relation.value.sort_field) === false)
fieldsList.push(relation.value.sort_field);
const fieldsToFetch = addRelatedPrimaryKeyToFields(relatedCollection.value.collection, fieldsList);
try {
const endpoint = relatedCollection.value.collection.startsWith('directus_')
? `/${relatedCollection.value.collection.substring(9)}`
@@ -306,7 +309,7 @@ export default defineComponent({
if (primaryKeys && primaryKeys.length > 0) {
const response = await api.get(endpoint, {
params: {
fields: fieldsList,
fields: fieldsToFetch,
[`filter[${pkField}][_in]`]: primaryKeys.join(','),
},
});

View File

@@ -0,0 +1,40 @@
import { useFieldsStore } from '@/stores/';
import useCollection from '@/composables/use-collection';
/**
* Adds the primary key field for any passed relational dot-notation field to the array of fields.
* Useful for cases where you need to fetch a single piece of nested relational data, but also need
* access to its primary key.
*
* @example
* const collection = 'articles';
* const fields = ['title', 'user.name'];
*
* addRelatedPrimaryKeyToFields(collection, fields);
* // => ['title', 'user.name', 'user.id'];
*/
export function addRelatedPrimaryKeyToFields(currentCollection: string, fields: string[]): string[] {
if (!fields?.length) return [];
const fieldsStore = useFieldsStore();
const sanitizedFields: string[] = [];
for (const fieldName of fields) {
sanitizedFields.push(fieldName);
if (!fieldName.includes('.')) continue;
const fieldParts = fieldName.split('.');
const field = fieldsStore.getField(currentCollection, fieldName);
const { primaryKeyField } = useCollection(field.collection);
const includeField = fieldParts.slice(0, -1).concat(primaryKeyField.value.field).join('.');
if (!sanitizedFields.includes(includeField)) {
sanitizedFields.push(includeField);
}
}
return sanitizedFields;
}