@sanity/dashboard 5.0.1 → 6.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +5 -51
  3. package/dist/index.d.ts +54 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +605 -0
  6. package/dist/index.js.map +1 -0
  7. package/package.json +37 -79
  8. package/lib/index.d.mts +0 -65
  9. package/lib/index.d.ts +0 -65
  10. package/lib/index.esm.js +0 -568
  11. package/lib/index.esm.js.map +0 -1
  12. package/lib/index.js +0 -564
  13. package/lib/index.js.map +0 -1
  14. package/lib/index.mjs +0 -568
  15. package/lib/index.mjs.map +0 -1
  16. package/sanity.json +0 -8
  17. package/src/components/DashboardLayout.tsx +0 -10
  18. package/src/components/DashboardWidgetContainer.tsx +0 -69
  19. package/src/components/NotFoundWidget.tsx +0 -30
  20. package/src/components/WidgetGroup.tsx +0 -106
  21. package/src/containers/Dashboard.tsx +0 -19
  22. package/src/containers/DashboardContext.tsx +0 -8
  23. package/src/containers/WidgetContainer.tsx +0 -21
  24. package/src/index.ts +0 -7
  25. package/src/plugin.tsx +0 -72
  26. package/src/types.ts +0 -21
  27. package/src/versionedClient.ts +0 -5
  28. package/src/widgets/projectInfo/ProjectInfo.tsx +0 -221
  29. package/src/widgets/projectInfo/index.ts +0 -10
  30. package/src/widgets/projectInfo/types.ts +0 -28
  31. package/src/widgets/projectUsers/ProjectUser.tsx +0 -45
  32. package/src/widgets/projectUsers/ProjectUsers.tsx +0 -148
  33. package/src/widgets/projectUsers/index.ts +0 -10
  34. package/src/widgets/sanityTutorials/SanityTutorials.tsx +0 -77
  35. package/src/widgets/sanityTutorials/Tutorial.tsx +0 -111
  36. package/src/widgets/sanityTutorials/dataAdapter.ts +0 -49
  37. package/src/widgets/sanityTutorials/index.ts +0 -10
  38. package/v2-incompatible.js +0 -11
package/lib/index.js DELETED
@@ -1,564 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: !0 });
3
- var jsxRuntime = require("react/jsx-runtime"), react = require("react"), ui = require("@sanity/ui"), styledComponents = require("styled-components"), sanity = require("sanity"), rxjs = require("rxjs"), operators = require("rxjs/operators"), icons = require("@sanity/icons"), imageUrlBuilder = require("@sanity/image-url");
4
- function _interopDefaultCompat(e) {
5
- return e && typeof e == "object" && "default" in e ? e : { default: e };
6
- }
7
- var imageUrlBuilder__default = /* @__PURE__ */ _interopDefaultCompat(imageUrlBuilder);
8
- const Root$3 = styledComponents.styled(ui.Card)`
9
- display: flex;
10
- flex-direction: column;
11
- justify-content: stretch;
12
- height: 100%;
13
- box-sizing: border-box;
14
- position: relative;
15
- `, Header = styledComponents.styled(ui.Card)`
16
- position: sticky;
17
- top: 0;
18
- z-index: 2;
19
- border-top-left-radius: inherit;
20
- border-top-right-radius: inherit;
21
- `, Footer = styledComponents.styled(ui.Card)`
22
- position: sticky;
23
- overflow: hidden;
24
- bottom: 0;
25
- z-index: 2;
26
- border-bottom-right-radius: inherit;
27
- border-bottom-left-radius: inherit;
28
- margin-top: auto;
29
- `, Content = styledComponents.styled(ui.Box)`
30
- position: relative;
31
- z-index: 1;
32
- height: stretch;
33
- min-height: 21.5em;
34
-
35
- @media (min-width: ${({ theme }) => theme.sanity.media[0]}px) {
36
- overflow-y: auto;
37
- outline: none;
38
- }
39
- `, DashboardWidgetContainer = react.forwardRef(function(props, ref) {
40
- const { header, children, footer } = props;
41
- return /* @__PURE__ */ jsxRuntime.jsxs(Root$3, { radius: 3, display: "flex", ref, children: [
42
- header && /* @__PURE__ */ jsxRuntime.jsx(Header, { borderBottom: !0, paddingX: 3, paddingY: 4, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { size: 1, textOverflow: "ellipsis", children: header }) }),
43
- children && /* @__PURE__ */ jsxRuntime.jsx(Content, { children }),
44
- footer && /* @__PURE__ */ jsxRuntime.jsx(Footer, { borderTop: !0, children: footer })
45
- ] });
46
- });
47
- function useVersionedClient() {
48
- return sanity.useClient({ apiVersion: "2024-08-01" });
49
- }
50
- const DashboardContext = react.createContext({ widgets: [] });
51
- function useDashboardConfig() {
52
- return react.useContext(DashboardContext);
53
- }
54
- function WidgetContainer(props) {
55
- const config = useDashboardConfig(), layout = react.useMemo(
56
- () => ({
57
- ...props.layout || {},
58
- ...config.layout || {}
59
- }),
60
- [props.layout, config.layout]
61
- );
62
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { shadow: 1, "data-width": layout.width, "data-height": layout.height, children: react.createElement(props.component, {}) });
63
- }
64
- function isUrl(url) {
65
- return url && /^https?:\/\//.test(`${url}`);
66
- }
67
- function getGraphQLUrl(projectId, dataset) {
68
- return `https://${projectId}.api.sanity.io/v1/graphql/${dataset}/default`;
69
- }
70
- function getGroqUrl(projectId, dataset) {
71
- return `https://${projectId}.api.sanity.io/v1/groq/${dataset}`;
72
- }
73
- function getManageUrl(projectId) {
74
- return `https://manage.sanity.io/projects/${projectId}`;
75
- }
76
- const NO_EXPERIMENTAL = [], NO_DATA = [];
77
- function ProjectInfo(props) {
78
- const { __experimental_before = NO_EXPERIMENTAL, data = NO_DATA } = props, [studioApps, setStudioApps] = react.useState(), [graphQLApi, setGraphQLApi] = react.useState(), versionedClient = useVersionedClient(), { projectId = "unknown", dataset = "unknown" } = versionedClient.config();
79
- react.useEffect(() => {
80
- const subscriptions = [];
81
- return subscriptions.push(
82
- versionedClient.observable.request({ uri: "/user-applications", tag: "dashboard.project-info" }).subscribe({
83
- next: (result) => setStudioApps(result.filter((app) => app.type === "studio")),
84
- error: (error) => {
85
- console.error("Error while resolving user applications", error), setStudioApps({
86
- error: "Something went wrong while resolving user applications. See console."
87
- });
88
- }
89
- })
90
- ), subscriptions.push(
91
- versionedClient.observable.request({
92
- method: "HEAD",
93
- uri: `/graphql/${dataset}/default`,
94
- tag: "dashboard.project-info.graphql-api"
95
- }).subscribe({
96
- next: () => setGraphQLApi(getGraphQLUrl(projectId, dataset)),
97
- error: (error) => {
98
- error.statusCode === 404 ? setGraphQLApi(void 0) : (console.error("Error while looking for graphQLApi", error), setGraphQLApi({
99
- error: "Something went wrong while looking up graphQLApi. See console."
100
- }));
101
- }
102
- })
103
- ), () => {
104
- subscriptions.forEach((s) => s.unsubscribe());
105
- };
106
- }, [dataset, projectId, versionedClient, setGraphQLApi]);
107
- const assembleTableRows = react.useMemo(() => {
108
- let result = [
109
- {
110
- title: "Sanity project",
111
- rows: [
112
- { title: "Project ID", value: projectId },
113
- { title: "Dataset", value: dataset }
114
- ]
115
- }
116
- ];
117
- const apps = data.filter((item) => item.category === "apps");
118
- (Array.isArray(studioApps) ? studioApps : []).forEach((app) => {
119
- apps.push({
120
- title: app.title || "Studio",
121
- value: app.urlType === "internal" ? `https://${app.appHost}.sanity.studio` : app.appHost
122
- });
123
- }), apps.length > 0 && (result = result.concat([{ title: "Apps", rows: apps }])), result = result.concat(
124
- [
125
- {
126
- title: "APIs",
127
- rows: [
128
- { title: "GROQ", value: getGroqUrl(projectId, dataset) },
129
- {
130
- title: "GraphQL",
131
- value: (typeof graphQLApi == "object" ? "Error" : graphQLApi) ?? "Not deployed"
132
- }
133
- ]
134
- }
135
- ],
136
- data.filter((item) => item.category === "apis")
137
- );
138
- const otherStuff = {};
139
- return data.forEach((item) => {
140
- item.category && item.category !== "apps" && item.category !== "apis" && (otherStuff[item.category] || (otherStuff[item.category] = []), otherStuff[item.category].push(item));
141
- }), Object.keys(otherStuff).forEach((category) => {
142
- result.push({ title: category, rows: otherStuff[category] });
143
- }), result;
144
- }, [graphQLApi, studioApps, projectId, dataset, data]);
145
- return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
146
- __experimental_before.map((widgetConfig, idx) => /* @__PURE__ */ jsxRuntime.jsx(WidgetContainer, { ...widgetConfig }, idx)),
147
- /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { height: "fill", marginTop: __experimental_before?.length > 0 ? 4 : 0, children: /* @__PURE__ */ jsxRuntime.jsx(
148
- DashboardWidgetContainer,
149
- {
150
- footer: /* @__PURE__ */ jsxRuntime.jsx(
151
- ui.Button,
152
- {
153
- style: { width: "100%" },
154
- paddingX: 2,
155
- paddingY: 4,
156
- mode: "bleed",
157
- tone: "primary",
158
- text: "Manage project",
159
- as: "a",
160
- href: getManageUrl(projectId)
161
- }
162
- ),
163
- children: /* @__PURE__ */ jsxRuntime.jsx(
164
- ui.Card,
165
- {
166
- paddingY: 4,
167
- radius: 2,
168
- role: "table",
169
- "aria-label": "Project info",
170
- "aria-describedby": "project_info_table",
171
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 4, children: [
172
- /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { paddingX: 3, as: "header", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { size: 1, as: "h2", id: "project_info_table", children: "Project info" }) }),
173
- assembleTableRows.map((item) => !item || !item.rows ? null : /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 3, children: [
174
- /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { borderBottom: !0, padding: 3, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Label, { size: 0, muted: !0, role: "columnheader", children: item.title }) }),
175
- /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 4, paddingX: 3, role: "rowgroup", children: item.rows.map((row) => /* @__PURE__ */ jsxRuntime.jsxs(ui.Grid, { columns: 2, role: "row", children: [
176
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { weight: "medium", role: "rowheader", children: row.title }),
177
- typeof row.value == "object" && /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, children: row.value?.error }),
178
- typeof row.value == "string" && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: isUrl(row.value) ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, role: "cell", style: { wordBreak: "break-word" }, children: /* @__PURE__ */ jsxRuntime.jsx("a", { href: row.value, children: row.value }) }) : /* @__PURE__ */ jsxRuntime.jsx(ui.Code, { size: 1, role: "cell", style: { wordBreak: "break-word" }, children: row.value }) })
179
- ] }, `${row.value}-${row.title}`)) })
180
- ] }, item.title))
181
- ] })
182
- }
183
- )
184
- }
185
- ) })
186
- ] });
187
- }
188
- function projectInfoWidget(config) {
189
- return {
190
- name: "project-info",
191
- component: ProjectInfo,
192
- layout: config?.layout ?? { width: "medium" }
193
- };
194
- }
195
- const Root$2 = styledComponents.styled(ui.Flex)`
196
- height: ${ui.rem(33)}; // 33 = PREVIEW_SIZES.default.media.height
197
- box-sizing: content-box;
198
- `;
199
- function ProjectUser({ user, isRobot, roles }) {
200
- const listFormat = sanity.useListFormat({ style: "narrow" });
201
- return /* @__PURE__ */ jsxRuntime.jsx(Root$2, { align: "center", children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { align: "center", flex: 1, gap: 2, children: [
202
- /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { flex: "none", children: isRobot ? /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 2, children: /* @__PURE__ */ jsxRuntime.jsx(icons.RobotIcon, {}) }) : /* @__PURE__ */ jsxRuntime.jsx(sanity.UserAvatar, { user }) }),
203
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { flex: 1, space: 2, children: [
204
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, style: { color: "inherit" }, textOverflow: "ellipsis", weight: "medium", children: user.displayName }),
205
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { muted: !0, size: 1, textOverflow: "ellipsis", children: listFormat.format(roles) })
206
- ] })
207
- ] }) });
208
- }
209
- function getInviteUrl(projectId) {
210
- return `https://manage.sanity.io/projects/${projectId}/members`;
211
- }
212
- function ProjectUsers() {
213
- const [project, setProject] = react.useState(), [users, setUsers] = react.useState(), [error, setError] = react.useState(), userStore = sanity.useUserStore(), versionedClient = useVersionedClient(), fetchData = react.useCallback(() => {
214
- const { projectId } = versionedClient.config(), subscription = versionedClient.observable.request({
215
- uri: `/projects/${projectId}`,
216
- tag: "dashboard.project-users"
217
- }).pipe(
218
- operators.switchMap(
219
- (_project) => rxjs.from(userStore.getUsers(_project.members.map((mem) => mem.id))).pipe(
220
- operators.map((_users) => ({ project: _project, users: _users }))
221
- )
222
- )
223
- ).subscribe({
224
- next: ({ users: _users, project: _project }) => {
225
- setProject(_project), setUsers(
226
- (Array.isArray(_users) ? _users : [_users]).sort(
227
- (userA, userB) => sortUsersByRobotStatus(userA, userB, _project)
228
- )
229
- );
230
- },
231
- error: (e) => setError(e)
232
- });
233
- return () => subscription.unsubscribe();
234
- }, [userStore, versionedClient]);
235
- react.useEffect(() => fetchData(), [fetchData]);
236
- const handleRetryFetch = react.useCallback(() => fetchData(), [fetchData]), isLoading = !users || !project;
237
- return error ? /* @__PURE__ */ jsxRuntime.jsx(DashboardWidgetContainer, { header: "Project users", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { padding: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Text, { children: [
238
- "Something went wrong while fetching data. You could",
239
- " ",
240
- /* @__PURE__ */ jsxRuntime.jsx("a", { onClick: handleRetryFetch, title: "Retry users fetch", style: { cursor: "pointer" }, children: "retry" }),
241
- "..?"
242
- ] }) }) }) : /* @__PURE__ */ jsxRuntime.jsxs(
243
- DashboardWidgetContainer,
244
- {
245
- header: "Project users",
246
- footer: /* @__PURE__ */ jsxRuntime.jsx(
247
- ui.Button,
248
- {
249
- style: { width: "100%" },
250
- paddingX: 2,
251
- paddingY: 4,
252
- mode: "bleed",
253
- tone: "primary",
254
- text: "Manage members",
255
- as: "a",
256
- loading: isLoading,
257
- href: isLoading ? void 0 : getInviteUrl(project.id)
258
- }
259
- ),
260
- children: [
261
- isLoading && /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { paddingY: 5, paddingX: 2, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 4, children: [
262
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { align: "center", muted: !0, size: 1, children: /* @__PURE__ */ jsxRuntime.jsx(ui.Spinner, {}) }),
263
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { align: "center", size: 1, muted: !0, children: "Loading items\u2026" })
264
- ] }) }),
265
- !isLoading && /* @__PURE__ */ jsxRuntime.jsx(ui.Stack, { space: 3, padding: 3, children: users?.map((user) => {
266
- const membership = project.members.find((member) => member.id === user.id);
267
- return /* @__PURE__ */ jsxRuntime.jsx(
268
- ProjectUser,
269
- {
270
- user,
271
- isRobot: membership?.isRobot ?? !1,
272
- roles: membership?.roles.map((role) => role.title) || []
273
- },
274
- user.id
275
- );
276
- }) })
277
- ]
278
- }
279
- );
280
- }
281
- function sortUsersByRobotStatus(userA, userB, project) {
282
- const { members } = project, membershipA = members.find((member) => member.id === userA?.id), membershipB = members.find((member) => member.id === userB?.id);
283
- return membershipA?.isRobot === membershipB?.isRobot ? (membershipA?.createdAt || "") > (membershipB?.createdAt || "") ? 1 : -1 : membershipA?.isRobot ? 1 : -1;
284
- }
285
- function projectUsersWidget(config) {
286
- return {
287
- name: "project-info",
288
- component: ProjectUsers,
289
- layout: config?.layout
290
- };
291
- }
292
- const PlayIconBox = styledComponents.styled(ui.Box)`
293
- position: absolute;
294
- top: 50%;
295
- left: 50%;
296
- transform: translate(-50%, -50%);
297
-
298
- &:before {
299
- content: '';
300
- position: absolute;
301
- top: 50%;
302
- left: 50%;
303
- transform: translate(-50%, -50%);
304
- width: 2.75em;
305
- height: 2.75em;
306
- border-radius: 50%;
307
- background: ${({ theme }) => theme.sanity.color.card.enabled.bg};
308
- opacity: 0.75;
309
- }
310
- `, Root$1 = styledComponents.styled(ui.Flex)`
311
- &:hover {
312
- ${PlayIconBox} {
313
- &:before {
314
- opacity: 1;
315
- }
316
- }
317
- }
318
- `, PosterCard = styledComponents.styled(ui.Card)`
319
- width: 100%;
320
- padding-bottom: calc(9 / 16 * 100%);
321
- position: relative;
322
- `, Poster = styledComponents.styled.img`
323
- position: absolute;
324
- top: 0;
325
- left: 0;
326
- height: 100%;
327
- width: 100%;
328
- object-fit: cover;
329
- display: block;
330
-
331
- &:not([src]) {
332
- display: none;
333
- }
334
- `;
335
- function Tutorial(props) {
336
- const { title, posterURL, showPlayIcon, href, presenterName, presenterSubtitle } = props;
337
- return /* @__PURE__ */ jsxRuntime.jsx(Root$1, { flex: 1, children: /* @__PURE__ */ jsxRuntime.jsx(
338
- ui.Card,
339
- {
340
- sizing: "border",
341
- flex: 1,
342
- padding: 2,
343
- radius: 2,
344
- as: "a",
345
- href,
346
- target: "_blank",
347
- rel: "noopener noreferrer",
348
- style: { position: "relative" },
349
- children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", style: { height: "100%" }, children: [
350
- posterURL && /* @__PURE__ */ jsxRuntime.jsxs(PosterCard, { marginBottom: 1, children: [
351
- /* @__PURE__ */ jsxRuntime.jsx(Poster, { src: posterURL }),
352
- showPlayIcon && /* @__PURE__ */ jsxRuntime.jsx(PlayIconBox, { display: "flex", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { align: "center", children: /* @__PURE__ */ jsxRuntime.jsx(icons.PlayIcon, {}) }) })
353
- ] }),
354
- /* @__PURE__ */ jsxRuntime.jsxs(ui.Flex, { direction: "column", justify: "space-between", paddingY: 2, flex: 1, children: [
355
- /* @__PURE__ */ jsxRuntime.jsx(ui.Heading, { as: "h3", size: 1, children: title }),
356
- /* @__PURE__ */ jsxRuntime.jsx(ui.Box, { marginTop: 4, children: /* @__PURE__ */ jsxRuntime.jsxs(ui.Stack, { space: 2, flex: 1, children: [
357
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 1, children: presenterName }),
358
- /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { size: 0, style: { opacity: 0.7 }, children: presenterSubtitle })
359
- ] }) })
360
- ] })
361
- ] })
362
- }
363
- ) });
364
- }
365
- const tutorialsProjectConfig = {
366
- projectId: "3do82whm",
367
- dataset: "next"
368
- };
369
- function useDataAdapter() {
370
- const versionedClient = useVersionedClient();
371
- return react.useMemo(
372
- () => ({
373
- getFeed: (templateRepoId) => {
374
- const uri = templateRepoId ? `/addons/dashboard?templateRepoId=${templateRepoId}` : "/addons/dashboard";
375
- return versionedClient.observable.request({
376
- uri,
377
- tag: "dashboard.sanity-tutorials",
378
- withCredentials: !1
379
- });
380
- },
381
- urlBuilder: imageUrlBuilder__default.default(tutorialsProjectConfig)
382
- }),
383
- [versionedClient]
384
- );
385
- }
386
- function createUrl(slug, type) {
387
- return type === "tutorial" ? `https://www.sanity.io/docs/tutorials/${slug.current}` : type === "guide" ? `https://www.sanity.io/docs/guides/${slug.current}` : !1;
388
- }
389
- function SanityTutorials(props) {
390
- const { templateRepoId } = props, [feedItems, setFeedItems] = react.useState([]), { getFeed, urlBuilder } = useDataAdapter();
391
- return react.useEffect(() => {
392
- const subscription = getFeed(templateRepoId).subscribe((response) => {
393
- setFeedItems(response.items);
394
- });
395
- return () => {
396
- subscription.unsubscribe();
397
- };
398
- }, [setFeedItems, getFeed, templateRepoId]), /* @__PURE__ */ jsxRuntime.jsx(DashboardWidgetContainer, { header: "Learn about Sanity", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Flex, { as: "ul", overflow: "auto", align: "stretch", paddingY: 2, children: feedItems?.map((feedItem, index) => {
399
- if (!feedItem.title || !feedItem.guideOrTutorial && !feedItem.externalLink)
400
- return null;
401
- const presenter = feedItem.presenter || feedItem.guideOrTutorial?.presenter || {}, subtitle = feedItem.category, { guideOrTutorial = {} } = feedItem, href = (guideOrTutorial.slug ? createUrl(guideOrTutorial.slug, guideOrTutorial._type) : feedItem.externalLink) || feedItem.externalLink;
402
- return /* @__PURE__ */ jsxRuntime.jsx(
403
- ui.Flex,
404
- {
405
- as: "li",
406
- paddingRight: index < feedItems?.length - 1 ? 1 : 3,
407
- paddingLeft: index === 0 ? 3 : 0,
408
- align: "stretch",
409
- style: { minWidth: 272, width: "30%" },
410
- children: /* @__PURE__ */ jsxRuntime.jsx(
411
- Tutorial,
412
- {
413
- title: feedItem.title,
414
- href: href ?? "",
415
- presenterName: presenter.name,
416
- presenterSubtitle: subtitle,
417
- showPlayIcon: feedItem.hasVideo,
418
- posterURL: feedItem.poster ? urlBuilder.image(feedItem.poster).height(360).url() : void 0
419
- }
420
- )
421
- },
422
- feedItem._id
423
- );
424
- }) }) });
425
- }
426
- function sanityTutorialsWidget(config) {
427
- return {
428
- name: "sanity-tutorials",
429
- component: SanityTutorials,
430
- layout: config?.layout ?? { width: "full" }
431
- };
432
- }
433
- function DashboardLayout(props) {
434
- return /* @__PURE__ */ jsxRuntime.jsx(ui.Container, { width: 4, padding: 4, sizing: "border", style: { height: "100%", overflowY: "auto" }, children: props.children });
435
- }
436
- const media = {
437
- small: (...args) => styledComponents.css`
438
- @media (min-width: ${({ theme }) => theme.sanity.media[0]}px) {
439
- ${styledComponents.css(...args)}
440
- }
441
- `,
442
- medium: (...args) => styledComponents.css`
443
- @media (min-width: ${({ theme }) => theme.sanity.media[2]}px) {
444
- ${styledComponents.css(...args)}
445
- }
446
- `
447
- }, Root = styledComponents.styled(ui.Grid)`
448
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
449
-
450
- & > div {
451
- overflow: hidden;
452
- }
453
-
454
- & > div[data-width='medium'] {
455
- ${media.small`
456
- grid-column: span 2;
457
- `}
458
- }
459
-
460
- & > div[data-width='large'] {
461
- ${media.small`
462
- grid-column: span 2;
463
- `}
464
-
465
- ${media.medium`
466
- grid-column: span 3;
467
- `}
468
- }
469
-
470
- & > div[data-width='full'] {
471
- ${media.small`
472
- grid-column: 1 / -1;
473
- `}
474
- }
475
-
476
- & > div[data-height='medium'] {
477
- ${media.small`
478
- grid-row: span 2;
479
- `}
480
- }
481
-
482
- & > div[data-height='large'] {
483
- ${media.small`
484
- grid-row: span 2;
485
- `}
486
-
487
- ${media.medium`
488
- grid-row: span 3;
489
- `}
490
- }
491
-
492
- & > div[data-height='full'] {
493
- ${media.medium`
494
- grid-row: 1 / -1;
495
- `}
496
- }
497
- `, NO_WIDGETS = [], NO_LAYOUT = {};
498
- function WidgetGroup(props) {
499
- const {
500
- config: { layout = NO_LAYOUT, widgets = NO_WIDGETS }
501
- } = props;
502
- return /* @__PURE__ */ jsxRuntime.jsxs(
503
- Root,
504
- {
505
- autoFlow: "row dense",
506
- "data-width": layout.width || "auto",
507
- "data-height": layout.height || "auto",
508
- gap: 4,
509
- children: [
510
- widgets.length ? null : /* @__PURE__ */ jsxRuntime.jsx(ui.Card, { padding: 4, shadow: 1, tone: "primary", children: /* @__PURE__ */ jsxRuntime.jsx(ui.Text, { align: "center", children: "Add some widgets to populate this space." }) }),
511
- widgets.map((widgetConfig, index) => widgetConfig.type === "__experimental_group" ? /* @__PURE__ */ jsxRuntime.jsx(WidgetGroup, { config: widgetConfig }, index) : widgetConfig.component ? /* @__PURE__ */ jsxRuntime.jsx(WidgetContainer, { ...widgetConfig }, index) : /* @__PURE__ */ jsxRuntime.jsxs(ui.Box, { children: [
512
- widgetConfig.name,
513
- " is missing widget component"
514
- ] }, index))
515
- ]
516
- }
517
- );
518
- }
519
- function Dashboard({ config }) {
520
- return config ? /* @__PURE__ */ jsxRuntime.jsx(DashboardContext.Provider, { value: config, children: /* @__PURE__ */ jsxRuntime.jsx(DashboardLayout, { children: /* @__PURE__ */ jsxRuntime.jsx(WidgetGroup, { config }) }) }) : null;
521
- }
522
- const strokeStyle = {
523
- stroke: "currentColor",
524
- strokeWidth: 1.2
525
- }, DashboardIcon = () => /* @__PURE__ */ jsxRuntime.jsxs(
526
- "svg",
527
- {
528
- "data-sanity-icon": !0,
529
- viewBox: "0 0 25 25",
530
- fill: "none",
531
- xmlns: "http://www.w3.org/2000/svg",
532
- preserveAspectRatio: "xMidYMid",
533
- width: "1em",
534
- height: "1em",
535
- children: [
536
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19.5 19.5H5.5V5.5H19.5V19.5Z", style: strokeStyle }),
537
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M5.5 12.5H19.5", style: strokeStyle }),
538
- /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M14.5 19.5V12.5M10.5 12.5V5.5", style: strokeStyle })
539
- ]
540
- }
541
- ), dashboardTool = sanity.definePlugin((config = {}) => {
542
- const pluginConfig = {
543
- layout: config.defaultLayout ?? {},
544
- widgets: config.widgets ?? []
545
- }, title = config.title ?? "Dashboard", name = config.name ?? "dashboard", icon = config.icon ?? DashboardIcon;
546
- return {
547
- name: "dashboard",
548
- tools: (prev, context) => [
549
- ...prev,
550
- {
551
- title,
552
- name,
553
- icon,
554
- component: () => /* @__PURE__ */ jsxRuntime.jsx(Dashboard, { config: pluginConfig })
555
- }
556
- ]
557
- };
558
- });
559
- exports.DashboardWidgetContainer = DashboardWidgetContainer;
560
- exports.dashboardTool = dashboardTool;
561
- exports.projectInfoWidget = projectInfoWidget;
562
- exports.projectUsersWidget = projectUsersWidget;
563
- exports.sanityTutorialsWidget = sanityTutorialsWidget;
564
- //# sourceMappingURL=index.js.map