@orion-studios/payload-studio 0.6.0-beta.18 → 0.6.0-beta.181
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/dist/admin/client.js +742 -540
- package/dist/admin/client.mjs +825 -632
- package/dist/admin/index.js +37 -25
- package/dist/admin/index.mjs +2 -2
- package/dist/admin-app/client.js +14 -5
- package/dist/admin-app/client.mjs +1 -1
- package/dist/admin-app/styles.css +257 -0
- package/dist/admin.css +80 -0
- package/dist/builder-v2/client.d.mts +18 -0
- package/dist/builder-v2/client.d.ts +18 -0
- package/dist/builder-v2/client.js +4328 -0
- package/dist/builder-v2/client.mjs +4203 -0
- package/dist/builder-v2/index.d.mts +249 -0
- package/dist/builder-v2/index.d.ts +249 -0
- package/dist/builder-v2/index.js +805 -0
- package/dist/builder-v2/index.mjs +755 -0
- package/dist/builder-v2/styles.css +2693 -0
- package/dist/{chunk-XKUTZ7IU.mjs → chunk-276KAPGM.mjs} +56 -5
- package/dist/{chunk-PF3EBZXF.mjs → chunk-7ZMXZRBP.mjs} +39 -3
- package/dist/{chunk-3AHBR7RI.mjs → chunk-KHK6RTGC.mjs} +40 -28
- package/dist/{chunk-KPIX7OSV.mjs → chunk-NF37A575.mjs} +14 -5
- package/dist/{chunk-OTHERBGX.mjs → chunk-ZADL33R6.mjs} +1 -1
- package/dist/{index-Cv-6qnrw.d.mts → index-D5zrOdyv.d.mts} +3 -1
- package/dist/{index-Crx_MtPw.d.ts → index-Dv-Alx4h.d.ts} +3 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +128 -29
- package/dist/index.mjs +10 -10
- package/dist/nextjs/index.js +39 -3
- package/dist/nextjs/index.mjs +2 -2
- package/dist/studio-pages/builder.css +66 -5
- package/dist/studio-pages/client.js +618 -73
- package/dist/studio-pages/client.mjs +641 -96
- package/dist/studio-pages/index.d.mts +1 -1
- package/dist/studio-pages/index.d.ts +1 -1
- package/dist/studio-pages/index.js +91 -4
- package/dist/studio-pages/index.mjs +3 -3
- package/package.json +22 -3
package/dist/admin/client.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
SiteFooterPreview,
|
|
10
10
|
adminNavIcons,
|
|
11
11
|
buildAdminPageLinkOptions
|
|
12
|
-
} from "../chunk-
|
|
12
|
+
} from "../chunk-NF37A575.mjs";
|
|
13
13
|
import "../chunk-ROTPP5CU.mjs";
|
|
14
14
|
import {
|
|
15
15
|
BlockPicker,
|
|
@@ -1273,9 +1273,9 @@ function WelcomeHeader({
|
|
|
1273
1273
|
}
|
|
1274
1274
|
|
|
1275
1275
|
// src/admin/components/studio/AdminStudioNav.tsx
|
|
1276
|
-
import { useMemo } from "react";
|
|
1276
|
+
import { useMemo, useState as useState7 } from "react";
|
|
1277
1277
|
import { usePathname } from "next/navigation";
|
|
1278
|
-
import {
|
|
1278
|
+
import { useAuth } from "@payloadcms/ui";
|
|
1279
1279
|
|
|
1280
1280
|
// src/admin/components/studio/adminPathUtils.ts
|
|
1281
1281
|
import { useEffect as useEffect6, useState as useState6 } from "react";
|
|
@@ -1648,8 +1648,26 @@ function NavIcon({ sectionID }) {
|
|
|
1648
1648
|
return null;
|
|
1649
1649
|
}
|
|
1650
1650
|
}
|
|
1651
|
+
function LogoutIcon() {
|
|
1652
|
+
const props = {
|
|
1653
|
+
fill: "none",
|
|
1654
|
+
height: iconSize2,
|
|
1655
|
+
stroke: "currentColor",
|
|
1656
|
+
strokeLinecap: "round",
|
|
1657
|
+
strokeLinejoin: "round",
|
|
1658
|
+
strokeWidth: 2,
|
|
1659
|
+
viewBox: "0 0 24 24",
|
|
1660
|
+
width: iconSize2
|
|
1661
|
+
};
|
|
1662
|
+
return /* @__PURE__ */ jsxs11("svg", { ...props, "aria-hidden": "true", children: [
|
|
1663
|
+
/* @__PURE__ */ jsx12("path", { d: "M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" }),
|
|
1664
|
+
/* @__PURE__ */ jsx12("polyline", { points: "10 17 5 12 10 7" }),
|
|
1665
|
+
/* @__PURE__ */ jsx12("line", { x1: "5", y1: "12", x2: "17", y2: "12" })
|
|
1666
|
+
] });
|
|
1667
|
+
}
|
|
1651
1668
|
function AdminStudioNav(props) {
|
|
1652
1669
|
const { user } = useAuth();
|
|
1670
|
+
const [loggingOut, setLoggingOut] = useState7(false);
|
|
1653
1671
|
const brandName = getPropString(props, "brandName", "Orion Studio");
|
|
1654
1672
|
const logoUrl = getPropString(props, "logoUrl", "");
|
|
1655
1673
|
const compact = getPropBoolean(props, "compact", false);
|
|
@@ -1660,6 +1678,18 @@ function AdminStudioNav(props) {
|
|
|
1660
1678
|
const dashboardPath = adminBasePath;
|
|
1661
1679
|
const userRole = readUserRole(user);
|
|
1662
1680
|
const links = useMemo(() => buildStudioNavItems(props, adminBasePath), [adminBasePath, props]);
|
|
1681
|
+
const logout = async () => {
|
|
1682
|
+
setLoggingOut(true);
|
|
1683
|
+
try {
|
|
1684
|
+
await fetch("/api/users/logout", {
|
|
1685
|
+
credentials: "include",
|
|
1686
|
+
method: "POST"
|
|
1687
|
+
});
|
|
1688
|
+
window.location.href = `${adminBasePath}/login`;
|
|
1689
|
+
} finally {
|
|
1690
|
+
setLoggingOut(false);
|
|
1691
|
+
}
|
|
1692
|
+
};
|
|
1663
1693
|
if (isStudioShellRoute(pathname, props, adminBasePath)) {
|
|
1664
1694
|
return null;
|
|
1665
1695
|
}
|
|
@@ -1750,7 +1780,38 @@ function AdminStudioNav(props) {
|
|
|
1750
1780
|
/* @__PURE__ */ jsx12("div", { style: { color: "var(--theme-elevation-700)", fontSize: "0.85rem" }, children: "Signed in as" }),
|
|
1751
1781
|
/* @__PURE__ */ jsx12("div", { style: { fontWeight: 800, marginBottom: "0.55rem" }, children: typeof user?.email === "string" ? user.email : "User" })
|
|
1752
1782
|
] }) : null,
|
|
1753
|
-
/* @__PURE__ */
|
|
1783
|
+
/* @__PURE__ */ jsxs11(
|
|
1784
|
+
"button",
|
|
1785
|
+
{
|
|
1786
|
+
"aria-label": "Log out",
|
|
1787
|
+
disabled: loggingOut,
|
|
1788
|
+
onClick: () => void logout(),
|
|
1789
|
+
style: {
|
|
1790
|
+
alignItems: "center",
|
|
1791
|
+
background: "transparent",
|
|
1792
|
+
border: "1px solid var(--theme-elevation-150)",
|
|
1793
|
+
borderRadius: 10,
|
|
1794
|
+
color: "var(--theme-elevation-900)",
|
|
1795
|
+
cursor: loggingOut ? "not-allowed" : "pointer",
|
|
1796
|
+
display: "inline-flex",
|
|
1797
|
+
font: "inherit",
|
|
1798
|
+
fontWeight: 800,
|
|
1799
|
+
gap: compact ? 0 : "0.45rem",
|
|
1800
|
+
justifyContent: "center",
|
|
1801
|
+
minHeight: compact ? 48 : 34,
|
|
1802
|
+
minWidth: compact ? 48 : 0,
|
|
1803
|
+
opacity: loggingOut ? 0.55 : 1,
|
|
1804
|
+
padding: compact ? 0 : "0.4rem 0.62rem",
|
|
1805
|
+
width: compact ? 48 : "auto"
|
|
1806
|
+
},
|
|
1807
|
+
title: "Log out",
|
|
1808
|
+
type: "button",
|
|
1809
|
+
children: [
|
|
1810
|
+
/* @__PURE__ */ jsx12(LogoutIcon, {}),
|
|
1811
|
+
!compact ? /* @__PURE__ */ jsx12("span", { children: loggingOut ? "Logging out..." : "Log out" }) : null
|
|
1812
|
+
]
|
|
1813
|
+
}
|
|
1814
|
+
)
|
|
1754
1815
|
]
|
|
1755
1816
|
}
|
|
1756
1817
|
)
|
|
@@ -1840,7 +1901,7 @@ function AdminPage({ title, description, breadcrumbs, actions, children }) {
|
|
|
1840
1901
|
}
|
|
1841
1902
|
|
|
1842
1903
|
// src/admin/components/studio/AdminStudioDashboardClient.tsx
|
|
1843
|
-
import { startTransition, useEffect as useEffect7, useMemo as useMemo3, useState as
|
|
1904
|
+
import { startTransition, useEffect as useEffect7, useMemo as useMemo3, useState as useState8 } from "react";
|
|
1844
1905
|
import Link from "next/link";
|
|
1845
1906
|
import { jsx as jsx16, jsxs as jsxs14 } from "react/jsx-runtime";
|
|
1846
1907
|
var SEVEN_DAYS_MS = 7 * 24 * 60 * 60 * 1e3;
|
|
@@ -2062,7 +2123,7 @@ function AdminStudioDashboardClient({
|
|
|
2062
2123
|
children
|
|
2063
2124
|
}) {
|
|
2064
2125
|
const role = isRole(userRole) ? userRole : void 0;
|
|
2065
|
-
const [state, setState] =
|
|
2126
|
+
const [state, setState] = useState8(
|
|
2066
2127
|
() => formsEnabled && canReviewForms(role) ? {
|
|
2067
2128
|
forms: { status: "loading" },
|
|
2068
2129
|
media: { status: "loading" },
|
|
@@ -2667,15 +2728,16 @@ function AdminStudioDashboard(rawProps) {
|
|
|
2667
2728
|
}
|
|
2668
2729
|
|
|
2669
2730
|
// src/admin/components/studio/AdminStudioPagesListView.tsx
|
|
2670
|
-
import { useEffect as
|
|
2731
|
+
import { useEffect as useEffect9, useMemo as useMemo5, useState as useState11 } from "react";
|
|
2671
2732
|
import Link2 from "next/link";
|
|
2733
|
+
import { usePathname as usePathname3 } from "next/navigation";
|
|
2734
|
+
import { useAuth as useAuth4 } from "@payloadcms/ui";
|
|
2735
|
+
|
|
2736
|
+
// src/admin/components/studio/AdminStudioNewPageView.tsx
|
|
2737
|
+
import { useState as useState9 } from "react";
|
|
2672
2738
|
import { useAuth as useAuth3 } from "@payloadcms/ui";
|
|
2673
2739
|
import { jsx as jsx18, jsxs as jsxs15 } from "react/jsx-runtime";
|
|
2674
|
-
var
|
|
2675
|
-
if (!user || typeof user !== "object") return false;
|
|
2676
|
-
const role = user.role;
|
|
2677
|
-
return typeof role === "string" && (role === "admin" || role === "developer");
|
|
2678
|
-
};
|
|
2740
|
+
var pageTemplates = ["standard", "landing", "services", "contact"];
|
|
2679
2741
|
var getPropString3 = (props, key, fallback) => {
|
|
2680
2742
|
if (!props || typeof props !== "object") return fallback;
|
|
2681
2743
|
const direct = props[key];
|
|
@@ -2687,101 +2749,115 @@ var getPropString3 = (props, key, fallback) => {
|
|
|
2687
2749
|
}
|
|
2688
2750
|
return fallback;
|
|
2689
2751
|
};
|
|
2690
|
-
|
|
2752
|
+
var canManagePages = (user) => {
|
|
2753
|
+
if (!user || typeof user !== "object") return false;
|
|
2754
|
+
const role = user.role;
|
|
2755
|
+
return role === "admin" || role === "developer" || role === "editor";
|
|
2756
|
+
};
|
|
2757
|
+
var slugify = (value) => value.toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
|
|
2758
|
+
function AdminStudioNewPageView(props) {
|
|
2691
2759
|
const { user } = useAuth3();
|
|
2692
|
-
const pagesCollectionSlug = getPropString3(props, "pagesCollectionSlug", "pages");
|
|
2693
2760
|
const adminBasePath = useAdminBasePath();
|
|
2694
|
-
const
|
|
2695
|
-
const [
|
|
2696
|
-
const [error, setError] =
|
|
2697
|
-
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
|
|
2701
|
-
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
try {
|
|
2713
|
-
const res = await fetch(apiURL, { credentials: "include" });
|
|
2714
|
-
if (!res.ok) {
|
|
2715
|
-
const body = await res.text();
|
|
2716
|
-
throw new Error(body || "Failed to fetch pages");
|
|
2717
|
-
}
|
|
2718
|
-
const data = await res.json();
|
|
2719
|
-
if (!cancelled) {
|
|
2720
|
-
setDocs(Array.isArray(data.docs) ? data.docs : []);
|
|
2721
|
-
}
|
|
2722
|
-
} catch (err) {
|
|
2723
|
-
if (!cancelled) {
|
|
2724
|
-
setError(err instanceof Error ? err.message : "Failed to fetch pages");
|
|
2725
|
-
}
|
|
2726
|
-
} finally {
|
|
2727
|
-
if (!cancelled) {
|
|
2728
|
-
setLoading(false);
|
|
2729
|
-
}
|
|
2761
|
+
const pagesCollectionSlug = getPropString3(props, "pagesCollectionSlug", "pages");
|
|
2762
|
+
const [submitting, setSubmitting] = useState9(false);
|
|
2763
|
+
const [error, setError] = useState9(null);
|
|
2764
|
+
if (!canManagePages(user)) {
|
|
2765
|
+
return /* @__PURE__ */ jsx18(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ jsx18(
|
|
2766
|
+
AdminPage,
|
|
2767
|
+
{
|
|
2768
|
+
breadcrumbs: [
|
|
2769
|
+
{ label: "Dashboard", href: adminBasePath },
|
|
2770
|
+
{ label: "Pages", href: resolveAdminPath(adminBasePath, "/pages") },
|
|
2771
|
+
{ label: "New Page" }
|
|
2772
|
+
],
|
|
2773
|
+
description: "You do not have access to create pages.",
|
|
2774
|
+
title: "New Page",
|
|
2775
|
+
children: /* @__PURE__ */ jsxs15("div", { className: "orion-admin-card", children: [
|
|
2776
|
+
/* @__PURE__ */ jsx18("strong", { children: "Access denied" }),
|
|
2777
|
+
/* @__PURE__ */ jsx18("span", { children: "This section is restricted to administrator, developer, and editor accounts." })
|
|
2778
|
+
] })
|
|
2730
2779
|
}
|
|
2731
|
-
};
|
|
2732
|
-
|
|
2733
|
-
|
|
2734
|
-
|
|
2735
|
-
|
|
2736
|
-
|
|
2737
|
-
|
|
2780
|
+
) });
|
|
2781
|
+
}
|
|
2782
|
+
const createPage = async (event) => {
|
|
2783
|
+
event.preventDefault();
|
|
2784
|
+
setSubmitting(true);
|
|
2785
|
+
setError(null);
|
|
2786
|
+
try {
|
|
2787
|
+
const formData = new FormData(event.currentTarget);
|
|
2788
|
+
const titleValue = String(formData.get("title") || "").trim();
|
|
2789
|
+
const slugValue = String(formData.get("slug") || "").trim();
|
|
2790
|
+
const templateValue = String(formData.get("template") || "standard").trim();
|
|
2791
|
+
const template = pageTemplates.includes(templateValue) ? templateValue : "standard";
|
|
2792
|
+
const title = titleValue || "Untitled Page";
|
|
2793
|
+
const slug = slugValue || slugify(title) || "untitled-page";
|
|
2794
|
+
const response = await fetch(`/api/${pagesCollectionSlug}`, {
|
|
2795
|
+
body: JSON.stringify({
|
|
2796
|
+
_status: "draft",
|
|
2797
|
+
slug,
|
|
2798
|
+
template,
|
|
2799
|
+
title
|
|
2800
|
+
}),
|
|
2801
|
+
credentials: "include",
|
|
2802
|
+
headers: {
|
|
2803
|
+
"Content-Type": "application/json"
|
|
2804
|
+
},
|
|
2805
|
+
method: "POST"
|
|
2806
|
+
});
|
|
2807
|
+
if (!response.ok) {
|
|
2808
|
+
throw new Error(`Failed to create page (${response.status}).`);
|
|
2809
|
+
}
|
|
2810
|
+
const payload = await response.json();
|
|
2811
|
+
const id = typeof payload.id === "string" || typeof payload.id === "number" ? String(payload.id) : "";
|
|
2812
|
+
if (!id) {
|
|
2813
|
+
throw new Error("Page created but no document ID was returned.");
|
|
2814
|
+
}
|
|
2815
|
+
window.location.assign(resolveAdminPath(adminBasePath, `/pages/${id}`));
|
|
2816
|
+
} catch (createError) {
|
|
2817
|
+
setError(createError instanceof Error ? createError.message : "Failed to create page.");
|
|
2818
|
+
} finally {
|
|
2819
|
+
setSubmitting(false);
|
|
2820
|
+
}
|
|
2821
|
+
};
|
|
2822
|
+
return /* @__PURE__ */ jsx18(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ jsx18(
|
|
2738
2823
|
AdminPage,
|
|
2739
2824
|
{
|
|
2740
|
-
actions: hasAdminAccess(user) ? /* @__PURE__ */ jsx18(Link2, { className: "orion-admin-action-button", href: newPagePath, children: "New Page" }) : null,
|
|
2741
2825
|
breadcrumbs: [
|
|
2742
2826
|
{ label: "Dashboard", href: adminBasePath },
|
|
2743
|
-
{ label: "Pages" }
|
|
2827
|
+
{ label: "Pages", href: resolveAdminPath(adminBasePath, "/pages") },
|
|
2828
|
+
{ label: "New Page" }
|
|
2744
2829
|
],
|
|
2745
|
-
description: "
|
|
2746
|
-
title: "
|
|
2747
|
-
children: [
|
|
2748
|
-
loading ? /* @__PURE__ */ jsx18("div", { className: "orion-admin-list-meta", children: "Loading..." }) : null,
|
|
2830
|
+
description: "Create a new page and open it in the custom editor.",
|
|
2831
|
+
title: "New Page",
|
|
2832
|
+
children: /* @__PURE__ */ jsxs15("form", { className: "orion-admin-form", onSubmit: createPage, children: [
|
|
2749
2833
|
error ? /* @__PURE__ */ jsx18("div", { className: "orion-admin-error", children: error }) : null,
|
|
2750
|
-
/* @__PURE__ */ jsxs15("
|
|
2751
|
-
|
|
2752
|
-
|
|
2753
|
-
|
|
2754
|
-
|
|
2755
|
-
|
|
2756
|
-
|
|
2757
|
-
|
|
2758
|
-
|
|
2759
|
-
|
|
2760
|
-
|
|
2761
|
-
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
|
|
2765
|
-
|
|
2766
|
-
|
|
2834
|
+
/* @__PURE__ */ jsxs15("label", { children: [
|
|
2835
|
+
"Title",
|
|
2836
|
+
/* @__PURE__ */ jsx18("input", { name: "title", placeholder: "Services", required: true, type: "text" })
|
|
2837
|
+
] }),
|
|
2838
|
+
/* @__PURE__ */ jsxs15("label", { children: [
|
|
2839
|
+
"Slug",
|
|
2840
|
+
/* @__PURE__ */ jsx18("input", { name: "slug", placeholder: "services", type: "text" })
|
|
2841
|
+
] }),
|
|
2842
|
+
/* @__PURE__ */ jsxs15("label", { children: [
|
|
2843
|
+
"Template",
|
|
2844
|
+
/* @__PURE__ */ jsxs15("select", { defaultValue: "standard", name: "template", children: [
|
|
2845
|
+
/* @__PURE__ */ jsx18("option", { value: "standard", children: "Standard" }),
|
|
2846
|
+
/* @__PURE__ */ jsx18("option", { value: "landing", children: "Landing" }),
|
|
2847
|
+
/* @__PURE__ */ jsx18("option", { value: "contact", children: "Contact" }),
|
|
2848
|
+
/* @__PURE__ */ jsx18("option", { value: "services", children: "Services" })
|
|
2849
|
+
] })
|
|
2850
|
+
] }),
|
|
2851
|
+
/* @__PURE__ */ jsx18("button", { disabled: submitting, type: "submit", children: submitting ? "Creating..." : "Create Page" })
|
|
2852
|
+
] })
|
|
2767
2853
|
}
|
|
2768
2854
|
) });
|
|
2769
2855
|
}
|
|
2770
2856
|
|
|
2771
2857
|
// src/admin/components/studio/AdminStudioPageEditView.tsx
|
|
2772
|
-
import { useEffect as
|
|
2773
|
-
import { SetStepNav
|
|
2858
|
+
import { useEffect as useEffect8, useMemo as useMemo4, useRef as useRef3, useState as useState10 } from "react";
|
|
2859
|
+
import { SetStepNav } from "@payloadcms/ui";
|
|
2774
2860
|
import { Fragment as Fragment4, jsx as jsx19, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2775
|
-
var hasAdminAccess2 = (user) => {
|
|
2776
|
-
if (!user || typeof user !== "object") return false;
|
|
2777
|
-
const role = user.role;
|
|
2778
|
-
return typeof role === "string" && (role === "admin" || role === "developer");
|
|
2779
|
-
};
|
|
2780
|
-
var isEditor = (user) => {
|
|
2781
|
-
if (!user || typeof user !== "object") return false;
|
|
2782
|
-
const role = user.role;
|
|
2783
|
-
return typeof role === "string" && role === "editor";
|
|
2784
|
-
};
|
|
2785
2861
|
var getPropString4 = (props, key, fallback) => {
|
|
2786
2862
|
if (!props || typeof props !== "object") return fallback;
|
|
2787
2863
|
const direct = props[key];
|
|
@@ -2809,20 +2885,14 @@ var getPageIDFromPathname = (pathname) => {
|
|
|
2809
2885
|
return pagePart ? decodeURIComponent(pagePart) : null;
|
|
2810
2886
|
};
|
|
2811
2887
|
function AdminStudioPageEditView(props) {
|
|
2812
|
-
const { user } = useAuth4();
|
|
2813
2888
|
const adminBasePath = useAdminBasePath();
|
|
2814
2889
|
const iframeRef = useRef3(null);
|
|
2815
|
-
const [saving, setSaving] = useState9(null);
|
|
2816
|
-
const [dirty, setDirty] = useState9(false);
|
|
2817
|
-
const [hasUnpublishedChanges, setHasUnpublishedChanges] = useState9(false);
|
|
2818
|
-
const [canUndo, setCanUndo] = useState9(false);
|
|
2819
|
-
const [canRedo, setCanRedo] = useState9(false);
|
|
2820
2890
|
const builderBasePath = getPropString4(props, "builderBasePath", "/builder");
|
|
2821
2891
|
const pagesPath = resolveAdminPath(adminBasePath, "/pages");
|
|
2822
|
-
const pageIDFromParams =
|
|
2823
|
-
const [pageID, setPageID] =
|
|
2824
|
-
const [didResolvePathFallback, setDidResolvePathFallback] =
|
|
2825
|
-
|
|
2892
|
+
const pageIDFromParams = useMemo4(() => getParam(props.params, "id"), [props.params]);
|
|
2893
|
+
const [pageID, setPageID] = useState10(pageIDFromParams);
|
|
2894
|
+
const [didResolvePathFallback, setDidResolvePathFallback] = useState10(false);
|
|
2895
|
+
useEffect8(() => {
|
|
2826
2896
|
if (pageIDFromParams) {
|
|
2827
2897
|
setPageID(pageIDFromParams);
|
|
2828
2898
|
setDidResolvePathFallback(true);
|
|
@@ -2833,96 +2903,6 @@ function AdminStudioPageEditView(props) {
|
|
|
2833
2903
|
}
|
|
2834
2904
|
setDidResolvePathFallback(true);
|
|
2835
2905
|
}, [pageIDFromParams]);
|
|
2836
|
-
const canPublish = hasAdminAccess2(user) || isEditor(user);
|
|
2837
|
-
const refreshUnpublishedState = async (id) => {
|
|
2838
|
-
try {
|
|
2839
|
-
const response = await fetch(
|
|
2840
|
-
`/api/pages/versions?depth=0&limit=25&sort=-updatedAt&where[parent][equals]=${encodeURIComponent(id)}`,
|
|
2841
|
-
{
|
|
2842
|
-
credentials: "include"
|
|
2843
|
-
}
|
|
2844
|
-
);
|
|
2845
|
-
if (!response.ok) {
|
|
2846
|
-
return;
|
|
2847
|
-
}
|
|
2848
|
-
const payload = await response.json();
|
|
2849
|
-
const docs = Array.isArray(payload.docs) ? payload.docs : [];
|
|
2850
|
-
let latestDraft = 0;
|
|
2851
|
-
let latestPublished = 0;
|
|
2852
|
-
docs.forEach((doc) => {
|
|
2853
|
-
const status = doc.version?._status;
|
|
2854
|
-
const millis = typeof doc.updatedAt === "string" ? Date.parse(doc.updatedAt) : Number.NaN;
|
|
2855
|
-
if (!Number.isFinite(millis)) {
|
|
2856
|
-
return;
|
|
2857
|
-
}
|
|
2858
|
-
if (status === "draft") {
|
|
2859
|
-
latestDraft = Math.max(latestDraft, millis);
|
|
2860
|
-
}
|
|
2861
|
-
if (status === "published") {
|
|
2862
|
-
latestPublished = Math.max(latestPublished, millis);
|
|
2863
|
-
}
|
|
2864
|
-
});
|
|
2865
|
-
setHasUnpublishedChanges(latestDraft > 0 && latestDraft >= latestPublished);
|
|
2866
|
-
} catch {
|
|
2867
|
-
}
|
|
2868
|
-
};
|
|
2869
|
-
useEffect9(() => {
|
|
2870
|
-
if (!pageID) {
|
|
2871
|
-
return;
|
|
2872
|
-
}
|
|
2873
|
-
void refreshUnpublishedState(pageID);
|
|
2874
|
-
}, [pageID]);
|
|
2875
|
-
const requestSave = (status) => {
|
|
2876
|
-
const iframe = iframeRef.current;
|
|
2877
|
-
if (!iframe?.contentWindow) {
|
|
2878
|
-
toast.error("Editor is not ready yet. Please try again.");
|
|
2879
|
-
return;
|
|
2880
|
-
}
|
|
2881
|
-
setSaving(status);
|
|
2882
|
-
iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type: "save", status }, "*");
|
|
2883
|
-
};
|
|
2884
|
-
const requestHistoryAction = (type) => {
|
|
2885
|
-
const iframe = iframeRef.current;
|
|
2886
|
-
if (!iframe?.contentWindow) {
|
|
2887
|
-
toast.error("Editor is not ready yet. Please try again.");
|
|
2888
|
-
return;
|
|
2889
|
-
}
|
|
2890
|
-
iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type }, "*");
|
|
2891
|
-
};
|
|
2892
|
-
useEffect9(() => {
|
|
2893
|
-
const onMessage = (event) => {
|
|
2894
|
-
const data = event.data;
|
|
2895
|
-
if (!data || data.source !== "payload-visual-builder-child" || typeof data.type !== "string") {
|
|
2896
|
-
return;
|
|
2897
|
-
}
|
|
2898
|
-
if (data.type === "dirty-state") {
|
|
2899
|
-
setDirty(Boolean(data.dirty));
|
|
2900
|
-
return;
|
|
2901
|
-
}
|
|
2902
|
-
if (data.type === "history-state") {
|
|
2903
|
-
setCanUndo(Boolean(data.canUndo));
|
|
2904
|
-
setCanRedo(Boolean(data.canRedo));
|
|
2905
|
-
return;
|
|
2906
|
-
}
|
|
2907
|
-
if (data.type === "save-result") {
|
|
2908
|
-
setSaving(null);
|
|
2909
|
-
if (data.ok) {
|
|
2910
|
-
if (data.status === "draft") {
|
|
2911
|
-
setHasUnpublishedChanges(true);
|
|
2912
|
-
} else if (data.status === "published") {
|
|
2913
|
-
setHasUnpublishedChanges(false);
|
|
2914
|
-
} else if (pageID) {
|
|
2915
|
-
void refreshUnpublishedState(pageID);
|
|
2916
|
-
}
|
|
2917
|
-
toast.success(typeof data.message === "string" ? data.message : "Saved.");
|
|
2918
|
-
} else {
|
|
2919
|
-
toast.error(typeof data.message === "string" ? data.message : "Save failed.");
|
|
2920
|
-
}
|
|
2921
|
-
}
|
|
2922
|
-
};
|
|
2923
|
-
window.addEventListener("message", onMessage);
|
|
2924
|
-
return () => window.removeEventListener("message", onMessage);
|
|
2925
|
-
}, []);
|
|
2926
2906
|
if (!pageID && !didResolvePathFallback) {
|
|
2927
2907
|
return /* @__PURE__ */ jsx19(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ jsxs16(Fragment4, { children: [
|
|
2928
2908
|
/* @__PURE__ */ jsx19(
|
|
@@ -2963,164 +2943,25 @@ function AdminStudioPageEditView(props) {
|
|
|
2963
2943
|
]
|
|
2964
2944
|
}
|
|
2965
2945
|
),
|
|
2966
|
-
/* @__PURE__ */
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
|
|
2972
|
-
|
|
2973
|
-
|
|
2974
|
-
|
|
2975
|
-
boxShadow: "0 12px 28px rgba(62, 42, 24, 0.08)",
|
|
2976
|
-
colorScheme: "light",
|
|
2977
|
-
display: "flex",
|
|
2978
|
-
gap: "0.6rem",
|
|
2979
|
-
justifyContent: "space-between",
|
|
2980
|
-
padding: "0.65rem 0.9rem",
|
|
2981
|
-
position: "sticky",
|
|
2982
|
-
top: 0,
|
|
2983
|
-
zIndex: 20
|
|
2984
|
-
},
|
|
2985
|
-
children: [
|
|
2986
|
-
/* @__PURE__ */ jsxs16("div", { style: { minWidth: 0 }, children: [
|
|
2987
|
-
/* @__PURE__ */ jsx19("div", { style: { color: "var(--orion-admin-text)", fontWeight: 900 }, children: "Page Editor" }),
|
|
2988
|
-
/* @__PURE__ */ jsxs16(
|
|
2989
|
-
"div",
|
|
2990
|
-
{
|
|
2991
|
-
style: {
|
|
2992
|
-
color: "var(--orion-admin-muted)",
|
|
2993
|
-
fontSize: "0.85rem",
|
|
2994
|
-
overflow: "hidden",
|
|
2995
|
-
textOverflow: "ellipsis"
|
|
2996
|
-
},
|
|
2997
|
-
children: [
|
|
2998
|
-
"Editing: ",
|
|
2999
|
-
pageID
|
|
3000
|
-
]
|
|
3001
|
-
}
|
|
3002
|
-
)
|
|
3003
|
-
] }),
|
|
3004
|
-
/* @__PURE__ */ jsxs16("div", { style: { alignItems: "center", display: "flex", gap: "0.5rem" }, children: [
|
|
3005
|
-
/* @__PURE__ */ jsx19("div", { style: { color: dirty ? "var(--orion-admin-text)" : "var(--orion-admin-muted)", fontSize: "0.85rem", fontWeight: 700 }, children: dirty ? "Unsaved changes" : "All changes saved" }),
|
|
3006
|
-
/* @__PURE__ */ jsx19(
|
|
3007
|
-
"div",
|
|
3008
|
-
{
|
|
3009
|
-
style: {
|
|
3010
|
-
background: hasUnpublishedChanges ? "#fff3cd" : "var(--orion-admin-accent-subtle)",
|
|
3011
|
-
border: `1px solid ${hasUnpublishedChanges ? "#f0c36d" : "color-mix(in srgb, var(--orion-admin-accent) 36%, transparent)"}`,
|
|
3012
|
-
borderRadius: 999,
|
|
3013
|
-
color: hasUnpublishedChanges ? "#6a4a00" : "var(--orion-admin-accent)",
|
|
3014
|
-
fontSize: "0.75rem",
|
|
3015
|
-
fontWeight: 800,
|
|
3016
|
-
padding: "0.2rem 0.55rem",
|
|
3017
|
-
whiteSpace: "nowrap"
|
|
3018
|
-
},
|
|
3019
|
-
title: hasUnpublishedChanges ? "There are saved draft changes not yet published." : "The live page matches the latest published content.",
|
|
3020
|
-
children: hasUnpublishedChanges ? "Unpublished draft changes" : "Live is up to date"
|
|
3021
|
-
}
|
|
3022
|
-
),
|
|
3023
|
-
/* @__PURE__ */ jsx19(
|
|
3024
|
-
"button",
|
|
3025
|
-
{
|
|
3026
|
-
disabled: !canUndo,
|
|
3027
|
-
onClick: () => requestHistoryAction("undo"),
|
|
3028
|
-
style: {
|
|
3029
|
-
background: "transparent",
|
|
3030
|
-
border: "1px solid var(--orion-admin-card-border)",
|
|
3031
|
-
borderRadius: 12,
|
|
3032
|
-
cursor: canUndo ? "pointer" : "not-allowed",
|
|
3033
|
-
color: "var(--orion-admin-text)",
|
|
3034
|
-
fontWeight: 800,
|
|
3035
|
-
padding: "0.5rem 0.65rem"
|
|
3036
|
-
},
|
|
3037
|
-
type: "button",
|
|
3038
|
-
children: "Undo"
|
|
3039
|
-
}
|
|
3040
|
-
),
|
|
3041
|
-
/* @__PURE__ */ jsx19(
|
|
3042
|
-
"button",
|
|
3043
|
-
{
|
|
3044
|
-
disabled: !canRedo,
|
|
3045
|
-
onClick: () => requestHistoryAction("redo"),
|
|
3046
|
-
style: {
|
|
3047
|
-
background: "transparent",
|
|
3048
|
-
border: "1px solid var(--orion-admin-card-border)",
|
|
3049
|
-
borderRadius: 12,
|
|
3050
|
-
cursor: canRedo ? "pointer" : "not-allowed",
|
|
3051
|
-
color: "var(--orion-admin-text)",
|
|
3052
|
-
fontWeight: 800,
|
|
3053
|
-
padding: "0.5rem 0.65rem"
|
|
3054
|
-
},
|
|
3055
|
-
type: "button",
|
|
3056
|
-
children: "Redo"
|
|
3057
|
-
}
|
|
3058
|
-
),
|
|
3059
|
-
/* @__PURE__ */ jsx19(
|
|
3060
|
-
"button",
|
|
3061
|
-
{
|
|
3062
|
-
disabled: saving !== null,
|
|
3063
|
-
onClick: () => requestSave("draft"),
|
|
3064
|
-
style: {
|
|
3065
|
-
background: "var(--orion-admin-card-bg)",
|
|
3066
|
-
border: "1px solid var(--orion-admin-card-border)",
|
|
3067
|
-
borderRadius: 12,
|
|
3068
|
-
cursor: saving ? "not-allowed" : "pointer",
|
|
3069
|
-
color: "var(--orion-admin-text)",
|
|
3070
|
-
fontWeight: 800,
|
|
3071
|
-
padding: "0.5rem 0.75rem"
|
|
3072
|
-
},
|
|
3073
|
-
type: "button",
|
|
3074
|
-
children: saving === "draft" ? "Saving\u2026" : "Save Draft"
|
|
3075
|
-
}
|
|
3076
|
-
),
|
|
3077
|
-
/* @__PURE__ */ jsx19(
|
|
3078
|
-
"button",
|
|
3079
|
-
{
|
|
3080
|
-
disabled: !canPublish || saving !== null,
|
|
3081
|
-
onClick: () => requestSave("published"),
|
|
3082
|
-
style: {
|
|
3083
|
-
background: canPublish ? "var(--orion-admin-button-bg)" : "var(--orion-admin-card-border)",
|
|
3084
|
-
border: "none",
|
|
3085
|
-
borderRadius: 12,
|
|
3086
|
-
color: canPublish ? "var(--orion-admin-button-text)" : "var(--orion-admin-text)",
|
|
3087
|
-
cursor: !canPublish || saving ? "not-allowed" : "pointer",
|
|
3088
|
-
fontWeight: 900,
|
|
3089
|
-
padding: "0.5rem 0.75rem"
|
|
3090
|
-
},
|
|
3091
|
-
type: "button",
|
|
3092
|
-
title: !canPublish ? "You do not have publish permissions." : void 0,
|
|
3093
|
-
children: saving === "published" ? "Publishing\u2026" : "Publish"
|
|
3094
|
-
}
|
|
3095
|
-
)
|
|
3096
|
-
] })
|
|
3097
|
-
]
|
|
3098
|
-
}
|
|
3099
|
-
),
|
|
3100
|
-
/* @__PURE__ */ jsx19(
|
|
3101
|
-
"iframe",
|
|
3102
|
-
{
|
|
3103
|
-
ref: iframeRef,
|
|
3104
|
-
src: `${builderBasePath.replace(/\/$/, "")}/${pageID}`,
|
|
3105
|
-
style: { border: "none", height: "100%", width: "100%" },
|
|
3106
|
-
title: "Page Builder",
|
|
3107
|
-
onLoad: () => {
|
|
3108
|
-
const iframe = iframeRef.current;
|
|
3109
|
-
if (!iframe?.contentWindow) return;
|
|
3110
|
-
iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type: "dirty-check-request" }, "*");
|
|
3111
|
-
iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type: "history-check-request" }, "*");
|
|
3112
|
-
}
|
|
3113
|
-
}
|
|
3114
|
-
)
|
|
3115
|
-
] })
|
|
2946
|
+
/* @__PURE__ */ jsx19("div", { style: { height: "100dvh", overflow: "hidden" }, children: /* @__PURE__ */ jsx19(
|
|
2947
|
+
"iframe",
|
|
2948
|
+
{
|
|
2949
|
+
ref: iframeRef,
|
|
2950
|
+
src: `${builderBasePath.replace(/\/$/, "")}/${pageID}`,
|
|
2951
|
+
style: { border: "none", height: "100%", width: "100%" },
|
|
2952
|
+
title: "Page Builder"
|
|
2953
|
+
}
|
|
2954
|
+
) })
|
|
3116
2955
|
] }) });
|
|
3117
2956
|
}
|
|
3118
2957
|
|
|
3119
|
-
// src/admin/components/studio/
|
|
3120
|
-
import { useState as useState10 } from "react";
|
|
3121
|
-
import { useAuth as useAuth5 } from "@payloadcms/ui";
|
|
2958
|
+
// src/admin/components/studio/AdminStudioPagesListView.tsx
|
|
3122
2959
|
import { jsx as jsx20, jsxs as jsxs17 } from "react/jsx-runtime";
|
|
3123
|
-
var
|
|
2960
|
+
var hasAdminAccess = (user) => {
|
|
2961
|
+
if (!user || typeof user !== "object") return false;
|
|
2962
|
+
const role = user.role;
|
|
2963
|
+
return typeof role === "string" && (role === "admin" || role === "developer");
|
|
2964
|
+
};
|
|
3124
2965
|
var getPropString5 = (props, key, fallback) => {
|
|
3125
2966
|
if (!props || typeof props !== "object") return fallback;
|
|
3126
2967
|
const direct = props[key];
|
|
@@ -3132,107 +2973,98 @@ var getPropString5 = (props, key, fallback) => {
|
|
|
3132
2973
|
}
|
|
3133
2974
|
return fallback;
|
|
3134
2975
|
};
|
|
3135
|
-
|
|
3136
|
-
if (!user || typeof user !== "object") return false;
|
|
3137
|
-
const role = user.role;
|
|
3138
|
-
return role === "admin" || role === "developer" || role === "editor";
|
|
3139
|
-
};
|
|
3140
|
-
var slugify = (value) => value.toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
|
|
3141
|
-
function AdminStudioNewPageView(props) {
|
|
3142
|
-
const { user } = useAuth5();
|
|
2976
|
+
function AdminStudioPagesListView(props) {
|
|
3143
2977
|
const adminBasePath = useAdminBasePath();
|
|
3144
|
-
const
|
|
3145
|
-
const
|
|
3146
|
-
const
|
|
3147
|
-
if (
|
|
3148
|
-
return /* @__PURE__ */ jsx20(
|
|
3149
|
-
AdminPage,
|
|
3150
|
-
{
|
|
3151
|
-
breadcrumbs: [
|
|
3152
|
-
{ label: "Dashboard", href: adminBasePath },
|
|
3153
|
-
{ label: "Pages", href: resolveAdminPath(adminBasePath, "/pages") },
|
|
3154
|
-
{ label: "New Page" }
|
|
3155
|
-
],
|
|
3156
|
-
description: "You do not have access to create pages.",
|
|
3157
|
-
title: "New Page",
|
|
3158
|
-
children: /* @__PURE__ */ jsxs17("div", { className: "orion-admin-card", children: [
|
|
3159
|
-
/* @__PURE__ */ jsx20("strong", { children: "Access denied" }),
|
|
3160
|
-
/* @__PURE__ */ jsx20("span", { children: "This section is restricted to administrator, developer, and editor accounts." })
|
|
3161
|
-
] })
|
|
3162
|
-
}
|
|
3163
|
-
) });
|
|
2978
|
+
const pathname = usePathname3();
|
|
2979
|
+
const pagesPath = resolveAdminPath(adminBasePath, "/pages");
|
|
2980
|
+
const nestedPagePath = pathname && pathname.startsWith(`${pagesPath}/`) ? pathname.slice(`${pagesPath}/`.length).split("/")[0] : "";
|
|
2981
|
+
if (nestedPagePath === "new") {
|
|
2982
|
+
return /* @__PURE__ */ jsx20(AdminStudioNewPageView, { ...props });
|
|
3164
2983
|
}
|
|
3165
|
-
|
|
3166
|
-
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
|
|
2984
|
+
if (nestedPagePath) {
|
|
2985
|
+
return /* @__PURE__ */ jsx20(AdminStudioPageEditView, { ...props });
|
|
2986
|
+
}
|
|
2987
|
+
return /* @__PURE__ */ jsx20(AdminStudioPagesIndexView, { ...props, adminBasePath });
|
|
2988
|
+
}
|
|
2989
|
+
function AdminStudioPagesIndexView({
|
|
2990
|
+
adminBasePath,
|
|
2991
|
+
...props
|
|
2992
|
+
}) {
|
|
2993
|
+
const { user } = useAuth4();
|
|
2994
|
+
const pagesCollectionSlug = getPropString5(props, "pagesCollectionSlug", "pages");
|
|
2995
|
+
const newPagePath = resolveAdminPath(adminBasePath, "/pages/new");
|
|
2996
|
+
const [loading, setLoading] = useState11(true);
|
|
2997
|
+
const [error, setError] = useState11(null);
|
|
2998
|
+
const [docs, setDocs] = useState11([]);
|
|
2999
|
+
const apiURL = useMemo5(() => {
|
|
3000
|
+
const params = new URLSearchParams({
|
|
3001
|
+
depth: "0",
|
|
3002
|
+
limit: "100",
|
|
3003
|
+
sort: "-updatedAt",
|
|
3004
|
+
draft: "true"
|
|
3005
|
+
});
|
|
3006
|
+
return `/api/${pagesCollectionSlug}?${params.toString()}`;
|
|
3007
|
+
}, [pagesCollectionSlug]);
|
|
3008
|
+
useEffect9(() => {
|
|
3009
|
+
let cancelled = false;
|
|
3010
|
+
const run = async () => {
|
|
3011
|
+
setLoading(true);
|
|
3012
|
+
setError(null);
|
|
3013
|
+
try {
|
|
3014
|
+
const res = await fetch(apiURL, { credentials: "include" });
|
|
3015
|
+
if (!res.ok) {
|
|
3016
|
+
const body = await res.text();
|
|
3017
|
+
throw new Error(body || "Failed to fetch pages");
|
|
3018
|
+
}
|
|
3019
|
+
const data = await res.json();
|
|
3020
|
+
if (!cancelled) {
|
|
3021
|
+
setDocs(Array.isArray(data.docs) ? data.docs : []);
|
|
3022
|
+
}
|
|
3023
|
+
} catch (err) {
|
|
3024
|
+
if (!cancelled) {
|
|
3025
|
+
setError(err instanceof Error ? err.message : "Failed to fetch pages");
|
|
3026
|
+
}
|
|
3027
|
+
} finally {
|
|
3028
|
+
if (!cancelled) {
|
|
3029
|
+
setLoading(false);
|
|
3030
|
+
}
|
|
3197
3031
|
}
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
return /* @__PURE__ */ jsx20(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ jsx20(
|
|
3032
|
+
};
|
|
3033
|
+
void run();
|
|
3034
|
+
return () => {
|
|
3035
|
+
cancelled = true;
|
|
3036
|
+
};
|
|
3037
|
+
}, [apiURL]);
|
|
3038
|
+
return /* @__PURE__ */ jsx20(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ jsxs17(
|
|
3206
3039
|
AdminPage,
|
|
3207
3040
|
{
|
|
3041
|
+
actions: hasAdminAccess(user) ? /* @__PURE__ */ jsx20(Link2, { className: "orion-admin-action-button", href: newPagePath, children: "New Page" }) : null,
|
|
3208
3042
|
breadcrumbs: [
|
|
3209
3043
|
{ label: "Dashboard", href: adminBasePath },
|
|
3210
|
-
{ label: "Pages"
|
|
3211
|
-
{ label: "New Page" }
|
|
3044
|
+
{ label: "Pages" }
|
|
3212
3045
|
],
|
|
3213
|
-
description: "
|
|
3214
|
-
title: "
|
|
3215
|
-
children:
|
|
3046
|
+
description: "Open a page to edit it in the inline custom builder.",
|
|
3047
|
+
title: "Pages",
|
|
3048
|
+
children: [
|
|
3049
|
+
loading ? /* @__PURE__ */ jsx20("div", { className: "orion-admin-list-meta", children: "Loading..." }) : null,
|
|
3216
3050
|
error ? /* @__PURE__ */ jsx20("div", { className: "orion-admin-error", children: error }) : null,
|
|
3217
|
-
/* @__PURE__ */ jsxs17("
|
|
3218
|
-
"
|
|
3219
|
-
|
|
3220
|
-
|
|
3221
|
-
|
|
3222
|
-
|
|
3223
|
-
|
|
3224
|
-
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
|
|
3233
|
-
|
|
3234
|
-
/* @__PURE__ */ jsx20("button", { disabled: submitting, type: "submit", children: submitting ? "Creating..." : "Create Page" })
|
|
3235
|
-
] })
|
|
3051
|
+
/* @__PURE__ */ jsxs17("div", { className: "orion-admin-list", children: [
|
|
3052
|
+
!loading && !error && docs.length === 0 ? /* @__PURE__ */ jsxs17("div", { className: "orion-admin-card", children: [
|
|
3053
|
+
/* @__PURE__ */ jsx20("strong", { children: "No pages yet" }),
|
|
3054
|
+
/* @__PURE__ */ jsx20("span", { children: "Create the first page to start building content." })
|
|
3055
|
+
] }) : null,
|
|
3056
|
+
docs.map((doc) => {
|
|
3057
|
+
const id = typeof doc.id === "string" || typeof doc.id === "number" ? String(doc.id) : "";
|
|
3058
|
+
if (!id) return null;
|
|
3059
|
+
const title = typeof doc.title === "string" ? doc.title : "Untitled Page";
|
|
3060
|
+
const status = typeof doc._status === "string" ? doc._status : "draft";
|
|
3061
|
+
return /* @__PURE__ */ jsxs17(Link2, { className: "orion-admin-list-item", href: resolveAdminPath(adminBasePath, `/pages/${id}`), children: [
|
|
3062
|
+
/* @__PURE__ */ jsx20("div", { children: /* @__PURE__ */ jsx20("strong", { children: title }) }),
|
|
3063
|
+
/* @__PURE__ */ jsx20("span", { className: "orion-admin-pill", children: status })
|
|
3064
|
+
] }, id);
|
|
3065
|
+
})
|
|
3066
|
+
] })
|
|
3067
|
+
]
|
|
3236
3068
|
}
|
|
3237
3069
|
) });
|
|
3238
3070
|
}
|
|
@@ -3285,7 +3117,7 @@ function AdminStudioGlobalsView(props) {
|
|
|
3285
3117
|
}
|
|
3286
3118
|
|
|
3287
3119
|
// src/admin/components/studio/AdminStudioSiteSettingsGlobalView.tsx
|
|
3288
|
-
import { useEffect as useEffect10, useMemo as useMemo6, useState as
|
|
3120
|
+
import { useEffect as useEffect10, useMemo as useMemo6, useState as useState12 } from "react";
|
|
3289
3121
|
import { jsx as jsx22, jsxs as jsxs19 } from "react/jsx-runtime";
|
|
3290
3122
|
var getPropString6 = (props, key, fallback) => {
|
|
3291
3123
|
if (!props || typeof props !== "object") return fallback;
|
|
@@ -3371,12 +3203,12 @@ function AdminStudioSiteSettingsGlobalView(props) {
|
|
|
3371
3203
|
const mediaCollectionSlug = getPropString6(props, "mediaCollectionSlug", "media");
|
|
3372
3204
|
const adminBasePath = useAdminBasePath();
|
|
3373
3205
|
const resolvedGlobalsBasePath = resolveAdminPath(adminBasePath, globalsBasePath);
|
|
3374
|
-
const [loading, setLoading] =
|
|
3375
|
-
const [saving, setSaving] =
|
|
3376
|
-
const [error, setError] =
|
|
3377
|
-
const [savedMessage, setSavedMessage] =
|
|
3378
|
-
const [globalData, setGlobalData] =
|
|
3379
|
-
const [mediaOptions, setMediaOptions] =
|
|
3206
|
+
const [loading, setLoading] = useState12(true);
|
|
3207
|
+
const [saving, setSaving] = useState12(false);
|
|
3208
|
+
const [error, setError] = useState12(null);
|
|
3209
|
+
const [savedMessage, setSavedMessage] = useState12(null);
|
|
3210
|
+
const [globalData, setGlobalData] = useState12({});
|
|
3211
|
+
const [mediaOptions, setMediaOptions] = useState12([]);
|
|
3380
3212
|
useEffect10(() => {
|
|
3381
3213
|
let cancelled = false;
|
|
3382
3214
|
const run = async () => {
|
|
@@ -3661,7 +3493,7 @@ function AdminStudioSiteSettingsGlobalView(props) {
|
|
|
3661
3493
|
}
|
|
3662
3494
|
|
|
3663
3495
|
// src/admin/components/studio/AdminStudioSocialMediaGlobalView.tsx
|
|
3664
|
-
import { useEffect as useEffect11, useMemo as useMemo7, useState as
|
|
3496
|
+
import { useEffect as useEffect11, useMemo as useMemo7, useState as useState13 } from "react";
|
|
3665
3497
|
|
|
3666
3498
|
// src/shared/socialMedia.ts
|
|
3667
3499
|
var SOCIAL_MEDIA_PLATFORM_LABELS = {
|
|
@@ -3798,11 +3630,11 @@ function AdminStudioSocialMediaGlobalView(props) {
|
|
|
3798
3630
|
const globalsBasePath = getPropString7(props, "globalsBasePath", "/globals");
|
|
3799
3631
|
const adminBasePath = useAdminBasePath();
|
|
3800
3632
|
const resolvedGlobalsBasePath = resolveAdminPath(adminBasePath, globalsBasePath);
|
|
3801
|
-
const [loading, setLoading] =
|
|
3802
|
-
const [saving, setSaving] =
|
|
3803
|
-
const [error, setError] =
|
|
3804
|
-
const [savedMessage, setSavedMessage] =
|
|
3805
|
-
const [globalData, setGlobalData] =
|
|
3633
|
+
const [loading, setLoading] = useState13(true);
|
|
3634
|
+
const [saving, setSaving] = useState13(false);
|
|
3635
|
+
const [error, setError] = useState13(null);
|
|
3636
|
+
const [savedMessage, setSavedMessage] = useState13(null);
|
|
3637
|
+
const [globalData, setGlobalData] = useState13({});
|
|
3806
3638
|
useEffect11(() => {
|
|
3807
3639
|
let cancelled = false;
|
|
3808
3640
|
const run = async () => {
|
|
@@ -3942,7 +3774,7 @@ function AdminStudioSocialMediaGlobalView(props) {
|
|
|
3942
3774
|
}
|
|
3943
3775
|
|
|
3944
3776
|
// src/admin/components/studio/AdminStudioHeaderGlobalView.tsx
|
|
3945
|
-
import { useEffect as useEffect12, useMemo as useMemo8, useState as
|
|
3777
|
+
import { useEffect as useEffect12, useMemo as useMemo8, useState as useState14 } from "react";
|
|
3946
3778
|
import { SetStepNav as SetStepNav2 } from "@payloadcms/ui";
|
|
3947
3779
|
|
|
3948
3780
|
// src/nextjs/utilities/socialMedia.ts
|
|
@@ -4038,15 +3870,15 @@ function AdminStudioHeaderGlobalView(props) {
|
|
|
4038
3870
|
const adminBasePath = useAdminBasePath();
|
|
4039
3871
|
const resolvedGlobalsBasePath = resolveAdminPath(adminBasePath, globalsBasePath);
|
|
4040
3872
|
const rawGlobalPath = resolveAdminPath(adminBasePath, `/globals/${globalSlug}`);
|
|
4041
|
-
const [loading, setLoading] =
|
|
4042
|
-
const [saving, setSaving] =
|
|
4043
|
-
const [error, setError] =
|
|
4044
|
-
const [savedMessage, setSavedMessage] =
|
|
4045
|
-
const [initialItems, setInitialItems] =
|
|
4046
|
-
const [liveItems, setLiveItems] =
|
|
4047
|
-
const [pages, setPages] =
|
|
4048
|
-
const [siteSettings, setSiteSettings] =
|
|
4049
|
-
const [socialMedia, setSocialMedia] =
|
|
3873
|
+
const [loading, setLoading] = useState14(true);
|
|
3874
|
+
const [saving, setSaving] = useState14(false);
|
|
3875
|
+
const [error, setError] = useState14(null);
|
|
3876
|
+
const [savedMessage, setSavedMessage] = useState14(null);
|
|
3877
|
+
const [initialItems, setInitialItems] = useState14([]);
|
|
3878
|
+
const [liveItems, setLiveItems] = useState14([]);
|
|
3879
|
+
const [pages, setPages] = useState14([]);
|
|
3880
|
+
const [siteSettings, setSiteSettings] = useState14({});
|
|
3881
|
+
const [socialMedia, setSocialMedia] = useState14({});
|
|
4050
3882
|
useEffect12(() => {
|
|
4051
3883
|
let cancelled = false;
|
|
4052
3884
|
const run = async () => {
|
|
@@ -4213,7 +4045,7 @@ function AdminStudioHeaderGlobalView(props) {
|
|
|
4213
4045
|
}
|
|
4214
4046
|
|
|
4215
4047
|
// src/admin/components/studio/AdminStudioFooterGlobalView.tsx
|
|
4216
|
-
import { useEffect as useEffect13, useMemo as useMemo9, useState as
|
|
4048
|
+
import { useEffect as useEffect13, useMemo as useMemo9, useState as useState15 } from "react";
|
|
4217
4049
|
import { SetStepNav as SetStepNav3 } from "@payloadcms/ui";
|
|
4218
4050
|
import { jsx as jsx25, jsxs as jsxs22 } from "react/jsx-runtime";
|
|
4219
4051
|
var getPropString9 = (props, key, fallback) => {
|
|
@@ -4321,17 +4153,17 @@ function AdminStudioFooterGlobalView(props) {
|
|
|
4321
4153
|
const adminBasePath = useAdminBasePath();
|
|
4322
4154
|
const resolvedGlobalsBasePath = resolveAdminPath(adminBasePath, globalsBasePath);
|
|
4323
4155
|
const rawGlobalPath = resolveAdminPath(adminBasePath, `/globals/${globalSlug}`);
|
|
4324
|
-
const [loading, setLoading] =
|
|
4325
|
-
const [saving, setSaving] =
|
|
4326
|
-
const [error, setError] =
|
|
4327
|
-
const [savedMessage, setSavedMessage] =
|
|
4328
|
-
const [doc, setDoc] =
|
|
4156
|
+
const [loading, setLoading] = useState15(true);
|
|
4157
|
+
const [saving, setSaving] = useState15(false);
|
|
4158
|
+
const [error, setError] = useState15(null);
|
|
4159
|
+
const [savedMessage, setSavedMessage] = useState15(null);
|
|
4160
|
+
const [doc, setDoc] = useState15({
|
|
4329
4161
|
contactEmail: "",
|
|
4330
4162
|
contactPhone: "",
|
|
4331
4163
|
copyright: ""
|
|
4332
4164
|
});
|
|
4333
|
-
const [siteSettings, setSiteSettings] =
|
|
4334
|
-
const [socialMedia, setSocialMedia] =
|
|
4165
|
+
const [siteSettings, setSiteSettings] = useState15({});
|
|
4166
|
+
const [socialMedia, setSocialMedia] = useState15({});
|
|
4335
4167
|
useEffect13(() => {
|
|
4336
4168
|
let cancelled = false;
|
|
4337
4169
|
const run = async () => {
|
|
@@ -4588,7 +4420,7 @@ function AdminStudioFooterGlobalView(props) {
|
|
|
4588
4420
|
}
|
|
4589
4421
|
|
|
4590
4422
|
// src/admin/components/studio/AdminStudioContactFormView.tsx
|
|
4591
|
-
import { useEffect as useEffect14, useMemo as useMemo10, useState as
|
|
4423
|
+
import { useEffect as useEffect14, useMemo as useMemo10, useState as useState16 } from "react";
|
|
4592
4424
|
import { SetStepNav as SetStepNav4 } from "@payloadcms/ui";
|
|
4593
4425
|
import { jsx as jsx26, jsxs as jsxs23 } from "react/jsx-runtime";
|
|
4594
4426
|
var defaultDoc = {
|
|
@@ -4679,11 +4511,11 @@ function AdminStudioContactFormView(props) {
|
|
|
4679
4511
|
const adminBasePath = useAdminBasePath();
|
|
4680
4512
|
const resolvedGlobalsBasePath = resolveAdminPath(adminBasePath, globalsBasePath);
|
|
4681
4513
|
const rawGlobalPath = resolveAdminPath(adminBasePath, `/globals/${globalSlug}`);
|
|
4682
|
-
const [doc, setDoc] =
|
|
4683
|
-
const [error, setError] =
|
|
4684
|
-
const [isLoading, setIsLoading] =
|
|
4685
|
-
const [isSaving, setIsSaving] =
|
|
4686
|
-
const [savedMessage, setSavedMessage] =
|
|
4514
|
+
const [doc, setDoc] = useState16(defaultDoc);
|
|
4515
|
+
const [error, setError] = useState16(null);
|
|
4516
|
+
const [isLoading, setIsLoading] = useState16(true);
|
|
4517
|
+
const [isSaving, setIsSaving] = useState16(false);
|
|
4518
|
+
const [savedMessage, setSavedMessage] = useState16(null);
|
|
4687
4519
|
useEffect14(() => {
|
|
4688
4520
|
let mounted = true;
|
|
4689
4521
|
const load = async () => {
|
|
@@ -4914,7 +4746,7 @@ function AdminStudioContactFormView(props) {
|
|
|
4914
4746
|
}
|
|
4915
4747
|
|
|
4916
4748
|
// src/admin/components/studio/AdminStudioMediaView.tsx
|
|
4917
|
-
import { useEffect as useEffect15, useMemo as useMemo11, useState as
|
|
4749
|
+
import { useEffect as useEffect15, useMemo as useMemo11, useState as useState17 } from "react";
|
|
4918
4750
|
import { jsx as jsx27, jsxs as jsxs24 } from "react/jsx-runtime";
|
|
4919
4751
|
var MEDIA_LIBRARY_SYNC_EVENT = "orion-media-library-updated";
|
|
4920
4752
|
var getPropString11 = (props, key, fallback) => {
|
|
@@ -4931,9 +4763,9 @@ var getPropString11 = (props, key, fallback) => {
|
|
|
4931
4763
|
function AdminStudioMediaView(props) {
|
|
4932
4764
|
const mediaCollectionSlug = getPropString11(props, "mediaCollectionSlug", "media");
|
|
4933
4765
|
const adminBasePath = useAdminBasePath();
|
|
4934
|
-
const [docs, setDocs] =
|
|
4935
|
-
const [loading, setLoading] =
|
|
4936
|
-
const [error, setError] =
|
|
4766
|
+
const [docs, setDocs] = useState17([]);
|
|
4767
|
+
const [loading, setLoading] = useState17(true);
|
|
4768
|
+
const [error, setError] = useState17(null);
|
|
4937
4769
|
const apiURL = useMemo11(() => {
|
|
4938
4770
|
const params = new URLSearchParams({
|
|
4939
4771
|
depth: "0",
|
|
@@ -5023,7 +4855,7 @@ function AdminStudioMediaView(props) {
|
|
|
5023
4855
|
}
|
|
5024
4856
|
|
|
5025
4857
|
// src/admin/components/studio/AdminStudioMediaItemView.tsx
|
|
5026
|
-
import { useEffect as useEffect16, useMemo as useMemo12, useState as
|
|
4858
|
+
import { useEffect as useEffect16, useMemo as useMemo12, useState as useState18 } from "react";
|
|
5027
4859
|
import { jsx as jsx28, jsxs as jsxs25 } from "react/jsx-runtime";
|
|
5028
4860
|
var getPropString12 = (props, key, fallback) => {
|
|
5029
4861
|
if (!props || typeof props !== "object") return fallback;
|
|
@@ -5055,11 +4887,11 @@ function AdminStudioMediaItemView(props) {
|
|
|
5055
4887
|
const adminBasePath = useAdminBasePath();
|
|
5056
4888
|
const mediaPath = resolveAdminPath(adminBasePath, "/media");
|
|
5057
4889
|
const mediaIDFromParams = useMemo12(() => getParam2(props.params, "id"), [props.params]);
|
|
5058
|
-
const [mediaID, setMediaID] =
|
|
5059
|
-
const [doc, setDoc] =
|
|
5060
|
-
const [loading, setLoading] =
|
|
5061
|
-
const [error, setError] =
|
|
5062
|
-
const [savedMessage, setSavedMessage] =
|
|
4890
|
+
const [mediaID, setMediaID] = useState18(mediaIDFromParams);
|
|
4891
|
+
const [doc, setDoc] = useState18(null);
|
|
4892
|
+
const [loading, setLoading] = useState18(true);
|
|
4893
|
+
const [error, setError] = useState18(null);
|
|
4894
|
+
const [savedMessage, setSavedMessage] = useState18(null);
|
|
5063
4895
|
useEffect16(() => {
|
|
5064
4896
|
if (mediaIDFromParams) {
|
|
5065
4897
|
setMediaID(mediaIDFromParams);
|
|
@@ -5171,8 +5003,8 @@ function AdminStudioMediaItemView(props) {
|
|
|
5171
5003
|
|
|
5172
5004
|
// src/admin/components/studio/AdminStudioFormsView.tsx
|
|
5173
5005
|
import Link3 from "next/link";
|
|
5174
|
-
import { useEffect as useEffect17, useMemo as useMemo13, useState as
|
|
5175
|
-
import { useAuth as
|
|
5006
|
+
import { useEffect as useEffect17, useMemo as useMemo13, useState as useState19 } from "react";
|
|
5007
|
+
import { useAuth as useAuth5 } from "@payloadcms/ui";
|
|
5176
5008
|
import { jsx as jsx29, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
5177
5009
|
var FORM_TONES = [
|
|
5178
5010
|
{
|
|
@@ -5214,17 +5046,17 @@ var FORM_TONE_OVERRIDES = {
|
|
|
5214
5046
|
var IDENTITY_KEYS = /* @__PURE__ */ new Set(["contactEmail", "email", "firstName", "lastName", "name"]);
|
|
5215
5047
|
var RESPONSE_FIELD_PREVIEW_LIMIT = 3;
|
|
5216
5048
|
var RESPONSE_SCROLL_THRESHOLD = 3;
|
|
5217
|
-
var
|
|
5049
|
+
var hasAdminAccess2 = (user) => {
|
|
5218
5050
|
if (!user || typeof user !== "object") return false;
|
|
5219
5051
|
const role = user.role;
|
|
5220
5052
|
return typeof role === "string" && (role === "admin" || role === "developer");
|
|
5221
5053
|
};
|
|
5222
|
-
var
|
|
5054
|
+
var isEditor = (user) => {
|
|
5223
5055
|
if (!user || typeof user !== "object") return false;
|
|
5224
5056
|
const role = user.role;
|
|
5225
5057
|
return typeof role === "string" && role === "editor";
|
|
5226
5058
|
};
|
|
5227
|
-
var canReviewForms2 = (user) =>
|
|
5059
|
+
var canReviewForms2 = (user) => hasAdminAccess2(user) || isEditor(user);
|
|
5228
5060
|
var getPropString13 = (props, key, fallback) => {
|
|
5229
5061
|
if (!props || typeof props !== "object") return fallback;
|
|
5230
5062
|
const direct = props[key];
|
|
@@ -5390,7 +5222,7 @@ var renderEmptyMessage = (message) => /* @__PURE__ */ jsxs26("div", { className:
|
|
|
5390
5222
|
/* @__PURE__ */ jsx29("span", { children: message })
|
|
5391
5223
|
] });
|
|
5392
5224
|
function AdminStudioFormsView(props) {
|
|
5393
|
-
const { user } =
|
|
5225
|
+
const { user } = useAuth5();
|
|
5394
5226
|
const formsCollectionSlug = getPropString13(props, "formsCollectionSlug", "forms");
|
|
5395
5227
|
const formSubmissionsCollectionSlug = getPropString13(
|
|
5396
5228
|
props,
|
|
@@ -5401,10 +5233,10 @@ function AdminStudioFormsView(props) {
|
|
|
5401
5233
|
const studioFormsPath = resolveAdminPath(adminBasePath, "/forms");
|
|
5402
5234
|
const studioSubmissionsPath = resolveAdminPath(adminBasePath, "/forms/submissions");
|
|
5403
5235
|
const studioUploadsPath = resolveAdminPath(adminBasePath, "/forms/uploads");
|
|
5404
|
-
const [forms, setForms] =
|
|
5405
|
-
const [submissions, setSubmissions] =
|
|
5406
|
-
const [loading, setLoading] =
|
|
5407
|
-
const [error, setError] =
|
|
5236
|
+
const [forms, setForms] = useState19([]);
|
|
5237
|
+
const [submissions, setSubmissions] = useState19([]);
|
|
5238
|
+
const [loading, setLoading] = useState19(true);
|
|
5239
|
+
const [error, setError] = useState19(null);
|
|
5408
5240
|
useEffect17(() => {
|
|
5409
5241
|
if (!canReviewForms2(user)) {
|
|
5410
5242
|
return;
|
|
@@ -5701,7 +5533,7 @@ function AdminStudioFormsView(props) {
|
|
|
5701
5533
|
|
|
5702
5534
|
// src/admin/components/studio/AdminStudioFormDetailView.tsx
|
|
5703
5535
|
import Link4 from "next/link";
|
|
5704
|
-
import { useEffect as useEffect18, useMemo as useMemo14, useState as
|
|
5536
|
+
import { useEffect as useEffect18, useMemo as useMemo14, useState as useState20 } from "react";
|
|
5705
5537
|
|
|
5706
5538
|
// src/admin/components/studio/formsStudioShared.ts
|
|
5707
5539
|
var FORM_TONES2 = [
|
|
@@ -5910,15 +5742,22 @@ var getFormTitle2 = (value) => {
|
|
|
5910
5742
|
// src/admin/components/studio/AdminStudioFormDetailView.tsx
|
|
5911
5743
|
import { Fragment as Fragment5, jsx as jsx30, jsxs as jsxs27 } from "react/jsx-runtime";
|
|
5912
5744
|
var getNonEmptyText = (value, fallback = "") => typeof value === "string" && value.trim().length > 0 ? value : fallback;
|
|
5913
|
-
var
|
|
5745
|
+
var normalizeSteps = (value) => {
|
|
5914
5746
|
if (!Array.isArray(value)) {
|
|
5915
|
-
return
|
|
5747
|
+
return [];
|
|
5916
5748
|
}
|
|
5917
|
-
|
|
5918
|
-
|
|
5919
|
-
|
|
5920
|
-
|
|
5749
|
+
return value.map((step) => step && typeof step === "object" && !Array.isArray(step) ? step : {});
|
|
5750
|
+
};
|
|
5751
|
+
var normalizeFormResponse = (value) => {
|
|
5752
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
5753
|
+
return {};
|
|
5754
|
+
}
|
|
5755
|
+
const record = value;
|
|
5756
|
+
const nestedDoc = record.doc;
|
|
5757
|
+
if (nestedDoc && typeof nestedDoc === "object" && !Array.isArray(nestedDoc)) {
|
|
5758
|
+
return nestedDoc;
|
|
5921
5759
|
}
|
|
5760
|
+
return record;
|
|
5922
5761
|
};
|
|
5923
5762
|
var toEditorState = (doc) => {
|
|
5924
5763
|
const emails = doc.emails && typeof doc.emails === "object" ? doc.emails : null;
|
|
@@ -5934,7 +5773,7 @@ var toEditorState = (doc) => {
|
|
|
5934
5773
|
sendAdmin: emails?.sendAdmin !== false,
|
|
5935
5774
|
sendConfirmation: emails?.sendConfirmation !== false,
|
|
5936
5775
|
slug: getNonEmptyText(doc.slug),
|
|
5937
|
-
|
|
5776
|
+
steps: normalizeSteps(doc.steps),
|
|
5938
5777
|
submitLabel: getNonEmptyText(doc.submitLabel, "Submit"),
|
|
5939
5778
|
successMessage: getNonEmptyText(doc.successMessage),
|
|
5940
5779
|
title: getNonEmptyText(doc.title, "Untitled Form")
|
|
@@ -5945,25 +5784,72 @@ var checkboxLabelStyle = {
|
|
|
5945
5784
|
display: "flex",
|
|
5946
5785
|
gap: "0.6rem"
|
|
5947
5786
|
};
|
|
5948
|
-
var codeStyle = {
|
|
5949
|
-
background: "color-mix(in srgb, var(--orion-admin-card-bg) 82%, black)",
|
|
5950
|
-
border: "1px solid var(--orion-admin-card-border)",
|
|
5951
|
-
borderRadius: "var(--orion-admin-radius-sm)",
|
|
5952
|
-
color: "var(--orion-admin-text)",
|
|
5953
|
-
fontFamily: "ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, monospace",
|
|
5954
|
-
fontSize: "0.86rem",
|
|
5955
|
-
lineHeight: 1.55,
|
|
5956
|
-
margin: 0,
|
|
5957
|
-
maxHeight: "28rem",
|
|
5958
|
-
overflow: "auto",
|
|
5959
|
-
padding: "0.9rem",
|
|
5960
|
-
whiteSpace: "pre-wrap"
|
|
5961
|
-
};
|
|
5962
5787
|
var sectionGridStyle = {
|
|
5963
5788
|
display: "grid",
|
|
5964
5789
|
gap: "1rem",
|
|
5965
5790
|
gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))"
|
|
5966
5791
|
};
|
|
5792
|
+
var fieldTypeOptions = [
|
|
5793
|
+
"text",
|
|
5794
|
+
"textarea",
|
|
5795
|
+
"email",
|
|
5796
|
+
"phone",
|
|
5797
|
+
"url",
|
|
5798
|
+
"select",
|
|
5799
|
+
"radio",
|
|
5800
|
+
"checkbox",
|
|
5801
|
+
"checkbox-group",
|
|
5802
|
+
"date",
|
|
5803
|
+
"file"
|
|
5804
|
+
];
|
|
5805
|
+
var getFields = (step) => Array.isArray(step.fields) ? step.fields.map(
|
|
5806
|
+
(field) => field && typeof field === "object" && !Array.isArray(field) ? field : {}
|
|
5807
|
+
) : [];
|
|
5808
|
+
var toOptionsText = (value) => Array.isArray(value) ? value.map((entry) => {
|
|
5809
|
+
if (entry && typeof entry === "object" && !Array.isArray(entry)) {
|
|
5810
|
+
const record = entry;
|
|
5811
|
+
const label = typeof record.label === "string" ? record.label : "";
|
|
5812
|
+
const optionValue = typeof record.value === "string" ? record.value : label;
|
|
5813
|
+
return label && optionValue && label !== optionValue ? `${label} | ${optionValue}` : label || optionValue;
|
|
5814
|
+
}
|
|
5815
|
+
return typeof entry === "string" ? entry : "";
|
|
5816
|
+
}).filter(Boolean).join("\n") : "";
|
|
5817
|
+
var fromOptionsText = (value) => value.split("\n").map((entry) => entry.trim()).filter(Boolean).map((entry) => {
|
|
5818
|
+
const [label, optionValue] = entry.split("|").map((part) => part.trim());
|
|
5819
|
+
return {
|
|
5820
|
+
label,
|
|
5821
|
+
value: optionValue || label
|
|
5822
|
+
};
|
|
5823
|
+
});
|
|
5824
|
+
var slugifyFieldName = (value) => value.trim().replace(/[^a-z0-9]+/gi, " ").trim().replace(/\s+([a-z0-9])/gi, (_, char) => char.toUpperCase()).replace(/^./, (char) => char.toLowerCase());
|
|
5825
|
+
var blankField = () => ({
|
|
5826
|
+
label: "New field",
|
|
5827
|
+
name: "newField",
|
|
5828
|
+
required: false,
|
|
5829
|
+
type: "text"
|
|
5830
|
+
});
|
|
5831
|
+
var blankStep = () => ({
|
|
5832
|
+
fields: [blankField()],
|
|
5833
|
+
title: "New step"
|
|
5834
|
+
});
|
|
5835
|
+
var getStepTitle = (step, stepIndex) => getNonEmptyText(step.title, `Step ${stepIndex + 1}`);
|
|
5836
|
+
var getFieldLabel = (field, fieldIndex) => getNonEmptyText(field.label, getNonEmptyText(field.name, `Field ${fieldIndex + 1}`));
|
|
5837
|
+
var formatFieldTypeLabel = (value) => getNonEmptyText(value, "text").replace(/-/g, " ").replace(/^./, (char) => char.toUpperCase());
|
|
5838
|
+
var getStepDestination = (stepIndex, stepCount) => {
|
|
5839
|
+
if (stepIndex < stepCount - 1) {
|
|
5840
|
+
return `Next: Step ${stepIndex + 2}`;
|
|
5841
|
+
}
|
|
5842
|
+
return "Then: Submit form";
|
|
5843
|
+
};
|
|
5844
|
+
var moveItem = (items, fromIndex, toIndex) => {
|
|
5845
|
+
if (toIndex < 0 || toIndex >= items.length) {
|
|
5846
|
+
return items;
|
|
5847
|
+
}
|
|
5848
|
+
const nextItems = [...items];
|
|
5849
|
+
const [item] = nextItems.splice(fromIndex, 1);
|
|
5850
|
+
nextItems.splice(toIndex, 0, item);
|
|
5851
|
+
return nextItems;
|
|
5852
|
+
};
|
|
5967
5853
|
function getFormIDFromPathname(pathname) {
|
|
5968
5854
|
const marker = "/forms/";
|
|
5969
5855
|
const raw = getIDFromPathname(pathname, marker);
|
|
@@ -5982,15 +5868,15 @@ function AdminStudioFormDetailView(props) {
|
|
|
5982
5868
|
const adminBasePath = useAdminBasePath();
|
|
5983
5869
|
const formsPath = resolveAdminPath(adminBasePath, "/forms");
|
|
5984
5870
|
const formIDFromParams = useMemo14(() => getParam3(props.params, "id"), [props.params]);
|
|
5985
|
-
const [formID, setFormID] =
|
|
5986
|
-
const [didResolvePathFallback, setDidResolvePathFallback] =
|
|
5987
|
-
const [doc, setDoc] =
|
|
5988
|
-
const [submissions, setSubmissions] =
|
|
5989
|
-
const [editorState, setEditorState] =
|
|
5990
|
-
const [loading, setLoading] =
|
|
5991
|
-
const [error, setError] =
|
|
5992
|
-
const [saving, setSaving] =
|
|
5993
|
-
const [savedMessage, setSavedMessage] =
|
|
5871
|
+
const [formID, setFormID] = useState20(formIDFromParams);
|
|
5872
|
+
const [didResolvePathFallback, setDidResolvePathFallback] = useState20(false);
|
|
5873
|
+
const [doc, setDoc] = useState20(null);
|
|
5874
|
+
const [submissions, setSubmissions] = useState20([]);
|
|
5875
|
+
const [editorState, setEditorState] = useState20(null);
|
|
5876
|
+
const [loading, setLoading] = useState20(true);
|
|
5877
|
+
const [error, setError] = useState20(null);
|
|
5878
|
+
const [saving, setSaving] = useState20(false);
|
|
5879
|
+
const [savedMessage, setSavedMessage] = useState20(null);
|
|
5994
5880
|
useEffect18(() => {
|
|
5995
5881
|
if (formIDFromParams) {
|
|
5996
5882
|
setFormID(formIDFromParams);
|
|
@@ -6026,7 +5912,7 @@ function AdminStudioFormDetailView(props) {
|
|
|
6026
5912
|
if (!submissionsResponse.ok) {
|
|
6027
5913
|
throw new Error(`Failed to load submissions (${submissionsResponse.status}).`);
|
|
6028
5914
|
}
|
|
6029
|
-
const nextDoc = await formResponse.json();
|
|
5915
|
+
const nextDoc = normalizeFormResponse(await formResponse.json());
|
|
6030
5916
|
const submissionsPayload = await submissionsResponse.json();
|
|
6031
5917
|
const nextSubmissions = Array.isArray(submissionsPayload.docs) ? submissionsPayload.docs : [];
|
|
6032
5918
|
setDoc(nextDoc);
|
|
@@ -6056,10 +5942,6 @@ function AdminStudioFormDetailView(props) {
|
|
|
6056
5942
|
setError(null);
|
|
6057
5943
|
setSavedMessage(null);
|
|
6058
5944
|
try {
|
|
6059
|
-
const parsedSteps = JSON.parse(editorState.stepsText);
|
|
6060
|
-
if (!Array.isArray(parsedSteps)) {
|
|
6061
|
-
throw new Error("Structure JSON must be an array of steps.");
|
|
6062
|
-
}
|
|
6063
5945
|
const payload = {
|
|
6064
5946
|
emails: {
|
|
6065
5947
|
adminRecipients: editorState.adminRecipientsText.split("\n").map((value) => value.trim()).filter(Boolean).map((email) => ({ email })),
|
|
@@ -6071,7 +5953,7 @@ function AdminStudioFormDetailView(props) {
|
|
|
6071
5953
|
sendConfirmation: editorState.sendConfirmation
|
|
6072
5954
|
},
|
|
6073
5955
|
slug: editorState.slug.trim(),
|
|
6074
|
-
steps:
|
|
5956
|
+
steps: editorState.steps,
|
|
6075
5957
|
submitLabel: editorState.submitLabel.trim(),
|
|
6076
5958
|
successMessage: editorState.successMessage,
|
|
6077
5959
|
title: editorState.title.trim()
|
|
@@ -6087,7 +5969,7 @@ function AdminStudioFormDetailView(props) {
|
|
|
6087
5969
|
if (!response.ok) {
|
|
6088
5970
|
throw new Error(`Failed to save form (${response.status}).`);
|
|
6089
5971
|
}
|
|
6090
|
-
const nextDoc = await response.json();
|
|
5972
|
+
const nextDoc = normalizeFormResponse(await response.json());
|
|
6091
5973
|
setDoc(nextDoc);
|
|
6092
5974
|
setEditorState(toEditorState(nextDoc));
|
|
6093
5975
|
setSavedMessage("Saved.");
|
|
@@ -6117,8 +5999,52 @@ function AdminStudioFormDetailView(props) {
|
|
|
6117
5999
|
const toneStyle = getFormToneStyle2(slug, title || formID || "form");
|
|
6118
6000
|
const fieldLabels = doc ? buildFieldLabelMap2(doc) : /* @__PURE__ */ new Map();
|
|
6119
6001
|
const latestSubmission = submissions[0];
|
|
6120
|
-
const stepCount =
|
|
6121
|
-
const fieldCount = doc ? getFieldCount2(doc) : 0;
|
|
6002
|
+
const stepCount = editorState?.steps.length || 0;
|
|
6003
|
+
const fieldCount = editorState ? editorState.steps.reduce((count, step) => count + getFields(step).length, 0) : doc ? getFieldCount2(doc) : 0;
|
|
6004
|
+
const updateStep = (stepIndex, patch) => {
|
|
6005
|
+
setEditorState(
|
|
6006
|
+
(current) => current ? {
|
|
6007
|
+
...current,
|
|
6008
|
+
steps: current.steps.map(
|
|
6009
|
+
(step, index) => index === stepIndex ? { ...step, ...patch } : step
|
|
6010
|
+
)
|
|
6011
|
+
} : current
|
|
6012
|
+
);
|
|
6013
|
+
};
|
|
6014
|
+
const updateField = (stepIndex, fieldIndex, patch) => {
|
|
6015
|
+
setEditorState((current) => {
|
|
6016
|
+
if (!current) return current;
|
|
6017
|
+
return {
|
|
6018
|
+
...current,
|
|
6019
|
+
steps: current.steps.map((step, index) => {
|
|
6020
|
+
if (index !== stepIndex) return step;
|
|
6021
|
+
const fields = getFields(step).map(
|
|
6022
|
+
(field, currentFieldIndex) => currentFieldIndex === fieldIndex ? { ...field, ...patch } : field
|
|
6023
|
+
);
|
|
6024
|
+
return { ...step, fields };
|
|
6025
|
+
})
|
|
6026
|
+
};
|
|
6027
|
+
});
|
|
6028
|
+
};
|
|
6029
|
+
const moveStep = (stepIndex, direction) => {
|
|
6030
|
+
setEditorState(
|
|
6031
|
+
(current) => current ? {
|
|
6032
|
+
...current,
|
|
6033
|
+
steps: moveItem(current.steps, stepIndex, stepIndex + direction)
|
|
6034
|
+
} : current
|
|
6035
|
+
);
|
|
6036
|
+
};
|
|
6037
|
+
const moveField = (stepIndex, fieldIndex, direction) => {
|
|
6038
|
+
setEditorState((current) => {
|
|
6039
|
+
if (!current) return current;
|
|
6040
|
+
return {
|
|
6041
|
+
...current,
|
|
6042
|
+
steps: current.steps.map(
|
|
6043
|
+
(step, index) => index === stepIndex ? { ...step, fields: moveItem(getFields(step), fieldIndex, fieldIndex + direction) } : step
|
|
6044
|
+
)
|
|
6045
|
+
};
|
|
6046
|
+
});
|
|
6047
|
+
};
|
|
6122
6048
|
return /* @__PURE__ */ jsx30(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ jsxs27(
|
|
6123
6049
|
AdminPage,
|
|
6124
6050
|
{
|
|
@@ -6197,10 +6123,9 @@ function AdminStudioFormDetailView(props) {
|
|
|
6197
6123
|
/* @__PURE__ */ jsxs27("div", { style: { display: "grid", gap: "1rem" }, children: [
|
|
6198
6124
|
/* @__PURE__ */ jsxs27("div", { className: "orion-admin-card", children: [
|
|
6199
6125
|
/* @__PURE__ */ jsx30("strong", { children: "Step preview" }),
|
|
6200
|
-
/* @__PURE__ */ jsx30("span", { children: "Review the
|
|
6201
|
-
/* @__PURE__ */ jsx30("div", { style: { display: "grid", gap: "0.85rem", marginTop: "1rem" }, children:
|
|
6202
|
-
const
|
|
6203
|
-
const fields = Array.isArray(record?.fields) ? record.fields : [];
|
|
6126
|
+
/* @__PURE__ */ jsx30("span", { children: "Review the public workflow as visitors will move through it." }),
|
|
6127
|
+
/* @__PURE__ */ jsx30("div", { style: { display: "grid", gap: "0.85rem", marginTop: "1rem" }, children: editorState.steps.length > 0 ? editorState.steps.map((record, stepIndex) => {
|
|
6128
|
+
const fields = getFields(record);
|
|
6204
6129
|
return /* @__PURE__ */ jsxs27("div", { className: "orion-admin-form", children: [
|
|
6205
6130
|
/* @__PURE__ */ jsxs27("div", { children: [
|
|
6206
6131
|
/* @__PURE__ */ jsxs27("strong", { children: [
|
|
@@ -6252,7 +6177,7 @@ function AdminStudioFormDetailView(props) {
|
|
|
6252
6177
|
] }, `step-${stepIndex}`);
|
|
6253
6178
|
}) : /* @__PURE__ */ jsxs27("div", { className: "orion-admin-empty-state", children: [
|
|
6254
6179
|
/* @__PURE__ */ jsx30("strong", { children: "No steps configured" }),
|
|
6255
|
-
/* @__PURE__ */ jsx30("span", { children: "Add at least one step in
|
|
6180
|
+
/* @__PURE__ */ jsx30("span", { children: "Add at least one step in Form settings to publish this form." })
|
|
6256
6181
|
] }) })
|
|
6257
6182
|
] }),
|
|
6258
6183
|
/* @__PURE__ */ jsxs27("div", { className: "orion-admin-card", children: [
|
|
@@ -6434,32 +6359,296 @@ function AdminStudioFormDetailView(props) {
|
|
|
6434
6359
|
] })
|
|
6435
6360
|
] })
|
|
6436
6361
|
] }),
|
|
6437
|
-
/* @__PURE__ */ jsxs27("
|
|
6438
|
-
"
|
|
6439
|
-
|
|
6440
|
-
|
|
6441
|
-
|
|
6442
|
-
|
|
6443
|
-
|
|
6444
|
-
|
|
6445
|
-
|
|
6446
|
-
|
|
6447
|
-
|
|
6448
|
-
|
|
6449
|
-
|
|
6450
|
-
|
|
6451
|
-
|
|
6452
|
-
|
|
6453
|
-
|
|
6362
|
+
/* @__PURE__ */ jsxs27("div", { className: "orion-admin-card orion-admin-workflow-editor", children: [
|
|
6363
|
+
/* @__PURE__ */ jsxs27("div", { className: "orion-admin-workflow-editor-header", children: [
|
|
6364
|
+
/* @__PURE__ */ jsxs27("div", { children: [
|
|
6365
|
+
/* @__PURE__ */ jsx30("strong", { children: "Form steps" }),
|
|
6366
|
+
/* @__PURE__ */ jsx30("span", { children: "Build the visitor flow, then edit each step's fields below." })
|
|
6367
|
+
] }),
|
|
6368
|
+
/* @__PURE__ */ jsx30(
|
|
6369
|
+
"button",
|
|
6370
|
+
{
|
|
6371
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
6372
|
+
onClick: () => setEditorState(
|
|
6373
|
+
(current) => current ? { ...current, steps: [...current.steps, blankStep()] } : current
|
|
6374
|
+
),
|
|
6375
|
+
type: "button",
|
|
6376
|
+
children: "Add step"
|
|
6377
|
+
}
|
|
6378
|
+
)
|
|
6379
|
+
] }),
|
|
6380
|
+
editorState.steps.length === 0 ? /* @__PURE__ */ jsxs27("div", { className: "orion-admin-empty-state", children: [
|
|
6381
|
+
/* @__PURE__ */ jsx30("strong", { children: "No steps configured" }),
|
|
6382
|
+
/* @__PURE__ */ jsx30("span", { children: "Add a first step to start building the public form flow." })
|
|
6383
|
+
] }) : null,
|
|
6384
|
+
/* @__PURE__ */ jsx30("div", { className: "orion-admin-step-editor-list", children: editorState.steps.map((step, stepIndex) => {
|
|
6385
|
+
const fields = getFields(step);
|
|
6386
|
+
const requiredCount = fields.filter((field) => field.required === true).length;
|
|
6387
|
+
return /* @__PURE__ */ jsxs27("details", { className: "orion-admin-step-editor", open: true, children: [
|
|
6388
|
+
/* @__PURE__ */ jsxs27("summary", { className: "orion-admin-step-editor-summary", children: [
|
|
6389
|
+
/* @__PURE__ */ jsx30("span", { className: "orion-admin-workflow-node-number", children: stepIndex + 1 }),
|
|
6390
|
+
/* @__PURE__ */ jsx30("span", { className: "orion-admin-step-editor-title", children: getStepTitle(step, stepIndex) }),
|
|
6391
|
+
/* @__PURE__ */ jsxs27("span", { className: "orion-admin-step-editor-meta", children: [
|
|
6392
|
+
fields.length,
|
|
6393
|
+
" field",
|
|
6394
|
+
fields.length === 1 ? "" : "s",
|
|
6395
|
+
requiredCount > 0 ? ` \xB7 ${requiredCount} required` : ""
|
|
6396
|
+
] }),
|
|
6397
|
+
/* @__PURE__ */ jsx30("span", { className: "orion-admin-workflow-node-destination", children: getStepDestination(stepIndex, editorState.steps.length) })
|
|
6398
|
+
] }),
|
|
6399
|
+
/* @__PURE__ */ jsxs27("div", { className: "orion-admin-step-editor-body", children: [
|
|
6400
|
+
/* @__PURE__ */ jsxs27("div", { className: "orion-admin-step-editor-actions", children: [
|
|
6401
|
+
/* @__PURE__ */ jsx30(
|
|
6402
|
+
"button",
|
|
6403
|
+
{
|
|
6404
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
6405
|
+
disabled: stepIndex === 0,
|
|
6406
|
+
onClick: () => moveStep(stepIndex, -1),
|
|
6407
|
+
type: "button",
|
|
6408
|
+
children: "Move up"
|
|
6409
|
+
}
|
|
6410
|
+
),
|
|
6411
|
+
/* @__PURE__ */ jsx30(
|
|
6412
|
+
"button",
|
|
6413
|
+
{
|
|
6414
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
6415
|
+
disabled: stepIndex === editorState.steps.length - 1,
|
|
6416
|
+
onClick: () => moveStep(stepIndex, 1),
|
|
6417
|
+
type: "button",
|
|
6418
|
+
children: "Move down"
|
|
6419
|
+
}
|
|
6420
|
+
),
|
|
6421
|
+
/* @__PURE__ */ jsx30(
|
|
6422
|
+
"button",
|
|
6423
|
+
{
|
|
6424
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
6425
|
+
onClick: () => setEditorState(
|
|
6426
|
+
(current) => current ? {
|
|
6427
|
+
...current,
|
|
6428
|
+
steps: current.steps.filter((_, index) => index !== stepIndex)
|
|
6429
|
+
} : current
|
|
6430
|
+
),
|
|
6431
|
+
type: "button",
|
|
6432
|
+
children: "Remove step"
|
|
6433
|
+
}
|
|
6434
|
+
)
|
|
6435
|
+
] }),
|
|
6436
|
+
/* @__PURE__ */ jsxs27("div", { className: "orion-admin-step-settings-grid", children: [
|
|
6437
|
+
/* @__PURE__ */ jsxs27("label", { children: [
|
|
6438
|
+
"Step title",
|
|
6439
|
+
/* @__PURE__ */ jsx30(
|
|
6440
|
+
"input",
|
|
6441
|
+
{
|
|
6442
|
+
onChange: (event) => updateStep(stepIndex, { title: event.target.value }),
|
|
6443
|
+
type: "text",
|
|
6444
|
+
value: getNonEmptyText(step.title)
|
|
6445
|
+
}
|
|
6446
|
+
)
|
|
6447
|
+
] }),
|
|
6448
|
+
/* @__PURE__ */ jsxs27("label", { children: [
|
|
6449
|
+
"Next button label",
|
|
6450
|
+
/* @__PURE__ */ jsx30(
|
|
6451
|
+
"input",
|
|
6452
|
+
{
|
|
6453
|
+
onChange: (event) => updateStep(stepIndex, { nextLabel: event.target.value }),
|
|
6454
|
+
placeholder: "Next",
|
|
6455
|
+
type: "text",
|
|
6456
|
+
value: getNonEmptyText(step.nextLabel)
|
|
6457
|
+
}
|
|
6458
|
+
)
|
|
6459
|
+
] })
|
|
6460
|
+
] }),
|
|
6461
|
+
/* @__PURE__ */ jsxs27("label", { children: [
|
|
6462
|
+
"Step intro text",
|
|
6463
|
+
/* @__PURE__ */ jsx30(
|
|
6464
|
+
"textarea",
|
|
6465
|
+
{
|
|
6466
|
+
onChange: (event) => updateStep(stepIndex, { subtitle: event.target.value }),
|
|
6467
|
+
rows: 3,
|
|
6468
|
+
value: getNonEmptyText(step.subtitle)
|
|
6469
|
+
}
|
|
6470
|
+
)
|
|
6471
|
+
] }),
|
|
6472
|
+
/* @__PURE__ */ jsxs27("label", { style: checkboxLabelStyle, children: [
|
|
6473
|
+
/* @__PURE__ */ jsx30(
|
|
6474
|
+
"input",
|
|
6475
|
+
{
|
|
6476
|
+
checked: step.allowSkip === true,
|
|
6477
|
+
onChange: (event) => updateStep(stepIndex, { allowSkip: event.target.checked }),
|
|
6478
|
+
type: "checkbox"
|
|
6479
|
+
}
|
|
6480
|
+
),
|
|
6481
|
+
"Allow visitors to skip this step"
|
|
6482
|
+
] }),
|
|
6483
|
+
/* @__PURE__ */ jsxs27("div", { className: "orion-admin-field-list-header", children: [
|
|
6484
|
+
/* @__PURE__ */ jsxs27("div", { children: [
|
|
6485
|
+
/* @__PURE__ */ jsx30("strong", { children: "Fields in this step" }),
|
|
6486
|
+
/* @__PURE__ */ jsx30("span", { children: "These appear together before the visitor moves to the next step." })
|
|
6487
|
+
] }),
|
|
6488
|
+
/* @__PURE__ */ jsx30(
|
|
6489
|
+
"button",
|
|
6490
|
+
{
|
|
6491
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
6492
|
+
onClick: () => setEditorState(
|
|
6493
|
+
(current) => current ? {
|
|
6494
|
+
...current,
|
|
6495
|
+
steps: current.steps.map(
|
|
6496
|
+
(currentStep, index) => index === stepIndex ? { ...currentStep, fields: [...getFields(currentStep), blankField()] } : currentStep
|
|
6497
|
+
)
|
|
6498
|
+
} : current
|
|
6499
|
+
),
|
|
6500
|
+
type: "button",
|
|
6501
|
+
children: "Add field"
|
|
6502
|
+
}
|
|
6503
|
+
)
|
|
6504
|
+
] }),
|
|
6505
|
+
fields.length > 0 ? /* @__PURE__ */ jsx30("div", { className: "orion-admin-field-editor-list", children: fields.map((field, fieldIndex) => {
|
|
6506
|
+
const label = getFieldLabel(field, fieldIndex);
|
|
6507
|
+
const fieldType = getNonEmptyText(field.type, "text");
|
|
6508
|
+
return /* @__PURE__ */ jsxs27("details", { className: "orion-admin-field-editor", children: [
|
|
6509
|
+
/* @__PURE__ */ jsxs27("summary", { className: "orion-admin-field-editor-summary", children: [
|
|
6510
|
+
/* @__PURE__ */ jsx30("span", { className: "orion-admin-field-order", children: fieldIndex + 1 }),
|
|
6511
|
+
/* @__PURE__ */ jsx30("span", { className: "orion-admin-field-editor-title", children: label }),
|
|
6512
|
+
/* @__PURE__ */ jsxs27("span", { className: "orion-admin-field-editor-meta", children: [
|
|
6513
|
+
formatFieldTypeLabel(fieldType),
|
|
6514
|
+
field.required === true ? " \xB7 Required" : ""
|
|
6515
|
+
] })
|
|
6516
|
+
] }),
|
|
6517
|
+
/* @__PURE__ */ jsxs27("div", { className: "orion-admin-field-editor-body", children: [
|
|
6518
|
+
/* @__PURE__ */ jsxs27("div", { className: "orion-admin-step-editor-actions", children: [
|
|
6519
|
+
/* @__PURE__ */ jsx30(
|
|
6520
|
+
"button",
|
|
6521
|
+
{
|
|
6522
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
6523
|
+
disabled: fieldIndex === 0,
|
|
6524
|
+
onClick: () => moveField(stepIndex, fieldIndex, -1),
|
|
6525
|
+
type: "button",
|
|
6526
|
+
children: "Move up"
|
|
6527
|
+
}
|
|
6528
|
+
),
|
|
6529
|
+
/* @__PURE__ */ jsx30(
|
|
6530
|
+
"button",
|
|
6531
|
+
{
|
|
6532
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
6533
|
+
disabled: fieldIndex === fields.length - 1,
|
|
6534
|
+
onClick: () => moveField(stepIndex, fieldIndex, 1),
|
|
6535
|
+
type: "button",
|
|
6536
|
+
children: "Move down"
|
|
6537
|
+
}
|
|
6538
|
+
),
|
|
6539
|
+
/* @__PURE__ */ jsx30(
|
|
6540
|
+
"button",
|
|
6541
|
+
{
|
|
6542
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
6543
|
+
onClick: () => setEditorState((current) => {
|
|
6544
|
+
if (!current) return current;
|
|
6545
|
+
return {
|
|
6546
|
+
...current,
|
|
6547
|
+
steps: current.steps.map(
|
|
6548
|
+
(currentStep, index) => index === stepIndex ? {
|
|
6549
|
+
...currentStep,
|
|
6550
|
+
fields: getFields(currentStep).filter(
|
|
6551
|
+
(_, currentFieldIndex) => currentFieldIndex !== fieldIndex
|
|
6552
|
+
)
|
|
6553
|
+
} : currentStep
|
|
6554
|
+
)
|
|
6555
|
+
};
|
|
6556
|
+
}),
|
|
6557
|
+
type: "button",
|
|
6558
|
+
children: "Remove field"
|
|
6559
|
+
}
|
|
6560
|
+
)
|
|
6561
|
+
] }),
|
|
6562
|
+
/* @__PURE__ */ jsxs27("div", { className: "orion-admin-step-settings-grid", children: [
|
|
6563
|
+
/* @__PURE__ */ jsxs27("label", { children: [
|
|
6564
|
+
"Field label",
|
|
6565
|
+
/* @__PURE__ */ jsx30(
|
|
6566
|
+
"input",
|
|
6567
|
+
{
|
|
6568
|
+
onChange: (event) => {
|
|
6569
|
+
const nextLabel = event.target.value;
|
|
6570
|
+
const currentName = getNonEmptyText(field.name);
|
|
6571
|
+
updateField(stepIndex, fieldIndex, {
|
|
6572
|
+
label: nextLabel,
|
|
6573
|
+
name: currentName || slugifyFieldName(nextLabel)
|
|
6574
|
+
});
|
|
6575
|
+
},
|
|
6576
|
+
type: "text",
|
|
6577
|
+
value: label
|
|
6578
|
+
}
|
|
6579
|
+
)
|
|
6580
|
+
] }),
|
|
6581
|
+
/* @__PURE__ */ jsxs27("label", { children: [
|
|
6582
|
+
"Field type",
|
|
6583
|
+
/* @__PURE__ */ jsx30(
|
|
6584
|
+
"select",
|
|
6585
|
+
{
|
|
6586
|
+
onChange: (event) => updateField(stepIndex, fieldIndex, { type: event.target.value }),
|
|
6587
|
+
value: fieldType,
|
|
6588
|
+
children: fieldTypeOptions.map((option) => /* @__PURE__ */ jsx30("option", { value: option, children: formatFieldTypeLabel(option) }, option))
|
|
6589
|
+
}
|
|
6590
|
+
)
|
|
6591
|
+
] })
|
|
6592
|
+
] }),
|
|
6593
|
+
/* @__PURE__ */ jsxs27("label", { children: [
|
|
6594
|
+
"Field key",
|
|
6595
|
+
/* @__PURE__ */ jsx30(
|
|
6596
|
+
"input",
|
|
6597
|
+
{
|
|
6598
|
+
onChange: (event) => updateField(stepIndex, fieldIndex, { name: event.target.value }),
|
|
6599
|
+
type: "text",
|
|
6600
|
+
value: getNonEmptyText(field.name)
|
|
6601
|
+
}
|
|
6602
|
+
)
|
|
6603
|
+
] }),
|
|
6604
|
+
/* @__PURE__ */ jsxs27("label", { style: checkboxLabelStyle, children: [
|
|
6605
|
+
/* @__PURE__ */ jsx30(
|
|
6606
|
+
"input",
|
|
6607
|
+
{
|
|
6608
|
+
checked: field.required === true,
|
|
6609
|
+
onChange: (event) => updateField(stepIndex, fieldIndex, { required: event.target.checked }),
|
|
6610
|
+
type: "checkbox"
|
|
6611
|
+
}
|
|
6612
|
+
),
|
|
6613
|
+
"Required"
|
|
6614
|
+
] }),
|
|
6615
|
+
/* @__PURE__ */ jsxs27("label", { children: [
|
|
6616
|
+
"Help text",
|
|
6617
|
+
/* @__PURE__ */ jsx30(
|
|
6618
|
+
"textarea",
|
|
6619
|
+
{
|
|
6620
|
+
onChange: (event) => updateField(stepIndex, fieldIndex, { helpText: event.target.value }),
|
|
6621
|
+
rows: 2,
|
|
6622
|
+
value: getNonEmptyText(field.helpText)
|
|
6623
|
+
}
|
|
6624
|
+
)
|
|
6625
|
+
] }),
|
|
6626
|
+
["select", "radio", "checkbox-group"].includes(fieldType) ? /* @__PURE__ */ jsxs27("label", { children: [
|
|
6627
|
+
"Options",
|
|
6628
|
+
/* @__PURE__ */ jsx30(
|
|
6629
|
+
"textarea",
|
|
6630
|
+
{
|
|
6631
|
+
onChange: (event) => updateField(stepIndex, fieldIndex, {
|
|
6632
|
+
options: fromOptionsText(event.target.value)
|
|
6633
|
+
}),
|
|
6634
|
+
placeholder: "Option one\nOption two",
|
|
6635
|
+
rows: 4,
|
|
6636
|
+
value: toOptionsText(field.options)
|
|
6637
|
+
}
|
|
6638
|
+
)
|
|
6639
|
+
] }) : null
|
|
6640
|
+
] })
|
|
6641
|
+
] }, `edit-field-${stepIndex}-${fieldIndex}`);
|
|
6642
|
+
}) }) : /* @__PURE__ */ jsxs27("div", { className: "orion-admin-empty-state", children: [
|
|
6643
|
+
/* @__PURE__ */ jsx30("strong", { children: "No fields in this step" }),
|
|
6644
|
+
/* @__PURE__ */ jsx30("span", { children: "Add a field so visitors have something to answer here." })
|
|
6645
|
+
] })
|
|
6646
|
+
] })
|
|
6647
|
+
] }, `edit-step-${stepIndex}`);
|
|
6648
|
+
}) })
|
|
6454
6649
|
] }),
|
|
6455
|
-
/* @__PURE__ */ jsx30("div", { className: "orion-admin-list-meta", children: "Edit the public workflow as JSON. The saved payload must remain an array of step objects compatible with the form collection schema." }),
|
|
6456
6650
|
/* @__PURE__ */ jsx30("button", { disabled: saving, type: "submit", children: saving ? "Saving..." : "Save Form" })
|
|
6457
6651
|
] })
|
|
6458
|
-
] }),
|
|
6459
|
-
/* @__PURE__ */ jsxs27("div", { className: "orion-admin-card", children: [
|
|
6460
|
-
/* @__PURE__ */ jsx30("strong", { children: "Current structure payload" }),
|
|
6461
|
-
/* @__PURE__ */ jsx30("span", { children: "Reference snapshot of the form steps that will be written back on save." }),
|
|
6462
|
-
/* @__PURE__ */ jsx30("pre", { style: { ...codeStyle, marginTop: "1rem" }, children: editorState.stepsText })
|
|
6463
6652
|
] })
|
|
6464
6653
|
] }) : null
|
|
6465
6654
|
]
|
|
@@ -6469,27 +6658,19 @@ function AdminStudioFormDetailView(props) {
|
|
|
6469
6658
|
|
|
6470
6659
|
// src/admin/components/studio/AdminStudioFormSubmissionView.tsx
|
|
6471
6660
|
import Link5 from "next/link";
|
|
6472
|
-
import { useEffect as useEffect19, useMemo as useMemo15, useState as
|
|
6661
|
+
import { useEffect as useEffect19, useMemo as useMemo15, useState as useState21 } from "react";
|
|
6473
6662
|
import { Fragment as Fragment6, jsx as jsx31, jsxs as jsxs28 } from "react/jsx-runtime";
|
|
6474
|
-
var codeStyle2 = {
|
|
6475
|
-
background: "color-mix(in srgb, var(--orion-admin-card-bg) 82%, black)",
|
|
6476
|
-
border: "1px solid var(--orion-admin-card-border)",
|
|
6477
|
-
borderRadius: "var(--orion-admin-radius-sm)",
|
|
6478
|
-
color: "var(--orion-admin-text)",
|
|
6479
|
-
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
6480
|
-
fontSize: "0.86rem",
|
|
6481
|
-
lineHeight: 1.55,
|
|
6482
|
-
margin: 0,
|
|
6483
|
-
maxHeight: "28rem",
|
|
6484
|
-
overflow: "auto",
|
|
6485
|
-
padding: "0.9rem",
|
|
6486
|
-
whiteSpace: "pre-wrap"
|
|
6487
|
-
};
|
|
6488
6663
|
var sectionGridStyle2 = {
|
|
6489
6664
|
display: "grid",
|
|
6490
6665
|
gap: "1rem",
|
|
6491
6666
|
gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))"
|
|
6492
6667
|
};
|
|
6668
|
+
var nestedListStyle = {
|
|
6669
|
+
display: "grid",
|
|
6670
|
+
gap: "0.45rem",
|
|
6671
|
+
margin: 0,
|
|
6672
|
+
padding: 0
|
|
6673
|
+
};
|
|
6493
6674
|
var renderFieldValue = (value) => {
|
|
6494
6675
|
if (value === null || value === void 0) {
|
|
6495
6676
|
return /* @__PURE__ */ jsx31("span", { className: "orion-admin-list-meta", children: "No value" });
|
|
@@ -6503,7 +6684,26 @@ var renderFieldValue = (value) => {
|
|
|
6503
6684
|
if (typeof value === "string") {
|
|
6504
6685
|
return value.trim().length > 0 ? value : /* @__PURE__ */ jsx31("span", { className: "orion-admin-list-meta", children: "No value" });
|
|
6505
6686
|
}
|
|
6506
|
-
|
|
6687
|
+
if (Array.isArray(value)) {
|
|
6688
|
+
const entries = value.filter((entry) => entry !== null && entry !== void 0 && entry !== "");
|
|
6689
|
+
if (entries.length === 0) {
|
|
6690
|
+
return /* @__PURE__ */ jsx31("span", { className: "orion-admin-list-meta", children: "No value" });
|
|
6691
|
+
}
|
|
6692
|
+
return /* @__PURE__ */ jsx31("ul", { style: nestedListStyle, children: entries.map((entry, index) => /* @__PURE__ */ jsx31("li", { children: renderFieldValue(entry) }, index)) });
|
|
6693
|
+
}
|
|
6694
|
+
if (typeof value === "object") {
|
|
6695
|
+
const entries = Object.entries(value).filter(
|
|
6696
|
+
([, entryValue]) => entryValue !== null && entryValue !== void 0 && entryValue !== ""
|
|
6697
|
+
);
|
|
6698
|
+
if (entries.length === 0) {
|
|
6699
|
+
return /* @__PURE__ */ jsx31("span", { className: "orion-admin-list-meta", children: "No value" });
|
|
6700
|
+
}
|
|
6701
|
+
return /* @__PURE__ */ jsx31("div", { style: { display: "grid", gap: "0.65rem" }, children: entries.map(([key, entryValue]) => /* @__PURE__ */ jsxs28("div", { className: "orion-admin-meta-row", children: [
|
|
6702
|
+
/* @__PURE__ */ jsx31("span", { className: "orion-admin-meta-label", children: humanizeKey2(key) }),
|
|
6703
|
+
/* @__PURE__ */ jsx31("span", { className: "orion-admin-meta-value", children: renderFieldValue(entryValue) })
|
|
6704
|
+
] }, key)) });
|
|
6705
|
+
}
|
|
6706
|
+
return String(value);
|
|
6507
6707
|
};
|
|
6508
6708
|
function getSubmissionIDFromPathname(pathname) {
|
|
6509
6709
|
return getIDFromPathname(pathname, "/forms/submissions/");
|
|
@@ -6518,14 +6718,14 @@ function AdminStudioFormSubmissionView(props) {
|
|
|
6518
6718
|
const adminBasePath = useAdminBasePath();
|
|
6519
6719
|
const formsPath = resolveAdminPath(adminBasePath, "/forms");
|
|
6520
6720
|
const submissionIDFromParams = useMemo15(() => getParam3(props.params, "id"), [props.params]);
|
|
6521
|
-
const [submissionID, setSubmissionID] =
|
|
6522
|
-
const [didResolvePathFallback, setDidResolvePathFallback] =
|
|
6523
|
-
const [doc, setDoc] =
|
|
6524
|
-
const [formDoc, setFormDoc] =
|
|
6525
|
-
const [loading, setLoading] =
|
|
6526
|
-
const [error, setError] =
|
|
6527
|
-
const [confirmDelete, setConfirmDelete] =
|
|
6528
|
-
const [deleting, setDeleting] =
|
|
6721
|
+
const [submissionID, setSubmissionID] = useState21(submissionIDFromParams);
|
|
6722
|
+
const [didResolvePathFallback, setDidResolvePathFallback] = useState21(false);
|
|
6723
|
+
const [doc, setDoc] = useState21(null);
|
|
6724
|
+
const [formDoc, setFormDoc] = useState21(null);
|
|
6725
|
+
const [loading, setLoading] = useState21(true);
|
|
6726
|
+
const [error, setError] = useState21(null);
|
|
6727
|
+
const [confirmDelete, setConfirmDelete] = useState21(false);
|
|
6728
|
+
const [deleting, setDeleting] = useState21(false);
|
|
6529
6729
|
useEffect19(() => {
|
|
6530
6730
|
if (submissionIDFromParams) {
|
|
6531
6731
|
setSubmissionID(submissionIDFromParams);
|
|
@@ -6655,31 +6855,24 @@ function AdminStudioFormSubmissionView(props) {
|
|
|
6655
6855
|
/* @__PURE__ */ jsxs28("article", { className: "orion-admin-overview-stat", children: [
|
|
6656
6856
|
/* @__PURE__ */ jsx31("span", { className: "orion-admin-overview-stat-label", children: "Highlighted answers" }),
|
|
6657
6857
|
/* @__PURE__ */ jsx31("strong", { children: previewFields.length }),
|
|
6658
|
-
/* @__PURE__ */ jsx31("p", { children: "Readable answer previews
|
|
6858
|
+
/* @__PURE__ */ jsx31("p", { children: "Readable answer previews from this response." })
|
|
6659
6859
|
] })
|
|
6660
6860
|
] }),
|
|
6661
6861
|
/* @__PURE__ */ jsxs28("div", { style: sectionGridStyle2, children: [
|
|
6662
|
-
/* @__PURE__ */
|
|
6663
|
-
/* @__PURE__ */
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
/* @__PURE__ */
|
|
6667
|
-
/* @__PURE__ */
|
|
6668
|
-
|
|
6669
|
-
|
|
6670
|
-
|
|
6671
|
-
|
|
6672
|
-
|
|
6673
|
-
|
|
6674
|
-
|
|
6675
|
-
|
|
6676
|
-
] }),
|
|
6677
|
-
/* @__PURE__ */ jsxs28("div", { className: "orion-admin-card", children: [
|
|
6678
|
-
/* @__PURE__ */ jsx31("strong", { children: "Raw payload" }),
|
|
6679
|
-
/* @__PURE__ */ jsx31("span", { children: "Verbatim submission data for troubleshooting or export checks." }),
|
|
6680
|
-
/* @__PURE__ */ jsx31("pre", { style: { ...codeStyle2, marginTop: "1rem" }, children: JSON.stringify(doc.data ?? {}, null, 2) })
|
|
6681
|
-
] })
|
|
6682
|
-
] }),
|
|
6862
|
+
/* @__PURE__ */ jsx31("div", { style: { display: "grid", gap: "1rem" }, children: /* @__PURE__ */ jsxs28("div", { className: "orion-admin-card", children: [
|
|
6863
|
+
/* @__PURE__ */ jsx31("strong", { children: "Response details" }),
|
|
6864
|
+
/* @__PURE__ */ jsx31("span", { children: "Formatted answers using the current form field labels when available." }),
|
|
6865
|
+
/* @__PURE__ */ jsx31("div", { style: { display: "grid", gap: "0.85rem", marginTop: "1rem" }, children: answerEntries.length > 0 ? answerEntries.map(([key, value]) => /* @__PURE__ */ jsxs28("div", { className: "orion-admin-form", children: [
|
|
6866
|
+
/* @__PURE__ */ jsxs28("div", { children: [
|
|
6867
|
+
/* @__PURE__ */ jsx31("strong", { children: fieldLabels.get(key) || humanizeKey2(key) }),
|
|
6868
|
+
/* @__PURE__ */ jsx31("div", { className: "orion-admin-list-meta", children: key })
|
|
6869
|
+
] }),
|
|
6870
|
+
/* @__PURE__ */ jsx31("div", { children: renderFieldValue(value) })
|
|
6871
|
+
] }, key)) : /* @__PURE__ */ jsxs28("div", { className: "orion-admin-empty-state", children: [
|
|
6872
|
+
/* @__PURE__ */ jsx31("strong", { children: "No answers available" }),
|
|
6873
|
+
/* @__PURE__ */ jsx31("span", { children: "This submission does not contain visible response details." })
|
|
6874
|
+
] }) })
|
|
6875
|
+
] }) }),
|
|
6683
6876
|
/* @__PURE__ */ jsxs28("div", { style: { display: "grid", gap: "1rem" }, children: [
|
|
6684
6877
|
/* @__PURE__ */ jsxs28("div", { className: "orion-admin-card orion-admin-meta-table", children: [
|
|
6685
6878
|
/* @__PURE__ */ jsxs28("div", { className: "orion-admin-meta-row", children: [
|
|
@@ -6749,7 +6942,7 @@ function AdminStudioFormSubmissionView(props) {
|
|
|
6749
6942
|
}
|
|
6750
6943
|
|
|
6751
6944
|
// src/admin/components/studio/AdminStudioFormUploadView.tsx
|
|
6752
|
-
import { useEffect as useEffect20, useMemo as useMemo16, useState as
|
|
6945
|
+
import { useEffect as useEffect20, useMemo as useMemo16, useState as useState22 } from "react";
|
|
6753
6946
|
import { Fragment as Fragment7, jsx as jsx32, jsxs as jsxs29 } from "react/jsx-runtime";
|
|
6754
6947
|
var previewStyle = {
|
|
6755
6948
|
borderRadius: 14,
|
|
@@ -6766,15 +6959,15 @@ function AdminStudioFormUploadView(props) {
|
|
|
6766
6959
|
const adminBasePath = useAdminBasePath();
|
|
6767
6960
|
const formsPath = resolveAdminPath(adminBasePath, "/forms");
|
|
6768
6961
|
const uploadIDFromParams = useMemo16(() => getParam3(props.params, "id"), [props.params]);
|
|
6769
|
-
const [uploadID, setUploadID] =
|
|
6770
|
-
const [didResolvePathFallback, setDidResolvePathFallback] =
|
|
6771
|
-
const [doc, setDoc] =
|
|
6772
|
-
const [loading, setLoading] =
|
|
6773
|
-
const [error, setError] =
|
|
6774
|
-
const [savedMessage, setSavedMessage] =
|
|
6775
|
-
const [saving, setSaving] =
|
|
6776
|
-
const [confirmDelete, setConfirmDelete] =
|
|
6777
|
-
const [deleting, setDeleting] =
|
|
6962
|
+
const [uploadID, setUploadID] = useState22(uploadIDFromParams);
|
|
6963
|
+
const [didResolvePathFallback, setDidResolvePathFallback] = useState22(false);
|
|
6964
|
+
const [doc, setDoc] = useState22(null);
|
|
6965
|
+
const [loading, setLoading] = useState22(true);
|
|
6966
|
+
const [error, setError] = useState22(null);
|
|
6967
|
+
const [savedMessage, setSavedMessage] = useState22(null);
|
|
6968
|
+
const [saving, setSaving] = useState22(false);
|
|
6969
|
+
const [confirmDelete, setConfirmDelete] = useState22(false);
|
|
6970
|
+
const [deleting, setDeleting] = useState22(false);
|
|
6778
6971
|
useEffect20(() => {
|
|
6779
6972
|
if (uploadIDFromParams) {
|
|
6780
6973
|
setUploadID(uploadIDFromParams);
|
|
@@ -6965,26 +7158,26 @@ function AdminStudioFormUploadView(props) {
|
|
|
6965
7158
|
}
|
|
6966
7159
|
|
|
6967
7160
|
// src/admin/components/studio/AdminStudioToolsView.tsx
|
|
6968
|
-
import { useEffect as useEffect21, useState as
|
|
6969
|
-
import { useAuth as
|
|
7161
|
+
import { useEffect as useEffect21, useState as useState23 } from "react";
|
|
7162
|
+
import { useAuth as useAuth6 } from "@payloadcms/ui";
|
|
6970
7163
|
import { jsx as jsx33, jsxs as jsxs30 } from "react/jsx-runtime";
|
|
6971
7164
|
var userRoles = ["admin", "developer", "editor", "client"];
|
|
6972
|
-
var
|
|
7165
|
+
var hasAdminAccess3 = (user) => {
|
|
6973
7166
|
if (!user || typeof user !== "object") return false;
|
|
6974
7167
|
const role = user.role;
|
|
6975
7168
|
return typeof role === "string" && (role === "admin" || role === "developer");
|
|
6976
7169
|
};
|
|
6977
7170
|
var normalizeRole = (value) => userRoles.includes(value) ? value : "editor";
|
|
6978
7171
|
function AdminStudioToolsView(props) {
|
|
6979
|
-
const { user } =
|
|
7172
|
+
const { user } = useAuth6();
|
|
6980
7173
|
const adminBasePath = useAdminBasePath();
|
|
6981
|
-
const [docs, setDocs] =
|
|
6982
|
-
const [loading, setLoading] =
|
|
6983
|
-
const [error, setError] =
|
|
6984
|
-
const [savedMessage, setSavedMessage] =
|
|
6985
|
-
const [createSubmitting, setCreateSubmitting] =
|
|
6986
|
-
const [updatingUserID, setUpdatingUserID] =
|
|
6987
|
-
if (!
|
|
7174
|
+
const [docs, setDocs] = useState23([]);
|
|
7175
|
+
const [loading, setLoading] = useState23(true);
|
|
7176
|
+
const [error, setError] = useState23(null);
|
|
7177
|
+
const [savedMessage, setSavedMessage] = useState23(null);
|
|
7178
|
+
const [createSubmitting, setCreateSubmitting] = useState23(false);
|
|
7179
|
+
const [updatingUserID, setUpdatingUserID] = useState23(null);
|
|
7180
|
+
if (!hasAdminAccess3(user)) {
|
|
6988
7181
|
return /* @__PURE__ */ jsx33(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ jsx33(
|
|
6989
7182
|
AdminPage,
|
|
6990
7183
|
{
|
|
@@ -7257,7 +7450,7 @@ function StudioDocumentRedirect({
|
|
|
7257
7450
|
}
|
|
7258
7451
|
|
|
7259
7452
|
// src/admin/components/studio/StudioBackBreadcrumb.tsx
|
|
7260
|
-
import { useEffect as useEffect24, useState as
|
|
7453
|
+
import { useEffect as useEffect24, useState as useState24 } from "react";
|
|
7261
7454
|
import { SetStepNav as SetStepNav5 } from "@payloadcms/ui";
|
|
7262
7455
|
import { jsx as jsx37 } from "react/jsx-runtime";
|
|
7263
7456
|
var toTitle = (slug) => slug.split("-").filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1)).join(" ");
|
|
@@ -7304,7 +7497,7 @@ var buildNav = (pathname, adminBasePath) => {
|
|
|
7304
7497
|
};
|
|
7305
7498
|
function StudioBackBreadcrumb() {
|
|
7306
7499
|
const adminBasePath = useAdminBasePath();
|
|
7307
|
-
const [pathname, setPathname] =
|
|
7500
|
+
const [pathname, setPathname] = useState24("");
|
|
7308
7501
|
useEffect24(() => {
|
|
7309
7502
|
const update = () => setPathname(window.location.pathname);
|
|
7310
7503
|
update();
|