@orion-studios/payload-studio 0.5.0-beta.99 → 0.6.0-beta.10

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 (62) hide show
  1. package/README.md +58 -68
  2. package/dist/admin/client.d.mts +7 -1
  3. package/dist/admin/client.d.ts +7 -1
  4. package/dist/admin/client.js +5446 -985
  5. package/dist/admin/client.mjs +4408 -1090
  6. package/dist/admin/index.d.mts +2 -1
  7. package/dist/admin/index.d.ts +2 -1
  8. package/dist/admin/index.js +396 -55
  9. package/dist/admin/index.mjs +2 -1
  10. package/dist/admin-app/client.d.mts +1 -0
  11. package/dist/admin-app/client.d.ts +1 -0
  12. package/dist/admin-app/client.js +285 -109
  13. package/dist/admin-app/client.mjs +59 -871
  14. package/dist/admin-app/index.d.mts +2 -1
  15. package/dist/admin-app/index.d.ts +2 -1
  16. package/dist/admin-app/index.mjs +5 -3
  17. package/dist/admin-app/styles.css +2118 -56
  18. package/dist/admin.css +158 -35
  19. package/dist/blocks/index.js +415 -200
  20. package/dist/blocks/index.mjs +2 -2
  21. package/dist/{chunk-XK3K5GRP.mjs → chunk-JQAHXYAM.mjs} +271 -67
  22. package/dist/chunk-KPIX7OSV.mjs +1051 -0
  23. package/dist/chunk-OQSEJXC4.mjs +166 -0
  24. package/dist/{chunk-XHWQJUX5.mjs → chunk-OTHERBGX.mjs} +3 -3
  25. package/dist/chunk-PF3EBZXF.mjs +326 -0
  26. package/dist/{chunk-XVH5SCBD.mjs → chunk-RKTIFEUY.mjs} +4 -19
  27. package/dist/chunk-W2UOCJDX.mjs +32 -0
  28. package/dist/{chunk-74XFAVXU.mjs → chunk-WLOPFFN2.mjs} +387 -55
  29. package/dist/{chunk-C4J35SPJ.mjs → chunk-XKUTZ7IU.mjs} +257 -452
  30. package/dist/{index-ZbOx4OCF.d.mts → index-52HdVLQq.d.ts} +12 -22
  31. package/dist/index-Bm2SaC3r.d.mts +187 -0
  32. package/dist/index-CkT_eyhK.d.ts +187 -0
  33. package/dist/index-Crx_MtPw.d.ts +223 -0
  34. package/dist/index-Cv-6qnrw.d.mts +223 -0
  35. package/dist/{index-ZbOx4OCF.d.ts → index-DEQC3Dwj.d.mts} +12 -22
  36. package/dist/{index-BIwu3qIH.d.mts → index-DWmudwDm.d.mts} +2 -1
  37. package/dist/{index-BIwu3qIH.d.ts → index-DWmudwDm.d.ts} +2 -1
  38. package/dist/index.d.mts +5 -4
  39. package/dist/index.d.ts +5 -4
  40. package/dist/index.js +1868 -1202
  41. package/dist/index.mjs +10 -8
  42. package/dist/nextjs/index.js +5 -684
  43. package/dist/nextjs/index.mjs +2 -3
  44. package/dist/sitePreviewTypes-BkHCWxNW.d.mts +58 -0
  45. package/dist/sitePreviewTypes-BkHCWxNW.d.ts +58 -0
  46. package/dist/studio/index.d.mts +1 -1
  47. package/dist/studio/index.d.ts +1 -1
  48. package/dist/studio-pages/builder.css +125 -83
  49. package/dist/studio-pages/client.d.mts +58 -1
  50. package/dist/studio-pages/client.d.ts +58 -1
  51. package/dist/studio-pages/client.js +450 -241
  52. package/dist/studio-pages/client.mjs +455 -247
  53. package/dist/studio-pages/index.d.mts +3 -2
  54. package/dist/studio-pages/index.d.ts +3 -2
  55. package/dist/studio-pages/index.js +418 -183
  56. package/dist/studio-pages/index.mjs +15 -6
  57. package/package.json +10 -4
  58. package/dist/chunk-SIL2J5MF.mjs +0 -155
  59. package/dist/index-BnoqmQDP.d.mts +0 -219
  60. package/dist/index-CTpik6fR.d.ts +0 -219
  61. package/dist/index-R7hA134j.d.mts +0 -140
  62. package/dist/index-vjrjy0P4.d.ts +0 -140
@@ -1,3 +1,6 @@
1
+ import {
2
+ adminNavIcons
3
+ } from "./chunk-W2UOCJDX.mjs";
1
4
  import {
2
5
  SOCIAL_MEDIA_DEFAULT_ICON_BY_PLATFORM,
3
6
  SOCIAL_MEDIA_ICON_OPTIONS,
@@ -51,6 +54,7 @@ var themePreferenceField = createThemePreferenceField("brand-light");
51
54
 
52
55
  // src/shared/studioSections.ts
53
56
  var studioRoles = /* @__PURE__ */ new Set(["admin", "editor", "client"]);
57
+ var studioIcons = new Set(adminNavIcons);
54
58
  var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
55
59
  var isAbsoluteExternalURL = (value) => /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(value) || value.startsWith("//");
56
60
  var normalizePathLikeValue = (value) => {
@@ -91,6 +95,7 @@ var normalizeCard = (value) => {
91
95
  ...typeof value.description === "string" && value.description.trim().length > 0 ? { description: value.description.trim() } : {}
92
96
  };
93
97
  };
98
+ var normalizeIcon = (value) => typeof value === "string" && studioIcons.has(value) ? value : void 0;
94
99
  var resolveStudioSections = (value) => {
95
100
  if (!Array.isArray(value)) {
96
101
  return [];
@@ -116,6 +121,7 @@ var resolveStudioSections = (value) => {
116
121
  label,
117
122
  href,
118
123
  matchPrefixes,
124
+ ...normalizeIcon(entry.icon) ? { icon: normalizeIcon(entry.icon) } : {},
119
125
  ...normalizeRoles(entry.roles) ? { roles: normalizeRoles(entry.roles) } : {},
120
126
  ...normalizeCard(entry.card) ? { card: normalizeCard(entry.card) } : {}
121
127
  });
@@ -180,17 +186,29 @@ function configureAdmin(config) {
180
186
  brandPrimary = "#3b82f6",
181
187
  brandSecondary = "#8b5cf6",
182
188
  defaultTheme = "brand-light",
183
- logoUrl
189
+ logoUrl,
190
+ allowThemePreference = false,
191
+ userSessionDurationSeconds = 60 * 60 * 24
184
192
  } = config;
185
193
  const studioEnabled = config.studio?.enabled ?? true;
194
+ const formsEnabled = config.studio?.forms?.enabled ?? false;
195
+ const formsCollectionSlug = config.studio?.forms?.collectionSlug || "forms";
196
+ const formSubmissionsCollectionSlug = config.studio?.forms?.submissionsCollectionSlug || "form-submissions";
197
+ const formUploadsCollectionSlug = config.studio?.forms?.uploadsCollectionSlug || "form-uploads";
186
198
  const pagesCollectionSlug = config.studio?.pages?.collectionSlug || "pages";
199
+ const builderBasePath = config.studio?.pages?.builderBasePath || "/builder";
187
200
  const mediaCollectionSlug = config.studio?.media?.collectionSlug || "media";
188
- const contactFormStudioPath = "/studio-contact-form";
201
+ const globalsBasePath = "/site-globals";
202
+ const pagesBasePath = "/pages";
203
+ const formsBasePath = "/forms";
204
+ const mediaBasePath = "/media";
205
+ const toolsBasePath = "/tools";
206
+ const contactFormStudioPath = "/contact-form";
189
207
  const configuredGlobals = config.studio?.globals || [
190
208
  { slug: "site-settings", label: "Website Settings" },
191
209
  { slug: "header", label: "Header & Navigation" },
192
210
  { slug: "footer", label: "Footer" },
193
- { slug: "contact-form", label: "Contact Form" }
211
+ { slug: "social-media", label: "Social Media" }
194
212
  ];
195
213
  const globals = configuredGlobals.map((global) => {
196
214
  if (global.slug !== "contact-form" || global.href) {
@@ -203,24 +221,78 @@ function configureAdmin(config) {
203
221
  });
204
222
  const studioSections = resolveStudioSections(config.studio?.sections || []);
205
223
  const studioSectionViews = resolveStudioSectionViews(config.studio?.sections || []);
224
+ const sitePreview = config.studio?.sitePreview;
206
225
  let cssPath;
207
226
  const pkgDist = getPkgDistDir();
208
227
  const sourceCssPath = path.resolve(pkgDist, "admin.css");
209
- if (config.basePath && fs.existsSync(sourceCssPath)) {
210
- let css = fs.readFileSync(sourceCssPath, "utf-8");
211
- css = css.replace("--brand-primary: #3b82f6;", `--brand-primary: ${brandPrimary};`);
212
- css = css.replace("--brand-secondary: #8b5cf6;", `--brand-secondary: ${brandSecondary};`);
213
- const genDir = path.resolve(config.basePath, ".generated");
228
+ const adminAppCssPath = path.resolve(pkgDist, "admin-app", "styles.css");
229
+ const cssSources = [sourceCssPath, adminAppCssPath].filter((filePath) => fs.existsSync(filePath));
230
+ if (cssSources.length === 0) {
231
+ cssPath = sourceCssPath;
232
+ } else {
233
+ let css = cssSources.map((filePath) => fs.readFileSync(filePath, "utf-8")).join("\n\n");
234
+ css = css.replace(
235
+ "--orion-cms-brand-primary-fallback: #3b82f6;",
236
+ `--orion-cms-brand-primary-fallback: ${brandPrimary};`
237
+ );
238
+ css = css.replace(
239
+ "--orion-cms-brand-secondary-fallback: #8b5cf6;",
240
+ `--orion-cms-brand-secondary-fallback: ${brandSecondary};`
241
+ );
242
+ const outputBasePath = config.basePath || process.cwd();
243
+ const genDir = path.resolve(outputBasePath, ".generated");
214
244
  if (!fs.existsSync(genDir)) {
215
245
  fs.mkdirSync(genDir, { recursive: true });
216
246
  }
217
247
  const genPath = path.resolve(genDir, "admin.css");
218
248
  fs.writeFileSync(genPath, css);
219
249
  cssPath = genPath;
220
- } else {
221
- cssPath = sourceCssPath;
222
250
  }
223
251
  const clientPath = "@orion-studios/payload-studio/admin/client";
252
+ const studioNavClientProps = {
253
+ brandName,
254
+ formSubmissionsCollectionSlug,
255
+ formsCollectionSlug,
256
+ formsEnabled,
257
+ formUploadsCollectionSlug,
258
+ globalsBasePath,
259
+ globalsExtraMatchPrefixes: [contactFormStudioPath],
260
+ logoUrl,
261
+ mediaCollectionSlug,
262
+ pagesCollectionSlug,
263
+ sections: studioSections
264
+ };
265
+ const studioBackBreadcrumbComponent = {
266
+ exportName: "StudioBackBreadcrumb",
267
+ path: clientPath
268
+ };
269
+ const hasMatchingComponent = (items, exportName) => Array.isArray(items) && items.some(
270
+ (item) => item && typeof item === "object" && item.exportName === exportName && item.path === clientPath
271
+ );
272
+ const appendComponent = (items, component, exportName) => hasMatchingComponent(items, exportName) ? items || [] : [...items || [], component];
273
+ const attachStudioBackBreadcrumbToCollection = (collection) => {
274
+ if (!studioEnabled) {
275
+ return collection;
276
+ }
277
+ const existingBeforeDocumentControls = collection.admin?.components?.edit?.beforeDocumentControls;
278
+ return {
279
+ ...collection,
280
+ admin: {
281
+ ...collection.admin,
282
+ components: {
283
+ ...collection.admin?.components,
284
+ edit: {
285
+ ...collection.admin?.components?.edit,
286
+ beforeDocumentControls: appendComponent(
287
+ existingBeforeDocumentControls,
288
+ studioBackBreadcrumbComponent,
289
+ "StudioBackBreadcrumb"
290
+ )
291
+ }
292
+ }
293
+ }
294
+ };
295
+ };
224
296
  return {
225
297
  admin: {
226
298
  css: cssPath,
@@ -229,15 +301,7 @@ function configureAdmin(config) {
229
301
  Nav: {
230
302
  exportName: "AdminStudioNav",
231
303
  path: clientPath,
232
- clientProps: {
233
- brandName,
234
- logoUrl,
235
- globalsBasePath: "/studio-globals",
236
- globalsExtraMatchPrefixes: [contactFormStudioPath],
237
- mediaCollectionSlug,
238
- pagesCollectionSlug,
239
- sections: studioSections
240
- }
304
+ clientProps: studioNavClientProps
241
305
  }
242
306
  } : {},
243
307
  graphics: {
@@ -263,37 +327,113 @@ function configureAdmin(config) {
263
327
  Component: {
264
328
  exportName: studioEnabled ? "AdminStudioDashboard" : "Dashboard",
265
329
  path: clientPath,
266
- clientProps: {
267
- brandName,
268
- logoUrl,
269
- globalsBasePath: "/studio-globals",
270
- globalsExtraMatchPrefixes: [contactFormStudioPath],
271
- mediaCollectionSlug,
272
- pagesCollectionSlug,
273
- sections: studioSections
274
- }
330
+ clientProps: studioNavClientProps
275
331
  }
276
332
  },
277
333
  ...studioEnabled ? {
278
334
  studioGlobals: {
279
- path: "/studio-globals",
335
+ path: globalsBasePath,
280
336
  Component: {
281
337
  exportName: "AdminStudioGlobalsView",
282
338
  path: clientPath,
283
339
  clientProps: {
340
+ ...studioNavClientProps,
284
341
  globals,
285
- globalsBasePath: "/studio-globals"
342
+ globalsBasePath
343
+ }
344
+ }
345
+ },
346
+ studioPages: {
347
+ path: pagesBasePath,
348
+ Component: {
349
+ exportName: "AdminStudioPagesListView",
350
+ path: clientPath,
351
+ clientProps: {
352
+ ...studioNavClientProps,
353
+ pagesCollectionSlug
354
+ }
355
+ }
356
+ },
357
+ studioPageEditor: {
358
+ path: `${pagesBasePath}/:id`,
359
+ Component: {
360
+ exportName: "AdminStudioPageEditView",
361
+ path: clientPath,
362
+ clientProps: {
363
+ ...studioNavClientProps,
364
+ builderBasePath
365
+ }
366
+ }
367
+ },
368
+ studioPageNew: {
369
+ path: `${pagesBasePath}/new`,
370
+ Component: {
371
+ exportName: "AdminStudioNewPageView",
372
+ path: clientPath,
373
+ clientProps: {
374
+ ...studioNavClientProps,
375
+ pagesCollectionSlug
286
376
  }
287
377
  }
288
378
  },
289
379
  studioContactForm: {
290
- path: "/studio-contact-form",
380
+ path: contactFormStudioPath,
291
381
  Component: {
292
382
  exportName: "AdminStudioContactFormView",
293
383
  path: clientPath,
294
384
  clientProps: {
385
+ ...studioNavClientProps,
295
386
  globalSlug: "contact-form",
296
- globalsBasePath: "/studio-globals"
387
+ globalsBasePath
388
+ }
389
+ }
390
+ },
391
+ ...formsEnabled ? {
392
+ studioForms: {
393
+ path: formsBasePath,
394
+ Component: {
395
+ exportName: "AdminStudioFormsView",
396
+ path: clientPath,
397
+ clientProps: {
398
+ ...studioNavClientProps,
399
+ formsCollectionSlug,
400
+ formSubmissionsCollectionSlug,
401
+ formUploadsCollectionSlug
402
+ }
403
+ }
404
+ }
405
+ } : {},
406
+ studioMedia: {
407
+ path: mediaBasePath,
408
+ Component: {
409
+ exportName: "AdminStudioMediaView",
410
+ path: clientPath,
411
+ clientProps: {
412
+ ...studioNavClientProps,
413
+ mediaCollectionSlug
414
+ }
415
+ }
416
+ },
417
+ studioMediaItem: {
418
+ path: `${mediaBasePath}/:id`,
419
+ Component: {
420
+ exportName: "AdminStudioMediaItemView",
421
+ path: clientPath,
422
+ clientProps: {
423
+ ...studioNavClientProps,
424
+ mediaCollectionSlug
425
+ }
426
+ }
427
+ },
428
+ studioTools: {
429
+ path: toolsBasePath,
430
+ Component: {
431
+ exportName: "AdminStudioToolsView",
432
+ path: clientPath,
433
+ clientProps: {
434
+ ...studioNavClientProps,
435
+ mediaCollectionSlug,
436
+ pagesCollectionSlug
297
437
  }
298
438
  }
299
439
  },
@@ -302,7 +442,13 @@ function configureAdmin(config) {
302
442
  id,
303
443
  {
304
444
  path: view.path,
305
- Component: view.Component
445
+ Component: {
446
+ ...view.Component,
447
+ clientProps: {
448
+ ...studioNavClientProps,
449
+ ...view.Component.clientProps || {}
450
+ }
451
+ }
306
452
  }
307
453
  ])
308
454
  )
@@ -313,19 +459,39 @@ function configureAdmin(config) {
313
459
  exportName: "ThemeProvider",
314
460
  path: clientPath,
315
461
  clientProps: {
462
+ allowThemePreference,
316
463
  defaultTheme
317
464
  }
318
465
  }
319
466
  ],
320
- afterNavLinks: [
467
+ beforeLogin: [
321
468
  {
322
- exportName: "ThemeSwitcher",
469
+ exportName: "AdminLoginIntro",
323
470
  path: clientPath,
324
471
  clientProps: {
325
- defaultTheme
472
+ brandName,
473
+ logoUrl
326
474
  }
327
475
  }
328
- ]
476
+ ],
477
+ afterLogin: [
478
+ {
479
+ exportName: "AdminLoginPasswordToggle",
480
+ path: clientPath
481
+ }
482
+ ],
483
+ ...allowThemePreference ? {
484
+ afterNavLinks: [
485
+ {
486
+ exportName: "ThemeSwitcher",
487
+ path: clientPath,
488
+ clientProps: {
489
+ allowThemePreference,
490
+ defaultTheme
491
+ }
492
+ }
493
+ ]
494
+ } : {}
329
495
  },
330
496
  meta: {
331
497
  titleSuffix: ` \u2014 ${brandName}`
@@ -340,10 +506,85 @@ function configureAdmin(config) {
340
506
  const hasThemePreference = existingFields.some(
341
507
  (field) => typeof field === "object" && field !== null && "name" in field && field.name === "themePreference"
342
508
  );
343
- return {
509
+ const normalizedAuth = usersCollection.auth === true ? {
510
+ tokenExpiration: userSessionDurationSeconds,
511
+ useSessions: true
512
+ } : usersCollection.auth && typeof usersCollection.auth === "object" ? {
513
+ ...usersCollection.auth,
514
+ tokenExpiration: usersCollection.auth.tokenExpiration ?? userSessionDurationSeconds,
515
+ useSessions: usersCollection.auth.useSessions ?? true
516
+ } : usersCollection.auth;
517
+ const nextCollection = {
344
518
  ...usersCollection,
345
- fields: hasThemePreference ? existingFields : [...existingFields, createThemePreferenceField(defaultTheme)]
519
+ auth: normalizedAuth,
520
+ fields: !allowThemePreference || hasThemePreference ? existingFields : [...existingFields, createThemePreferenceField(defaultTheme)]
346
521
  };
522
+ return attachStudioBackBreadcrumbToCollection(nextCollection);
523
+ },
524
+ wrapPagesCollection(pagesCollection) {
525
+ if (!studioEnabled) {
526
+ return pagesCollection;
527
+ }
528
+ const collectionWithBreadcrumb = attachStudioBackBreadcrumbToCollection(pagesCollection);
529
+ const existingEditMenuItems = collectionWithBreadcrumb.admin?.components?.edit?.editMenuItems;
530
+ const existingViews = collectionWithBreadcrumb.admin?.components?.views;
531
+ const existingEditViews = existingViews?.edit;
532
+ const hasCustomEditView = Boolean(
533
+ existingEditViews?.root || existingEditViews?.default && typeof existingEditViews.default === "object" && existingEditViews.default.Component
534
+ );
535
+ return {
536
+ ...collectionWithBreadcrumb,
537
+ admin: {
538
+ ...collectionWithBreadcrumb.admin,
539
+ components: {
540
+ ...collectionWithBreadcrumb.admin?.components,
541
+ edit: {
542
+ ...collectionWithBreadcrumb.admin?.components?.edit,
543
+ editMenuItems: appendComponent(
544
+ existingEditMenuItems,
545
+ {
546
+ exportName: "OpenInStudioMenuItem",
547
+ path: clientPath,
548
+ clientProps: {
549
+ pagesPathBase: pagesBasePath
550
+ }
551
+ },
552
+ "OpenInStudioMenuItem"
553
+ )
554
+ },
555
+ views: {
556
+ ...existingViews,
557
+ ...hasCustomEditView ? {} : {
558
+ edit: {
559
+ ...existingEditViews,
560
+ default: {
561
+ ...typeof existingEditViews?.default === "object" ? existingEditViews.default : {},
562
+ Component: {
563
+ exportName: "PageEditRedirectToStudio",
564
+ path: clientPath,
565
+ clientProps: {
566
+ pagesPathBase: pagesBasePath
567
+ }
568
+ }
569
+ }
570
+ }
571
+ }
572
+ }
573
+ }
574
+ }
575
+ };
576
+ },
577
+ wrapMediaCollection(mediaCollection) {
578
+ return attachStudioBackBreadcrumbToCollection(mediaCollection);
579
+ },
580
+ wrapFormsCollection(formsCollection) {
581
+ return attachStudioBackBreadcrumbToCollection(formsCollection);
582
+ },
583
+ wrapFormSubmissionsCollection(formSubmissionsCollection) {
584
+ return attachStudioBackBreadcrumbToCollection(formSubmissionsCollection);
585
+ },
586
+ wrapFormUploadsCollection(formUploadsCollection) {
587
+ return attachStudioBackBreadcrumbToCollection(formUploadsCollection);
347
588
  },
348
589
  wrapGlobals(globals2) {
349
590
  const labelMap = {
@@ -356,25 +597,110 @@ function configureAdmin(config) {
356
597
  return globals2.map((global) => {
357
598
  const mapping = labelMap[global.slug];
358
599
  if (!mapping) return global;
600
+ const shouldAttachSiteSettingsEditView = studioEnabled && global.slug === "site-settings";
601
+ const shouldAttachSocialMediaEditView = studioEnabled && global.slug === "social-media";
359
602
  const shouldAttachContactFormRedirect = studioEnabled && global.slug === "contact-form";
603
+ const shouldAttachHeaderEditView = studioEnabled && global.slug === "header";
604
+ const shouldAttachFooterEditView = studioEnabled && global.slug === "footer";
360
605
  const existingViews = global.admin?.components?.views;
361
606
  const existingEditViews = existingViews?.edit;
362
- const hasCustomContactFormEditView = Boolean(
607
+ const hasCustomEditView = Boolean(
363
608
  existingEditViews?.root || existingEditViews?.default && typeof existingEditViews.default === "object" && existingEditViews.default.Component
364
609
  );
365
- const contactFormEditViews = shouldAttachContactFormRedirect && !hasCustomContactFormEditView ? {
366
- ...existingEditViews,
367
- default: {
368
- ...typeof existingEditViews?.default === "object" ? existingEditViews.default : {},
369
- Component: {
370
- exportName: "StudioContactFormRedirect",
371
- path: clientPath,
372
- clientProps: {
373
- studioContactFormPath: contactFormStudioPath
610
+ const nextEditViews = (() => {
611
+ if (shouldAttachSiteSettingsEditView && !hasCustomEditView) {
612
+ return {
613
+ ...existingEditViews,
614
+ default: {
615
+ ...typeof existingEditViews?.default === "object" ? existingEditViews.default : {},
616
+ Component: {
617
+ exportName: "AdminStudioSiteSettingsGlobalView",
618
+ path: clientPath,
619
+ clientProps: {
620
+ ...studioNavClientProps,
621
+ globalSlug: global.slug,
622
+ mediaCollectionSlug
623
+ }
624
+ }
374
625
  }
375
- }
626
+ };
627
+ }
628
+ if (shouldAttachSocialMediaEditView && !hasCustomEditView) {
629
+ return {
630
+ ...existingEditViews,
631
+ default: {
632
+ ...typeof existingEditViews?.default === "object" ? existingEditViews.default : {},
633
+ Component: {
634
+ exportName: "AdminStudioSocialMediaGlobalView",
635
+ path: clientPath,
636
+ clientProps: {
637
+ ...studioNavClientProps,
638
+ globalSlug: global.slug
639
+ }
640
+ }
641
+ }
642
+ };
643
+ }
644
+ if (shouldAttachHeaderEditView && !hasCustomEditView) {
645
+ return {
646
+ ...existingEditViews,
647
+ default: {
648
+ ...typeof existingEditViews?.default === "object" ? existingEditViews.default : {},
649
+ Component: {
650
+ exportName: "AdminStudioHeaderGlobalView",
651
+ path: clientPath,
652
+ clientProps: {
653
+ ...studioNavClientProps,
654
+ actionHref: sitePreview?.header?.actionHref,
655
+ actionLabel: sitePreview?.header?.actionLabel,
656
+ globalSlug: global.slug,
657
+ locationSummary: sitePreview?.locationSummary,
658
+ pagesCollectionSlug
659
+ }
660
+ }
661
+ }
662
+ };
663
+ }
664
+ if (shouldAttachFooterEditView && !hasCustomEditView) {
665
+ return {
666
+ ...existingEditViews,
667
+ default: {
668
+ ...typeof existingEditViews?.default === "object" ? existingEditViews.default : {},
669
+ Component: {
670
+ exportName: "AdminStudioFooterGlobalView",
671
+ path: clientPath,
672
+ clientProps: {
673
+ ...studioNavClientProps,
674
+ builtByHref: sitePreview?.footer?.builtByHref,
675
+ builtByLabel: sitePreview?.footer?.builtByLabel,
676
+ description: sitePreview?.footer?.description,
677
+ footerCategories: sitePreview?.footer?.footerCategories,
678
+ footerLinks: sitePreview?.footer?.footerLinks,
679
+ globalSlug: global.slug,
680
+ locationSummary: sitePreview?.locationSummary
681
+ }
682
+ }
683
+ }
684
+ };
685
+ }
686
+ if (shouldAttachContactFormRedirect && !hasCustomEditView) {
687
+ return {
688
+ ...existingEditViews,
689
+ default: {
690
+ ...typeof existingEditViews?.default === "object" ? existingEditViews.default : {},
691
+ Component: {
692
+ exportName: "StudioContactFormRedirect",
693
+ path: clientPath,
694
+ clientProps: {
695
+ studioContactFormPath: contactFormStudioPath
696
+ }
697
+ }
698
+ }
699
+ };
376
700
  }
377
- } : existingEditViews;
701
+ return existingEditViews;
702
+ })();
703
+ const existingBeforeDocumentControls = global.admin?.components?.elements?.beforeDocumentControls;
378
704
  return {
379
705
  ...global,
380
706
  admin: {
@@ -382,12 +708,18 @@ function configureAdmin(config) {
382
708
  group: mapping.group,
383
709
  components: {
384
710
  ...global.admin?.components,
385
- ...shouldAttachContactFormRedirect ? {
711
+ elements: {
712
+ ...global.admin?.components?.elements,
713
+ beforeDocumentControls: studioEnabled ? appendComponent(
714
+ existingBeforeDocumentControls,
715
+ studioBackBreadcrumbComponent,
716
+ "StudioBackBreadcrumb"
717
+ ) : existingBeforeDocumentControls
718
+ },
719
+ ...nextEditViews ? {
386
720
  views: {
387
721
  ...existingViews,
388
- ...contactFormEditViews ? {
389
- edit: contactFormEditViews
390
- } : {}
722
+ edit: nextEditViews
391
723
  }
392
724
  } : {}
393
725
  }