Skip to content

Instantly share code, notes, and snippets.

@Jamiewarb
Last active January 3, 2024 13:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jamiewarb/f49ad4945aa14d1c3023c20e9a987c9c to your computer and use it in GitHub Desktop.
Save Jamiewarb/f49ad4945aa14d1c3023c20e9a987c9c to your computer and use it in GitHub Desktop.
Pages setup
import type { SanityDocument } from 'sanity';
import type { ListItemBuilder } from 'sanity/desk';
import { AddIcon, WarningFilledIcon } from '@sanity/icons';
import { map } from 'rxjs/operators';
import { defineRegionStructure } from '~/utils/defineStructure';
import { regionalDocumentTypeList } from '~/utils/regionalDocumentListItem';
import { options } from '~/config/options';
import { TEMPLATES } from '~/constants/templates';
import { INTENT } from '~/constants/sanity/intent';
// Usually imported from elsewhere to avoid magic strings for these special strings
enum DOCUMENT { PAGES = 'pages' };
const PARENT_FIELD = 'parent';
const LOCALISE_LANGUAGE_FIELD_NAME = 'language';
export default defineRegionStructure<ListItemBuilder>((S, regionContext) => {
const { schema, locale } = regionContext;
const filter = `_type == "${DOCUMENT.PAGES}" && !defined(${PARENT_FIELD}) && !(_id in path("drafts.**")) && ${LOCALISE_LANGUAGE_FIELD_NAME} == "${regionContext.locale.code}"`;
const query = `*[${filter}]{ _id, title }`;
const opts = { apiVersion: options.apiVersion };
return S.listItem()
.title(schema?.get(DOCUMENT.PAGES)?.title || 'Desk Error: Unnamed')
.icon(schema?.get(DOCUMENT.PAGES)?.icon || WarningFilledIcon)
.child(
regionContext.documentStore.listenQuery(query, {}, opts).pipe(
map((parents) =>
S.list()
.title('Pages')
.menuItems([
S.menuItem()
.title('Add')
.icon(AddIcon)
.intent({ type: INTENT.CREATE, params: [
{ type: DOCUMENT.PAGES, template: `${DOCUMENT.PAGES}-${TEMPLATES.IN_REGION}` },
{ locale: locale.code }
] }),
])
.items([
S.listItem()
.title('All Pages')
.icon(schema?.get(DOCUMENT.PAGES)?.icon || WarningFilledIcon)
.child(
regionalDocumentTypeList(DOCUMENT.PAGES, S, regionContext)
.title('All Pages')
// Use this list for displaying from search results
.canHandleIntent(
(intentName, params) =>
intentName === INTENT.EDIT && params.type === `${DOCUMENT.PAGES}-${TEMPLATES.IN_REGION}`
)
),
S.divider(),
S.listItem()
.title('Top-level Pages')
.icon(schema?.get(DOCUMENT.PAGES)?.icon || WarningFilledIcon)
.child(
regionalDocumentTypeList(DOCUMENT.PAGES, S, regionContext, {
filter: `!defined(${PARENT_FIELD})`
})
.title('Top-level Pages')
// Use this list for creating from parents menu
.canHandleIntent(
(intentName, params) =>
intentName === INTENT.CREATE && params.template === `${DOCUMENT.PAGES}-${TEMPLATES.IN_REGION}`
)
),
S.divider(),
...parents.map((parent: SanityDocument) => {
const title = parent.title as string;
return S.listItem({
id: parent._id,
title: title || 'Page',
schemaType: DOCUMENT.PAGES,
child: () =>
regionalDocumentTypeList(DOCUMENT.PAGES, S, regionContext)
.title(title)
.filter(`_type == $schemaType && (_id == $parentId || ${PARENT_FIELD}._ref == $parentId || ${PARENT_FIELD}->${PARENT_FIELD}._ref == $parentId || ${PARENT_FIELD}->${PARENT_FIELD}->${PARENT_FIELD}._ref == $parentId)`)
.params({ schemaType: DOCUMENT.PAGES, parentId: parent._id })
// Use this list for creating from child menu
.canHandleIntent(
(intentName, params) =>
intentName === INTENT.CREATE && params.template === `${DOCUMENT.PAGES}-${TEMPLATES.IN_REGION_CHILD}`
)
.initialValueTemplates([
S.initialValueTemplateItem(`${DOCUMENT.PAGES}-${TEMPLATES.IN_REGION_CHILD}`, {
parentId: parent._id,
}),
]),
});
})
])
)
)
);
});
import { defineField, defineType } from 'sanity';
import { DocumentsIcon } from '@sanity/icons';
// Usually imported from elsewhere to avoid magic strings for these special strings
enum DOCUMENT { PAGES = 'pages' };
const PARENT_FIELD = 'parent';
const LOCALISE_LANGUAGE_FIELD_NAME = 'language';
export default defineType({
name: DOCUMENT.PAGES,
title: 'Pages',
type: 'document',
icon: DocumentsIcon,
groups: [
{
title: 'Meta',
name: 'meta',
},
{
title: 'Content',
name: 'content',
},
{
title: 'SEO',
name: 'seo',
},
],
fields: [
// Other fields, e.g. slug, title, seo, metadata
defineField({
name: PARENT_FIELD,
type: 'reference',
description: 'If this page is a child of another page. Child pages are prefixed with their parent page\'s URL, e.g. /about-us/child-page',
to: [{ type: DOCUMENT.PAGES }],
options: {
filter: ({ document }) => ({
filter: `${LOCALISE_LANGUAGE_FIELD_NAME} == $language && _id != $id`,
params: { id: document._id, language: document[LOCALISE_LANGUAGE_FIELD_NAME] }
}),
},
}),
],
})
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment