mirror of
https://github.com/directus/directus.git
synced 2026-01-23 08:38:06 -05:00
Assign sort number when creating field(s) (#18877)
Co-authored-by: Jan Arends <jan.arends@mailbox.org> Co-authored-by: Rijk van Zanten <rijkvanzanten@me.com> Co-authored-by: Pascal Jufer <pascal-jufer@bluewin.ch>
This commit is contained in:
5
.changeset/dull-kings-marry.md
Normal file
5
.changeset/dull-kings-marry.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@directus/api': patch
|
||||
---
|
||||
|
||||
Implemented sort number for fields in collections on creation to ensure order is always retained
|
||||
@@ -4,7 +4,7 @@ import type { Accountability, FieldMeta, RawField, SchemaOverview } from '@direc
|
||||
import { addFieldFlag } from '@directus/utils';
|
||||
import type Keyv from 'keyv';
|
||||
import type { Knex } from 'knex';
|
||||
import { chunk, omit } from 'lodash-es';
|
||||
import { chunk, groupBy, merge, omit } from 'lodash-es';
|
||||
import { clearSystemCache, getCache } from '../cache.js';
|
||||
import { ALIAS_TYPES } from '../constants.js';
|
||||
import type { Helpers } from '../database/helpers/index.js';
|
||||
@@ -145,7 +145,30 @@ export class CollectionsService {
|
||||
|
||||
const fieldPayloads = payload.fields!.filter((field) => field.meta).map((field) => field.meta) as FieldMeta[];
|
||||
|
||||
await fieldItemsService.createMany(fieldPayloads, {
|
||||
// Sort new fields that does not have any group defined, in ascending order.
|
||||
// Lodash merge is used so that the "sort" can be overridden if defined.
|
||||
let sortedFieldPayloads = fieldPayloads
|
||||
.filter((field) => field?.group === undefined || field?.group === null)
|
||||
.map((field, index) => merge({ sort: index + 1 }, field));
|
||||
|
||||
// Sort remaining new fields with group defined, if any, in ascending order.
|
||||
// sortedFieldPayloads will be less than fieldPayloads if it filtered out any fields with group defined.
|
||||
if (sortedFieldPayloads.length < fieldPayloads.length) {
|
||||
const fieldsWithGroups = groupBy(
|
||||
fieldPayloads.filter((field) => field?.group),
|
||||
(field) => field?.group
|
||||
);
|
||||
|
||||
// The sort order is restarted from 1 for fields in each group and appended to sortedFieldPayloads.
|
||||
// Lodash merge is used so that the "sort" can be overridden if defined.
|
||||
for (const [_group, fields] of Object.entries(fieldsWithGroups)) {
|
||||
sortedFieldPayloads = sortedFieldPayloads.concat(
|
||||
fields.map((field, index) => merge({ sort: index + 1 }, field))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
await fieldItemsService.createMany(sortedFieldPayloads, {
|
||||
bypassEmitAction: (params) =>
|
||||
opts?.bypassEmitAction ? opts.bypassEmitAction(params) : nestedActionEvents.push(params),
|
||||
bypassLimits: true,
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { Accountability, Field, FieldMeta, RawField, SchemaOverview, Type }
|
||||
import { addFieldFlag, toArray } from '@directus/utils';
|
||||
import type Keyv from 'keyv';
|
||||
import type { Knex } from 'knex';
|
||||
import { isEqual, isNil } from 'lodash-es';
|
||||
import { isEqual, isNil, merge } from 'lodash-es';
|
||||
import { clearSystemCache, getCache } from '../cache.js';
|
||||
import { ALIAS_TYPES } from '../constants.js';
|
||||
import { translateDatabaseError } from '../database/errors/translate.js';
|
||||
@@ -308,9 +308,17 @@ export class FieldsService {
|
||||
}
|
||||
|
||||
if (hookAdjustedField.meta) {
|
||||
const existingSortRecord: Record<'max', number | null> | undefined = await trx
|
||||
.from('directus_fields')
|
||||
.where(hookAdjustedField.meta?.group ? { collection, group: hookAdjustedField.meta.group } : { collection })
|
||||
.max('sort', { as: 'max' })
|
||||
.first();
|
||||
|
||||
const newSortValue: number = existingSortRecord?.max ? existingSortRecord.max + 1 : 1;
|
||||
|
||||
await itemsService.createOne(
|
||||
{
|
||||
...hookAdjustedField.meta,
|
||||
...merge({ sort: newSortValue }, hookAdjustedField.meta),
|
||||
collection: collection,
|
||||
field: hookAdjustedField.field,
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user