fix: #1204
This commit is contained in:
@@ -70,7 +70,7 @@ async function find<T extends TypeWithID = any>(incomingArgs: Arguments): Promis
|
||||
// Access
|
||||
// /////////////////////////////////////
|
||||
|
||||
const queryToBuild: { where?: Where} = {
|
||||
const queryToBuild: { where?: Where } = {
|
||||
where: {
|
||||
and: [],
|
||||
},
|
||||
@@ -128,7 +128,13 @@ async function find<T extends TypeWithID = any>(incomingArgs: Arguments): Promis
|
||||
// Find
|
||||
// /////////////////////////////////////
|
||||
|
||||
const [sortProperty, sortOrder] = buildSortParam(args.sort, collectionConfig.timestamps);
|
||||
const [sortProperty, sortOrder] = buildSortParam({
|
||||
sort: args.sort,
|
||||
config: payload.config,
|
||||
fields: collectionConfig.fields,
|
||||
timestamps: collectionConfig.timestamps,
|
||||
locale,
|
||||
});
|
||||
|
||||
const optionsToExecute = {
|
||||
page: page || 1,
|
||||
|
||||
@@ -9,6 +9,7 @@ import { buildSortParam } from '../../mongoose/buildSortParam';
|
||||
import { PaginatedDocs } from '../../mongoose/types';
|
||||
import { TypeWithVersion } from '../../versions/types';
|
||||
import { afterRead } from '../../fields/hooks/afterRead';
|
||||
import { buildVersionCollectionFields } from '../../versions/buildCollectionFields';
|
||||
|
||||
export type Arguments = {
|
||||
collection: Collection
|
||||
@@ -46,7 +47,7 @@ async function findVersions<T extends TypeWithVersion<T> = any>(args: Arguments)
|
||||
// Access
|
||||
// /////////////////////////////////////
|
||||
|
||||
const queryToBuild: { where?: Where} = {};
|
||||
const queryToBuild: { where?: Where } = {};
|
||||
let useEstimatedCount = false;
|
||||
|
||||
if (where) {
|
||||
@@ -89,7 +90,13 @@ async function findVersions<T extends TypeWithVersion<T> = any>(args: Arguments)
|
||||
// Find
|
||||
// /////////////////////////////////////
|
||||
|
||||
const [sortProperty, sortOrder] = buildSortParam(args.sort || '-updatedAt', true);
|
||||
const [sortProperty, sortOrder] = buildSortParam({
|
||||
sort: args.sort || '-updatedAt',
|
||||
fields: buildVersionCollectionFields(collectionConfig),
|
||||
timestamps: true,
|
||||
config: payload.config,
|
||||
locale,
|
||||
});
|
||||
|
||||
const optionsToExecute = {
|
||||
page: page || 1,
|
||||
|
||||
@@ -9,6 +9,7 @@ import { buildSortParam } from '../../mongoose/buildSortParam';
|
||||
import { TypeWithVersion } from '../../versions/types';
|
||||
import { SanitizedGlobalConfig } from '../config/types';
|
||||
import { afterRead } from '../../fields/hooks/afterRead';
|
||||
import { buildVersionGlobalFields } from '../../versions/buildGlobalFields';
|
||||
|
||||
export type Arguments = {
|
||||
globalConfig: SanitizedGlobalConfig
|
||||
@@ -44,7 +45,7 @@ async function findVersions<T extends TypeWithVersion<T> = any>(args: Arguments)
|
||||
// Access
|
||||
// /////////////////////////////////////
|
||||
|
||||
const queryToBuild: { where?: Where} = {};
|
||||
const queryToBuild: { where?: Where } = {};
|
||||
let useEstimatedCount = false;
|
||||
|
||||
if (where) {
|
||||
@@ -87,7 +88,13 @@ async function findVersions<T extends TypeWithVersion<T> = any>(args: Arguments)
|
||||
// Find
|
||||
// /////////////////////////////////////
|
||||
|
||||
const [sortProperty, sortOrder] = buildSortParam(args.sort || '-updatedAt', true);
|
||||
const [sortProperty, sortOrder] = buildSortParam({
|
||||
sort: args.sort || '-updatedAt',
|
||||
fields: buildVersionGlobalFields(globalConfig),
|
||||
timestamps: true,
|
||||
config: payload.config,
|
||||
locale,
|
||||
});
|
||||
|
||||
const optionsToExecute = {
|
||||
page: page || 1,
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
export const buildSortParam = (sort: string, timestamps: boolean) => {
|
||||
import { Config } from '../config/types';
|
||||
import { getLocalizedSortProperty } from './getLocalizedSortProperty';
|
||||
import { Field } from '../fields/config/types';
|
||||
|
||||
type Args = {
|
||||
sort: string
|
||||
config: Config
|
||||
fields: Field[]
|
||||
timestamps: boolean
|
||||
locale: string
|
||||
}
|
||||
|
||||
export const buildSortParam = ({ sort, config, fields, timestamps, locale }: Args): [string, string] => {
|
||||
let sortProperty: string;
|
||||
let sortOrder = 'desc';
|
||||
|
||||
@@ -15,7 +27,16 @@ export const buildSortParam = (sort: string, timestamps: boolean) => {
|
||||
sortOrder = 'asc';
|
||||
}
|
||||
|
||||
if (sortProperty === 'id') sortProperty = '_id';
|
||||
if (sortProperty === 'id') {
|
||||
sortProperty = '_id';
|
||||
} else {
|
||||
sortProperty = getLocalizedSortProperty({
|
||||
segments: sortProperty.split('.'),
|
||||
config,
|
||||
fields,
|
||||
locale,
|
||||
});
|
||||
}
|
||||
|
||||
return [sortProperty, sortOrder];
|
||||
};
|
||||
|
||||
182
src/mongoose/getLocalizedSortProperty.spec.ts
Normal file
182
src/mongoose/getLocalizedSortProperty.spec.ts
Normal file
@@ -0,0 +1,182 @@
|
||||
import { Config } from '../config/types';
|
||||
import { getLocalizedSortProperty } from './getLocalizedSortProperty';
|
||||
|
||||
const config = {
|
||||
localization: {
|
||||
locales: ['en', 'es'],
|
||||
},
|
||||
} as Config;
|
||||
|
||||
describe('get localized sort property', () => {
|
||||
it('passes through a non-localized sort property', () => {
|
||||
const result = getLocalizedSortProperty({
|
||||
segments: ['title'],
|
||||
config,
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
},
|
||||
],
|
||||
locale: 'en',
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual('title');
|
||||
});
|
||||
|
||||
it('properly localizes an un-localized sort property', () => {
|
||||
const result = getLocalizedSortProperty({
|
||||
segments: ['title'],
|
||||
config,
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
],
|
||||
locale: 'en',
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual('title.en');
|
||||
});
|
||||
|
||||
it('keeps specifically asked-for localized sort properties', () => {
|
||||
const result = getLocalizedSortProperty({
|
||||
segments: ['title', 'es'],
|
||||
config,
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
],
|
||||
locale: 'en',
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual('title.es');
|
||||
});
|
||||
|
||||
it('properly localizes nested sort properties', () => {
|
||||
const result = getLocalizedSortProperty({
|
||||
segments: ['group', 'title'],
|
||||
config,
|
||||
fields: [
|
||||
{
|
||||
name: 'group',
|
||||
type: 'group',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
locale: 'en',
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual('group.title.en');
|
||||
});
|
||||
|
||||
it('keeps requested locale with nested sort properties', () => {
|
||||
const result = getLocalizedSortProperty({
|
||||
segments: ['group', 'title', 'es'],
|
||||
config,
|
||||
fields: [
|
||||
{
|
||||
name: 'group',
|
||||
type: 'group',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
locale: 'en',
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual('group.title.es');
|
||||
});
|
||||
|
||||
it('properly localizes field within row', () => {
|
||||
const result = getLocalizedSortProperty({
|
||||
segments: ['title'],
|
||||
config,
|
||||
fields: [
|
||||
{
|
||||
type: 'row',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
locale: 'en',
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual('title.en');
|
||||
});
|
||||
|
||||
it('properly localizes field within named tab', () => {
|
||||
const result = getLocalizedSortProperty({
|
||||
segments: ['tab', 'title'],
|
||||
config,
|
||||
fields: [
|
||||
{
|
||||
type: 'tabs',
|
||||
tabs: [
|
||||
{
|
||||
name: 'tab',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
locale: 'en',
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual('tab.title.en');
|
||||
});
|
||||
|
||||
it('properly localizes field within unnamed tab', () => {
|
||||
const result = getLocalizedSortProperty({
|
||||
segments: ['title'],
|
||||
config,
|
||||
fields: [
|
||||
{
|
||||
type: 'tabs',
|
||||
tabs: [
|
||||
{
|
||||
label: 'Tab',
|
||||
fields: [
|
||||
{
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
locale: 'en',
|
||||
});
|
||||
|
||||
expect(result).toStrictEqual('title.en');
|
||||
});
|
||||
});
|
||||
89
src/mongoose/getLocalizedSortProperty.ts
Normal file
89
src/mongoose/getLocalizedSortProperty.ts
Normal file
@@ -0,0 +1,89 @@
|
||||
import { Config } from '../config/types';
|
||||
import { Field, fieldAffectsData, fieldIsPresentationalOnly } from '../fields/config/types';
|
||||
import flattenTopLevelFields from '../utilities/flattenTopLevelFields';
|
||||
|
||||
type Args = {
|
||||
segments: string[]
|
||||
config: Config
|
||||
fields: Field[]
|
||||
locale: string
|
||||
result?: string
|
||||
}
|
||||
|
||||
export const getLocalizedSortProperty = ({
|
||||
segments: incomingSegments,
|
||||
config,
|
||||
fields: incomingFields,
|
||||
locale,
|
||||
result: incomingResult,
|
||||
}: Args): string => {
|
||||
// If localization is not enabled, accept exactly
|
||||
// what is sent in
|
||||
if (!config.localization) {
|
||||
return incomingSegments.join('.');
|
||||
}
|
||||
|
||||
// Flatten incoming fields (row, etc)
|
||||
const fields = flattenTopLevelFields(incomingFields);
|
||||
|
||||
const segments = [...incomingSegments];
|
||||
|
||||
// Retrieve first segment, and remove from segments
|
||||
const firstSegment = segments.shift();
|
||||
|
||||
// Attempt to find a matched field
|
||||
const matchedField = fields.find((field) => fieldAffectsData(field) && field.name === firstSegment);
|
||||
|
||||
if (matchedField && !fieldIsPresentationalOnly(matchedField)) {
|
||||
let nextFields: Field[];
|
||||
const remainingSegments = [...segments];
|
||||
let localizedSegment = matchedField.name;
|
||||
|
||||
if (matchedField.localized) {
|
||||
// Check to see if next segment is a locale
|
||||
if (segments.length > 0) {
|
||||
const nextSegmentIsLocale = config.localization.locales.includes(remainingSegments[0]);
|
||||
|
||||
// If next segment is locale, remove it from remaining segments
|
||||
// and use it to localize the current segment
|
||||
if (nextSegmentIsLocale) {
|
||||
const nextSegment = remainingSegments.shift();
|
||||
localizedSegment = `${matchedField.name}.${nextSegment}`;
|
||||
}
|
||||
} else {
|
||||
// If no more segments, but field is localized, use default locale
|
||||
localizedSegment = `${matchedField.name}.${locale}`;
|
||||
}
|
||||
}
|
||||
|
||||
// If there are subfields, pass them through
|
||||
if (matchedField.type === 'tab' || matchedField.type === 'group' || matchedField.type === 'array') {
|
||||
nextFields = matchedField.fields;
|
||||
}
|
||||
|
||||
if (matchedField.type === 'blocks') {
|
||||
nextFields = matchedField.blocks.reduce((flattenedBlockFields, block) => {
|
||||
return [
|
||||
...flattenedBlockFields,
|
||||
...block.fields.filter((blockField) => (fieldAffectsData(blockField) && (blockField.name !== 'blockType' && blockField.name !== 'blockName')) || !fieldAffectsData(blockField)),
|
||||
];
|
||||
}, []);
|
||||
}
|
||||
|
||||
const result = incomingResult ? `${incomingResult}.${localizedSegment}` : localizedSegment;
|
||||
|
||||
if (nextFields) {
|
||||
return getLocalizedSortProperty({
|
||||
segments: remainingSegments,
|
||||
config,
|
||||
fields: nextFields,
|
||||
locale,
|
||||
result,
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
return incomingSegments.join('.');
|
||||
};
|
||||
@@ -30,7 +30,7 @@ const flattenFields = (fields: Field[], keepPresentationalFields?: boolean): (Fi
|
||||
...field.tabs.reduce((tabFields, tab) => {
|
||||
return [
|
||||
...tabFields,
|
||||
...(tabHasName(tab) ? [tab] : flattenFields(tab.fields, keepPresentationalFields)),
|
||||
...(tabHasName(tab) ? [{ ...tab, type: 'tab' }] : flattenFields(tab.fields, keepPresentationalFields)),
|
||||
];
|
||||
}, []),
|
||||
];
|
||||
|
||||
@@ -56,6 +56,7 @@ export default buildConfig({
|
||||
name: 'title',
|
||||
type: 'text',
|
||||
localized: true,
|
||||
index: true,
|
||||
},
|
||||
{
|
||||
name: 'description',
|
||||
|
||||
Reference in New Issue
Block a user