Feat: Allow using subfields as identifier field (#3219)
This commit is contained in:
@ -6,6 +6,8 @@ import collections, {
|
||||
selectEntrySlug,
|
||||
selectFieldsMediaFolders,
|
||||
selectMediaFolders,
|
||||
getFieldsNames,
|
||||
selectField,
|
||||
} from '../collections';
|
||||
import { FILES, FOLDER } from 'Constants/collectionTypes';
|
||||
|
||||
@ -237,4 +239,70 @@ describe('collections', () => {
|
||||
).toEqual(['file_media_folder', 'image_media_folder']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('getFieldsNames', () => {
|
||||
it('should get flat fields names', () => {
|
||||
const collection = fromJS({
|
||||
fields: [{ name: 'en' }, { name: 'es' }],
|
||||
});
|
||||
expect(getFieldsNames(collection.get('fields').toArray())).toEqual(['en', 'es']);
|
||||
});
|
||||
|
||||
it('should get nested fields names', () => {
|
||||
const collection = fromJS({
|
||||
fields: [
|
||||
{ name: 'en', fields: [{ name: 'title' }, { name: 'body' }] },
|
||||
{ name: 'es', fields: [{ name: 'title' }, { name: 'body' }] },
|
||||
{ name: 'it', field: { name: 'title', fields: [{ name: 'subTitle' }] } },
|
||||
],
|
||||
});
|
||||
expect(getFieldsNames(collection.get('fields').toArray())).toEqual([
|
||||
'en',
|
||||
'es',
|
||||
'it',
|
||||
'en.title',
|
||||
'en.body',
|
||||
'es.title',
|
||||
'es.body',
|
||||
'it.title',
|
||||
'it.title.subTitle',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('selectField', () => {
|
||||
it('should return top field by key', () => {
|
||||
const collection = fromJS({
|
||||
fields: [{ name: 'en' }, { name: 'es' }],
|
||||
});
|
||||
expect(selectField(collection, 'en')).toBe(collection.get('fields').get(0));
|
||||
});
|
||||
|
||||
it('should return nested field by key', () => {
|
||||
const collection = fromJS({
|
||||
fields: [
|
||||
{ name: 'en', fields: [{ name: 'title' }, { name: 'body' }] },
|
||||
{ name: 'es', fields: [{ name: 'title' }, { name: 'body' }] },
|
||||
{ name: 'it', field: { name: 'title', fields: [{ name: 'subTitle' }] } },
|
||||
],
|
||||
});
|
||||
|
||||
expect(selectField(collection, 'en.title')).toBe(
|
||||
collection
|
||||
.get('fields')
|
||||
.get(0)
|
||||
.get('fields')
|
||||
.get(0),
|
||||
);
|
||||
|
||||
expect(selectField(collection, 'it.title.subTitle')).toBe(
|
||||
collection
|
||||
.get('fields')
|
||||
.get(2)
|
||||
.get('field')
|
||||
.get('fields')
|
||||
.get(0),
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -14,6 +14,7 @@ import {
|
||||
EntryMap,
|
||||
} from '../types/redux';
|
||||
import { selectMediaFolder } from './entries';
|
||||
import { keyToPathArray } from '../lib/stringTemplate';
|
||||
|
||||
const collections = (state = null, action: CollectionsAction) => {
|
||||
switch (action.type) {
|
||||
@ -186,10 +187,46 @@ export const selectAllowDeletion = (collection: Collection) =>
|
||||
selectors[collection.get('type')].allowDeletion(collection);
|
||||
export const selectTemplateName = (collection: Collection, slug: string) =>
|
||||
selectors[collection.get('type')].templateName(collection, slug);
|
||||
|
||||
export const getFieldsNames = (fields: EntryField[], prefix = '') => {
|
||||
let names = fields.map(f => `${prefix}${f.get('name')}`);
|
||||
|
||||
fields.forEach((f, index) => {
|
||||
if (f.has('fields')) {
|
||||
const fields = f.get('fields')?.toArray() as EntryField[];
|
||||
names = [...names, ...getFieldsNames(fields, `${names[index]}.`)];
|
||||
}
|
||||
if (f.has('field')) {
|
||||
const field = f.get('field') as EntryField;
|
||||
names = [...names, ...getFieldsNames([field], `${names[index]}.`)];
|
||||
}
|
||||
});
|
||||
|
||||
return names;
|
||||
};
|
||||
|
||||
export const selectField = (collection: Collection, key: string) => {
|
||||
const array = keyToPathArray(key);
|
||||
let name: string | undefined;
|
||||
let field;
|
||||
let fields = collection.get('fields', List<EntryField>()).toArray();
|
||||
while ((name = array.shift()) && fields) {
|
||||
field = fields.find(f => f.get('name') === name);
|
||||
if (field?.has('fields')) {
|
||||
fields = field?.get('fields')?.toArray() as EntryField[];
|
||||
}
|
||||
if (field?.has('field')) {
|
||||
fields = [field?.get('field') as EntryField];
|
||||
}
|
||||
}
|
||||
|
||||
return field;
|
||||
};
|
||||
|
||||
export const selectIdentifier = (collection: Collection) => {
|
||||
const identifier = collection.get('identifier_field');
|
||||
const identifierFields = identifier ? [identifier, ...IDENTIFIER_FIELDS] : IDENTIFIER_FIELDS;
|
||||
const fieldNames = collection.get('fields', List<EntryField>()).map(field => field?.get('name'));
|
||||
const fieldNames = getFieldsNames(collection.get('fields', List<EntryField>()).toArray());
|
||||
return identifierFields.find(id =>
|
||||
fieldNames.find(name => name?.toLowerCase().trim() === id.toLowerCase().trim()),
|
||||
);
|
||||
|
Reference in New Issue
Block a user