sanity-plugin-dashboard-widget-document-list
3.0.193.0.20
~
Modified (2 files)
Index: package/package.json
===================================================================
--- package/package.json
+++ package/package.json
@@ -1,7 +1,7 @@
{
"name": "sanity-plugin-dashboard-widget-document-list",
- "version": "3.0.19",
+ "version": "3.0.20",
"description": "Dashboard widget for the Sanity Content Studio which displays a list of documents.",
"keywords": [
"dashboard",
"documents",
@@ -30,30 +30,30 @@
".": "./dist/index.js",
"./package.json": "./package.json"
},
"dependencies": {
- "@sanity/ui": "^4.0.4",
+ "@sanity/ui": "^4.2.7",
"lodash-es": "^4.18.1",
"rxjs": "^7.8.2"
},
"devDependencies": {
+ "@sanity/dashboard": "6.0.19",
"@sanity/tsconfig": "^2.2.1",
- "@sanity/tsdown-config": "^0.26.0",
+ "@sanity/tsdown-config": "^0.27.1",
"@types/lodash-es": "^4.17.12",
- "@types/react": "^19.2.18",
- "@types/react-dom": "^19.2.4",
- "oxc-transform-react": "^0.145.0",
- "react": "^19.2.8",
- "react-dom": "^19.2.8",
- "sanity": "^6.10.1",
- "tsdown": "^0.22.14",
- "@sanity/dashboard": "6.0.18"
+ "@types/react": "^19.3.0",
+ "@types/react-dom": "^19.3.0",
+ "oxc-transform-react": "^0.147.0",
+ "react": "^19.3.0",
+ "react-dom": "^19.3.0",
+ "sanity": "^6.16.0",
+ "tsdown": "^0.22.14"
},
"peerDependencies": {
+ "@sanity/dashboard": "^6.0.19",
"react": "^19.2",
"react-dom": "^19.2",
- "sanity": "^5 || ^6.0.0-0",
- "@sanity/dashboard": "^6.0.18"
+ "sanity": "^5 || ^6.0.0-0"
},
"engines": {
"node": ">=20.19 <22 || >=22.12"
}, Index: package/dist/index.js.map
===================================================================
--- package/dist/index.js.map
+++ package/dist/index.js.map
@@ -1,1 +1,1 @@
-{"version":3,"file":"index.js","names":["{\n ...defaultProps,\n ...props,\n }","{apiVersion}","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])","{assembledQuery: query, params: queryParams}","types ? intersection(types, documentTypes) : documentTypes","`*[_type in $types] | order(${order}) [0...${limit * 2}]`","(typeName) => {\n const schemaType = schema.get(typeName)\n return schemaType?.type?.name === 'document'\n }","{types: types ? intersection(types, documentTypes) : documentTypes}","{\n assembledQuery: `*[_type in $types] | order(${order}) [0...${limit * 2}]`,\n params: {types: types ? intersection(types, documentTypes) : documentTypes},\n }","() => {\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]","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 )","error && <div>{error.message}</div>","!error && loading && (\n <Card padding={4}>\n <Flex justify=\"center\">\n <Spinner muted />\n </Flex>\n </Card>\n )","!error && !documents && !loading && <div>Could not locate any documents :/</div>","documents && documents.map((doc) => <MenuEntry key={doc._id} doc={doc} />)","(doc) => <MenuEntry key={doc._id} doc={doc} />","<Stack gap={2}>\n {documents && documents.map((doc) => <MenuEntry key={doc._id} doc={doc} />)}\n </Stack>","<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 gap={2}>\n {documents && documents.map((doc) => <MenuEntry key={doc._id} doc={doc} />)}\n </Stack>\n </Card>","<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 gap={2}>\n {documents && documents.map((doc) => <MenuEntry key={doc._id} doc={doc} />)}\n </Stack>\n </Card>\n </DashboardWidgetContainer>","{doc}: {doc: SanityDocument}","schema.get(doc._type)","_type","{}","getPublishedId(doc._id)","_id","{\n type: doc._type,\n id: getPublishedId(doc._id),\n }","doc._type","{width: '100%'}","type ? (\n <Preview layout=\"default\" schemaType={type} value={doc} key={doc._id} />\n ) : (\n 'Schema-type missing'\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>"],"sources":["../src/sanityConnector.ts","../src/DocumentList.tsx","../src/plugin.tsx"],"sourcesContent":["import uniqBy from 'lodash-es/uniqBy.js'\nimport {type Observable, of as observableOf} from 'rxjs'\nimport {delay, mergeMap, switchMap, tap} from 'rxjs/operators'\nimport type {SanityClient, 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.join(', ')}. Error: ${error.message}`)\n })\n}\n\nexport function getSubscription(\n query: string,\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-es/intersection.js'\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 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\nfunction 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 gap={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"],"mappings":"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"}
\ No newline at end of file
+{"version":3,"file":"index.js","names":["observableOf","{\n ...defaultProps,\n ...props,\n }","{apiVersion}","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])","{assembledQuery: query, params: queryParams}","types ? intersection(types, documentTypes) : documentTypes","`*[_type in $types] | order(${order}) [0...${limit * 2}]`","(typeName) => {\n const schemaType = schema.get(typeName)\n return schemaType?.type?.name === 'document'\n }","{types: types ? intersection(types, documentTypes) : documentTypes}","{\n assembledQuery: `*[_type in $types] | order(${order}) [0...${limit * 2}]`,\n params: {types: types ? intersection(types, documentTypes) : documentTypes},\n }","() => {\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]","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 )","error && <div>{error.message}</div>","!error && loading && (\n <Card padding={4}>\n <Flex justify=\"center\">\n <Spinner muted />\n </Flex>\n </Card>\n )","!error && !documents && !loading && <div>Could not locate any documents :/</div>","documents && documents.map((doc) => <MenuEntry key={doc._id} doc={doc} />)","(doc) => <MenuEntry key={doc._id} doc={doc} />","<Stack gap={2}>\n {documents && documents.map((doc) => <MenuEntry key={doc._id} doc={doc} />)}\n </Stack>","<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 gap={2}>\n {documents && documents.map((doc) => <MenuEntry key={doc._id} doc={doc} />)}\n </Stack>\n </Card>","<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 gap={2}>\n {documents && documents.map((doc) => <MenuEntry key={doc._id} doc={doc} />)}\n </Stack>\n </Card>\n </DashboardWidgetContainer>","{doc}: {doc: SanityDocument}","schema.get(doc._type)","_type","{}","getPublishedId(doc._id)","_id","{\n type: doc._type,\n id: getPublishedId(doc._id),\n }","doc._type","{width: '100%'}","type ? (\n <Preview layout=\"default\" schemaType={type} value={doc} key={doc._id} />\n ) : (\n 'Schema-type missing'\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>","_c"],"sources":["../src/sanityConnector.ts","../src/DocumentList.tsx","../src/plugin.tsx"],"sourcesContent":["import uniqBy from 'lodash-es/uniqBy.js'\nimport {type Observable, of as observableOf} from 'rxjs'\nimport {delay, mergeMap, switchMap, tap} from 'rxjs/operators'\nimport type {SanityClient, 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.join(', ')}. Error: ${error.message}`)\n })\n}\n\nexport function getSubscription(\n query: string,\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-es/intersection.js'\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 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\nfunction 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 gap={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"],"mappings":"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"}
\ No newline at end of file