sanity-plugin-dashboard-widget-document-list
Version:
1 lines • 11.9 kB
Source Map (JSON)
{"version":3,"file":"index.cjs","sources":["../src/sanityConnector.ts","../src/DocumentList.tsx","../src/plugin.tsx"],"sourcesContent":["import type {SanityClient} from '@sanity/client'\nimport uniqBy from 'lodash/uniqBy'\nimport {type Observable, of as observableOf} from 'rxjs'\nimport {delay, mergeMap, switchMap, tap} from 'rxjs/operators'\nimport type {SanityDocument} from 'sanity'\n\nconst draftId = (nonDraftDoc: SanityDocument) => `drafts.${nonDraftDoc._id}`\n\nfunction prepareDocumentList(\n incoming: SanityDocument | SanityDocument[],\n client: SanityClient,\n): Promise<SanityDocument[]> {\n if (!incoming) {\n return Promise.resolve([])\n }\n const documents = Array.isArray(incoming) ? incoming : [incoming]\n\n const ids = documents.filter((doc) => !doc._id.startsWith('drafts.')).map(draftId)\n\n return client\n .fetch<SanityDocument[]>('*[_id in $ids]', {ids})\n .then((drafts) => {\n const outgoing = documents.map((doc) => {\n const foundDraft = drafts.find((draft) => draft._id === draftId(doc))\n return foundDraft || doc\n })\n return uniqBy(outgoing, '_id')\n })\n .catch((error) => {\n throw new Error(`Problems fetching docs ${ids}. Error: ${error.message}`)\n })\n}\n\nexport function getSubscription(\n query: string,\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n params: Record<string, any>,\n client: SanityClient,\n): Observable<SanityDocument[]> {\n return client\n .listen(query, params, {\n events: ['welcome', 'mutation'],\n includeResult: false,\n visibility: 'query',\n })\n .pipe(\n switchMap((event) => {\n return observableOf(1).pipe(\n event.type === 'welcome' ? tap() : delay(1000),\n mergeMap(() =>\n client\n .fetch(query, params)\n .then((incoming) => {\n return prepareDocumentList(incoming, client)\n })\n .catch((error) => {\n if (error.message.startsWith('Problems fetching docs')) {\n throw error\n }\n throw new Error(\n `Query failed ${query} and ${JSON.stringify(params)}. Error: ${error.message}`,\n )\n }),\n ),\n )\n }),\n )\n}\n","import {DashboardWidgetContainer} from '@sanity/dashboard'\nimport {Card, Flex, Spinner, Stack} from '@sanity/ui'\nimport {intersection} from 'lodash'\nimport {type ReactNode, useEffect, useMemo, useState} from 'react'\nimport {\n getPublishedId,\n IntentButton,\n Preview,\n type SanityDocument,\n useClient,\n useSchema,\n} from 'sanity'\n\nimport {getSubscription} from './sanityConnector'\n\nexport interface DocumentListConfig {\n title?: string\n types?: string[]\n query?: string\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n queryParams?: Record<string, any>\n order?: string\n limit?: number\n showCreateButton?: boolean\n createButtonText?: string\n apiVersion?: string\n}\n\nconst defaultProps = {\n title: 'Last created',\n order: '_createdAt desc',\n limit: 10,\n queryParams: {},\n showCreateButton: true,\n apiVersion: 'v1',\n}\n\nexport function DocumentList(props: DocumentListConfig): ReactNode {\n const {\n query,\n limit,\n apiVersion,\n queryParams,\n types,\n order,\n title,\n showCreateButton,\n createButtonText,\n } = {\n ...defaultProps,\n ...props,\n }\n\n const [documents, setDocuments] = useState<SanityDocument[] | undefined>()\n const [loading, setLoading] = useState<boolean>(true)\n const [error, setError] = useState<Error | undefined>()\n\n const versionedClient = useClient({apiVersion})\n const schema = useSchema()\n\n const {assembledQuery, params} = useMemo(() => {\n if (query) {\n return {assembledQuery: query, params: queryParams}\n }\n\n const documentTypes = schema.getTypeNames().filter((typeName) => {\n const schemaType = schema.get(typeName)\n return schemaType?.type?.name === 'document'\n })\n\n return {\n assembledQuery: `*[_type in $types] | order(${order}) [0...${limit * 2}]`,\n params: {types: types ? intersection(types, documentTypes) : documentTypes},\n }\n }, [schema, query, queryParams, order, limit, types])\n\n useEffect(() => {\n if (!assembledQuery) {\n return\n }\n\n const subscription = getSubscription(assembledQuery, params, versionedClient).subscribe({\n next: (d) => {\n setDocuments(d.slice(0, limit))\n setLoading(false)\n },\n error: (e) => {\n setError(e)\n setLoading(false)\n },\n })\n // eslint-disable-next-line consistent-return\n return () => {\n subscription.unsubscribe()\n }\n }, [limit, versionedClient, assembledQuery, params])\n\n return (\n <DashboardWidgetContainer\n header={title}\n footer={\n types &&\n types.length === 1 &&\n showCreateButton && (\n <IntentButton\n mode=\"bleed\"\n style={{width: '100%'}}\n // paddingX={2}\n paddingY={4}\n tone=\"primary\"\n type=\"button\"\n intent=\"create\"\n params={{type: types[0]}}\n text={createButtonText || `Create new ${types[0]}`}\n />\n )\n }\n >\n <Card>\n {error && <div>{error.message}</div>}\n {!error && loading && (\n <Card padding={4}>\n <Flex justify=\"center\">\n <Spinner muted />\n </Flex>\n </Card>\n )}\n {!error && !documents && !loading && <div>Could not locate any documents :/</div>}\n <Stack space={2}>\n {documents && documents.map((doc) => <MenuEntry key={doc._id} doc={doc} />)}\n </Stack>\n </Card>\n </DashboardWidgetContainer>\n )\n}\n\nfunction MenuEntry({doc}: {doc: SanityDocument}) {\n const schema = useSchema()\n const type = schema.get(doc._type)\n return (\n <Card flex={1}>\n <IntentButton\n intent=\"edit\"\n mode=\"bleed\"\n tooltipProps={{}}\n // padding={1}\n // radius={0}\n params={{\n type: doc._type,\n id: getPublishedId(doc._id),\n }}\n style={{width: '100%'}}\n >\n {type ? (\n <Preview layout=\"default\" schemaType={type} value={doc} key={doc._id} />\n ) : (\n 'Schema-type missing'\n )}\n </IntentButton>\n </Card>\n )\n}\n\nexport default DocumentList\n","import type {DashboardWidget, LayoutConfig} from '@sanity/dashboard'\n\nimport DocumentList, {type DocumentListConfig} from './DocumentList'\n\nexport interface DocumentListWidgetConfig extends DocumentListConfig {\n layout?: LayoutConfig\n}\n\nexport function documentListWidget(config: DocumentListWidgetConfig): DashboardWidget {\n return {\n name: 'document-list-widget',\n component: function component() {\n return <DocumentList {...config} />\n },\n layout: config.layout,\n }\n}\n"],"names":["Object","defineProperty","exports","value","jsxRuntime","require","dashboard","ui","intersection","react","sanity","uniqBy","rxjs","operators","_interopDefaultCompat","e","default","intersection__default","uniqBy__default","draftId","nonDraftDoc","_id","getSubscription","query","params","client","listen","events","includeResult","visibility","pipe","switchMap","event","observableOf","type","tap","delay","mergeMap","fetch","then","incoming","Promise","resolve","documents","Array","isArray","ids","filter","doc","startsWith","map","drafts","outgoing","find","draft","catch","error","Error","message","prepareDocumentList","JSON","stringify","defaultProps","title","order","limit","queryParams","showCreateButton","apiVersion","DocumentList","props","types","createButtonText","setDocuments","useState","loading","setLoading","setError","versionedClient","useClient","schema","useSchema","assembledQuery","useMemo","documentTypes","getTypeNames","typeName","_a","schemaType","get","name","useEffect","subscription","subscribe","next","d","slice","unsubscribe","jsx","DashboardWidgetContainer","header","footer","length","IntentButton","mode","style","width","paddingY","tone","intent","text","children","Card","padding","Flex","justify","Spinner","muted","Stack","space","MenuEntry","_type","flex","tooltipProps","id","getPublishedId","Preview","layout","documentListWidget","config","component"],"mappings":"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"}