fix: search file collections using top level file fields (#3948)

This commit is contained in:
Erez Rokah 2020-06-25 17:41:32 +03:00 committed by GitHub
parent c95437790f
commit 5d710dbd69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 73 additions and 13 deletions

View File

@ -2,6 +2,7 @@ import { resolveBackend, Backend, extractSearchFields } from '../backend';
import registry from 'Lib/registry';
import { FOLDER } from 'Constants/collectionTypes';
import { Map, List, fromJS } from 'immutable';
import { FILES } from '../constants/collectionTypes';
jest.mock('Lib/registry');
jest.mock('netlify-cms-lib-util');
@ -555,6 +556,23 @@ describe('Backend', () => {
{ path: 'pages/not-me.md', slug: 'not-me', data: { title: 'not me' } },
];
const files = [
{
path: 'files/file1.md',
slug: 'file1',
data: {
author: 'find me by author',
},
},
{
path: 'files/file2.md',
slug: 'file2',
data: {
other: 'find me by other',
},
},
];
const implementation = {
init: jest.fn(() => implementation),
};
@ -570,6 +588,9 @@ describe('Backend', () => {
if (collection.get('name') === 'pages') {
return Promise.resolve(pages);
}
if (collection.get('name') === 'files') {
return Promise.resolve(files);
}
return Promise.resolve([]);
});
});
@ -609,6 +630,32 @@ describe('Backend', () => {
});
});
it('should search in file collection using top level fields', async () => {
const collections = [
fromJS({
name: 'files',
files: [
{
name: 'file1',
fields: [{ name: 'author', widget: 'string' }],
},
{
name: 'file2',
fields: [{ name: 'other', widget: 'string' }],
},
],
type: FILES,
}),
];
expect(await backend.search(collections, 'find me by author')).toEqual({
entries: [files[0]],
});
expect(await backend.search(collections, 'find me by other')).toEqual({
entries: [files[1]],
});
});
it('should query collections by title', async () => {
const results = await backend.query(collections[0], ['title'], 'find me by title');

View File

@ -36,6 +36,7 @@ import {
blobToFileObj,
asyncLock,
AsyncLock,
UnpublishedEntry,
} from 'netlify-cms-lib-util';
import { basename, join, extname, dirname } from 'path';
import { status } from './constants/publishModes';
@ -54,7 +55,6 @@ import {
import AssetProxy from './valueObjects/AssetProxy';
import { FOLDER, FILES } from './constants/collectionTypes';
import { selectCustomPath } from './reducers/entryDraft';
import { UnpublishedEntry } from 'netlify-cms-lib-util/src/implementation';
const { extractTemplateVars, dateParsers } = stringTemplate;
@ -446,20 +446,33 @@ export class Backend {
const summaryFields = extractTemplateVars(summary);
// TODO: pass search fields in as an argument
const searchFields = [
selectInferedField(collection, 'title'),
selectInferedField(collection, 'shortTitle'),
selectInferedField(collection, 'author'),
...summaryFields.map(elem => {
if (dateParsers[elem]) {
return selectInferedField(collection, 'date');
}
return elem;
}),
].filter(Boolean) as string[];
let searchFields: (string | null | undefined)[] = [];
if (collection.get('type') === FILES) {
collection.get('files')?.forEach(f => {
const topLevelFields = f!
.get('fields')
.map(f => f!.get('name'))
.toArray();
searchFields = [...searchFields, ...topLevelFields];
});
} else {
searchFields = [
selectInferedField(collection, 'title'),
selectInferedField(collection, 'shortTitle'),
selectInferedField(collection, 'author'),
...summaryFields.map(elem => {
if (dateParsers[elem]) {
return selectInferedField(collection, 'date');
}
return elem;
}),
];
}
const filteredSearchFields = searchFields.filter(Boolean) as string[];
const collectionEntries = await this.listAllEntries(collection);
return fuzzy.filter(searchTerm, collectionEntries, {
extract: extractSearchFields(uniq(searchFields)),
extract: extractSearchFields(uniq(filteredSearchFields)),
});
})
.map(p =>