fix: relation widget performance (#3975)

This commit is contained in:
Erez Rokah
2020-07-06 14:05:01 +03:00
committed by GitHub
parent 126b86cdc4
commit c7e0fe8492
9 changed files with 566 additions and 166 deletions

View File

@ -18,6 +18,7 @@
},
"peerDependencies": {
"immutable": "^3.7.6",
"lodash": "^4.17.11",
"moment": "^2.24.0"
}
}

View File

@ -4,6 +4,7 @@ import {
compileStringTemplate,
parseDateFromEntry,
extractTemplateVars,
expandPath,
} from '../stringTemplate';
describe('stringTemplate', () => {
describe('keyToPathArray', () => {
@ -107,4 +108,66 @@ describe('stringTemplate', () => {
).toBe('SLUG');
});
});
describe('expandPath', () => {
it('should expand wildcard paths', () => {
const data = {
categories: [
{
name: 'category 1',
},
{
name: 'category 2',
},
],
};
expect(expandPath({ data, path: 'categories.*.name' })).toEqual([
'categories.0.name',
'categories.1.name',
]);
});
it('should handle wildcard at the end of the path', () => {
const data = {
nested: {
otherNested: {
list: [
{
title: 'title 1',
nestedList: [{ description: 'description 1' }, { description: 'description 2' }],
},
{
title: 'title 2',
nestedList: [{ description: 'description 2' }, { description: 'description 2' }],
},
],
},
},
};
expect(expandPath({ data, path: 'nested.otherNested.list.*.nestedList.*' })).toEqual([
'nested.otherNested.list.0.nestedList.0',
'nested.otherNested.list.0.nestedList.1',
'nested.otherNested.list.1.nestedList.0',
'nested.otherNested.list.1.nestedList.1',
]);
});
it('should handle non wildcard index', () => {
const data = {
categories: [
{
name: 'category 1',
},
{
name: 'category 2',
},
],
};
const path = 'categories.0.name';
expect(expandPath({ data, path })).toEqual(['categories.0.name']);
});
});
});

View File

@ -1,6 +1,7 @@
import moment from 'moment';
import { Map } from 'immutable';
import { basename, extname } from 'path';
import { get, trimEnd } from 'lodash';
const FIELD_PREFIX = 'fields.';
const templateContentPattern = '[^}{]+';
@ -60,6 +61,41 @@ export const keyToPathArray = (key?: string) => {
return parts;
};
export const expandPath = ({
data,
path,
paths = [],
}: {
data: Record<string, unknown>;
path: string;
paths?: string[];
}) => {
if (path.endsWith('.*')) {
path = path + '.';
}
const sep = '.*.';
const parts = path.split(sep);
if (parts.length === 1) {
paths.push(path);
} else {
const partialPath = parts[0];
const value = get(data, partialPath);
if (Array.isArray(value)) {
value.forEach((_, index) => {
expandPath({
data,
path: trimEnd(`${partialPath}.${index}.${parts.slice(1).join(sep)}`, '.'),
paths,
});
});
}
}
return paths;
};
// Allow `fields.` prefix in placeholder to override built in replacements
// like "slug" and "year" with values from fields of the same name.
function getExplicitFieldReplacement(key: string, data: Map<string, unknown>) {