@sanity/dashboard 4.1.0 → 4.1.2

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/lib/index.mjs CHANGED
@@ -53,16 +53,29 @@ 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
+ };
56
64
  function WidgetContainer(props) {
57
65
  const config = useDashboardConfig(), layout = useMemo(
58
- () => ({
59
- ...props.layout || {},
60
- ...config.layout || {}
61
- }),
66
+ () => __spreadValues$2(__spreadValues$2({}, props.layout || {}), config.layout || {}),
62
67
  [props.layout, config.layout]
63
68
  );
64
69
  return /* @__PURE__ */ jsx(Card, { shadow: 1, "data-width": layout.width, "data-height": layout.height, children: createElement(props.component, {}) });
65
70
  }
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
+ };
66
79
  function isUrl(url) {
67
80
  return url && /^https?:\/\//.test(`${url}`);
68
81
  }
@@ -107,6 +120,7 @@ function ProjectInfo(props) {
107
120
  };
108
121
  }, [dataset, projectId, versionedClient, setGraphQLApi]);
109
122
  const assembleTableRows = useMemo(() => {
123
+ var _a;
110
124
  let result = [
111
125
  {
112
126
  title: "Sanity project",
@@ -130,7 +144,7 @@ function ProjectInfo(props) {
130
144
  { title: "GROQ", value: getGroqUrl(projectId, dataset) },
131
145
  {
132
146
  title: "GraphQL",
133
- value: (typeof graphQLApi == "object" ? "Error" : graphQLApi) ?? "Not deployed"
147
+ value: (_a = typeof graphQLApi == "object" ? "Error" : graphQLApi) != null ? _a : "Not deployed"
134
148
  }
135
149
  ]
136
150
  }
@@ -145,8 +159,8 @@ function ProjectInfo(props) {
145
159
  }), result;
146
160
  }, [graphQLApi, studioApps, projectId, dataset, data]);
147
161
  return /* @__PURE__ */ jsxs(Fragment, { children: [
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(
162
+ __experimental_before.map((widgetConfig, idx) => /* @__PURE__ */ jsx(WidgetContainer, __spreadValues$1({}, widgetConfig), idx)),
163
+ /* @__PURE__ */ jsx(Box, { height: "fill", marginTop: (__experimental_before == null ? void 0 : __experimental_before.length) > 0 ? 4 : 0, children: /* @__PURE__ */ jsx(
150
164
  DashboardWidgetContainer,
151
165
  {
152
166
  footer: /* @__PURE__ */ jsx(
@@ -174,11 +188,14 @@ function ProjectInfo(props) {
174
188
  /* @__PURE__ */ jsx(Box, { paddingX: 3, as: "header", children: /* @__PURE__ */ jsx(Heading, { size: 1, as: "h2", id: "project_info_table", children: "Project info" }) }),
175
189
  assembleTableRows.map((item) => !item || !item.rows ? null : /* @__PURE__ */ jsxs(Stack, { space: 3, children: [
176
190
  /* @__PURE__ */ jsx(Card, { borderBottom: !0, padding: 3, children: /* @__PURE__ */ jsx(Label, { size: 0, muted: !0, role: "columnheader", children: item.title }) }),
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}`)) })
191
+ /* @__PURE__ */ jsx(Stack, { space: 4, paddingX: 3, role: "rowgroup", children: item.rows.map((row) => {
192
+ var _a;
193
+ return /* @__PURE__ */ jsxs(Grid, { columns: 2, role: "row", children: [
194
+ /* @__PURE__ */ jsx(Text, { weight: "medium", role: "rowheader", children: row.title }),
195
+ typeof row.value == "object" && /* @__PURE__ */ jsx(Text, { size: 1, children: (_a = row.value) == null ? void 0 : _a.error }),
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
+ }) })
182
199
  ] }, item.title))
183
200
  ] })
184
201
  }
@@ -188,10 +205,11 @@ function ProjectInfo(props) {
188
205
  ] });
189
206
  }
190
207
  function projectInfoWidget(config) {
208
+ var _a;
191
209
  return {
192
210
  name: "project-info",
193
211
  component: ProjectInfo,
194
- layout: config?.layout ?? { width: "medium" }
212
+ layout: (_a = config == null ? void 0 : config.layout) != null ? _a : { width: "medium" }
195
213
  };
196
214
  }
197
215
  const Root$2 = styled(Flex)`
@@ -264,14 +282,15 @@ function ProjectUsers() {
264
282
  /* @__PURE__ */ jsx(Text, { align: "center", muted: !0, size: 1, children: /* @__PURE__ */ jsx(Spinner, {}) }),
265
283
  /* @__PURE__ */ jsx(Text, { align: "center", size: 1, muted: !0, children: "Loading items\u2026" })
266
284
  ] }) }),
267
- !isLoading && /* @__PURE__ */ jsx(Stack, { space: 3, padding: 3, children: users?.map((user) => {
285
+ !isLoading && /* @__PURE__ */ jsx(Stack, { space: 3, padding: 3, children: users == null ? void 0 : users.map((user) => {
286
+ var _a;
268
287
  const membership = project.members.find((member) => member.id === user.id);
269
288
  return /* @__PURE__ */ jsx(
270
289
  ProjectUser,
271
290
  {
272
291
  user,
273
- isRobot: membership?.isRobot ?? !1,
274
- roles: membership?.roles.map((role) => role.title) || []
292
+ isRobot: (_a = membership == null ? void 0 : membership.isRobot) != null ? _a : !1,
293
+ roles: (membership == null ? void 0 : membership.roles.map((role) => role.title)) || []
275
294
  },
276
295
  user.id
277
296
  );
@@ -281,14 +300,14 @@ function ProjectUsers() {
281
300
  );
282
301
  }
283
302
  function sortUsersByRobotStatus(userA, userB, project) {
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;
303
+ const { members } = project, membershipA = members.find((member) => member.id === (userA == null ? void 0 : userA.id)), membershipB = members.find((member) => member.id === (userB == null ? void 0 : userB.id));
304
+ return (membershipA == null ? void 0 : membershipA.isRobot) === (membershipB == null ? void 0 : membershipB.isRobot) ? ((membershipA == null ? void 0 : membershipA.createdAt) || "") > ((membershipB == null ? void 0 : membershipB.createdAt) || "") ? 1 : -1 : membershipA != null && membershipA.isRobot ? 1 : -1;
286
305
  }
287
306
  function projectUsersWidget(config) {
288
307
  return {
289
308
  name: "project-info",
290
309
  component: ProjectUsers,
291
- layout: config?.layout
310
+ layout: config == null ? void 0 : config.layout
292
311
  };
293
312
  }
294
313
  const PlayIconBox = styled(Box)`
@@ -397,15 +416,16 @@ function SanityTutorials(props) {
397
416
  return () => {
398
417
  subscription.unsubscribe();
399
418
  };
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) => {
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 == null ? void 0 : feedItems.map((feedItem, index) => {
420
+ var _a;
401
421
  if (!feedItem.title || !feedItem.guideOrTutorial && !feedItem.externalLink)
402
422
  return null;
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;
423
+ const presenter = feedItem.presenter || ((_a = feedItem.guideOrTutorial) == null ? void 0 : _a.presenter) || {}, subtitle = feedItem.category, { guideOrTutorial = {} } = feedItem, href = (guideOrTutorial.slug ? createUrl(guideOrTutorial.slug, guideOrTutorial._type) : feedItem.externalLink) || feedItem.externalLink;
404
424
  return /* @__PURE__ */ jsx(
405
425
  Flex,
406
426
  {
407
427
  as: "li",
408
- paddingRight: index < feedItems?.length - 1 ? 1 : 3,
428
+ paddingRight: index < (feedItems == null ? void 0 : feedItems.length) - 1 ? 1 : 3,
409
429
  paddingLeft: index === 0 ? 3 : 0,
410
430
  align: "stretch",
411
431
  style: { minWidth: 272, width: "30%" },
@@ -413,7 +433,7 @@ function SanityTutorials(props) {
413
433
  Tutorial,
414
434
  {
415
435
  title: feedItem.title,
416
- href: href ?? "",
436
+ href: href != null ? href : "",
417
437
  presenterName: presenter.name,
418
438
  presenterSubtitle: subtitle,
419
439
  showPlayIcon: feedItem.hasVideo,
@@ -426,15 +446,24 @@ function SanityTutorials(props) {
426
446
  }) }) });
427
447
  }
428
448
  function sanityTutorialsWidget(config) {
449
+ var _a;
429
450
  return {
430
451
  name: "sanity-tutorials",
431
452
  component: SanityTutorials,
432
- layout: config?.layout ?? { width: "full" }
453
+ layout: (_a = config == null ? void 0 : config.layout) != null ? _a : { width: "full" }
433
454
  };
434
455
  }
435
456
  function DashboardLayout(props) {
436
457
  return /* @__PURE__ */ jsx(Container, { width: 4, padding: 4, sizing: "border", style: { height: "100%", overflowY: "auto" }, children: props.children });
437
458
  }
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
+ };
438
467
  const media = {
439
468
  small: (...args) => css`
440
469
  @media (min-width: ${({ theme }) => theme.sanity.media[0]}px) {
@@ -510,7 +539,7 @@ function WidgetGroup(props) {
510
539
  gap: 4,
511
540
  children: [
512
541
  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." }) }),
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: [
542
+ widgets.map((widgetConfig, index) => widgetConfig.type === "__experimental_group" ? /* @__PURE__ */ jsx(WidgetGroup, { config: widgetConfig }, index) : widgetConfig.component ? /* @__PURE__ */ jsx(WidgetContainer, __spreadValues({}, widgetConfig), index) : /* @__PURE__ */ jsxs(Box, { children: [
514
543
  widgetConfig.name,
515
544
  " is missing widget component"
516
545
  ] }, index))
@@ -541,10 +570,11 @@ const strokeStyle = {
541
570
  ]
542
571
  }
543
572
  ), dashboardTool = definePlugin((config = {}) => {
573
+ var _a, _b, _c, _d, _e;
544
574
  const pluginConfig = {
545
- layout: config.defaultLayout ?? {},
546
- widgets: config.widgets ?? []
547
- }, title = config.title ?? "Dashboard", name = config.name ?? "dashboard", icon = config.icon ?? DashboardIcon;
575
+ layout: (_a = config.defaultLayout) != null ? _a : {},
576
+ widgets: (_b = config.widgets) != null ? _b : []
577
+ }, title = (_c = config.title) != null ? _c : "Dashboard", name = (_d = config.name) != null ? _d : "dashboard", icon = (_e = config.icon) != null ? _e : DashboardIcon;
548
578
  return {
549
579
  name: "dashboard",
550
580
  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"],"mappings":";;;;;;;;;AAIA,MAAMA,SAAO,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GASlB,SAAS,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAQpB,SAAS,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAUpB,UAAU,OAAO,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,uBAMH,CAAC,EAAC,YAAW,MAAM,OAAO,MAAM,CAAC,CAAC;AAAA;AAAA;AAAA;AAAA,GAY5C,2BAA2B,WAAW,SACjD,OACA,KACA;AACA,QAAM,EAAC,QAAQ,UAAU,OAAA,IAAU;AAEnC,8BACGA,QAAK,EAAA,QAAQ,GAAG,SAAQ,QAAO,KAC7B,UAAA;AAAA,IAAA,UACE,oBAAA,QAAA,EAAO,cAAY,IAAC,UAAU,GAAG,UAAU,GAC1C,UAAA,oBAAC,WAAQ,MAAM,GAAG,cAAa,YAC5B,iBACH,CAAA,GACF;AAAA,IAED,YAAa,oBAAA,SAAA,EAAS,SAAS,CAAA;AAAA,IAC/B,UAAU,oBAAC,QAAO,EAAA,WAAS,IAAE,UAAO,QAAA;AAAA,EACvC,EAAA,CAAA;AAEJ,CAAC;AClEM,SAAS,qBAAqB;AACnC,SAAO,UAAU,EAAC,YAAY,aAAa,CAAA;AAC7C;ACDO,MAAM,mBAAmB,cAA+B,EAAC,SAAS,CAAA,EAAG,CAAA;AAErE,SAAS,qBAAsC;AACpD,SAAO,WAAW,gBAAgB;AACpC;ACFO,SAAS,gBAAgB,OAAwB;AAChD,QAAA,SAAS,sBACT,SAAS;AAAA,IACb,OAAO;AAAA,MACL,GAAI,MAAM,UAAU,CAAC;AAAA,MACrB,GAAI,OAAO,UAAU,CAAC;AAAA,IAAA;AAAA,IAExB,CAAC,MAAM,QAAQ,OAAO,MAAM;AAAA,EAAA;AAG9B,SACG,oBAAA,MAAA,EAAK,QAAQ,GAAG,cAAY,OAAO,OAAO,eAAa,OAAO,QAC5D,UAAc,cAAA,MAAM,WAAW,CAAA,CAAE,EACpC,CAAA;AAEJ;ACXA,SAAS,MAAM,KAAc;AAC3B,SAAO,OAAO,eAAe,KAAK,GAAG,GAAG,EAAE;AAC5C;AAEA,SAAS,cAAc,WAAmB,SAAiB;AAClD,SAAA,WAAW,SAAS,6BAA6B,OAAO;AACjE;AAEA,SAAS,WAAW,WAAmB,SAAiB;AAC/C,SAAA,WAAW,SAAS,0BAA0B,OAAO;AAC9D;AAEA,SAAS,aAAa,WAAmB;AACvC,SAAO,qCAAqC,SAAS;AACvD;AAEA,MAAM,kBAAqC,CAAA,GACrC,UAAyB;AAExB,SAAS,YAAY,OAAyB;AACnD,QAAM,EAAC,wBAAwB,iBAAiB,OAAO,QAAO,IAAI,OAC5D,CAAC,YAAY,aAAa,IAAI,SAAA,GAC9B,CAAC,YAAY,aAAa,IAAI,SAC9B,GAAA,kBAAkB,mBAAmB,GACrC,EAAC,YAAY,WAAW,UAAU,UAAS,IAAI,gBAAgB,OAAO;AAE5E,YAAU,MAAM;AACd,UAAM,gBAAgC,CAAA;AAExB,WAAA,cAAA;AAAA,MACZ,gBAAgB,WACb,QAA2B,EAAC,KAAK,sBAAsB,KAAK,0BAAyB,EACrF,UAAU;AAAA,QACT,MAAM,CAAC,WAAW,cAAc,OAAO,OAAO,CAAC,QAAQ,IAAI,SAAS,QAAQ,CAAC;AAAA,QAC7E,OAAO,CAAC,UAAU;AAChB,kBAAQ,MAAM,2CAA2C,KAAK,GAC9D,cAAc;AAAA,YACZ,OAAO;AAAA,UAAA,CACR;AAAA,QACH;AAAA,MAAA,CACD;AAAA,OAIL,cAAc;AAAA,MACZ,gBAAgB,WACb,QAAQ;AAAA,QACP,QAAQ;AAAA,QACR,KAAK,YAAY,OAAO;AAAA,QACxB,KAAK;AAAA,MACN,CAAA,EACA,UAAU;AAAA,QACT,MAAM,MAAM,cAAc,cAAc,WAAW,OAAO,CAAC;AAAA,QAC3D,OAAO,CAAC,UAAU;AACZ,gBAAM,eAAe,MACvB,cAAc,MAAS,KAEvB,QAAQ,MAAM,sCAAsC,KAAK,GACzD,cAAc;AAAA,YACZ,OAAO;AAAA,UACR,CAAA;AAAA,QAEL;AAAA,MAAA,CACD;AAAA,IAAA,GAGE,MAAM;AACX,oBAAc,QAAQ,CAAC,MAAM,EAAE,YAAa,CAAA;AAAA,IAAA;AAAA,KAE7C,CAAC,SAAS,WAAW,iBAAiB,aAAa,CAAC;AAEjD,QAAA,oBAAoB,QAAQ,MAAM;AACtC,QAAI,SAAgB;AAAA,MAClB;AAAA,QACE,OAAO;AAAA,QACP,MAAM;AAAA,UACJ,EAAC,OAAO,cAAc,OAAO,UAAS;AAAA,UACtC,EAAC,OAAO,WAAW,OAAO,QAAO;AAAA,QACnC;AAAA,MACF;AAAA,IAAA;AAGF,UAAM,OAAc,KAAK,OAAO,CAAC,SAAS,KAAK,aAAa,MAAM;AAGhE,KAAA,MAAM,QAAQ,UAAU,IAAI,aAAa,IAAI,QAAQ,CAAC,QAAQ;AAC9D,WAAK,KAAK;AAAA,QACR,OAAO,IAAI,SAAS;AAAA,QACpB,OAAO,IAAI,YAAY,aAAa,WAAW,IAAI,OAAO,mBAAmB,IAAI;AAAA,MAAA,CAClF;AAAA,IAAA,CACF,GAEG,KAAK,SAAS,MAChB,SAAS,OAAO,OAAO,CAAC,EAAC,OAAO,QAAQ,MAAM,KAAK,CAAA,CAAC,IAItD,SAAS,OAAO;AAAA,MACd;AAAA,QACE;AAAA,UACE,OAAO;AAAA,UACP,MAAM;AAAA,YACJ,EAAC,OAAO,QAAQ,OAAO,WAAW,WAAW,OAAO,EAAC;AAAA,YACrD;AAAA,cACE,OAAO;AAAA,cACP,QAAQ,OAAO,cAAe,WAAW,UAAU,eAAe;AAAA,YACpE;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,KAAK,OAAO,CAAC,SAAS,KAAK,aAAa,MAAM;AAAA,IAAA;AAIhD,UAAM,aAA4C,CAAA;AAC7C,WAAA,KAAA,QAAQ,CAAC,SAAS;AACjB,WAAK,YAAY,KAAK,aAAa,UAAU,KAAK,aAAa,WAC5D,WAAW,KAAK,QAAQ,MAC3B,WAAW,KAAK,QAAQ,IAAI,CAAA,IAE9B,WAAW,KAAK,QAAQ,EAAE,KAAK,IAAI;AAAA,IAAA,CAEtC,GACD,OAAO,KAAK,UAAU,EAAE,QAAQ,CAAC,aAAa;AACrC,aAAA,KAAK,EAAC,OAAO,UAAU,MAAM,WAAW,QAAQ,GAAE;AAAA,IAC1D,CAAA,GAEM;AAAA,EAAA,GACN,CAAC,YAAY,YAAY,WAAW,SAAS,IAAI,CAAC;AAErD,SAEK,qBAAA,UAAA,EAAA,UAAA;AAAA,IAAsB,sBAAA,IAAI,CAAC,cAAc,4BACvC,iBAA2B,EAAA,GAAG,gBAAT,GAAuB,CAC9C;AAAA,IACD,oBAAC,OAAI,QAAO,QAAO,WAAW,uBAAuB,SAAS,IAAI,IAAI,GACpE,UAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,QACE;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO,EAAC,OAAO,OAAM;AAAA,YACrB,UAAU;AAAA,YACV,UAAU;AAAA,YACV,MAAK;AAAA,YACL,MAAK;AAAA,YACL,MAAK;AAAA,YACL,IAAG;AAAA,YACH,MAAM,aAAa,SAAS;AAAA,UAAA;AAAA,QAC9B;AAAA,QAGF,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,UAAU;AAAA,YACV,QAAQ;AAAA,YACR,MAAK;AAAA,YACL,cAAW;AAAA,YACX,oBAAiB;AAAA,YAEjB,UAAA,qBAAC,OAAM,EAAA,OAAO,GACZ,UAAA;AAAA,cAAA,oBAAC,KAAI,EAAA,UAAU,GAAG,IAAG,UACnB,UAAC,oBAAA,SAAA,EAAQ,MAAM,GAAG,IAAG,MAAK,IAAG,sBAAqB,yBAElD,CAAA,GACF;AAAA,cACC,kBAAkB,IAAI,CAAC,SAClB,CAAC,QAAQ,CAAC,KAAK,OACV,OAIN,qBAAA,OAAA,EAAuB,OAAO,GAC7B,UAAA;AAAA,gBAAA,oBAAC,MAAK,EAAA,cAAY,IAAC,SAAS,GAC1B,UAAC,oBAAA,OAAA,EAAM,MAAM,GAAG,OAAK,IAAC,MAAK,gBACxB,UAAA,KAAK,MACR,CAAA,GACF;AAAA,oCACC,OAAM,EAAA,OAAO,GAAG,UAAU,GAAG,MAAK,YAChC,UAAA,KAAK,KAAK,IAAI,CAAC,QAEZ,qBAAC,QAAuC,SAAS,GAAG,MAAK,OACvD,UAAA;AAAA,kBAAA,oBAAC,QAAK,QAAO,UAAS,MAAK,aACxB,cAAI,OACP;AAAA,kBACC,OAAO,IAAI,SAAU,YACpB,oBAAC,QAAK,MAAM,GAAI,UAAI,IAAA,OAAO,MAAM,CAAA;AAAA,kBAElC,OAAO,IAAI,SAAU,YAEjB,oBAAA,UAAA,EAAA,UAAA,MAAM,IAAI,KAAK,wBACb,MAAK,EAAA,MAAM,GAAG,MAAK,QAAO,OAAO,EAAC,WAAW,gBAC5C,UAAA,oBAAC,KAAE,EAAA,MAAM,IAAI,OAAQ,UAAA,IAAI,MAAM,CAAA,GACjC,wBAEC,MAAK,EAAA,MAAM,GAAG,MAAK,QAAO,OAAO,EAAC,WAAW,aAC3C,GAAA,UAAA,IAAI,OACP,EAEJ,CAAA;AAAA,gBAAA,KAlBO,GAAG,IAAI,KAAK,IAAI,IAAI,KAAK,EAoBpC,CAEH,GACH;AAAA,cAAA,KAhCU,KAAK,KAiCjB,CAEH;AAAA,YAAA,GACH;AAAA,UAAA;AAAA,QACF;AAAA,MAAA;AAAA,IAAA,GAEJ;AAAA,EACF,EAAA,CAAA;AAEJ;ACzNO,SAAS,kBAAkB,QAAmD;AAC5E,SAAA;AAAA,IACL,MAAM;AAAA,IACN,WAAW;AAAA,IACX,QAAQ,QAAQ,UAAU,EAAC,OAAO,SAAQ;AAAA,EAAA;AAE9C;ACHA,MAAMA,SAAO,OAAO,IAAI;AAAA,YACZ,IAAI,EAAE,CAAC;AAAA;AAAA;AAUZ,SAAS,YAAY,EAAC,MAAM,SAAS,SAA0B;AACpE,QAAM,aAAa,cAAc,EAAC,OAAO,SAAS,CAAA;AAEhD,SAAA,oBAACA,QAAK,EAAA,OAAM,UACV,UAAA,qBAAC,MAAK,EAAA,OAAM,UAAS,MAAM,GAAG,KAAK,GACjC,UAAA;AAAA,IAAA,oBAAC,KAAI,EAAA,MAAK,QACP,UAAA,8BACE,MAAK,EAAA,MAAM,GACV,UAAA,oBAAC,aAAU,EACb,CAAA,IAEC,oBAAA,YAAA,EAAW,KAAY,CAAA,GAE5B;AAAA,IAEC,qBAAA,OAAA,EAAM,MAAM,GAAG,OAAO,GACrB,UAAA;AAAA,MAAA,oBAAC,MAAK,EAAA,MAAM,GAAG,OAAO,EAAC,OAAO,UAAS,GAAG,cAAa,YAAW,QAAO,UACtE,eAAK,aACR;AAAA,MAEA,oBAAC,MAAK,EAAA,OAAK,IAAC,MAAM,GAAG,cAAa,YAC/B,UAAA,WAAW,OAAO,KAAK,EAC1B,CAAA;AAAA,IAAA,GACF;AAAA,EAAA,EACF,CAAA,EACF,CAAA;AAEJ;AClCA,SAAS,aAAa,WAAmB;AACvC,SAAO,qCAAqC,SAAS;AACvD;AAeO,SAAS,eAAe;AACvB,QAAA,CAAC,SAAS,UAAU,IAAI,SAAA,GACxB,CAAC,OAAO,QAAQ,IAAI,SAAA,GACpB,CAAC,OAAO,QAAQ,IAAI,YAEpB,YAAY,aAAA,GACZ,kBAAkB,mBAAmB,GAErC,YAAY,YAAY,MAAM;AAC5B,UAAA,EAAC,UAAa,IAAA,gBAAgB,OAC9B,GAAA,eAAe,gBAAgB,WAClC,QAAiB;AAAA,MAChB,KAAK,aAAa,SAAS;AAAA,MAC3B,KAAK;AAAA,IACN,CAAA,EACA;AAAA,MACC;AAAA,QAAU,CAAC,aACT,KAAK,UAAU,SAAS,SAAS,QAAQ,IAAI,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC,EAAE;AAAA,UAC9D,IAAI,CAAC,YAAY,EAAC,SAAS,UAAU,OAAO,SAAQ;AAAA,QACtD;AAAA,MACF;AAAA,MAED,UAAU;AAAA,MACT,MAAM,CAAC,EAAC,OAAO,QAAQ,SAAS,eAAc;AAC5C,mBAAW,QAAQ,GACnB;AAAA,WACG,MAAM,QAAQ,MAAM,IAAI,SAAS,CAAC,MAAM,GAAG;AAAA,YAAK,CAAC,OAAO,UACvD,uBAAuB,OAAO,OAAO,QAAQ;AAAA,UAC/C;AAAA,QAAA;AAAA,MAEJ;AAAA,MACA,OAAO,CAAC,MAAa,SAAS,CAAC;AAAA,IAAA,CAChC;AAEI,WAAA,MAAM,aAAa;EAAY,GACrC,CAAC,WAAW,eAAe,CAAC;AAE/B,YAAU,MAAM,UAAA,GAAa,CAAC,SAAS,CAAC;AAExC,QAAM,mBAAmB,YAAY,MAAM,aAAa,CAAC,SAAS,CAAC,GAE7D,YAAY,CAAC,SAAS,CAAC;AAEzB,SAAA,QAEC,oBAAA,0BAAA,EAAyB,QAAO,iBAC/B,8BAAC,KAAI,EAAA,SAAS,GACZ,UAAA,qBAAC,MAAK,EAAA,UAAA;AAAA,IAAA;AAAA,IACgD;AAAA,IACpD,oBAAC,KAAE,EAAA,SAAS,kBAAkB,OAAM,qBAAoB,OAAO,EAAC,QAAQ,UAAS,GAAG,UAEpF,QAAA,CAAA;AAAA,IAAI;AAAA,EAAA,GAEN,EAAA,CACF,EACF,CAAA,IAKF;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,QAAO;AAAA,MACP,QACE;AAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAO,EAAC,OAAO,OAAM;AAAA,UACrB,UAAU;AAAA,UACV,UAAU;AAAA,UACV,MAAK;AAAA,UACL,MAAK;AAAA,UACL,MAAK;AAAA,UACL,IAAG;AAAA,UACH,SAAS;AAAA,UACT,MAAM,YAAY,SAAY,aAAa,QAAQ,EAAE;AAAA,QAAA;AAAA,MACvD;AAAA,MAGD,UAAA;AAAA,QACC,aAAA,oBAAC,OAAI,UAAU,GAAG,UAAU,GAC1B,UAAA,qBAAC,OAAM,EAAA,OAAO,GACZ,UAAA;AAAA,UAAC,oBAAA,MAAA,EAAK,OAAM,UAAS,OAAK,IAAC,MAAM,GAC/B,UAAC,oBAAA,SAAA,CAAA,CAAQ,EACX,CAAA;AAAA,UACA,oBAAC,QAAK,OAAM,UAAS,MAAM,GAAG,OAAK,IAAC,UAEpC,sBAAA,CAAA;AAAA,QAAA,EAAA,CACF,EACF,CAAA;AAAA,QAGD,CAAC,aACA,oBAAC,OAAM,EAAA,OAAO,GAAG,SAAS,GACvB,UAAA,OAAO,IAAI,CAAC,SAAS;AACd,gBAAA,aAAa,QAAQ,QAAQ,KAAK,CAAC,WAAW,OAAO,OAAO,KAAK,EAAE;AAEvE,iBAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cAEC;AAAA,cACA,SAAS,YAAY,WAAW;AAAA,cAChC,OAAO,YAAY,MAAM,IAAI,CAAC,SAAS,KAAK,KAAK,KAAK,CAAC;AAAA,YAAA;AAAA,YAHlD,KAAK;AAAA,UAAA;AAAA,QAMf,CAAA,GACH;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAIR;AAEA,SAAS,uBAAuB,OAAa,OAAa,SAAkB;AACpE,QAAA,EAAC,YAAW,SACZ,cAAc,QAAQ,KAAK,CAAC,WAAW,OAAO,OAAO,OAAO,EAAE,GAC9D,cAAc,QAAQ,KAAK,CAAC,WAAW,OAAO,OAAO,OAAO,EAAE;AAGpE,SAAI,aAAa,YAAY,aAAa,WAChC,aAAa,aAAa,OAAO,aAAa,aAAa,MAAM,IAAI,KAIxE,aAAa,UAAU,IAAI;AACpC;AChJO,SAAS,mBAAmB,QAAmD;AAC7E,SAAA;AAAA,IACL,MAAM;AAAA,IACN,WAAW;AAAA,IACX,QAAQ,QAAQ;AAAA,EAAA;AAEpB;ACJA,MAAM,cAAc,OAAO,GAAG;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,kBAeZ,CAAC,EAAC,MAAK,MAAM,MAAM,OAAO,MAAM,KAAK,QAAQ,EAAE;AAAA;AAAA;AAAA,GAK3DA,SAAO,OAAO,IAAI;AAAA;AAAA,MAElB,WAAW;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,GAQX,aAAa,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA,GAMxB,SAAS,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAuBf,SAAS,SAAS,OAAsB;AAC7C,QAAM,EAAC,OAAO,WAAW,cAAc,MAAM,eAAe,kBAAqB,IAAA;AAG/E,SAAA,oBAACA,QAAK,EAAA,MAAM,GACV,UAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,QAAO;AAAA,MACP,MAAM;AAAA,MACN,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,IAAG;AAAA,MACH;AAAA,MACA,QAAO;AAAA,MACP,KAAI;AAAA,MACJ,OAAO,EAAC,UAAU,WAAU;AAAA,MAE5B,UAAA,qBAAC,QAAK,WAAU,UAAS,OAAO,EAAC,QAAQ,OACtC,GAAA,UAAA;AAAA,QACC,aAAA,qBAAC,YAAW,EAAA,cAAc,GACxB,UAAA;AAAA,UAAC,oBAAA,QAAA,EAAO,KAAK,UAAW,CAAA;AAAA,UACvB,gBACC,oBAAC,aAAY,EAAA,SAAQ,QACnB,UAAA,oBAAC,MAAK,EAAA,OAAM,UACV,UAAA,oBAAC,UAAS,CAAA,CAAA,EACZ,CAAA,GACF;AAAA,QAAA,GAEJ;AAAA,QAEF,qBAAC,QAAK,WAAU,UAAS,SAAQ,iBAAgB,UAAU,GAAG,MAAM,GAClE,UAAA;AAAA,UAAA,oBAAC,SAAQ,EAAA,IAAG,MAAK,MAAM,GACpB,UACH,OAAA;AAAA,UACA,oBAAC,OAAI,WAAW,GACd,+BAAC,OAAM,EAAA,OAAO,GAAG,MAAM,GACrB,UAAA;AAAA,YAAC,oBAAA,MAAA,EAAK,MAAM,GAAI,UAAc,eAAA;AAAA,YAC9B,oBAAC,QAAK,MAAM,GAAG,OAAO,EAAC,SAAS,IAAG,GAChC,UACH,kBAAA,CAAA;AAAA,UAAA,EAAA,CACF,EACF,CAAA;AAAA,QAAA,GACF;AAAA,MAAA,GACF;AAAA,IAAA;AAAA,EAEJ,EAAA,CAAA;AAEJ;AC1GA,MAAM,yBAAyB;AAAA,EAC7B,WAAW;AAAA,EACX,SAAS;AACX;AAuBO,SAAS,iBAAiB;AAC/B,QAAM,kBAAkB;AACjB,SAAA;AAAA,IACL,OAAO;AAAA,MACL,SAAS,CAAC,mBAA2B;AACnC,cAAM,MAAM,iBACR,oCAAoC,cAAc,KAClD;AACG,eAAA,gBAAgB,WAAW,QAA6B;AAAA,UAC7D;AAAA,UACA,KAAK;AAAA,UACL,iBAAiB;AAAA,QAAA,CAClB;AAAA,MACH;AAAA,MACA,YAAY,gBAAgB,sBAAsB;AAAA,IAAA;AAAA,IAEpD,CAAC,eAAe;AAAA,EAAA;AAEpB;AC1CA,SAAS,UAAU,MAAyB,MAAe;AACrD,SAAA,SAAS,aACJ,wCAAwC,KAAK,OAAO,KAClD,SAAS,UACX,qCAAqC,KAAK,OAAO,KAEnD;AACT;AAMO,SAAS,gBAAgB,OAA6B;AAC3D,QAAM,EAAC,eAAc,IAAI,OACnB,CAAC,WAAW,YAAY,IAAI,SAAqB,CAAA,CAAE,GAEnD,EAAC,SAAS,eAAc,eAAe;AAE7C,SAAA,UAAU,MAAM;AACd,UAAM,eAAe,QAAQ,cAAc,EAAE,UAAU,CAAC,aAAa;AACnE,mBAAa,SAAS,KAAK;AAAA,IAAA,CAC5B;AACD,WAAO,MAAM;AACX,mBAAa,YAAY;AAAA,IAAA;AAAA,EAE7B,GAAG,CAAC,cAAc,SAAS,cAAc,CAAC,GAKxC,oBAAC,0BAAyB,EAAA,QAHd,sBAIV,UAAA,oBAAC,QAAK,IAAG,MAAK,UAAS,QAAO,OAAM,WAAU,UAAU,GACrD,UAAW,WAAA,IAAI,CAAC,UAAU,UAAU;AACnC,QAAI,CAAC,SAAS,SAAU,CAAC,SAAS,mBAAmB,CAAC,SAAS;AACtD,aAAA;AAET,UAAM,YAAY,SAAS,aAAa,SAAS,iBAAiB,aAAa,CAAC,GAC1E,WAAW,SAAS,UACpB,EAAC,kBAAkB,CAAA,EAAW,IAAI,UAClC,QACH,gBAAgB,OACb,UAAU,gBAAgB,MAAM,gBAAgB,KAAK,IACrD,SAAS,iBAAiB,SAAS;AAGvC,WAAA;AAAA,MAAC;AAAA,MAAA;AAAA,QACC,IAAG;AAAA,QAEH,cAAc,QAAQ,WAAW,SAAS,IAAI,IAAI;AAAA,QAClD,aAAa,UAAU,IAAI,IAAI;AAAA,QAC/B,OAAM;AAAA,QACN,OAAO,EAAC,UAAU,KAAK,OAAO,MAAK;AAAA,QAEnC,UAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC,OAAO,SAAS;AAAA,YAChB,MAAM,QAAQ;AAAA,YACd,eAAe,UAAU;AAAA,YACzB,mBAAmB;AAAA,YACnB,cAAc,SAAS;AAAA,YACvB,WACE,SAAS,SAAS,WAAW,MAAM,SAAS,MAAM,EAAE,OAAO,GAAG,EAAE,IAAA,IAAQ;AAAA,UAAA;AAAA,QAE5E;AAAA,MAAA;AAAA,MAfK,SAAS;AAAA,IAAA;AAAA,EAgBhB,CAEH,GACH,EACF,CAAA;AAEJ;ACzEO,SAAS,sBAAsB,QAAmD;AAChF,SAAA;AAAA,IACL,MAAM;AAAA,IACN,WAAW;AAAA,IACX,QAAQ,QAAQ,UAAU,EAAC,OAAO,OAAM;AAAA,EAAA;AAE5C;ACNO,SAAS,gBAAgB,OAA8B;AAC5D,6BACG,WAAU,EAAA,OAAO,GAAG,SAAS,GAAG,QAAO,UAAS,OAAO,EAAC,QAAQ,QAAQ,WAAW,OAAM,GACvF,gBAAM,SACT,CAAA;AAEJ;ACHA,MAAM,QAAQ;AAAA,EACZ,OAAO,IAAI,SAAiC;AAAA,yBACrB,CAAC,EAAC,YAAW,MAAM,OAAO,MAAM,CAAC,CAAC;AAAA,QACnD,IAAI,GAAG,IAAI,CAAC;AAAA;AAAA;AAAA,EAGlB,QAAQ,IAAI,SAAiC;AAAA,yBACtB,CAAC,EAAC,YAAW,MAAM,OAAO,MAAM,CAAC,CAAC;AAAA,QACnD,IAAI,GAAG,IAAI,CAAC;AAAA;AAAA;AAGpB,GAEM,OAAO,OAAO,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,MAQlB,MAAM;AAAA;AAAA,KAEP;AAAA;AAAA;AAAA;AAAA,MAIC,MAAM;AAAA;AAAA,KAEP;AAAA;AAAA,MAEC,MAAM;AAAA;AAAA,KAEP;AAAA;AAAA;AAAA;AAAA,MAIC,MAAM;AAAA;AAAA,KAEP;AAAA;AAAA;AAAA;AAAA,MAIC,MAAM;AAAA;AAAA,KAEP;AAAA;AAAA;AAAA;AAAA,MAIC,MAAM;AAAA;AAAA,KAEP;AAAA;AAAA,MAEC,MAAM;AAAA;AAAA,KAEP;AAAA;AAAA;AAAA;AAAA,MAIC,MAAM;AAAA;AAAA,KAEP;AAAA;AAAA,GAQC,aAAgC,CAAA,GAChC,YAA0B;AAEzB,SAAS,YAAY,OAAyB;AAC7C,QAAA;AAAA,IACJ,QAAQ,EAAC,SAAS,WAAW,UAAU,WAAU;AAAA,EAC/C,IAAA;AAEF,SAAA;AAAA,IAAC;AAAA,IAAA;AAAA,MACC,UAAS;AAAA,MACT,cAAY,OAAO,SAAS;AAAA,MAC5B,eAAa,OAAO,UAAU;AAAA,MAC9B,KAAK;AAAA,MAEJ,UAAA;AAAA,QAAA,QAAQ,SAAS,OACf,oBAAA,MAAA,EAAK,SAAS,GAAG,QAAQ,GAAG,MAAK,WAChC,UAAC,oBAAA,MAAA,EAAK,OAAM,UAAS,qDAAwC,CAAA,GAC/D;AAAA,QAED,QAAQ,IAAI,CAAC,cAAc,UACtB,aAAa,SAAS,yBACjB,oBAAC,aAAwB,EAAA,QAAQ,gBAAf,KAA6B,IAEpD,aAAa,YACP,oBAAA,iBAAA,EAA6B,GAAG,aAAX,GAAA,KAAyB,IAEjD,qBAAC,KAAiB,EAAA,UAAA;AAAA,UAAa,aAAA;AAAA,UAAK;AAAA,QAAA,EAAA,GAA1B,KAAsD,CACxE;AAAA,MAAA;AAAA,IAAA;AAAA,EAAA;AAGP;ACnGgB,SAAA,UAAU,EAAC,UAAoC;AAC7D,SAAK,SAKH,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,QAChC,UAAC,oBAAA,iBAAA,EACC,UAAC,oBAAA,aAAA,EAAY,OAAgB,CAAA,EAC/B,CAAA,GACF,IARO;AAUX;ACbA,MAAM,cAA6B;AAAA,EACjC,QAAQ;AAAA,EACR,aAAa;AACf,GAEM,gBAAgB,MACpB;AAAA,EAAC;AAAA,EAAA;AAAA,IACC,oBAAgB;AAAA,IAChB,SAAQ;AAAA,IACR,MAAK;AAAA,IACL,OAAM;AAAA,IACN,qBAAoB;AAAA,IACpB,OAAM;AAAA,IACN,QAAO;AAAA,IAEP,UAAA;AAAA,MAAA,oBAAC,QAAK,EAAA,GAAE,iCAAgC,OAAO,aAAa;AAAA,MAC3D,oBAAA,QAAA,EAAK,GAAE,kBAAiB,OAAO,aAAa;AAAA,MAC5C,oBAAA,QAAA,EAAK,GAAE,iCAAgC,OAAO,aAAa;AAAA,IAAA;AAAA,EAAA;AAC9D,GAwBW,gBAAgB,aAAoC,CAAC,SAAS,OAAO;AAChF,QAAM,eAAgC;AAAA,IACpC,QAAQ,OAAO,iBAAiB,CAAC;AAAA,IACjC,SAAS,OAAO,WAAW,CAAC;AAAA,EAC9B,GAEM,QAAQ,OAAO,SAAS,aACxB,OAAO,OAAO,QAAQ,aACtB,OAAO,OAAO,QAAQ;AAErB,SAAA;AAAA,IACL,MAAM;AAAA,IACN,OAAO,CAAC,MAAM,YACL;AAAA,MACL,GAAG;AAAA,MACH;AAAA,QACE;AAAA,QACA;AAAA,QACA;AAAA,QACA,WAAW,MAAO,oBAAA,WAAA,EAAU,QAAQ,aAAc,CAAA;AAAA,MACpD;AAAA,IACF;AAAA,EAAA;AAGN,CAAC;"}
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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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sanity/dashboard",
3
- "version": "4.1.0",
3
+ "version": "4.1.2",
4
4
  "description": "Tool for rendering dashboard widgets",
5
5
  "keywords": [
6
6
  "sanity",
@@ -56,44 +56,44 @@
56
56
  },
57
57
  "browserslist": "extends @sanity/browserslist-config",
58
58
  "dependencies": {
59
- "@sanity/icons": "^3.3.0",
60
- "@sanity/image-url": "^1.0.2",
59
+ "@sanity/icons": "^3.5.2",
60
+ "@sanity/image-url": "^1.1.0",
61
61
  "@sanity/incompatible-plugin": "^1.0.4",
62
- "@sanity/ui": "^2.6.8",
62
+ "@sanity/ui": "^2.10.9",
63
63
  "lodash": "^4.17.21",
64
64
  "rxjs": "^7.8.1"
65
65
  },
66
66
  "devDependencies": {
67
- "@commitlint/cli": "^19.5.0",
68
- "@commitlint/config-conventional": "^19.5.0",
69
- "@sanity/pkg-utils": "^6.11.2",
67
+ "@commitlint/cli": "^19.6.0",
68
+ "@commitlint/config-conventional": "^19.6.0",
69
+ "@sanity/pkg-utils": "^6.12.0",
70
70
  "@sanity/plugin-kit": "^4.0.18",
71
71
  "@sanity/semantic-release-preset": "^5.0.0",
72
- "@types/react": "^18.3.10",
72
+ "@types/react": "^18.3.16",
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
78
  "eslint-plugin-prettier": "^5.2.1",
79
- "eslint-plugin-react": "^7.37.1",
79
+ "eslint-plugin-react": "^7.37.2",
80
80
  "eslint-plugin-react-hooks": "^4.6.2",
81
81
  "husky": "^8.0.3",
82
- "lint-staged": "^13.3.0",
83
- "npm-run-all2": "^5.0.0",
84
- "prettier": "^3.3.3",
85
- "prettier-plugin-packagejson": "^2.5.2",
86
- "semantic-release": "^24.1.2",
82
+ "lint-staged": "^15.2.11",
83
+ "npm-run-all2": "^5.0.2",
84
+ "prettier": "^3.4.2",
85
+ "prettier-plugin-packagejson": "^2.5.6",
87
86
  "react": "^18.3.1",
88
87
  "react-dom": "^18.3.1",
89
88
  "react-is": "^18.3.1",
90
89
  "rimraf": "^6.0.0",
91
- "sanity": "^3.59.0",
90
+ "sanity": "^3.67.1",
91
+ "semantic-release": "^24.2.0",
92
92
  "styled-components": "^6.1.13",
93
- "typescript": "^5.6.2"
93
+ "typescript": "^5.7.2"
94
94
  },
95
95
  "peerDependencies": {
96
- "react": "^18",
96
+ "react": "^18 || >=19.0.0-0",
97
97
  "sanity": "^3",
98
98
  "styled-components": "^6.1"
99
99
  },
@@ -101,7 +101,8 @@
101
101
  "node": ">=18"
102
102
  },
103
103
  "overrides": {
104
- "conventional-changelog-conventionalcommits": ">= 8.0.0"
104
+ "conventional-changelog-conventionalcommits": ">= 8.0.0",
105
+ "cross-spawn": "^7.0.6"
105
106
  },
106
107
  "sanityExchangeUrl": "https://www.sanity.io/exchange/dashboard"
107
108
  }