Skip to content

Commit ae3b1c4

Browse files
authored
feat: allow custom collection sort (#714)
1 parent f091260 commit ae3b1c4

6 files changed

Lines changed: 45 additions & 7 deletions

File tree

.changeset/gentle-sorts-add.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@blinkk/root-cms': patch
3+
---
4+
5+
feat: add custom sort options to schema.collection()

docs/collections/Pages.schema.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ export default schema.collection({
1919
},
2020
},
2121
autolock: true,
22+
sortOptions: [
23+
{id: 'title', label: 'Title A-Z', field: 'fields.meta.title'},
24+
],
2225

2326
fields: [
2427
schema.object({

packages/root-cms/core/schema.test.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,3 +416,4 @@ test('define schema', () => {
416416
}
417417
`);
418418
});
419+

packages/root-cms/core/schema.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,6 +330,23 @@ export type Collection = Schema & {
330330
src: string;
331331
};
332332
};
333+
/**
334+
* Custom sort options available when listing documents in the CMS.
335+
*
336+
* NOTE: a new DB index may need to be created for the sort option. The first
337+
* time using the sort option, you will get an error that provides a link for
338+
* creating the index.
339+
*/
340+
sortOptions?: Array<{
341+
/** Unique identifier for the sort option. */
342+
id: string;
343+
/** Label displayed in the CMS UI. */
344+
label: string;
345+
/** DB field path to sort by, e.g. 'fields.meta.title'. */
346+
field: string;
347+
/** Sort direction. Defaults to ascending. */
348+
direction?: 'asc' | 'desc';
349+
}>;
333350
/**
334351
* Regular expression used to validate document slugs. Should be provided as a
335352
* string so it can be serialized to the CMS UI.

packages/root-cms/ui/hooks/useDocsList.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,15 @@ export function useDocsList(collectionId: string, options: {orderBy: string}) {
4141
dbQuery = query(dbCollection, queryOrderby(documentId()));
4242
} else if (orderBy === 'slugDesc') {
4343
dbQuery = query(dbCollection, queryOrderby(documentId(), 'desc'));
44+
} else {
45+
const col = window.__ROOT_CTX.collections[collectionId] as any;
46+
const custom = col?.sortOptions?.find((s: any) => s.id === orderBy);
47+
if (custom) {
48+
dbQuery =
49+
custom.direction === 'desc'
50+
? query(dbCollection, queryOrderby(custom.field, 'desc'))
51+
: query(dbCollection, queryOrderby(custom.field));
52+
}
4453
}
4554
await notifyErrors(async () => {
4655
const snapshot = await getDocs(dbQuery);

packages/root-cms/ui/pages/CollectionPage/CollectionPage.tsx

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,15 @@ CollectionPage.Collection = (props: CollectionProps) => {
153153
return <></>;
154154
}
155155

156+
const sortOptions = [
157+
{value: 'slug', label: 'A-Z'},
158+
{value: 'slugDesc', label: 'Z-A'},
159+
{value: 'newest', label: 'Newest'},
160+
{value: 'oldest', label: 'Oldest'},
161+
{value: 'modifiedAt', label: 'Last modified'},
162+
...(collection.sortOptions?.map((s: any) => ({value: s.id, label: s.label})) || []),
163+
];
164+
156165
const [loading, listDocs, docs] = useDocsList(props.collection, {orderBy});
157166

158167
return (
@@ -193,13 +202,7 @@ CollectionPage.Collection = (props: CollectionProps) => {
193202
onChange={(value: any) =>
194203
setOrderBy(value || 'modifiedAt')
195204
}
196-
data={[
197-
{value: 'slug', label: 'A-Z'},
198-
{value: 'slugDesc', label: 'Z-A'},
199-
{value: 'newest', label: 'Newest'},
200-
{value: 'oldest', label: 'Oldest'},
201-
{value: 'modifiedAt', label: 'Last modified'},
202-
]}
205+
data={sortOptions}
203206
/>
204207
</div>
205208
<div className="CollectionPage__collection__docsTab__controls__newDoc">

0 commit comments

Comments
 (0)