@sanity/dashboard 2.30.1 → 3.0.0-sanity-v3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/README.md +123 -44
  2. package/lib/cjs/index.js +1002 -0
  3. package/lib/cjs/index.js.map +1 -0
  4. package/lib/esm/index.js +977 -0
  5. package/lib/esm/index.js.map +1 -0
  6. package/lib/types/index.d.ts +42 -0
  7. package/lib/types/index.d.ts.map +1 -0
  8. package/package.json +53 -14
  9. package/src/components/DashboardLayout.tsx +10 -0
  10. package/src/components/DashboardWidgetContainer.tsx +69 -0
  11. package/src/components/NotFoundWidget.tsx +30 -0
  12. package/src/components/WidgetGroup.tsx +108 -0
  13. package/src/containers/Dashboard.tsx +19 -0
  14. package/src/containers/DashboardContext.tsx +8 -0
  15. package/src/containers/WidgetContainer.tsx +21 -0
  16. package/src/index.tsx +62 -0
  17. package/src/types.ts +21 -0
  18. package/src/versionedClient.ts +7 -0
  19. package/src/widgets/projectInfo/ProjectInfo.tsx +233 -0
  20. package/src/widgets/projectInfo/index.ts +10 -0
  21. package/src/widgets/projectUsers/ProjectUsers.tsx +171 -0
  22. package/src/widgets/projectUsers/index.ts +10 -0
  23. package/src/widgets/sanityTutorials/SanityTutorials.tsx +77 -0
  24. package/src/widgets/sanityTutorials/Tutorial.tsx +111 -0
  25. package/src/widgets/sanityTutorials/dataAdapter.ts +48 -0
  26. package/src/widgets/sanityTutorials/index.ts +10 -0
  27. package/.babelrc +0 -4
  28. package/lib/DashboardTool.js +0 -59
  29. package/lib/components/DashboardLayout.js +0 -35
  30. package/lib/components/NotFoundWidget.js +0 -51
  31. package/lib/components/WidgetGroup.js +0 -67
  32. package/lib/components/dashboardWidget.js +0 -51
  33. package/lib/containers/Dashboard.js +0 -32
  34. package/lib/containers/WidgetContainer.js +0 -56
  35. package/lib/dashboardConfig.js +0 -16
  36. package/lib/legacyParts.js +0 -55
  37. package/lib/versionedClient.js +0 -20
  38. package/lib/widget.css +0 -62
  39. package/lib/widgets/projectInfo/ProjectInfo.js +0 -265
  40. package/lib/widgets/projectInfo/index.js +0 -19
  41. package/lib/widgets/projectUsers/ProjectUsers.js +0 -188
  42. package/lib/widgets/projectUsers/index.js +0 -16
  43. package/lib/widgets/sanityTutorials/SanityTutorials.js +0 -115
  44. package/lib/widgets/sanityTutorials/Tutorial.js +0 -111
  45. package/lib/widgets/sanityTutorials/dataAdapter.js +0 -28
  46. package/lib/widgets/sanityTutorials/index.js +0 -19
  47. package/sanity.json +0 -59
  48. package/tsconfig.json +0 -17
@@ -0,0 +1 @@
1
+ {"mappings":"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","sources":["src/index.tsx","src/containers/Dashboard.tsx","src/components/DashboardLayout.tsx","src/components/WidgetGroup.tsx","src/containers/WidgetContainer.tsx","src/containers/DashboardContext.tsx","src/types.ts","src/components/DashboardWidgetContainer.tsx","src/widgets/projectInfo/index.ts","src/widgets/projectInfo/ProjectInfo.tsx","src/versionedClient.ts","src/widgets/projectUsers/index.ts","src/widgets/projectUsers/ProjectUsers.tsx","src/widgets/sanityTutorials/index.ts","src/widgets/sanityTutorials/SanityTutorials.tsx","src/widgets/sanityTutorials/Tutorial.tsx","src/widgets/sanityTutorials/dataAdapter.ts"],"sourcesContent":["import React, {CSSProperties} from 'react'\nimport {Dashboard} from './containers/Dashboard'\nimport {createPlugin} from 'sanity'\nimport {DashboardConfig, DashboardWidget, LayoutConfig} from './types'\n\nconst strokeStyle: CSSProperties = {\n stroke: 'currentColor',\n strokeWidth: 1.2,\n}\n\nconst DashboardIcon = () => (\n <svg\n data-sanity-icon\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n preserveAspectRatio=\"xMidYMid\"\n width=\"1em\"\n height=\"1em\"\n >\n <path d=\"M19.5 19.5H5.5V5.5H19.5V19.5Z\" style={strokeStyle} />\n <path d=\"M5.5 12.5H19.5\" style={strokeStyle} />\n <path d=\"M14.5 19.5V12.5M10.5 12.5V5.5\" style={strokeStyle} />\n </svg>\n)\n\nexport * from './types'\nexport * from './components/DashboardWidgetContainer'\nexport * from './widgets/projectInfo'\nexport * from './widgets/projectUsers'\nexport * from './widgets/sanityTutorials'\n\nexport interface DashboardPluginConfig {\n widgets?: DashboardWidget[]\n\n /**\n * Will be used for widgets that do not define a layout directly.\n */\n defaultLayout?: LayoutConfig\n}\n\nexport const dashboardTool = createPlugin<DashboardPluginConfig>((config = {}) => {\n const pluginConfig: DashboardConfig = {\n layout: config.defaultLayout ?? {},\n widgets: config.widgets ?? [],\n }\n\n return {\n name: 'dashboard',\n tools: (prev, context) => {\n return [\n ...prev,\n {\n title: 'Dashboard',\n name: 'dashboard',\n icon: DashboardIcon,\n component: () => <Dashboard config={pluginConfig} />,\n },\n ]\n },\n }\n})\n","import React from 'react'\nimport {DashboardLayout} from '../components/DashboardLayout'\nimport {WidgetGroup} from '../components/WidgetGroup'\nimport {DashboardContext} from './DashboardContext'\nimport {DashboardConfig} from '../types'\n\nexport function Dashboard({config}: {config: DashboardConfig}) {\n if (!config) {\n return null\n }\n\n return (\n <DashboardContext.Provider value={config}>\n <DashboardLayout>\n <WidgetGroup config={config} />\n </DashboardLayout>\n </DashboardContext.Provider>\n )\n}\n","import React, {PropsWithChildren} from 'react'\nimport {Container} from '@sanity/ui'\n\nexport function DashboardLayout(props: PropsWithChildren<{}>) {\n return (\n <Container width={4} padding={4} sizing=\"border\" style={{minHeight: '100%'}}>\n {props.children}\n </Container>\n )\n}\n","import React from 'react'\nimport styled, {css} from 'styled-components'\nimport {Box, Card, Grid, Text} from '@sanity/ui'\nimport {WidgetContainer} from '../containers/WidgetContainer'\nimport {DashboardConfig, LayoutConfig, DashboardWidget} from '../types'\n\nconst media = {\n small: (...args: Parameters<typeof css>) =>\n css`\n @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {\n ${css(...args)}\n }\n `,\n medium: (...args: Parameters<typeof css>) =>\n css`\n @media (min-width: ${({theme}) => theme.sanity.media[2]}px) {\n ${css(...args)}\n }\n `,\n}\n\nconst Root = styled(Grid)`\n grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));\n\n & > div {\n overflow: hidden;\n }\n\n & > div[data-width='medium'] {\n ${media.small`\n grid-column: span 2;\n `}\n }\n\n & > div[data-width='large'] {\n ${media.small`\n grid-column: span 2;\n `}\n\n ${media.medium`\n grid-column: span 3;\n `}\n }\n\n & > div[data-width='full'] {\n ${media.small`\n grid-column: 1 / -1;\n `}\n }\n\n & > div[data-height='medium'] {\n ${media.small`\n grid-row: span 2;\n `}\n }\n\n & > div[data-height='large'] {\n ${media.small`\n grid-row: span 2;\n `}\n\n ${media.medium`\n grid-row: span 3;\n `}\n }\n\n & > div[data-height='full'] {\n ${media.medium`\n grid-row: 1 / -1;\n `}\n }\n`\n\nexport interface WidgetGroupProps {\n config: Partial<DashboardConfig>\n}\n\nconst NO_WIDGETS: DashboardWidget[] = []\nconst NO_LAYOUT: LayoutConfig = {}\n\nexport function WidgetGroup(props: WidgetGroupProps) {\n const {\n config: {layout = NO_LAYOUT, widgets = NO_WIDGETS},\n } = props\n return (\n <Root\n autoFlow=\"row dense\"\n data-width={layout.width || 'auto'}\n data-height={layout.height || 'auto'}\n gap={4}\n >\n {widgets.length ? null : (\n <Card padding={4} shadow={1} tone=\"primary\">\n <Text align=\"center\">Add some widgets to populate this space.</Text>\n </Card>\n )}\n {widgets.map((widgetConfig, index) => {\n if (widgetConfig.type === '__experimental_group') {\n return <WidgetGroup key={index} config={widgetConfig} />\n }\n if (widgetConfig.component) {\n return <WidgetContainer key={index} {...widgetConfig} />\n }\n return <Box key={index}>{widgetConfig.name} is missing widget component</Box>\n })}\n </Root>\n )\n}\n","import React, {createElement, useMemo} from 'react'\nimport {useDashboardConfig} from './DashboardContext'\nimport {Card} from '@sanity/ui'\nimport {DashboardWidget} from '../types'\n\nexport function WidgetContainer(props: DashboardWidget) {\n const config = useDashboardConfig()\n const layout = useMemo(\n () => ({\n ...(props.layout || {}),\n ...(config.layout || {}),\n }),\n [props.layout, config.layout]\n )\n\n return (\n <Card shadow={1} data-width={layout.width} data-height={layout.height}>\n {createElement(props.component, {})}\n </Card>\n )\n}\n","import {createContext, useContext} from 'react'\nimport {DashboardConfig} from '../types'\n\nexport const DashboardContext = createContext<DashboardConfig>({widgets: []})\n\nexport function useDashboardConfig(): DashboardConfig {\n return useContext(DashboardContext)\n}\n","import {ComponentClass, FunctionComponent} from 'react'\n\nexport interface DashboardWidget {\n name: string\n type?: '__experimental_group'\n component: FunctionComponent<any> | ComponentClass<any>\n layout?: LayoutConfig\n widgets?: DashboardWidget[]\n}\n\nexport type LayoutSize = 'auto' | 'small' | 'medium' | 'large' | 'full'\n\nexport interface LayoutConfig {\n width?: LayoutSize\n height?: LayoutSize\n}\n\nexport interface DashboardConfig {\n widgets: DashboardWidget[]\n layout?: LayoutConfig\n}\n","import React, {forwardRef} from 'react'\nimport {Card, Box, Heading} from '@sanity/ui'\nimport styled from 'styled-components'\n\nconst Root = styled(Card)`\n display: flex;\n flex-direction: column;\n justify-content: stretch;\n height: 100%;\n box-sizing: border-box;\n position: relative;\n`\n\nconst Header = styled(Card)`\n position: sticky;\n top: 0;\n z-index: 2;\n border-top-left-radius: inherit;\n border-top-right-radius: inherit;\n`\n\nconst Footer = styled(Card)`\n position: sticky;\n overflow: hidden;\n bottom: 0;\n z-index: 2;\n border-bottom-right-radius: inherit;\n border-bottom-left-radius: inherit;\n margin-top: auto;\n`\n\nconst Content = styled(Box)`\n position: relative;\n z-index: 1;\n height: stretch;\n min-height: 21.5em;\n\n @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {\n overflow-y: auto;\n outline: none;\n }\n`\n\ninterface DashboardWidgetProps {\n header?: string\n children: React.ReactNode\n footer?: React.ReactNode\n}\n\nexport const DashboardWidgetContainer = forwardRef(function DashboardWidgetContainer(\n props: DashboardWidgetProps,\n ref: React.Ref<HTMLDivElement>\n) {\n const {header, children, footer} = props\n\n return (\n <Root radius={3} display=\"flex\" ref={ref}>\n {header && (\n <Header borderBottom paddingX={3} paddingY={4}>\n <Heading size={1} textOverflow=\"ellipsis\">\n {header}\n </Heading>\n </Header>\n )}\n {children && <Content>{children}</Content>}\n {footer && <Footer borderTop>{footer}</Footer>}\n </Root>\n )\n})\n","import {ProjectInfo} from './ProjectInfo'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function projectInfoWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'project-info',\n component: ProjectInfo,\n layout: config?.layout ?? {width: 'medium'},\n }\n}\n","import React, {useEffect, useMemo, useState} from 'react'\nimport {Box, Card, Stack, Heading, Grid, Label, Text, Code, Button} from '@sanity/ui'\nimport {useVersionedClient} from '../../versionedClient'\nimport {Subscription} from 'rxjs'\nimport {WidgetContainer} from '../../containers/WidgetContainer'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\nimport {DashboardWidget} from '../../types'\n\nexport interface ProjectInfoProps {\n __experimental_before?: DashboardWidget[]\n data: ProjectData[]\n}\n\ninterface App {\n title: string\n rows?: App[]\n value?: string | {error: string}\n}\n\ninterface ProjectData {\n title: string\n category?: string\n}\n\nfunction isUrl(url?: string) {\n return url && /^https?:\\/\\//.test(`${url}`)\n}\n\nfunction getGraphQlUrl(projectId: string, dataset: string) {\n return `https://${projectId}.api.sanity.io/v1/graphql/${dataset}/default`\n}\n\nfunction getGroqUrl(projectId: string, dataset: string) {\n return `https://${projectId}.api.sanity.io/v1/groq/${dataset}`\n}\n\nfunction getManageUrl(projectId: string) {\n return `https://manage.sanity.io/projects/${projectId}`\n}\n\nconst NO_EXPERIMENTAL: DashboardWidget[] = []\nconst NO_DATA: ProjectData[] = []\n\nexport function ProjectInfo(props: ProjectInfoProps) {\n const {__experimental_before = NO_EXPERIMENTAL, data = NO_DATA} = props\n const [studioHost, setStudioHost] = useState<string | {error: string} | undefined>()\n const [graphqlApi, setGraphQlApi] = useState<string | {error: string} | undefined>()\n const versionedClient = useVersionedClient()\n const {projectId = 'unknown', dataset = 'unknown'} = versionedClient.config()\n\n useEffect(() => {\n const subscriptions: Subscription[] = []\n\n subscriptions.push(\n versionedClient.observable\n .request<{studioHost: string}>({uri: `/projects/${projectId}`})\n .subscribe({\n next: (result) => {\n const {studioHost: host} = result\n setStudioHost(host ? `https://${host}.sanity.studio` : undefined)\n },\n error: (error) => {\n console.error('Error while looking for studioHost', error)\n setStudioHost({\n error: 'Something went wrong while looking up studioHost. See console.',\n })\n },\n })\n )\n\n // ping assumed graphql endpoint\n subscriptions.push(\n versionedClient.observable\n .request({\n method: 'HEAD',\n uri: `/graphql/${dataset}/default`,\n })\n .subscribe({\n next: () => setGraphQlApi(getGraphQlUrl(projectId, dataset)),\n error: (error) => {\n if (error.statusCode === 404) {\n setGraphQlApi(undefined)\n } else {\n console.error('Error while looking for graphqlApi', error)\n setGraphQlApi({\n error: 'Something went wrong while looking up graphqlApi. See console.',\n })\n }\n },\n })\n )\n\n return () => {\n subscriptions.forEach((s) => s.unsubscribe())\n }\n }, [dataset, projectId, versionedClient, setGraphQlApi, setStudioHost])\n\n const assembleTableRows = useMemo(() => {\n let result: App[] = [\n {\n title: 'Sanity project',\n rows: [\n {title: 'Project ID', value: projectId},\n {title: 'Dataset', value: dataset},\n ],\n },\n ]\n\n // Handle any apps\n const apps: App[] = [\n studioHost ? {title: 'Studio', value: studioHost} : null,\n ...data.filter((item) => item.category === 'apps'),\n ].filter((a): a is App => !!a)\n if (apps.length > 0) {\n result = result.concat([{title: 'Apps', rows: apps}])\n }\n\n // Handle APIs\n result = result.concat(\n [\n {\n title: 'APIs',\n rows: [\n {title: 'GROQ', value: getGroqUrl(projectId, dataset)},\n {\n title: 'GraphQL',\n value: (typeof graphqlApi === 'object' ? 'Error' : graphqlApi) ?? 'Not deployed',\n },\n ],\n },\n ],\n data.filter((item) => item.category === 'apis')\n )\n\n // Handle whatever else there might be\n const otherStuff: Record<string, ProjectData[]> = {}\n data.forEach((item) => {\n if (item.category && item.category !== 'apps' && item.category !== 'apis') {\n if (!otherStuff[item.category]) {\n otherStuff[item.category] = []\n }\n otherStuff[item.category].push(item)\n }\n })\n Object.keys(otherStuff).forEach((category) => {\n result.push({title: category, rows: otherStuff[category]})\n })\n\n return result\n }, [graphqlApi, studioHost, projectId, dataset, data])\n\n return (\n <>\n {__experimental_before.map((widgetConfig, idx) => (\n <WidgetContainer key={idx} {...widgetConfig} />\n ))}\n <Box height=\"fill\" marginTop={__experimental_before?.length > 0 ? 4 : 0}>\n <DashboardWidgetContainer\n footer={\n <Button\n style={{width: '100%'}}\n paddingX={2}\n paddingY={4}\n mode=\"bleed\"\n tone=\"primary\"\n text=\"Manage project\"\n as=\"a\"\n href={getManageUrl(projectId)}\n />\n }\n >\n <Card\n paddingY={4}\n radius={2}\n role=\"table\"\n aria-label=\"Project info\"\n aria-describedby=\"project_info_table\"\n >\n <Stack space={4}>\n <Box paddingX={3} as=\"header\">\n <Heading size={1} as=\"h2\" id=\"project_info_table\">\n Project info\n </Heading>\n </Box>\n {assembleTableRows.map((item) => {\n if (!item || !item.rows) {\n return null\n }\n\n return (\n <Stack key={item.title} space={3}>\n <Card borderBottom padding={3}>\n <Label size={0} muted role=\"columnheader\">\n {item.title}\n </Label>\n </Card>\n <Stack space={4} paddingX={3} role=\"rowgroup\">\n {item.rows.map((row) => {\n return (\n <Grid key={row.title} columns={2} role=\"row\">\n <Text weight=\"medium\" role=\"rowheader\">\n {row.title}\n </Text>\n {typeof row.value === 'object' && (\n <Text size={1}>{row.value?.error}</Text>\n )}\n {typeof row.value === 'string' && (\n <>\n {isUrl(row.value) ? (\n <Text size={1} role=\"cell\" style={{wordBreak: 'break-word'}}>\n <a href={row.value}>{row.value}</a>\n </Text>\n ) : (\n <Code size={1} role=\"cell\" style={{wordBreak: 'break-word'}}>\n {row.value}\n </Code>\n )}\n </>\n )}\n </Grid>\n )\n })}\n </Stack>\n </Stack>\n )\n })}\n </Stack>\n </Card>\n </DashboardWidgetContainer>\n </Box>\n </>\n )\n}\n","import {useClient} from 'sanity'\nimport {useMemo} from 'react'\n\nexport function useVersionedClient() {\n const client = useClient()\n return useMemo(() => client.withConfig({apiVersion: '1'}), [client])\n}\n","import {ProjectUsers} from './ProjectUsers'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function projectUsersWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'project-info',\n component: ProjectUsers,\n layout: config?.layout,\n }\n}\n","import React, {useCallback, useEffect, useState} from 'react'\nimport {map, switchMap} from 'rxjs/operators'\nimport {Stack, Spinner, Card, Box, Text, Button} from '@sanity/ui'\nimport {RobotIcon} from '@sanity/icons'\nimport styled from 'styled-components'\nimport {useSource} from 'sanity'\nimport {DefaultPreview} from 'sanity/_unstable'\nimport {useVersionedClient} from '../../versionedClient'\nimport {User} from '@sanity/types'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\n\nconst AvatarWrapper = styled(Card)`\n box-sizing: border-box;\n border-radius: 50%;\n border-color: transparent;\n overflow: hidden;\n width: 100%;\n height: 100%;\n\n & > img {\n width: 100%;\n height: auto;\n }\n`\n\nfunction getInviteUrl(projectId: string) {\n return `https://manage.sanity.io/projects/${projectId}/team/invite`\n}\n\ninterface Member {\n id: string\n role: string\n isRobot: boolean\n}\n\ninterface Project {\n id: string\n members: Member[]\n}\n\nexport function ProjectUsers() {\n const [project, setProject] = useState<Project | undefined>()\n const [users, setUsers] = useState<User[] | undefined>()\n const [error, setError] = useState<Error | undefined>()\n\n const versionedClient = useVersionedClient()\n const {\n __internal: {userStore},\n } = useSource()\n\n const fetchData = useCallback(() => {\n const {projectId} = versionedClient.config()\n const subscription = versionedClient.observable\n .request<Project>({\n uri: `/projects/${projectId}`,\n })\n .pipe(\n switchMap((_project) =>\n userStore.observable\n .getUsers(_project.members.map((mem) => mem.id))\n .pipe(map((_users) => ({project: _project, users: _users})))\n )\n )\n .subscribe({\n next: ({users: _users, project: _project}) => {\n setProject(_project)\n setUsers(\n (Array.isArray(_users) ? _users : [_users]).sort((userA, userB) =>\n sortUsersByRobotStatus(userA, userB, _project)\n )\n )\n },\n error: (e: Error) => setError(e),\n })\n\n return () => subscription.unsubscribe()\n }, [userStore, versionedClient])\n\n useEffect(() => fetchData(), [fetchData])\n\n const handleRetryFetch = useCallback(() => fetchData(), [fetchData])\n\n const isLoading = !users || !project\n\n if (error) {\n return (\n <DashboardWidgetContainer header=\"Project users\">\n <Box padding={4}>\n <Text>\n Something went wrong while fetching data. You could{' '}\n <a onClick={handleRetryFetch} title=\"Retry users fetch\" style={{cursor: 'pointer'}}>\n retry\n </a>\n ..?\n </Text>\n </Box>\n </DashboardWidgetContainer>\n )\n }\n\n return (\n <DashboardWidgetContainer\n header=\"Project users\"\n footer={\n <Button\n style={{width: '100%'}}\n paddingX={2}\n paddingY={4}\n mode=\"bleed\"\n tone=\"primary\"\n text=\"Invite members\"\n as=\"a\"\n loading={isLoading}\n href={isLoading ? undefined : getInviteUrl(project.id)}\n />\n }\n >\n {isLoading && (\n <Box paddingY={5} paddingX={2}>\n <Stack space={4}>\n <Text align=\"center\" muted size={1}>\n <Spinner />\n </Text>\n <Text align=\"center\" size={1} muted>\n Loading items...\n </Text>\n </Stack>\n </Box>\n )}\n\n {!isLoading && (\n <Stack space={3} padding={3}>\n {users?.map((user) => {\n const membership = project.members.find((member) => member.id === user.id)\n const media = membership?.isRobot ? (\n <Text size={3}>\n <RobotIcon />\n </Text>\n ) : (\n <AvatarWrapper tone=\"transparent\">\n {user?.imageUrl && <img src={user.imageUrl} alt={user?.displayName} />}\n </AvatarWrapper>\n )\n return (\n <Box key={user.id}>\n <DefaultPreview\n title={user.displayName}\n subtitle={membership?.role}\n media={media}\n />\n </Box>\n )\n })}\n </Stack>\n )}\n </DashboardWidgetContainer>\n )\n}\n\nfunction sortUsersByRobotStatus(userA: User, userB: User, project: Project) {\n const {members} = project\n const membershipA = members.find((member) => member.id === userA?.id)\n const membershipB = members.find((member) => member.id === userB?.id)\n if (membershipA?.isRobot) {\n return 1\n }\n if (membershipB?.isRobot) {\n return -1\n }\n return 0\n}\n","import {SanityTutorials} from './SanityTutorials'\nimport {LayoutConfig, DashboardWidget} from '../../types'\n\nexport function sanityTutorialsWidget(config?: {layout?: LayoutConfig}): DashboardWidget {\n return {\n name: 'sanity-tutorials',\n component: SanityTutorials,\n layout: config?.layout ?? {width: 'full'},\n }\n}\n","import React, {useEffect, useState} from 'react'\nimport {Flex} from '@sanity/ui'\nimport {Tutorial} from './Tutorial'\nimport {FeedItem, Guide, useDataAdapter} from './dataAdapter'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\n\nfunction createUrl(slug: {current: string}, type?: string) {\n if (type === 'tutorial') {\n return `https://www.sanity.io/docs/tutorials/${slug.current}`\n } else if (type === 'guide') {\n return `https://www.sanity.io/docs/guides/${slug.current}`\n }\n return false\n}\n\nexport interface SanityTutorialsProps {\n templateRepoId: string\n}\n\nexport function SanityTutorials(props: SanityTutorialsProps) {\n const {templateRepoId} = props\n const [feedItems, setFeedItems] = useState<FeedItem[]>([])\n\n const {getFeed, urlBuilder} = useDataAdapter()\n\n useEffect(() => {\n const subscription = getFeed(templateRepoId).subscribe((response) => {\n setFeedItems(response.items)\n })\n return () => {\n subscription.unsubscribe()\n }\n }, [setFeedItems, getFeed, templateRepoId])\n\n const title = 'Learn about Sanity'\n\n return (\n <DashboardWidgetContainer header={title}>\n <Flex as=\"ul\" overflow=\"auto\" align=\"stretch\" paddingY={2}>\n {feedItems?.map((feedItem, index) => {\n if (!feedItem.title || (!feedItem.guideOrTutorial && !feedItem.externalLink)) {\n return null\n }\n const presenter = feedItem.presenter || feedItem.guideOrTutorial?.presenter || {}\n const subtitle = feedItem.category\n const {guideOrTutorial = {} as Guide} = feedItem\n const href =\n (guideOrTutorial.slug\n ? createUrl(guideOrTutorial.slug, guideOrTutorial._type)\n : feedItem.externalLink) || feedItem.externalLink\n\n return (\n <Flex\n as=\"li\"\n key={feedItem._id}\n paddingRight={index < feedItems?.length - 1 ? 1 : 3}\n paddingLeft={index === 0 ? 3 : 0}\n align=\"stretch\"\n style={{minWidth: 272, width: '30%'}}\n >\n <Tutorial\n title={feedItem.title}\n href={href ?? ''}\n presenterName={presenter.name}\n presenterSubtitle={subtitle}\n showPlayIcon={feedItem.hasVideo}\n posterURL={\n feedItem.poster ? urlBuilder.image(feedItem.poster).height(360).url() : undefined\n }\n />\n </Flex>\n )\n })}\n </Flex>\n </DashboardWidgetContainer>\n )\n}\n","import React from 'react'\nimport {Card, Box, Heading, Flex, Text, Stack} from '@sanity/ui'\nimport {PlayIcon} from '@sanity/icons'\nimport styled from 'styled-components'\n\nconst PlayIconBox = styled(Box)`\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n\n &:before {\n content: '';\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 2.75em;\n height: 2.75em;\n border-radius: 50%;\n background: ${({theme}) => theme.sanity.color.card.enabled.bg};\n opacity: 0.75;\n }\n`\n\nconst Root = styled(Flex)`\n &:hover {\n ${PlayIconBox} {\n &:before {\n opacity: 1;\n }\n }\n }\n`\n\nconst PosterCard = styled(Card)`\n width: 100%;\n padding-bottom: calc(9 / 16 * 100%);\n position: relative;\n`\n\nconst Poster = styled.img`\n position: absolute;\n top: 0;\n left: 0;\n height: 100%;\n width: 100%;\n object-fit: cover;\n display: block;\n\n &:not([src]) {\n display: none;\n }\n`\n\nexport interface TutorialProps {\n title: string\n posterURL?: string\n href: string\n showPlayIcon?: boolean\n presenterName?: string\n presenterSubtitle?: string\n}\n\nexport function Tutorial(props: TutorialProps) {\n const {title, posterURL, showPlayIcon, href, presenterName, presenterSubtitle} = props\n\n return (\n <Root flex={1}>\n <Card\n sizing=\"border\"\n flex={1}\n padding={2}\n radius={2}\n as=\"a\"\n href={href}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n style={{position: 'relative'}}\n >\n <Flex direction=\"column\" style={{height: '100%'}}>\n {posterURL && (\n <PosterCard marginBottom={1}>\n <Poster src={posterURL} />\n {showPlayIcon && (\n <PlayIconBox display=\"flex\">\n <Text align=\"center\">\n <PlayIcon />\n </Text>\n </PlayIconBox>\n )}\n </PosterCard>\n )}\n <Flex direction=\"column\" justify=\"space-between\" paddingY={2} flex={1}>\n <Heading as=\"h3\" size={1}>\n {title}\n </Heading>\n <Box marginTop={4}>\n <Stack space={2} flex={1}>\n <Text size={1}>{presenterName}</Text>\n <Text size={0} style={{opacity: 0.7}}>\n {presenterSubtitle}\n </Text>\n </Stack>\n </Box>\n </Flex>\n </Flex>\n </Card>\n </Root>\n )\n}\n","import {useMemo} from 'react'\nimport {useVersionedClient} from '../../versionedClient'\nimport imageUrlBuilder from '@sanity/image-url'\n\nconst tutorialsProjectConfig = {\n projectId: '3do82whm',\n dataset: 'next',\n}\n\nexport interface Guide {\n _type?: string\n slug?: {current: string}\n presenter?: {\n name?: string\n }\n}\n\nexport interface FeedItem {\n _id: string\n title?: string\n poster?: string\n category?: string\n guideOrTutorial?: Guide\n externalLink?: string\n presenter?: {\n name?: string\n }\n hasVideo?: boolean\n}\n\nexport function useDataAdapter() {\n const versionedClient = useVersionedClient()\n return useMemo(\n () => ({\n getFeed: (templateRepoId: string) => {\n const uri = templateRepoId\n ? `/addons/dashboard?templateRepoId=${templateRepoId}`\n : '/addons/dashboard'\n return versionedClient.observable.request<{items: FeedItem[]}>({\n uri,\n withCredentials: false,\n })\n },\n urlBuilder: imageUrlBuilder(tutorialsProjectConfig),\n }),\n [versionedClient]\n )\n}\n"],"names":[],"version":3,"file":"index.js.map"}
@@ -0,0 +1,42 @@
1
+ import React, { ComponentClass, FunctionComponent } from "react";
2
+ export interface DashboardWidget {
3
+ name: string;
4
+ type?: '__experimental_group';
5
+ component: FunctionComponent<any> | ComponentClass<any>;
6
+ layout?: LayoutConfig;
7
+ widgets?: DashboardWidget[];
8
+ }
9
+ export type LayoutSize = 'auto' | 'small' | 'medium' | 'large' | 'full';
10
+ export interface LayoutConfig {
11
+ width?: LayoutSize;
12
+ height?: LayoutSize;
13
+ }
14
+ export interface DashboardConfig {
15
+ widgets: DashboardWidget[];
16
+ layout?: LayoutConfig;
17
+ }
18
+ interface DashboardWidgetProps {
19
+ header?: string;
20
+ children: React.ReactNode;
21
+ footer?: React.ReactNode;
22
+ }
23
+ export const DashboardWidgetContainer: React.ForwardRefExoticComponent<DashboardWidgetProps & React.RefAttributes<HTMLDivElement>>;
24
+ export function projectInfoWidget(config?: {
25
+ layout?: LayoutConfig;
26
+ }): DashboardWidget;
27
+ export function projectUsersWidget(config?: {
28
+ layout?: LayoutConfig;
29
+ }): DashboardWidget;
30
+ export function sanityTutorialsWidget(config?: {
31
+ layout?: LayoutConfig;
32
+ }): DashboardWidget;
33
+ export interface DashboardPluginConfig {
34
+ widgets?: DashboardWidget[];
35
+ /**
36
+ * Will be used for widgets that do not define a layout directly.
37
+ */
38
+ defaultLayout?: LayoutConfig;
39
+ }
40
+ export const dashboardTool: import("sanity").Plugin<DashboardPluginConfig>;
41
+
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"mappings":";ACEA;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,CAAC,EAAE,sBAAsB,CAAA;IAC7B,SAAS,EAAE,kBAAkB,GAAG,CAAC,GAAG,eAAe,GAAG,CAAC,CAAA;IACvD,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,OAAO,CAAC,EAAE,eAAe,EAAE,CAAA;CAC5B;AAED,yBAAyB,MAAM,GAAG,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;AAEvE;IACE,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB,MAAM,CAAC,EAAE,UAAU,CAAA;CACpB;AAED;IACE,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B,MAAM,CAAC,EAAE,YAAY,CAAA;CACtB;AKuBD;IACE,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,SAAS,CAAA;IACzB,MAAM,CAAC,EAAE,MAAM,SAAS,CAAA;CACzB;AAED,OAAO,MAAM,qHAmBX,CAAA;AGjEF,kCAAkC,MAAM,CAAC,EAAE;IAAC,MAAM,CAAC,EAAE,YAAY,CAAA;CAAC,GAAG,eAAe,CAMnF;AEND,mCAAmC,MAAM,CAAC,EAAE;IAAC,MAAM,CAAC,EAAE,YAAY,CAAA;CAAC,GAAG,eAAe,CAMpF;AIND,sCAAsC,MAAM,CAAC,EAAE;IAAC,MAAM,CAAC,EAAE,YAAY,CAAA;CAAC,GAAG,eAAe,CAMvF;ACuBD;IACE,OAAO,CAAC,EAAE,eAAe,EAAE,CAAA;IAE3B;;OAEG;IACH,aAAa,CAAC,EAAE,YAAY,CAAA;CAC7B;AAED,OAAO,MAAM,6DAoBX,CAAA","sources":["src/src/components/DashboardLayout.tsx","src/src/types.ts","src/src/containers/DashboardContext.tsx","src/src/containers/WidgetContainer.tsx","src/src/components/WidgetGroup.tsx","src/src/containers/Dashboard.tsx","src/src/components/DashboardWidgetContainer.tsx","src/src/versionedClient.ts","src/src/widgets/projectInfo/ProjectInfo.tsx","src/src/widgets/projectInfo/index.ts","src/src/widgets/projectUsers/ProjectUsers.tsx","src/src/widgets/projectUsers/index.ts","src/src/widgets/sanityTutorials/Tutorial.tsx","src/src/widgets/sanityTutorials/dataAdapter.ts","src/src/widgets/sanityTutorials/SanityTutorials.tsx","src/src/widgets/sanityTutorials/index.ts","src/src/index.tsx","src/index.tsx"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"import React, {CSSProperties} from 'react'\nimport {Dashboard} from './containers/Dashboard'\nimport {createPlugin} from 'sanity'\nimport {DashboardConfig, DashboardWidget, LayoutConfig} from './types'\n\nconst strokeStyle: CSSProperties = {\n stroke: 'currentColor',\n strokeWidth: 1.2,\n}\n\nconst DashboardIcon = () => (\n <svg\n data-sanity-icon\n viewBox=\"0 0 25 25\"\n fill=\"none\"\n xmlns=\"http://www.w3.org/2000/svg\"\n preserveAspectRatio=\"xMidYMid\"\n width=\"1em\"\n height=\"1em\"\n >\n <path d=\"M19.5 19.5H5.5V5.5H19.5V19.5Z\" style={strokeStyle} />\n <path d=\"M5.5 12.5H19.5\" style={strokeStyle} />\n <path d=\"M14.5 19.5V12.5M10.5 12.5V5.5\" style={strokeStyle} />\n </svg>\n)\n\nexport * from './types'\nexport * from './components/DashboardWidgetContainer'\nexport * from './widgets/projectInfo'\nexport * from './widgets/projectUsers'\nexport * from './widgets/sanityTutorials'\n\nexport interface DashboardPluginConfig {\n widgets?: DashboardWidget[]\n\n /**\n * Will be used for widgets that do not define a layout directly.\n */\n defaultLayout?: LayoutConfig\n}\n\nexport const dashboardTool = createPlugin<DashboardPluginConfig>((config = {}) => {\n const pluginConfig: DashboardConfig = {\n layout: config.defaultLayout ?? {},\n widgets: config.widgets ?? [],\n }\n\n return {\n name: 'dashboard',\n tools: (prev, context) => {\n return [\n ...prev,\n {\n title: 'Dashboard',\n name: 'dashboard',\n icon: DashboardIcon,\n component: () => <Dashboard config={pluginConfig} />,\n },\n ]\n },\n }\n})\n"],"names":[],"version":3,"file":"index.d.ts.map"}
package/package.json CHANGED
@@ -1,13 +1,33 @@
1
1
  {
2
2
  "name": "@sanity/dashboard",
3
- "version": "2.30.1",
3
+ "version": "3.0.0-sanity-v3.0",
4
4
  "description": "Tool for rendering dashboard widgets",
5
- "main": "./lib/DashboardTool.js",
6
- "types": "./dist/dts",
5
+ "source": "./src/index.tsx",
6
+ "exports": {
7
+ ".": {
8
+ "require": "./lib/cjs/index.js",
9
+ "default": "./lib/esm/index.js"
10
+ }
11
+ },
12
+ "main": "./lib/cjs/index.js",
13
+ "module": "./lib/esm/index.js",
14
+ "types": "./lib/types/index.d.ts",
15
+ "files": [
16
+ "src",
17
+ "lib"
18
+ ],
7
19
  "author": "Sanity.io <hello@sanity.io>",
8
20
  "license": "MIT",
9
21
  "scripts": {
10
- "clean": "rimraf lib dest"
22
+ "clean": "rimraf lib",
23
+ "prebuild": "npm run clean && tsc --noEmit",
24
+ "build": "parcel build",
25
+ "watch": "parcel watch",
26
+ "lint": "eslint .",
27
+ "format": "prettier src -w",
28
+ "prepare": "husky install",
29
+ "compile": "tsc --noEmit",
30
+ "prepublishOnly": "npm run lint && npm run build"
11
31
  },
12
32
  "keywords": [
13
33
  "sanity",
@@ -20,22 +40,39 @@
20
40
  "sanity-tool"
21
41
  ],
22
42
  "dependencies": {
23
- "@sanity/icons": "^1.2.6",
43
+ "@sanity/icons": "^1.2.8",
24
44
  "@sanity/image-url": "^1.0.1",
25
- "@sanity/types": "2.29.5",
26
45
  "@sanity/ui": "^0.37.9",
27
- "lodash": "^4.17.15",
46
+ "lodash": "^4.17.21",
28
47
  "rxjs": "^6.5.3"
29
48
  },
30
49
  "devDependencies": {
31
- "@sanity/base": "2.30.1",
32
- "prop-types": "^15.6.0",
33
- "rimraf": "^2.7.1"
50
+ "@commitlint/cli": "^16.1.0",
51
+ "@commitlint/config-conventional": "^15.0.0",
52
+ "@parcel/packager-ts": "^2.6.0",
53
+ "@parcel/transformer-typescript-types": "^2.6.0",
54
+ "@types/styled-components": "^5.1.25",
55
+ "@typescript-eslint/eslint-plugin": "^5.12.0",
56
+ "@typescript-eslint/parser": "^5.12.0",
57
+ "eslint": "^8.7.0",
58
+ "eslint-config-prettier": "^8.3.0",
59
+ "eslint-config-sanity": "^5.1.0",
60
+ "eslint-plugin-prettier": "4.0.0",
61
+ "eslint-plugin-react": "^7.28.0",
62
+ "eslint-plugin-react-hooks": "^4.5.0",
63
+ "husky": "^7.0.0",
64
+ "lint-staged": "^12.3.3",
65
+ "parcel": "^2.6.0",
66
+ "prettier": "^2.5.1",
67
+ "react": "^17.0.0 || ^18.0.0",
68
+ "rimraf": "^3.0.2",
69
+ "sanity": "purple-unicorn",
70
+ "styled-components": "^5.3.5",
71
+ "typescript": "^4.7.3"
34
72
  },
35
73
  "peerDependencies": {
36
- "@sanity/base": "^2.0.0",
37
- "prop-types": "^15.6 || ^16",
38
- "react": "^16.9 || ^17",
74
+ "react": "^17.0.0 || ^18.0.0",
75
+ "sanity": "purple-unicorn",
39
76
  "styled-components": "^5.2.0"
40
77
  },
41
78
  "repository": {
@@ -47,5 +84,7 @@
47
84
  "url": "https://github.com/sanity-io/sanity/issues"
48
85
  },
49
86
  "homepage": "https://www.sanity.io/",
50
- "gitHead": "cf0a8097e331365ecea9635905d509218ce494ee"
87
+ "directories": {
88
+ "lib": "lib"
89
+ }
51
90
  }
@@ -0,0 +1,10 @@
1
+ import React, {PropsWithChildren} from 'react'
2
+ import {Container} from '@sanity/ui'
3
+
4
+ export function DashboardLayout(props: PropsWithChildren<{}>) {
5
+ return (
6
+ <Container width={4} padding={4} sizing="border" style={{minHeight: '100%'}}>
7
+ {props.children}
8
+ </Container>
9
+ )
10
+ }
@@ -0,0 +1,69 @@
1
+ import React, {forwardRef} from 'react'
2
+ import {Card, Box, Heading} from '@sanity/ui'
3
+ import styled from 'styled-components'
4
+
5
+ const Root = styled(Card)`
6
+ display: flex;
7
+ flex-direction: column;
8
+ justify-content: stretch;
9
+ height: 100%;
10
+ box-sizing: border-box;
11
+ position: relative;
12
+ `
13
+
14
+ const Header = styled(Card)`
15
+ position: sticky;
16
+ top: 0;
17
+ z-index: 2;
18
+ border-top-left-radius: inherit;
19
+ border-top-right-radius: inherit;
20
+ `
21
+
22
+ const Footer = styled(Card)`
23
+ position: sticky;
24
+ overflow: hidden;
25
+ bottom: 0;
26
+ z-index: 2;
27
+ border-bottom-right-radius: inherit;
28
+ border-bottom-left-radius: inherit;
29
+ margin-top: auto;
30
+ `
31
+
32
+ const Content = styled(Box)`
33
+ position: relative;
34
+ z-index: 1;
35
+ height: stretch;
36
+ min-height: 21.5em;
37
+
38
+ @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {
39
+ overflow-y: auto;
40
+ outline: none;
41
+ }
42
+ `
43
+
44
+ interface DashboardWidgetProps {
45
+ header?: string
46
+ children: React.ReactNode
47
+ footer?: React.ReactNode
48
+ }
49
+
50
+ export const DashboardWidgetContainer = forwardRef(function DashboardWidgetContainer(
51
+ props: DashboardWidgetProps,
52
+ ref: React.Ref<HTMLDivElement>
53
+ ) {
54
+ const {header, children, footer} = props
55
+
56
+ return (
57
+ <Root radius={3} display="flex" ref={ref}>
58
+ {header && (
59
+ <Header borderBottom paddingX={3} paddingY={4}>
60
+ <Heading size={1} textOverflow="ellipsis">
61
+ {header}
62
+ </Heading>
63
+ </Header>
64
+ )}
65
+ {children && <Content>{children}</Content>}
66
+ {footer && <Footer borderTop>{footer}</Footer>}
67
+ </Root>
68
+ )
69
+ })
@@ -0,0 +1,30 @@
1
+ import React, {PropsWithChildren, ReactNode} from 'react'
2
+ import {Card, Stack, Heading, Box} from '@sanity/ui'
3
+ import styled from 'styled-components'
4
+
5
+ const Root = styled(Card)`
6
+ display: flex;
7
+ flex-direction: column;
8
+ justify-content: stretch;
9
+ height: 100%;
10
+ `
11
+
12
+ export type NotFoundWidgetProps = PropsWithChildren<{
13
+ title?: ReactNode
14
+ }>
15
+
16
+ export function NotFoundWidget(props: NotFoundWidgetProps) {
17
+ const {title, children} = props
18
+ return (
19
+ <Root radius={3} paddingX={3} paddingY={4} tone="critical">
20
+ <Stack space={2}>
21
+ {title && (
22
+ <Heading size={1} as="h2">
23
+ {title}
24
+ </Heading>
25
+ )}
26
+ {children && <Box>{children}</Box>}
27
+ </Stack>
28
+ </Root>
29
+ )
30
+ }
@@ -0,0 +1,108 @@
1
+ import React from 'react'
2
+ import styled, {css} from 'styled-components'
3
+ import {Box, Card, Grid, Text} from '@sanity/ui'
4
+ import {WidgetContainer} from '../containers/WidgetContainer'
5
+ import {DashboardConfig, LayoutConfig, DashboardWidget} from '../types'
6
+
7
+ const media = {
8
+ small: (...args: Parameters<typeof css>) =>
9
+ css`
10
+ @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {
11
+ ${css(...args)}
12
+ }
13
+ `,
14
+ medium: (...args: Parameters<typeof css>) =>
15
+ css`
16
+ @media (min-width: ${({theme}) => theme.sanity.media[2]}px) {
17
+ ${css(...args)}
18
+ }
19
+ `,
20
+ }
21
+
22
+ const Root = styled(Grid)`
23
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
24
+
25
+ & > div {
26
+ overflow: hidden;
27
+ }
28
+
29
+ & > div[data-width='medium'] {
30
+ ${media.small`
31
+ grid-column: span 2;
32
+ `}
33
+ }
34
+
35
+ & > div[data-width='large'] {
36
+ ${media.small`
37
+ grid-column: span 2;
38
+ `}
39
+
40
+ ${media.medium`
41
+ grid-column: span 3;
42
+ `}
43
+ }
44
+
45
+ & > div[data-width='full'] {
46
+ ${media.small`
47
+ grid-column: 1 / -1;
48
+ `}
49
+ }
50
+
51
+ & > div[data-height='medium'] {
52
+ ${media.small`
53
+ grid-row: span 2;
54
+ `}
55
+ }
56
+
57
+ & > div[data-height='large'] {
58
+ ${media.small`
59
+ grid-row: span 2;
60
+ `}
61
+
62
+ ${media.medium`
63
+ grid-row: span 3;
64
+ `}
65
+ }
66
+
67
+ & > div[data-height='full'] {
68
+ ${media.medium`
69
+ grid-row: 1 / -1;
70
+ `}
71
+ }
72
+ `
73
+
74
+ export interface WidgetGroupProps {
75
+ config: Partial<DashboardConfig>
76
+ }
77
+
78
+ const NO_WIDGETS: DashboardWidget[] = []
79
+ const NO_LAYOUT: LayoutConfig = {}
80
+
81
+ export function WidgetGroup(props: WidgetGroupProps) {
82
+ const {
83
+ config: {layout = NO_LAYOUT, widgets = NO_WIDGETS},
84
+ } = props
85
+ return (
86
+ <Root
87
+ autoFlow="row dense"
88
+ data-width={layout.width || 'auto'}
89
+ data-height={layout.height || 'auto'}
90
+ gap={4}
91
+ >
92
+ {widgets.length ? null : (
93
+ <Card padding={4} shadow={1} tone="primary">
94
+ <Text align="center">Add some widgets to populate this space.</Text>
95
+ </Card>
96
+ )}
97
+ {widgets.map((widgetConfig, index) => {
98
+ if (widgetConfig.type === '__experimental_group') {
99
+ return <WidgetGroup key={index} config={widgetConfig} />
100
+ }
101
+ if (widgetConfig.component) {
102
+ return <WidgetContainer key={index} {...widgetConfig} />
103
+ }
104
+ return <Box key={index}>{widgetConfig.name} is missing widget component</Box>
105
+ })}
106
+ </Root>
107
+ )
108
+ }
@@ -0,0 +1,19 @@
1
+ import React from 'react'
2
+ import {DashboardLayout} from '../components/DashboardLayout'
3
+ import {WidgetGroup} from '../components/WidgetGroup'
4
+ import {DashboardContext} from './DashboardContext'
5
+ import {DashboardConfig} from '../types'
6
+
7
+ export function Dashboard({config}: {config: DashboardConfig}) {
8
+ if (!config) {
9
+ return null
10
+ }
11
+
12
+ return (
13
+ <DashboardContext.Provider value={config}>
14
+ <DashboardLayout>
15
+ <WidgetGroup config={config} />
16
+ </DashboardLayout>
17
+ </DashboardContext.Provider>
18
+ )
19
+ }
@@ -0,0 +1,8 @@
1
+ import {createContext, useContext} from 'react'
2
+ import {DashboardConfig} from '../types'
3
+
4
+ export const DashboardContext = createContext<DashboardConfig>({widgets: []})
5
+
6
+ export function useDashboardConfig(): DashboardConfig {
7
+ return useContext(DashboardContext)
8
+ }
@@ -0,0 +1,21 @@
1
+ import React, {createElement, useMemo} from 'react'
2
+ import {useDashboardConfig} from './DashboardContext'
3
+ import {Card} from '@sanity/ui'
4
+ import {DashboardWidget} from '../types'
5
+
6
+ export function WidgetContainer(props: DashboardWidget) {
7
+ const config = useDashboardConfig()
8
+ const layout = useMemo(
9
+ () => ({
10
+ ...(props.layout || {}),
11
+ ...(config.layout || {}),
12
+ }),
13
+ [props.layout, config.layout]
14
+ )
15
+
16
+ return (
17
+ <Card shadow={1} data-width={layout.width} data-height={layout.height}>
18
+ {createElement(props.component, {})}
19
+ </Card>
20
+ )
21
+ }
package/src/index.tsx ADDED
@@ -0,0 +1,62 @@
1
+ import React, {CSSProperties} from 'react'
2
+ import {Dashboard} from './containers/Dashboard'
3
+ import {createPlugin} from 'sanity'
4
+ import {DashboardConfig, DashboardWidget, LayoutConfig} from './types'
5
+
6
+ const strokeStyle: CSSProperties = {
7
+ stroke: 'currentColor',
8
+ strokeWidth: 1.2,
9
+ }
10
+
11
+ const DashboardIcon = () => (
12
+ <svg
13
+ data-sanity-icon
14
+ viewBox="0 0 25 25"
15
+ fill="none"
16
+ xmlns="http://www.w3.org/2000/svg"
17
+ preserveAspectRatio="xMidYMid"
18
+ width="1em"
19
+ height="1em"
20
+ >
21
+ <path d="M19.5 19.5H5.5V5.5H19.5V19.5Z" style={strokeStyle} />
22
+ <path d="M5.5 12.5H19.5" style={strokeStyle} />
23
+ <path d="M14.5 19.5V12.5M10.5 12.5V5.5" style={strokeStyle} />
24
+ </svg>
25
+ )
26
+
27
+ export * from './types'
28
+ export * from './components/DashboardWidgetContainer'
29
+ export * from './widgets/projectInfo'
30
+ export * from './widgets/projectUsers'
31
+ export * from './widgets/sanityTutorials'
32
+
33
+ export interface DashboardPluginConfig {
34
+ widgets?: DashboardWidget[]
35
+
36
+ /**
37
+ * Will be used for widgets that do not define a layout directly.
38
+ */
39
+ defaultLayout?: LayoutConfig
40
+ }
41
+
42
+ export const dashboardTool = createPlugin<DashboardPluginConfig>((config = {}) => {
43
+ const pluginConfig: DashboardConfig = {
44
+ layout: config.defaultLayout ?? {},
45
+ widgets: config.widgets ?? [],
46
+ }
47
+
48
+ return {
49
+ name: 'dashboard',
50
+ tools: (prev, context) => {
51
+ return [
52
+ ...prev,
53
+ {
54
+ title: 'Dashboard',
55
+ name: 'dashboard',
56
+ icon: DashboardIcon,
57
+ component: () => <Dashboard config={pluginConfig} />,
58
+ },
59
+ ]
60
+ },
61
+ }
62
+ })
package/src/types.ts ADDED
@@ -0,0 +1,21 @@
1
+ import {ComponentClass, FunctionComponent} from 'react'
2
+
3
+ export interface DashboardWidget {
4
+ name: string
5
+ type?: '__experimental_group'
6
+ component: FunctionComponent<any> | ComponentClass<any>
7
+ layout?: LayoutConfig
8
+ widgets?: DashboardWidget[]
9
+ }
10
+
11
+ export type LayoutSize = 'auto' | 'small' | 'medium' | 'large' | 'full'
12
+
13
+ export interface LayoutConfig {
14
+ width?: LayoutSize
15
+ height?: LayoutSize
16
+ }
17
+
18
+ export interface DashboardConfig {
19
+ widgets: DashboardWidget[]
20
+ layout?: LayoutConfig
21
+ }
@@ -0,0 +1,7 @@
1
+ import {useClient} from 'sanity'
2
+ import {useMemo} from 'react'
3
+
4
+ export function useVersionedClient() {
5
+ const client = useClient()
6
+ return useMemo(() => client.withConfig({apiVersion: '1'}), [client])
7
+ }