@sanity/dashboard 4.1.2 → 4.1.4
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.
- package/LICENSE +1 -1
- package/lib/index.esm.js +29 -59
- package/lib/index.esm.js.map +1 -1
- package/lib/index.js +28 -58
- package/lib/index.js.map +1 -1
- package/lib/index.mjs +29 -59
- package/lib/index.mjs.map +1 -1
- package/package.json +15 -15
package/lib/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { forwardRef, createContext, useContext, useMemo, createElement, useState, useEffect, useCallback } from "react";
|
|
3
|
-
import { Card, Box, Heading,
|
|
3
|
+
import { Card, Box, Heading, Stack, Label, Grid, Text, Code, Button, rem, Flex, Spinner, Container } from "@sanity/ui";
|
|
4
4
|
import { styled, css } from "styled-components";
|
|
5
5
|
import { useClient, useListFormat, UserAvatar, useUserStore, definePlugin } from "sanity";
|
|
6
6
|
import { from } from "rxjs";
|
|
@@ -53,29 +53,16 @@ const DashboardContext = createContext({ widgets: [] });
|
|
|
53
53
|
function useDashboardConfig() {
|
|
54
54
|
return useContext(DashboardContext);
|
|
55
55
|
}
|
|
56
|
-
var __defProp$2 = Object.defineProperty, __getOwnPropSymbols$2 = Object.getOwnPropertySymbols, __hasOwnProp$2 = Object.prototype.hasOwnProperty, __propIsEnum$2 = Object.prototype.propertyIsEnumerable, __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$2 = (a, b) => {
|
|
57
|
-
for (var prop in b || (b = {}))
|
|
58
|
-
__hasOwnProp$2.call(b, prop) && __defNormalProp$2(a, prop, b[prop]);
|
|
59
|
-
if (__getOwnPropSymbols$2)
|
|
60
|
-
for (var prop of __getOwnPropSymbols$2(b))
|
|
61
|
-
__propIsEnum$2.call(b, prop) && __defNormalProp$2(a, prop, b[prop]);
|
|
62
|
-
return a;
|
|
63
|
-
};
|
|
64
56
|
function WidgetContainer(props) {
|
|
65
57
|
const config = useDashboardConfig(), layout = useMemo(
|
|
66
|
-
() =>
|
|
58
|
+
() => ({
|
|
59
|
+
...props.layout || {},
|
|
60
|
+
...config.layout || {}
|
|
61
|
+
}),
|
|
67
62
|
[props.layout, config.layout]
|
|
68
63
|
);
|
|
69
64
|
return /* @__PURE__ */ jsx(Card, { shadow: 1, "data-width": layout.width, "data-height": layout.height, children: createElement(props.component, {}) });
|
|
70
65
|
}
|
|
71
|
-
var __defProp$1 = Object.defineProperty, __getOwnPropSymbols$1 = Object.getOwnPropertySymbols, __hasOwnProp$1 = Object.prototype.hasOwnProperty, __propIsEnum$1 = Object.prototype.propertyIsEnumerable, __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues$1 = (a, b) => {
|
|
72
|
-
for (var prop in b || (b = {}))
|
|
73
|
-
__hasOwnProp$1.call(b, prop) && __defNormalProp$1(a, prop, b[prop]);
|
|
74
|
-
if (__getOwnPropSymbols$1)
|
|
75
|
-
for (var prop of __getOwnPropSymbols$1(b))
|
|
76
|
-
__propIsEnum$1.call(b, prop) && __defNormalProp$1(a, prop, b[prop]);
|
|
77
|
-
return a;
|
|
78
|
-
};
|
|
79
66
|
function isUrl(url) {
|
|
80
67
|
return url && /^https?:\/\//.test(`${url}`);
|
|
81
68
|
}
|
|
@@ -120,7 +107,6 @@ function ProjectInfo(props) {
|
|
|
120
107
|
};
|
|
121
108
|
}, [dataset, projectId, versionedClient, setGraphQLApi]);
|
|
122
109
|
const assembleTableRows = useMemo(() => {
|
|
123
|
-
var _a;
|
|
124
110
|
let result = [
|
|
125
111
|
{
|
|
126
112
|
title: "Sanity project",
|
|
@@ -144,7 +130,7 @@ function ProjectInfo(props) {
|
|
|
144
130
|
{ title: "GROQ", value: getGroqUrl(projectId, dataset) },
|
|
145
131
|
{
|
|
146
132
|
title: "GraphQL",
|
|
147
|
-
value: (
|
|
133
|
+
value: (typeof graphQLApi == "object" ? "Error" : graphQLApi) ?? "Not deployed"
|
|
148
134
|
}
|
|
149
135
|
]
|
|
150
136
|
}
|
|
@@ -159,8 +145,8 @@ function ProjectInfo(props) {
|
|
|
159
145
|
}), result;
|
|
160
146
|
}, [graphQLApi, studioApps, projectId, dataset, data]);
|
|
161
147
|
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
162
|
-
__experimental_before.map((widgetConfig, idx) => /* @__PURE__ */ jsx(WidgetContainer,
|
|
163
|
-
/* @__PURE__ */ jsx(Box, { height: "fill", marginTop:
|
|
148
|
+
__experimental_before.map((widgetConfig, idx) => /* @__PURE__ */ jsx(WidgetContainer, { ...widgetConfig }, idx)),
|
|
149
|
+
/* @__PURE__ */ jsx(Box, { height: "fill", marginTop: __experimental_before?.length > 0 ? 4 : 0, children: /* @__PURE__ */ jsx(
|
|
164
150
|
DashboardWidgetContainer,
|
|
165
151
|
{
|
|
166
152
|
footer: /* @__PURE__ */ jsx(
|
|
@@ -188,14 +174,11 @@ function ProjectInfo(props) {
|
|
|
188
174
|
/* @__PURE__ */ jsx(Box, { paddingX: 3, as: "header", children: /* @__PURE__ */ jsx(Heading, { size: 1, as: "h2", id: "project_info_table", children: "Project info" }) }),
|
|
189
175
|
assembleTableRows.map((item) => !item || !item.rows ? null : /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
|
|
190
176
|
/* @__PURE__ */ jsx(Card, { borderBottom: !0, padding: 3, children: /* @__PURE__ */ jsx(Label, { size: 0, muted: !0, role: "columnheader", children: item.title }) }),
|
|
191
|
-
/* @__PURE__ */ jsx(Stack, { space: 4, paddingX: 3, role: "rowgroup", children: item.rows.map((row) => {
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
typeof row.value == "string" && /* @__PURE__ */ jsx(Fragment, { children: isUrl(row.value) ? /* @__PURE__ */ jsx(Text, { size: 1, role: "cell", style: { wordBreak: "break-word" }, children: /* @__PURE__ */ jsx("a", { href: row.value, children: row.value }) }) : /* @__PURE__ */ jsx(Code, { size: 1, role: "cell", style: { wordBreak: "break-word" }, children: row.value }) })
|
|
197
|
-
] }, `${row.value}-${row.title}`);
|
|
198
|
-
}) })
|
|
177
|
+
/* @__PURE__ */ jsx(Stack, { space: 4, paddingX: 3, role: "rowgroup", children: item.rows.map((row) => /* @__PURE__ */ jsxs(Grid, { columns: 2, role: "row", children: [
|
|
178
|
+
/* @__PURE__ */ jsx(Text, { weight: "medium", role: "rowheader", children: row.title }),
|
|
179
|
+
typeof row.value == "object" && /* @__PURE__ */ jsx(Text, { size: 1, children: row.value?.error }),
|
|
180
|
+
typeof row.value == "string" && /* @__PURE__ */ jsx(Fragment, { children: isUrl(row.value) ? /* @__PURE__ */ jsx(Text, { size: 1, role: "cell", style: { wordBreak: "break-word" }, children: /* @__PURE__ */ jsx("a", { href: row.value, children: row.value }) }) : /* @__PURE__ */ jsx(Code, { size: 1, role: "cell", style: { wordBreak: "break-word" }, children: row.value }) })
|
|
181
|
+
] }, `${row.value}-${row.title}`)) })
|
|
199
182
|
] }, item.title))
|
|
200
183
|
] })
|
|
201
184
|
}
|
|
@@ -205,11 +188,10 @@ function ProjectInfo(props) {
|
|
|
205
188
|
] });
|
|
206
189
|
}
|
|
207
190
|
function projectInfoWidget(config) {
|
|
208
|
-
var _a;
|
|
209
191
|
return {
|
|
210
192
|
name: "project-info",
|
|
211
193
|
component: ProjectInfo,
|
|
212
|
-
layout:
|
|
194
|
+
layout: config?.layout ?? { width: "medium" }
|
|
213
195
|
};
|
|
214
196
|
}
|
|
215
197
|
const Root$2 = styled(Flex)`
|
|
@@ -282,15 +264,14 @@ function ProjectUsers() {
|
|
|
282
264
|
/* @__PURE__ */ jsx(Text, { align: "center", muted: !0, size: 1, children: /* @__PURE__ */ jsx(Spinner, {}) }),
|
|
283
265
|
/* @__PURE__ */ jsx(Text, { align: "center", size: 1, muted: !0, children: "Loading items\u2026" })
|
|
284
266
|
] }) }),
|
|
285
|
-
!isLoading && /* @__PURE__ */ jsx(Stack, { space: 3, padding: 3, children: users
|
|
286
|
-
var _a;
|
|
267
|
+
!isLoading && /* @__PURE__ */ jsx(Stack, { space: 3, padding: 3, children: users?.map((user) => {
|
|
287
268
|
const membership = project.members.find((member) => member.id === user.id);
|
|
288
269
|
return /* @__PURE__ */ jsx(
|
|
289
270
|
ProjectUser,
|
|
290
271
|
{
|
|
291
272
|
user,
|
|
292
|
-
isRobot:
|
|
293
|
-
roles:
|
|
273
|
+
isRobot: membership?.isRobot ?? !1,
|
|
274
|
+
roles: membership?.roles.map((role) => role.title) || []
|
|
294
275
|
},
|
|
295
276
|
user.id
|
|
296
277
|
);
|
|
@@ -300,14 +281,14 @@ function ProjectUsers() {
|
|
|
300
281
|
);
|
|
301
282
|
}
|
|
302
283
|
function sortUsersByRobotStatus(userA, userB, project) {
|
|
303
|
-
const { members } = project, membershipA = members.find((member) => member.id ===
|
|
304
|
-
return
|
|
284
|
+
const { members } = project, membershipA = members.find((member) => member.id === userA?.id), membershipB = members.find((member) => member.id === userB?.id);
|
|
285
|
+
return membershipA?.isRobot === membershipB?.isRobot ? (membershipA?.createdAt || "") > (membershipB?.createdAt || "") ? 1 : -1 : membershipA?.isRobot ? 1 : -1;
|
|
305
286
|
}
|
|
306
287
|
function projectUsersWidget(config) {
|
|
307
288
|
return {
|
|
308
289
|
name: "project-info",
|
|
309
290
|
component: ProjectUsers,
|
|
310
|
-
layout: config
|
|
291
|
+
layout: config?.layout
|
|
311
292
|
};
|
|
312
293
|
}
|
|
313
294
|
const PlayIconBox = styled(Box)`
|
|
@@ -416,16 +397,15 @@ function SanityTutorials(props) {
|
|
|
416
397
|
return () => {
|
|
417
398
|
subscription.unsubscribe();
|
|
418
399
|
};
|
|
419
|
-
}, [setFeedItems, getFeed, templateRepoId]), /* @__PURE__ */ jsx(DashboardWidgetContainer, { header: "Learn about Sanity", children: /* @__PURE__ */ jsx(Flex, { as: "ul", overflow: "auto", align: "stretch", paddingY: 2, children: feedItems
|
|
420
|
-
var _a;
|
|
400
|
+
}, [setFeedItems, getFeed, templateRepoId]), /* @__PURE__ */ jsx(DashboardWidgetContainer, { header: "Learn about Sanity", children: /* @__PURE__ */ jsx(Flex, { as: "ul", overflow: "auto", align: "stretch", paddingY: 2, children: feedItems?.map((feedItem, index) => {
|
|
421
401
|
if (!feedItem.title || !feedItem.guideOrTutorial && !feedItem.externalLink)
|
|
422
402
|
return null;
|
|
423
|
-
const presenter = feedItem.presenter ||
|
|
403
|
+
const presenter = feedItem.presenter || feedItem.guideOrTutorial?.presenter || {}, subtitle = feedItem.category, { guideOrTutorial = {} } = feedItem, href = (guideOrTutorial.slug ? createUrl(guideOrTutorial.slug, guideOrTutorial._type) : feedItem.externalLink) || feedItem.externalLink;
|
|
424
404
|
return /* @__PURE__ */ jsx(
|
|
425
405
|
Flex,
|
|
426
406
|
{
|
|
427
407
|
as: "li",
|
|
428
|
-
paddingRight: index <
|
|
408
|
+
paddingRight: index < feedItems?.length - 1 ? 1 : 3,
|
|
429
409
|
paddingLeft: index === 0 ? 3 : 0,
|
|
430
410
|
align: "stretch",
|
|
431
411
|
style: { minWidth: 272, width: "30%" },
|
|
@@ -433,7 +413,7 @@ function SanityTutorials(props) {
|
|
|
433
413
|
Tutorial,
|
|
434
414
|
{
|
|
435
415
|
title: feedItem.title,
|
|
436
|
-
href: href
|
|
416
|
+
href: href ?? "",
|
|
437
417
|
presenterName: presenter.name,
|
|
438
418
|
presenterSubtitle: subtitle,
|
|
439
419
|
showPlayIcon: feedItem.hasVideo,
|
|
@@ -446,24 +426,15 @@ function SanityTutorials(props) {
|
|
|
446
426
|
}) }) });
|
|
447
427
|
}
|
|
448
428
|
function sanityTutorialsWidget(config) {
|
|
449
|
-
var _a;
|
|
450
429
|
return {
|
|
451
430
|
name: "sanity-tutorials",
|
|
452
431
|
component: SanityTutorials,
|
|
453
|
-
layout:
|
|
432
|
+
layout: config?.layout ?? { width: "full" }
|
|
454
433
|
};
|
|
455
434
|
}
|
|
456
435
|
function DashboardLayout(props) {
|
|
457
436
|
return /* @__PURE__ */ jsx(Container, { width: 4, padding: 4, sizing: "border", style: { height: "100%", overflowY: "auto" }, children: props.children });
|
|
458
437
|
}
|
|
459
|
-
var __defProp = Object.defineProperty, __getOwnPropSymbols = Object.getOwnPropertySymbols, __hasOwnProp = Object.prototype.hasOwnProperty, __propIsEnum = Object.prototype.propertyIsEnumerable, __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: !0, configurable: !0, writable: !0, value }) : obj[key] = value, __spreadValues = (a, b) => {
|
|
460
|
-
for (var prop in b || (b = {}))
|
|
461
|
-
__hasOwnProp.call(b, prop) && __defNormalProp(a, prop, b[prop]);
|
|
462
|
-
if (__getOwnPropSymbols)
|
|
463
|
-
for (var prop of __getOwnPropSymbols(b))
|
|
464
|
-
__propIsEnum.call(b, prop) && __defNormalProp(a, prop, b[prop]);
|
|
465
|
-
return a;
|
|
466
|
-
};
|
|
467
438
|
const media = {
|
|
468
439
|
small: (...args) => css`
|
|
469
440
|
@media (min-width: ${({ theme }) => theme.sanity.media[0]}px) {
|
|
@@ -539,7 +510,7 @@ function WidgetGroup(props) {
|
|
|
539
510
|
gap: 4,
|
|
540
511
|
children: [
|
|
541
512
|
widgets.length ? null : /* @__PURE__ */ jsx(Card, { padding: 4, shadow: 1, tone: "primary", children: /* @__PURE__ */ jsx(Text, { align: "center", children: "Add some widgets to populate this space." }) }),
|
|
542
|
-
widgets.map((widgetConfig, index) => widgetConfig.type === "__experimental_group" ? /* @__PURE__ */ jsx(WidgetGroup, { config: widgetConfig }, index) : widgetConfig.component ? /* @__PURE__ */ jsx(WidgetContainer,
|
|
513
|
+
widgets.map((widgetConfig, index) => widgetConfig.type === "__experimental_group" ? /* @__PURE__ */ jsx(WidgetGroup, { config: widgetConfig }, index) : widgetConfig.component ? /* @__PURE__ */ jsx(WidgetContainer, { ...widgetConfig }, index) : /* @__PURE__ */ jsxs(Box, { children: [
|
|
543
514
|
widgetConfig.name,
|
|
544
515
|
" is missing widget component"
|
|
545
516
|
] }, index))
|
|
@@ -570,11 +541,10 @@ const strokeStyle = {
|
|
|
570
541
|
]
|
|
571
542
|
}
|
|
572
543
|
), dashboardTool = definePlugin((config = {}) => {
|
|
573
|
-
var _a, _b, _c, _d, _e;
|
|
574
544
|
const pluginConfig = {
|
|
575
|
-
layout:
|
|
576
|
-
widgets:
|
|
577
|
-
}, title =
|
|
545
|
+
layout: config.defaultLayout ?? {},
|
|
546
|
+
widgets: config.widgets ?? []
|
|
547
|
+
}, title = config.title ?? "Dashboard", name = config.name ?? "dashboard", icon = config.icon ?? DashboardIcon;
|
|
578
548
|
return {
|
|
579
549
|
name: "dashboard",
|
|
580
550
|
tools: (prev, context) => [
|
package/lib/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","sources":["../src/components/DashboardWidgetContainer.tsx","../src/versionedClient.ts","../src/containers/DashboardContext.tsx","../src/containers/WidgetContainer.tsx","../src/widgets/projectInfo/ProjectInfo.tsx","../src/widgets/projectInfo/index.ts","../src/widgets/projectUsers/ProjectUser.tsx","../src/widgets/projectUsers/ProjectUsers.tsx","../src/widgets/projectUsers/index.ts","../src/widgets/sanityTutorials/Tutorial.tsx","../src/widgets/sanityTutorials/dataAdapter.ts","../src/widgets/sanityTutorials/SanityTutorials.tsx","../src/widgets/sanityTutorials/index.ts","../src/components/DashboardLayout.tsx","../src/components/WidgetGroup.tsx","../src/containers/Dashboard.tsx","../src/plugin.tsx"],"sourcesContent":["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 {useClient} from 'sanity'\n\nexport function useVersionedClient() {\n return useClient({apiVersion: '2024-08-01'})\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 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 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 {type DashboardWidget} from '../../types'\nimport {type App, type ProjectInfoProps, type ProjectData, UserApplication} from './types'\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 [studioApps, setStudioApps] = useState<UserApplication[] | {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<UserApplication[]>({uri: '/user-applications', tag: 'dashboard.project-info'})\n .subscribe({\n next: (result) => setStudioApps(result.filter((app) => app.type === 'studio')),\n error: (error) => {\n console.error('Error while resolving user applications', error)\n setStudioApps({\n error: 'Something went wrong while resolving user applications. 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 tag: 'dashboard.project-info.graphql-api',\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])\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 const apps: App[] = data.filter((item) => item.category === 'apps')\n\n // Handle studios\n ;(Array.isArray(studioApps) ? studioApps : []).forEach((app) => {\n apps.push({\n title: app.title || 'Studio',\n value: app.urlType === 'internal' ? `https://${app.appHost}.sanity.studio` : app.appHost,\n })\n })\n\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, studioApps, 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.value}-${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 {ProjectInfo} from './ProjectInfo'\nimport {type LayoutConfig, type 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 from 'react'\nimport {Box, Flex, rem, Stack, Text} from '@sanity/ui'\nimport {styled} from 'styled-components'\nimport {useListFormat, type User, UserAvatar} from 'sanity'\nimport {RobotIcon} from '@sanity/icons'\n\nconst Root = styled(Flex)`\n height: ${rem(33)}; // 33 = PREVIEW_SIZES.default.media.height\n box-sizing: content-box;\n`\n\nexport interface ProjectUserProps {\n user: User\n isRobot: boolean\n roles: string[]\n}\n\nexport function ProjectUser({user, isRobot, roles}: ProjectUserProps) {\n const listFormat = useListFormat({style: 'narrow'})\n return (\n <Root align=\"center\">\n <Flex align=\"center\" flex={1} gap={2}>\n <Box flex=\"none\">\n {isRobot ? (\n <Text size={2}>\n <RobotIcon />\n </Text>\n ) : (\n <UserAvatar user={user} />\n )}\n </Box>\n\n <Stack flex={1} space={2}>\n <Text size={1} style={{color: 'inherit'}} textOverflow=\"ellipsis\" weight=\"medium\">\n {user.displayName}\n </Text>\n\n <Text muted size={1} textOverflow=\"ellipsis\">\n {listFormat.format(roles)}\n </Text>\n </Stack>\n </Flex>\n </Root>\n )\n}\n","import React, {useCallback, useEffect, useState} from 'react'\nimport {from} from 'rxjs'\nimport {map, switchMap} from 'rxjs/operators'\nimport {Stack, Spinner, Box, Text, Button} from '@sanity/ui'\nimport {Role, useUserStore} from 'sanity'\nimport {useVersionedClient} from '../../versionedClient'\nimport {User} from 'sanity'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\nimport {ProjectUser} from './ProjectUser'\n\nfunction getInviteUrl(projectId: string) {\n return `https://manage.sanity.io/projects/${projectId}/members`\n}\n\ninterface Member {\n id: string\n roles: Role[]\n isRobot: boolean\n isCurrentUser: boolean\n createdAt: string\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 userStore = useUserStore()\n const versionedClient = useVersionedClient()\n\n const fetchData = useCallback(() => {\n const {projectId} = versionedClient.config()\n const subscription = versionedClient.observable\n .request<Project>({\n uri: `/projects/${projectId}`,\n tag: 'dashboard.project-users',\n })\n .pipe(\n switchMap((_project) =>\n from(userStore.getUsers(_project.members.map((mem) => mem.id))).pipe(\n map((_users) => ({project: _project, users: _users})),\n ),\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=\"Manage 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 return (\n <ProjectUser\n key={user.id}\n user={user}\n isRobot={membership?.isRobot ?? false}\n roles={membership?.roles.map((role) => role.title) || []}\n />\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\n // On ties, sort by when the user was added\n if (membershipA?.isRobot === membershipB?.isRobot) {\n return (membershipA?.createdAt || '') > (membershipB?.createdAt || '') ? 1 : -1\n }\n\n // Robots go to the bottom\n return membershipA?.isRobot ? 1 : -1\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 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 tag: 'dashboard.sanity-tutorials',\n withCredentials: false,\n })\n },\n urlBuilder: imageUrlBuilder(tutorialsProjectConfig),\n }),\n [versionedClient],\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 {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, {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={{height: '100%', overflowY: 'auto'}}>\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>) => css`\n @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {\n ${css(...args)}\n }\n `,\n medium: (...args: Parameters<typeof css>) => 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 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, {ComponentType, CSSProperties} from 'react'\nimport {Dashboard} from './containers/Dashboard'\nimport {definePlugin} 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 interface DashboardPluginConfig {\n /**\n * Dashboard tool title\n */\n title?: string\n /**\n * Dashboard tool name (used in url path)\n */\n name?: string\n /**\n * Dashboard tool icon\n */\n icon?: ComponentType\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 = definePlugin<DashboardPluginConfig>((config = {}) => {\n const pluginConfig: DashboardConfig = {\n layout: config.defaultLayout ?? {},\n widgets: config.widgets ?? [],\n }\n\n const title = config.title ?? 'Dashboard'\n const name = config.name ?? 'dashboard'\n const icon = config.icon ?? DashboardIcon\n\n return {\n name: 'dashboard',\n tools: (prev, context) => {\n return [\n ...prev,\n {\n title,\n name,\n icon,\n component: () => <Dashboard config={pluginConfig} />,\n },\n ]\n },\n }\n})\n"],"names":["Root","__spreadValues"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../src/components/DashboardWidgetContainer.tsx","../src/versionedClient.ts","../src/containers/DashboardContext.tsx","../src/containers/WidgetContainer.tsx","../src/widgets/projectInfo/ProjectInfo.tsx","../src/widgets/projectInfo/index.ts","../src/widgets/projectUsers/ProjectUser.tsx","../src/widgets/projectUsers/ProjectUsers.tsx","../src/widgets/projectUsers/index.ts","../src/widgets/sanityTutorials/Tutorial.tsx","../src/widgets/sanityTutorials/dataAdapter.ts","../src/widgets/sanityTutorials/SanityTutorials.tsx","../src/widgets/sanityTutorials/index.ts","../src/components/DashboardLayout.tsx","../src/components/WidgetGroup.tsx","../src/containers/Dashboard.tsx","../src/plugin.tsx"],"sourcesContent":["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 {useClient} from 'sanity'\n\nexport function useVersionedClient() {\n return useClient({apiVersion: '2024-08-01'})\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 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 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 {type DashboardWidget} from '../../types'\nimport {type App, type ProjectInfoProps, type ProjectData, UserApplication} from './types'\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 [studioApps, setStudioApps] = useState<UserApplication[] | {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<UserApplication[]>({uri: '/user-applications', tag: 'dashboard.project-info'})\n .subscribe({\n next: (result) => setStudioApps(result.filter((app) => app.type === 'studio')),\n error: (error) => {\n console.error('Error while resolving user applications', error)\n setStudioApps({\n error: 'Something went wrong while resolving user applications. 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 tag: 'dashboard.project-info.graphql-api',\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])\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 const apps: App[] = data.filter((item) => item.category === 'apps')\n\n // Handle studios\n ;(Array.isArray(studioApps) ? studioApps : []).forEach((app) => {\n apps.push({\n title: app.title || 'Studio',\n value: app.urlType === 'internal' ? `https://${app.appHost}.sanity.studio` : app.appHost,\n })\n })\n\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, studioApps, 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.value}-${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 {ProjectInfo} from './ProjectInfo'\nimport {type LayoutConfig, type 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 from 'react'\nimport {Box, Flex, rem, Stack, Text} from '@sanity/ui'\nimport {styled} from 'styled-components'\nimport {useListFormat, type User, UserAvatar} from 'sanity'\nimport {RobotIcon} from '@sanity/icons'\n\nconst Root = styled(Flex)`\n height: ${rem(33)}; // 33 = PREVIEW_SIZES.default.media.height\n box-sizing: content-box;\n`\n\nexport interface ProjectUserProps {\n user: User\n isRobot: boolean\n roles: string[]\n}\n\nexport function ProjectUser({user, isRobot, roles}: ProjectUserProps) {\n const listFormat = useListFormat({style: 'narrow'})\n return (\n <Root align=\"center\">\n <Flex align=\"center\" flex={1} gap={2}>\n <Box flex=\"none\">\n {isRobot ? (\n <Text size={2}>\n <RobotIcon />\n </Text>\n ) : (\n <UserAvatar user={user} />\n )}\n </Box>\n\n <Stack flex={1} space={2}>\n <Text size={1} style={{color: 'inherit'}} textOverflow=\"ellipsis\" weight=\"medium\">\n {user.displayName}\n </Text>\n\n <Text muted size={1} textOverflow=\"ellipsis\">\n {listFormat.format(roles)}\n </Text>\n </Stack>\n </Flex>\n </Root>\n )\n}\n","import React, {useCallback, useEffect, useState} from 'react'\nimport {from} from 'rxjs'\nimport {map, switchMap} from 'rxjs/operators'\nimport {Stack, Spinner, Box, Text, Button} from '@sanity/ui'\nimport {Role, useUserStore} from 'sanity'\nimport {useVersionedClient} from '../../versionedClient'\nimport {User} from 'sanity'\nimport {DashboardWidgetContainer} from '../../components/DashboardWidgetContainer'\nimport {ProjectUser} from './ProjectUser'\n\nfunction getInviteUrl(projectId: string) {\n return `https://manage.sanity.io/projects/${projectId}/members`\n}\n\ninterface Member {\n id: string\n roles: Role[]\n isRobot: boolean\n isCurrentUser: boolean\n createdAt: string\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 userStore = useUserStore()\n const versionedClient = useVersionedClient()\n\n const fetchData = useCallback(() => {\n const {projectId} = versionedClient.config()\n const subscription = versionedClient.observable\n .request<Project>({\n uri: `/projects/${projectId}`,\n tag: 'dashboard.project-users',\n })\n .pipe(\n switchMap((_project) =>\n from(userStore.getUsers(_project.members.map((mem) => mem.id))).pipe(\n map((_users) => ({project: _project, users: _users})),\n ),\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=\"Manage 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 return (\n <ProjectUser\n key={user.id}\n user={user}\n isRobot={membership?.isRobot ?? false}\n roles={membership?.roles.map((role) => role.title) || []}\n />\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\n // On ties, sort by when the user was added\n if (membershipA?.isRobot === membershipB?.isRobot) {\n return (membershipA?.createdAt || '') > (membershipB?.createdAt || '') ? 1 : -1\n }\n\n // Robots go to the bottom\n return membershipA?.isRobot ? 1 : -1\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 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 tag: 'dashboard.sanity-tutorials',\n withCredentials: false,\n })\n },\n urlBuilder: imageUrlBuilder(tutorialsProjectConfig),\n }),\n [versionedClient],\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 {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, {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={{height: '100%', overflowY: 'auto'}}>\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>) => css`\n @media (min-width: ${({theme}) => theme.sanity.media[0]}px) {\n ${css(...args)}\n }\n `,\n medium: (...args: Parameters<typeof css>) => 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 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, {ComponentType, CSSProperties} from 'react'\nimport {Dashboard} from './containers/Dashboard'\nimport {definePlugin} 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 interface DashboardPluginConfig {\n /**\n * Dashboard tool title\n */\n title?: string\n /**\n * Dashboard tool name (used in url path)\n */\n name?: string\n /**\n * Dashboard tool icon\n */\n icon?: ComponentType\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 = definePlugin<DashboardPluginConfig>((config = {}) => {\n const pluginConfig: DashboardConfig = {\n layout: config.defaultLayout ?? {},\n widgets: config.widgets ?? [],\n }\n\n const title = config.title ?? 'Dashboard'\n const name = config.name ?? 'dashboard'\n const icon = config.icon ?? DashboardIcon\n\n return {\n name: 'dashboard',\n tools: (prev, context) => {\n return [\n ...prev,\n {\n title,\n name,\n icon,\n component: () => <Dashboard config={pluginConfig} />,\n },\n ]\n },\n }\n})\n"],"names":["Root"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/dashboard",
|
|
3
|
-
"version": "4.1.
|
|
3
|
+
"version": "4.1.4",
|
|
4
4
|
"description": "Tool for rendering dashboard widgets",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -64,37 +64,37 @@
|
|
|
64
64
|
"rxjs": "^7.8.1"
|
|
65
65
|
},
|
|
66
66
|
"devDependencies": {
|
|
67
|
-
"@commitlint/cli": "^19.
|
|
68
|
-
"@commitlint/config-conventional": "^19.
|
|
69
|
-
"@sanity/pkg-utils": "^6.
|
|
70
|
-
"@sanity/plugin-kit": "^4.0.
|
|
67
|
+
"@commitlint/cli": "^19.8.0",
|
|
68
|
+
"@commitlint/config-conventional": "^19.8.0",
|
|
69
|
+
"@sanity/pkg-utils": "^6.13.4",
|
|
70
|
+
"@sanity/plugin-kit": "^4.0.19",
|
|
71
71
|
"@sanity/semantic-release-preset": "^5.0.0",
|
|
72
|
-
"@types/react": "^18.3.
|
|
72
|
+
"@types/react": "^18.3.18",
|
|
73
73
|
"@typescript-eslint/eslint-plugin": "^7.18.0",
|
|
74
74
|
"@typescript-eslint/parser": "^7.18.0",
|
|
75
75
|
"eslint": "^8.57.1",
|
|
76
76
|
"eslint-config-prettier": "^9.1.0",
|
|
77
77
|
"eslint-config-sanity": "^6.0.0",
|
|
78
|
-
"eslint-plugin-prettier": "^5.2.
|
|
79
|
-
"eslint-plugin-react": "^7.37.
|
|
78
|
+
"eslint-plugin-prettier": "^5.2.3",
|
|
79
|
+
"eslint-plugin-react": "^7.37.4",
|
|
80
80
|
"eslint-plugin-react-hooks": "^4.6.2",
|
|
81
81
|
"husky": "^8.0.3",
|
|
82
82
|
"lint-staged": "^15.2.11",
|
|
83
83
|
"npm-run-all2": "^5.0.2",
|
|
84
|
-
"prettier": "^3.
|
|
85
|
-
"prettier-plugin-packagejson": "^2.5.
|
|
84
|
+
"prettier": "^3.5.3",
|
|
85
|
+
"prettier-plugin-packagejson": "^2.5.10",
|
|
86
86
|
"react": "^18.3.1",
|
|
87
87
|
"react-dom": "^18.3.1",
|
|
88
88
|
"react-is": "^18.3.1",
|
|
89
89
|
"rimraf": "^6.0.0",
|
|
90
|
-
"sanity": "^3.
|
|
91
|
-
"semantic-release": "^24.2.
|
|
92
|
-
"styled-components": "^6.1.
|
|
93
|
-
"typescript": "^5.7.
|
|
90
|
+
"sanity": "^3.78.1",
|
|
91
|
+
"semantic-release": "^24.2.3",
|
|
92
|
+
"styled-components": "^6.1.15",
|
|
93
|
+
"typescript": "^5.7.3"
|
|
94
94
|
},
|
|
95
95
|
"peerDependencies": {
|
|
96
96
|
"react": "^18 || >=19.0.0-0",
|
|
97
|
-
"sanity": "^3",
|
|
97
|
+
"sanity": "^3 || ^4.0.0-0",
|
|
98
98
|
"styled-components": "^6.1"
|
|
99
99
|
},
|
|
100
100
|
"engines": {
|