@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.js
CHANGED
|
@@ -749,7 +749,7 @@ var init_OrionBlocksFieldImpl = __esm({
|
|
|
749
749
|
const schemaPath = schemaPathFromProps ?? name;
|
|
750
750
|
const minRows = minRowsProp ?? (required ? 1 : 0);
|
|
751
751
|
const { setDocFieldPreferences } = (0, import_DocumentInfo.useDocumentInfo)();
|
|
752
|
-
const { addFieldRow, dispatchFields, getFields, moveFieldRow, removeFieldRow, replaceState, setModified } = (0, import_Form.useForm)();
|
|
752
|
+
const { addFieldRow, dispatchFields, getFields: getFields2, moveFieldRow, removeFieldRow, replaceState, setModified } = (0, import_Form.useForm)();
|
|
753
753
|
const { code: locale } = (0, import_Locale.useLocale)();
|
|
754
754
|
const configContext = (0, import_Config.useConfig)();
|
|
755
755
|
const config = configContext?.config ?? {};
|
|
@@ -911,7 +911,7 @@ var init_OrionBlocksFieldImpl = __esm({
|
|
|
911
911
|
(rowIndex) => {
|
|
912
912
|
const result = clipboardCopy({
|
|
913
913
|
getDataToCopy: () => reduceFormStateByPath({
|
|
914
|
-
formState:
|
|
914
|
+
formState: getFields2(),
|
|
915
915
|
path: safePath,
|
|
916
916
|
rowIndex
|
|
917
917
|
}),
|
|
@@ -929,13 +929,13 @@ var init_OrionBlocksFieldImpl = __esm({
|
|
|
929
929
|
import_sonner.toast.success(t("general:copied"));
|
|
930
930
|
}
|
|
931
931
|
},
|
|
932
|
-
[clientBlocks,
|
|
932
|
+
[clientBlocks, getFields2, safePath, t, type]
|
|
933
933
|
);
|
|
934
934
|
const pasteRow = (0, import_react10.useCallback)(
|
|
935
935
|
(rowIndex) => {
|
|
936
936
|
const result = clipboardPaste({
|
|
937
937
|
onPaste: (dataFromClipboard) => {
|
|
938
|
-
const formState =
|
|
938
|
+
const formState = getFields2();
|
|
939
939
|
const newState = mergeFormStateFromClipboard({
|
|
940
940
|
dataFromClipboard,
|
|
941
941
|
formState,
|
|
@@ -952,11 +952,11 @@ var init_OrionBlocksFieldImpl = __esm({
|
|
|
952
952
|
import_sonner.toast.error(result);
|
|
953
953
|
}
|
|
954
954
|
},
|
|
955
|
-
[clientBlocks,
|
|
955
|
+
[clientBlocks, getFields2, replaceState, safePath, setModified, t]
|
|
956
956
|
);
|
|
957
957
|
const pasteBlocks = (0, import_react10.useCallback)(
|
|
958
958
|
(dataFromClipboard) => {
|
|
959
|
-
const formState =
|
|
959
|
+
const formState = getFields2();
|
|
960
960
|
const newState = mergeFormStateFromClipboard({
|
|
961
961
|
dataFromClipboard,
|
|
962
962
|
formState,
|
|
@@ -965,7 +965,7 @@ var init_OrionBlocksFieldImpl = __esm({
|
|
|
965
965
|
replaceState(newState);
|
|
966
966
|
setModified(true);
|
|
967
967
|
},
|
|
968
|
-
[
|
|
968
|
+
[getFields2, replaceState, safePath, setModified]
|
|
969
969
|
);
|
|
970
970
|
const hasMaxRows = Boolean(maxRows && rows.length >= maxRows);
|
|
971
971
|
const fieldErrorCount = errorPaths.length;
|
|
@@ -1042,7 +1042,7 @@ var init_OrionBlocksFieldImpl = __esm({
|
|
|
1042
1042
|
className: `${baseClass}__header-action`,
|
|
1043
1043
|
disabled,
|
|
1044
1044
|
getDataToCopy: () => reduceFormStateByPath({
|
|
1045
|
-
formState:
|
|
1045
|
+
formState: getFields2(),
|
|
1046
1046
|
path: safePath
|
|
1047
1047
|
}),
|
|
1048
1048
|
onPaste: pasteBlocks,
|
|
@@ -2873,8 +2873,26 @@ function NavIcon({ sectionID }) {
|
|
|
2873
2873
|
return null;
|
|
2874
2874
|
}
|
|
2875
2875
|
}
|
|
2876
|
+
function LogoutIcon() {
|
|
2877
|
+
const props = {
|
|
2878
|
+
fill: "none",
|
|
2879
|
+
height: iconSize2,
|
|
2880
|
+
stroke: "currentColor",
|
|
2881
|
+
strokeLinecap: "round",
|
|
2882
|
+
strokeLinejoin: "round",
|
|
2883
|
+
strokeWidth: 2,
|
|
2884
|
+
viewBox: "0 0 24 24",
|
|
2885
|
+
width: iconSize2
|
|
2886
|
+
};
|
|
2887
|
+
return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("svg", { ...props, "aria-hidden": "true", children: [
|
|
2888
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("path", { d: "M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" }),
|
|
2889
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("polyline", { points: "10 17 5 12 10 7" }),
|
|
2890
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("line", { x1: "5", y1: "12", x2: "17", y2: "12" })
|
|
2891
|
+
] });
|
|
2892
|
+
}
|
|
2876
2893
|
function AdminStudioNav(props) {
|
|
2877
2894
|
const { user } = (0, import_ui3.useAuth)();
|
|
2895
|
+
const [loggingOut, setLoggingOut] = (0, import_react13.useState)(false);
|
|
2878
2896
|
const brandName = getPropString(props, "brandName", "Orion Studio");
|
|
2879
2897
|
const logoUrl = getPropString(props, "logoUrl", "");
|
|
2880
2898
|
const compact = getPropBoolean(props, "compact", false);
|
|
@@ -2885,6 +2903,18 @@ function AdminStudioNav(props) {
|
|
|
2885
2903
|
const dashboardPath = adminBasePath;
|
|
2886
2904
|
const userRole = readUserRole(user);
|
|
2887
2905
|
const links = (0, import_react13.useMemo)(() => buildStudioNavItems(props, adminBasePath), [adminBasePath, props]);
|
|
2906
|
+
const logout = async () => {
|
|
2907
|
+
setLoggingOut(true);
|
|
2908
|
+
try {
|
|
2909
|
+
await fetch("/api/users/logout", {
|
|
2910
|
+
credentials: "include",
|
|
2911
|
+
method: "POST"
|
|
2912
|
+
});
|
|
2913
|
+
window.location.href = `${adminBasePath}/login`;
|
|
2914
|
+
} finally {
|
|
2915
|
+
setLoggingOut(false);
|
|
2916
|
+
}
|
|
2917
|
+
};
|
|
2888
2918
|
if (isStudioShellRoute(pathname, props, adminBasePath)) {
|
|
2889
2919
|
return null;
|
|
2890
2920
|
}
|
|
@@ -2975,7 +3005,38 @@ function AdminStudioNav(props) {
|
|
|
2975
3005
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { color: "var(--theme-elevation-700)", fontSize: "0.85rem" }, children: "Signed in as" }),
|
|
2976
3006
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("div", { style: { fontWeight: 800, marginBottom: "0.55rem" }, children: typeof user?.email === "string" ? user.email : "User" })
|
|
2977
3007
|
] }) : null,
|
|
2978
|
-
/* @__PURE__ */ (0, import_jsx_runtime16.
|
|
3008
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(
|
|
3009
|
+
"button",
|
|
3010
|
+
{
|
|
3011
|
+
"aria-label": "Log out",
|
|
3012
|
+
disabled: loggingOut,
|
|
3013
|
+
onClick: () => void logout(),
|
|
3014
|
+
style: {
|
|
3015
|
+
alignItems: "center",
|
|
3016
|
+
background: "transparent",
|
|
3017
|
+
border: "1px solid var(--theme-elevation-150)",
|
|
3018
|
+
borderRadius: 10,
|
|
3019
|
+
color: "var(--theme-elevation-900)",
|
|
3020
|
+
cursor: loggingOut ? "not-allowed" : "pointer",
|
|
3021
|
+
display: "inline-flex",
|
|
3022
|
+
font: "inherit",
|
|
3023
|
+
fontWeight: 800,
|
|
3024
|
+
gap: compact ? 0 : "0.45rem",
|
|
3025
|
+
justifyContent: "center",
|
|
3026
|
+
minHeight: compact ? 48 : 34,
|
|
3027
|
+
minWidth: compact ? 48 : 0,
|
|
3028
|
+
opacity: loggingOut ? 0.55 : 1,
|
|
3029
|
+
padding: compact ? 0 : "0.4rem 0.62rem",
|
|
3030
|
+
width: compact ? 48 : "auto"
|
|
3031
|
+
},
|
|
3032
|
+
title: "Log out",
|
|
3033
|
+
type: "button",
|
|
3034
|
+
children: [
|
|
3035
|
+
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)(LogoutIcon, {}),
|
|
3036
|
+
!compact ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { children: loggingOut ? "Logging out..." : "Log out" }) : null
|
|
3037
|
+
]
|
|
3038
|
+
}
|
|
3039
|
+
)
|
|
2979
3040
|
]
|
|
2980
3041
|
}
|
|
2981
3042
|
)
|
|
@@ -3048,6 +3109,14 @@ function NavIcon2({ name }) {
|
|
|
3048
3109
|
return null;
|
|
3049
3110
|
}
|
|
3050
3111
|
}
|
|
3112
|
+
function LogoutIcon2() {
|
|
3113
|
+
const props = { width: iconSize3, height: iconSize3, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", style: iconStyle };
|
|
3114
|
+
return /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("svg", { ...props, "aria-hidden": "true", children: [
|
|
3115
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("path", { d: "M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4" }),
|
|
3116
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("polyline", { points: "10 17 5 12 10 7" }),
|
|
3117
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("line", { x1: "5", y1: "12", x2: "17", y2: "12" })
|
|
3118
|
+
] });
|
|
3119
|
+
}
|
|
3051
3120
|
function AdminShellClient({
|
|
3052
3121
|
children,
|
|
3053
3122
|
brandName,
|
|
@@ -3059,14 +3128,12 @@ function AdminShellClient({
|
|
|
3059
3128
|
onLogout,
|
|
3060
3129
|
storageKey = "orion-admin-shell-collapsed"
|
|
3061
3130
|
}) {
|
|
3062
|
-
const [collapsed, setCollapsed] = (0, import_react14.useState)(
|
|
3131
|
+
const [collapsed, setCollapsed] = (0, import_react14.useState)(true);
|
|
3063
3132
|
const [loggingOut, setLoggingOut] = (0, import_react14.useState)(false);
|
|
3064
3133
|
(0, import_react14.useEffect)(() => {
|
|
3065
3134
|
try {
|
|
3066
3135
|
const stored = window.localStorage.getItem(storageKey);
|
|
3067
|
-
|
|
3068
|
-
setCollapsed(true);
|
|
3069
|
-
}
|
|
3136
|
+
setCollapsed(stored === "1");
|
|
3070
3137
|
} catch {
|
|
3071
3138
|
}
|
|
3072
3139
|
}, [storageKey]);
|
|
@@ -3128,7 +3195,10 @@ function AdminShellClient({
|
|
|
3128
3195
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "orion-admin-user-label", children: "Signed in as" }),
|
|
3129
3196
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("div", { className: "orion-admin-user-email", children: userEmail })
|
|
3130
3197
|
] }) : null,
|
|
3131
|
-
/* @__PURE__ */ (0, import_jsx_runtime17.
|
|
3198
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsxs)("button", { className: "orion-admin-logout", disabled: loggingOut, onClick: handleLogout, type: "button", children: [
|
|
3199
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)(LogoutIcon2, {}),
|
|
3200
|
+
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("span", { children: loggingOut ? "Logging out..." : "Log out" })
|
|
3201
|
+
] })
|
|
3132
3202
|
] })
|
|
3133
3203
|
] }),
|
|
3134
3204
|
/* @__PURE__ */ (0, import_jsx_runtime17.jsx)("main", { className: "orion-admin-main", children })
|
|
@@ -4040,15 +4110,16 @@ function AdminStudioDashboard(rawProps) {
|
|
|
4040
4110
|
}
|
|
4041
4111
|
|
|
4042
4112
|
// src/admin/components/studio/AdminStudioPagesListView.tsx
|
|
4043
|
-
var
|
|
4113
|
+
var import_react19 = require("react");
|
|
4044
4114
|
var import_link2 = __toESM(require("next/link"));
|
|
4115
|
+
var import_navigation3 = require("next/navigation");
|
|
4116
|
+
var import_ui7 = require("@payloadcms/ui");
|
|
4117
|
+
|
|
4118
|
+
// src/admin/components/studio/AdminStudioNewPageView.tsx
|
|
4119
|
+
var import_react17 = require("react");
|
|
4045
4120
|
var import_ui5 = require("@payloadcms/ui");
|
|
4046
4121
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
4047
|
-
var
|
|
4048
|
-
if (!user || typeof user !== "object") return false;
|
|
4049
|
-
const role = user.role;
|
|
4050
|
-
return typeof role === "string" && (role === "admin" || role === "developer");
|
|
4051
|
-
};
|
|
4122
|
+
var pageTemplates = ["standard", "landing", "services", "contact"];
|
|
4052
4123
|
var getPropString3 = (props, key, fallback) => {
|
|
4053
4124
|
if (!props || typeof props !== "object") return fallback;
|
|
4054
4125
|
const direct = props[key];
|
|
@@ -4060,83 +4131,107 @@ var getPropString3 = (props, key, fallback) => {
|
|
|
4060
4131
|
}
|
|
4061
4132
|
return fallback;
|
|
4062
4133
|
};
|
|
4063
|
-
|
|
4134
|
+
var canManagePages = (user) => {
|
|
4135
|
+
if (!user || typeof user !== "object") return false;
|
|
4136
|
+
const role = user.role;
|
|
4137
|
+
return role === "admin" || role === "developer" || role === "editor";
|
|
4138
|
+
};
|
|
4139
|
+
var slugify = (value) => value.toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
|
|
4140
|
+
function AdminStudioNewPageView(props) {
|
|
4064
4141
|
const { user } = (0, import_ui5.useAuth)();
|
|
4065
|
-
const pagesCollectionSlug = getPropString3(props, "pagesCollectionSlug", "pages");
|
|
4066
4142
|
const adminBasePath = useAdminBasePath();
|
|
4067
|
-
const
|
|
4068
|
-
const [
|
|
4143
|
+
const pagesCollectionSlug = getPropString3(props, "pagesCollectionSlug", "pages");
|
|
4144
|
+
const [submitting, setSubmitting] = (0, import_react17.useState)(false);
|
|
4069
4145
|
const [error, setError] = (0, import_react17.useState)(null);
|
|
4070
|
-
|
|
4071
|
-
|
|
4072
|
-
|
|
4073
|
-
|
|
4074
|
-
|
|
4075
|
-
|
|
4076
|
-
|
|
4077
|
-
|
|
4078
|
-
|
|
4079
|
-
|
|
4080
|
-
|
|
4081
|
-
|
|
4082
|
-
|
|
4083
|
-
|
|
4084
|
-
|
|
4085
|
-
try {
|
|
4086
|
-
const res = await fetch(apiURL, { credentials: "include" });
|
|
4087
|
-
if (!res.ok) {
|
|
4088
|
-
const body = await res.text();
|
|
4089
|
-
throw new Error(body || "Failed to fetch pages");
|
|
4090
|
-
}
|
|
4091
|
-
const data = await res.json();
|
|
4092
|
-
if (!cancelled) {
|
|
4093
|
-
setDocs(Array.isArray(data.docs) ? data.docs : []);
|
|
4094
|
-
}
|
|
4095
|
-
} catch (err) {
|
|
4096
|
-
if (!cancelled) {
|
|
4097
|
-
setError(err instanceof Error ? err.message : "Failed to fetch pages");
|
|
4098
|
-
}
|
|
4099
|
-
} finally {
|
|
4100
|
-
if (!cancelled) {
|
|
4101
|
-
setLoading(false);
|
|
4102
|
-
}
|
|
4146
|
+
if (!canManagePages(user)) {
|
|
4147
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4148
|
+
AdminPage,
|
|
4149
|
+
{
|
|
4150
|
+
breadcrumbs: [
|
|
4151
|
+
{ label: "Dashboard", href: adminBasePath },
|
|
4152
|
+
{ label: "Pages", href: resolveAdminPath(adminBasePath, "/pages") },
|
|
4153
|
+
{ label: "New Page" }
|
|
4154
|
+
],
|
|
4155
|
+
description: "You do not have access to create pages.",
|
|
4156
|
+
title: "New Page",
|
|
4157
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("div", { className: "orion-admin-card", children: [
|
|
4158
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("strong", { children: "Access denied" }),
|
|
4159
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("span", { children: "This section is restricted to administrator, developer, and editor accounts." })
|
|
4160
|
+
] })
|
|
4103
4161
|
}
|
|
4104
|
-
};
|
|
4105
|
-
|
|
4106
|
-
|
|
4107
|
-
|
|
4108
|
-
|
|
4109
|
-
|
|
4110
|
-
|
|
4162
|
+
) });
|
|
4163
|
+
}
|
|
4164
|
+
const createPage = async (event) => {
|
|
4165
|
+
event.preventDefault();
|
|
4166
|
+
setSubmitting(true);
|
|
4167
|
+
setError(null);
|
|
4168
|
+
try {
|
|
4169
|
+
const formData = new FormData(event.currentTarget);
|
|
4170
|
+
const titleValue = String(formData.get("title") || "").trim();
|
|
4171
|
+
const slugValue = String(formData.get("slug") || "").trim();
|
|
4172
|
+
const templateValue = String(formData.get("template") || "standard").trim();
|
|
4173
|
+
const template = pageTemplates.includes(templateValue) ? templateValue : "standard";
|
|
4174
|
+
const title = titleValue || "Untitled Page";
|
|
4175
|
+
const slug = slugValue || slugify(title) || "untitled-page";
|
|
4176
|
+
const response = await fetch(`/api/${pagesCollectionSlug}`, {
|
|
4177
|
+
body: JSON.stringify({
|
|
4178
|
+
_status: "draft",
|
|
4179
|
+
slug,
|
|
4180
|
+
template,
|
|
4181
|
+
title
|
|
4182
|
+
}),
|
|
4183
|
+
credentials: "include",
|
|
4184
|
+
headers: {
|
|
4185
|
+
"Content-Type": "application/json"
|
|
4186
|
+
},
|
|
4187
|
+
method: "POST"
|
|
4188
|
+
});
|
|
4189
|
+
if (!response.ok) {
|
|
4190
|
+
throw new Error(`Failed to create page (${response.status}).`);
|
|
4191
|
+
}
|
|
4192
|
+
const payload = await response.json();
|
|
4193
|
+
const id = typeof payload.id === "string" || typeof payload.id === "number" ? String(payload.id) : "";
|
|
4194
|
+
if (!id) {
|
|
4195
|
+
throw new Error("Page created but no document ID was returned.");
|
|
4196
|
+
}
|
|
4197
|
+
window.location.assign(resolveAdminPath(adminBasePath, `/pages/${id}`));
|
|
4198
|
+
} catch (createError) {
|
|
4199
|
+
setError(createError instanceof Error ? createError.message : "Failed to create page.");
|
|
4200
|
+
} finally {
|
|
4201
|
+
setSubmitting(false);
|
|
4202
|
+
}
|
|
4203
|
+
};
|
|
4204
|
+
return /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(
|
|
4111
4205
|
AdminPage,
|
|
4112
4206
|
{
|
|
4113
|
-
actions: hasAdminAccess(user) ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)(import_link2.default, { className: "orion-admin-action-button", href: newPagePath, children: "New Page" }) : null,
|
|
4114
4207
|
breadcrumbs: [
|
|
4115
4208
|
{ label: "Dashboard", href: adminBasePath },
|
|
4116
|
-
{ label: "Pages" }
|
|
4209
|
+
{ label: "Pages", href: resolveAdminPath(adminBasePath, "/pages") },
|
|
4210
|
+
{ label: "New Page" }
|
|
4117
4211
|
],
|
|
4118
|
-
description: "
|
|
4119
|
-
title: "
|
|
4120
|
-
children: [
|
|
4121
|
-
loading ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "orion-admin-list-meta", children: "Loading..." }) : null,
|
|
4212
|
+
description: "Create a new page and open it in the custom editor.",
|
|
4213
|
+
title: "New Page",
|
|
4214
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("form", { className: "orion-admin-form", onSubmit: createPage, children: [
|
|
4122
4215
|
error ? /* @__PURE__ */ (0, import_jsx_runtime23.jsx)("div", { className: "orion-admin-error", children: error }) : null,
|
|
4123
|
-
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("
|
|
4124
|
-
|
|
4125
|
-
|
|
4126
|
-
|
|
4127
|
-
|
|
4128
|
-
|
|
4129
|
-
|
|
4130
|
-
|
|
4131
|
-
|
|
4132
|
-
|
|
4133
|
-
|
|
4134
|
-
|
|
4135
|
-
|
|
4136
|
-
|
|
4137
|
-
|
|
4138
|
-
|
|
4139
|
-
|
|
4216
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { children: [
|
|
4217
|
+
"Title",
|
|
4218
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("input", { name: "title", placeholder: "Services", required: true, type: "text" })
|
|
4219
|
+
] }),
|
|
4220
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { children: [
|
|
4221
|
+
"Slug",
|
|
4222
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("input", { name: "slug", placeholder: "services", type: "text" })
|
|
4223
|
+
] }),
|
|
4224
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("label", { children: [
|
|
4225
|
+
"Template",
|
|
4226
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsxs)("select", { defaultValue: "standard", name: "template", children: [
|
|
4227
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: "standard", children: "Standard" }),
|
|
4228
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: "landing", children: "Landing" }),
|
|
4229
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: "contact", children: "Contact" }),
|
|
4230
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("option", { value: "services", children: "Services" })
|
|
4231
|
+
] })
|
|
4232
|
+
] }),
|
|
4233
|
+
/* @__PURE__ */ (0, import_jsx_runtime23.jsx)("button", { disabled: submitting, type: "submit", children: submitting ? "Creating..." : "Create Page" })
|
|
4234
|
+
] })
|
|
4140
4235
|
}
|
|
4141
4236
|
) });
|
|
4142
4237
|
}
|
|
@@ -4145,16 +4240,6 @@ function AdminStudioPagesListView(props) {
|
|
|
4145
4240
|
var import_react18 = require("react");
|
|
4146
4241
|
var import_ui6 = require("@payloadcms/ui");
|
|
4147
4242
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
4148
|
-
var hasAdminAccess2 = (user) => {
|
|
4149
|
-
if (!user || typeof user !== "object") return false;
|
|
4150
|
-
const role = user.role;
|
|
4151
|
-
return typeof role === "string" && (role === "admin" || role === "developer");
|
|
4152
|
-
};
|
|
4153
|
-
var isEditor = (user) => {
|
|
4154
|
-
if (!user || typeof user !== "object") return false;
|
|
4155
|
-
const role = user.role;
|
|
4156
|
-
return typeof role === "string" && role === "editor";
|
|
4157
|
-
};
|
|
4158
4243
|
var getPropString4 = (props, key, fallback) => {
|
|
4159
4244
|
if (!props || typeof props !== "object") return fallback;
|
|
4160
4245
|
const direct = props[key];
|
|
@@ -4182,14 +4267,8 @@ var getPageIDFromPathname = (pathname) => {
|
|
|
4182
4267
|
return pagePart ? decodeURIComponent(pagePart) : null;
|
|
4183
4268
|
};
|
|
4184
4269
|
function AdminStudioPageEditView(props) {
|
|
4185
|
-
const { user } = (0, import_ui6.useAuth)();
|
|
4186
4270
|
const adminBasePath = useAdminBasePath();
|
|
4187
4271
|
const iframeRef = (0, import_react18.useRef)(null);
|
|
4188
|
-
const [saving, setSaving] = (0, import_react18.useState)(null);
|
|
4189
|
-
const [dirty, setDirty] = (0, import_react18.useState)(false);
|
|
4190
|
-
const [hasUnpublishedChanges, setHasUnpublishedChanges] = (0, import_react18.useState)(false);
|
|
4191
|
-
const [canUndo, setCanUndo] = (0, import_react18.useState)(false);
|
|
4192
|
-
const [canRedo, setCanRedo] = (0, import_react18.useState)(false);
|
|
4193
4272
|
const builderBasePath = getPropString4(props, "builderBasePath", "/builder");
|
|
4194
4273
|
const pagesPath = resolveAdminPath(adminBasePath, "/pages");
|
|
4195
4274
|
const pageIDFromParams = (0, import_react18.useMemo)(() => getParam(props.params, "id"), [props.params]);
|
|
@@ -4206,96 +4285,6 @@ function AdminStudioPageEditView(props) {
|
|
|
4206
4285
|
}
|
|
4207
4286
|
setDidResolvePathFallback(true);
|
|
4208
4287
|
}, [pageIDFromParams]);
|
|
4209
|
-
const canPublish = hasAdminAccess2(user) || isEditor(user);
|
|
4210
|
-
const refreshUnpublishedState = async (id) => {
|
|
4211
|
-
try {
|
|
4212
|
-
const response = await fetch(
|
|
4213
|
-
`/api/pages/versions?depth=0&limit=25&sort=-updatedAt&where[parent][equals]=${encodeURIComponent(id)}`,
|
|
4214
|
-
{
|
|
4215
|
-
credentials: "include"
|
|
4216
|
-
}
|
|
4217
|
-
);
|
|
4218
|
-
if (!response.ok) {
|
|
4219
|
-
return;
|
|
4220
|
-
}
|
|
4221
|
-
const payload = await response.json();
|
|
4222
|
-
const docs = Array.isArray(payload.docs) ? payload.docs : [];
|
|
4223
|
-
let latestDraft = 0;
|
|
4224
|
-
let latestPublished = 0;
|
|
4225
|
-
docs.forEach((doc) => {
|
|
4226
|
-
const status = doc.version?._status;
|
|
4227
|
-
const millis = typeof doc.updatedAt === "string" ? Date.parse(doc.updatedAt) : Number.NaN;
|
|
4228
|
-
if (!Number.isFinite(millis)) {
|
|
4229
|
-
return;
|
|
4230
|
-
}
|
|
4231
|
-
if (status === "draft") {
|
|
4232
|
-
latestDraft = Math.max(latestDraft, millis);
|
|
4233
|
-
}
|
|
4234
|
-
if (status === "published") {
|
|
4235
|
-
latestPublished = Math.max(latestPublished, millis);
|
|
4236
|
-
}
|
|
4237
|
-
});
|
|
4238
|
-
setHasUnpublishedChanges(latestDraft > 0 && latestDraft >= latestPublished);
|
|
4239
|
-
} catch {
|
|
4240
|
-
}
|
|
4241
|
-
};
|
|
4242
|
-
(0, import_react18.useEffect)(() => {
|
|
4243
|
-
if (!pageID) {
|
|
4244
|
-
return;
|
|
4245
|
-
}
|
|
4246
|
-
void refreshUnpublishedState(pageID);
|
|
4247
|
-
}, [pageID]);
|
|
4248
|
-
const requestSave = (status) => {
|
|
4249
|
-
const iframe = iframeRef.current;
|
|
4250
|
-
if (!iframe?.contentWindow) {
|
|
4251
|
-
import_ui6.toast.error("Editor is not ready yet. Please try again.");
|
|
4252
|
-
return;
|
|
4253
|
-
}
|
|
4254
|
-
setSaving(status);
|
|
4255
|
-
iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type: "save", status }, "*");
|
|
4256
|
-
};
|
|
4257
|
-
const requestHistoryAction = (type) => {
|
|
4258
|
-
const iframe = iframeRef.current;
|
|
4259
|
-
if (!iframe?.contentWindow) {
|
|
4260
|
-
import_ui6.toast.error("Editor is not ready yet. Please try again.");
|
|
4261
|
-
return;
|
|
4262
|
-
}
|
|
4263
|
-
iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type }, "*");
|
|
4264
|
-
};
|
|
4265
|
-
(0, import_react18.useEffect)(() => {
|
|
4266
|
-
const onMessage = (event) => {
|
|
4267
|
-
const data = event.data;
|
|
4268
|
-
if (!data || data.source !== "payload-visual-builder-child" || typeof data.type !== "string") {
|
|
4269
|
-
return;
|
|
4270
|
-
}
|
|
4271
|
-
if (data.type === "dirty-state") {
|
|
4272
|
-
setDirty(Boolean(data.dirty));
|
|
4273
|
-
return;
|
|
4274
|
-
}
|
|
4275
|
-
if (data.type === "history-state") {
|
|
4276
|
-
setCanUndo(Boolean(data.canUndo));
|
|
4277
|
-
setCanRedo(Boolean(data.canRedo));
|
|
4278
|
-
return;
|
|
4279
|
-
}
|
|
4280
|
-
if (data.type === "save-result") {
|
|
4281
|
-
setSaving(null);
|
|
4282
|
-
if (data.ok) {
|
|
4283
|
-
if (data.status === "draft") {
|
|
4284
|
-
setHasUnpublishedChanges(true);
|
|
4285
|
-
} else if (data.status === "published") {
|
|
4286
|
-
setHasUnpublishedChanges(false);
|
|
4287
|
-
} else if (pageID) {
|
|
4288
|
-
void refreshUnpublishedState(pageID);
|
|
4289
|
-
}
|
|
4290
|
-
import_ui6.toast.success(typeof data.message === "string" ? data.message : "Saved.");
|
|
4291
|
-
} else {
|
|
4292
|
-
import_ui6.toast.error(typeof data.message === "string" ? data.message : "Save failed.");
|
|
4293
|
-
}
|
|
4294
|
-
}
|
|
4295
|
-
};
|
|
4296
|
-
window.addEventListener("message", onMessage);
|
|
4297
|
-
return () => window.removeEventListener("message", onMessage);
|
|
4298
|
-
}, []);
|
|
4299
4288
|
if (!pageID && !didResolvePathFallback) {
|
|
4300
4289
|
return /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(import_jsx_runtime24.Fragment, { children: [
|
|
4301
4290
|
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
@@ -4336,164 +4325,25 @@ function AdminStudioPageEditView(props) {
|
|
|
4336
4325
|
]
|
|
4337
4326
|
}
|
|
4338
4327
|
),
|
|
4339
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.
|
|
4340
|
-
|
|
4341
|
-
|
|
4342
|
-
|
|
4343
|
-
|
|
4344
|
-
|
|
4345
|
-
|
|
4346
|
-
|
|
4347
|
-
|
|
4348
|
-
boxShadow: "0 12px 28px rgba(62, 42, 24, 0.08)",
|
|
4349
|
-
colorScheme: "light",
|
|
4350
|
-
display: "flex",
|
|
4351
|
-
gap: "0.6rem",
|
|
4352
|
-
justifyContent: "space-between",
|
|
4353
|
-
padding: "0.65rem 0.9rem",
|
|
4354
|
-
position: "sticky",
|
|
4355
|
-
top: 0,
|
|
4356
|
-
zIndex: 20
|
|
4357
|
-
},
|
|
4358
|
-
children: [
|
|
4359
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { minWidth: 0 }, children: [
|
|
4360
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { color: "var(--orion-admin-text)", fontWeight: 900 }, children: "Page Editor" }),
|
|
4361
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(
|
|
4362
|
-
"div",
|
|
4363
|
-
{
|
|
4364
|
-
style: {
|
|
4365
|
-
color: "var(--orion-admin-muted)",
|
|
4366
|
-
fontSize: "0.85rem",
|
|
4367
|
-
overflow: "hidden",
|
|
4368
|
-
textOverflow: "ellipsis"
|
|
4369
|
-
},
|
|
4370
|
-
children: [
|
|
4371
|
-
"Editing: ",
|
|
4372
|
-
pageID
|
|
4373
|
-
]
|
|
4374
|
-
}
|
|
4375
|
-
)
|
|
4376
|
-
] }),
|
|
4377
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsxs)("div", { style: { alignItems: "center", display: "flex", gap: "0.5rem" }, children: [
|
|
4378
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { color: dirty ? "var(--orion-admin-text)" : "var(--orion-admin-muted)", fontSize: "0.85rem", fontWeight: 700 }, children: dirty ? "Unsaved changes" : "All changes saved" }),
|
|
4379
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4380
|
-
"div",
|
|
4381
|
-
{
|
|
4382
|
-
style: {
|
|
4383
|
-
background: hasUnpublishedChanges ? "#fff3cd" : "var(--orion-admin-accent-subtle)",
|
|
4384
|
-
border: `1px solid ${hasUnpublishedChanges ? "#f0c36d" : "color-mix(in srgb, var(--orion-admin-accent) 36%, transparent)"}`,
|
|
4385
|
-
borderRadius: 999,
|
|
4386
|
-
color: hasUnpublishedChanges ? "#6a4a00" : "var(--orion-admin-accent)",
|
|
4387
|
-
fontSize: "0.75rem",
|
|
4388
|
-
fontWeight: 800,
|
|
4389
|
-
padding: "0.2rem 0.55rem",
|
|
4390
|
-
whiteSpace: "nowrap"
|
|
4391
|
-
},
|
|
4392
|
-
title: hasUnpublishedChanges ? "There are saved draft changes not yet published." : "The live page matches the latest published content.",
|
|
4393
|
-
children: hasUnpublishedChanges ? "Unpublished draft changes" : "Live is up to date"
|
|
4394
|
-
}
|
|
4395
|
-
),
|
|
4396
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4397
|
-
"button",
|
|
4398
|
-
{
|
|
4399
|
-
disabled: !canUndo,
|
|
4400
|
-
onClick: () => requestHistoryAction("undo"),
|
|
4401
|
-
style: {
|
|
4402
|
-
background: "transparent",
|
|
4403
|
-
border: "1px solid var(--orion-admin-card-border)",
|
|
4404
|
-
borderRadius: 12,
|
|
4405
|
-
cursor: canUndo ? "pointer" : "not-allowed",
|
|
4406
|
-
color: "var(--orion-admin-text)",
|
|
4407
|
-
fontWeight: 800,
|
|
4408
|
-
padding: "0.5rem 0.65rem"
|
|
4409
|
-
},
|
|
4410
|
-
type: "button",
|
|
4411
|
-
children: "Undo"
|
|
4412
|
-
}
|
|
4413
|
-
),
|
|
4414
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4415
|
-
"button",
|
|
4416
|
-
{
|
|
4417
|
-
disabled: !canRedo,
|
|
4418
|
-
onClick: () => requestHistoryAction("redo"),
|
|
4419
|
-
style: {
|
|
4420
|
-
background: "transparent",
|
|
4421
|
-
border: "1px solid var(--orion-admin-card-border)",
|
|
4422
|
-
borderRadius: 12,
|
|
4423
|
-
cursor: canRedo ? "pointer" : "not-allowed",
|
|
4424
|
-
color: "var(--orion-admin-text)",
|
|
4425
|
-
fontWeight: 800,
|
|
4426
|
-
padding: "0.5rem 0.65rem"
|
|
4427
|
-
},
|
|
4428
|
-
type: "button",
|
|
4429
|
-
children: "Redo"
|
|
4430
|
-
}
|
|
4431
|
-
),
|
|
4432
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4433
|
-
"button",
|
|
4434
|
-
{
|
|
4435
|
-
disabled: saving !== null,
|
|
4436
|
-
onClick: () => requestSave("draft"),
|
|
4437
|
-
style: {
|
|
4438
|
-
background: "var(--orion-admin-card-bg)",
|
|
4439
|
-
border: "1px solid var(--orion-admin-card-border)",
|
|
4440
|
-
borderRadius: 12,
|
|
4441
|
-
cursor: saving ? "not-allowed" : "pointer",
|
|
4442
|
-
color: "var(--orion-admin-text)",
|
|
4443
|
-
fontWeight: 800,
|
|
4444
|
-
padding: "0.5rem 0.75rem"
|
|
4445
|
-
},
|
|
4446
|
-
type: "button",
|
|
4447
|
-
children: saving === "draft" ? "Saving\u2026" : "Save Draft"
|
|
4448
|
-
}
|
|
4449
|
-
),
|
|
4450
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4451
|
-
"button",
|
|
4452
|
-
{
|
|
4453
|
-
disabled: !canPublish || saving !== null,
|
|
4454
|
-
onClick: () => requestSave("published"),
|
|
4455
|
-
style: {
|
|
4456
|
-
background: canPublish ? "var(--orion-admin-button-bg)" : "var(--orion-admin-card-border)",
|
|
4457
|
-
border: "none",
|
|
4458
|
-
borderRadius: 12,
|
|
4459
|
-
color: canPublish ? "var(--orion-admin-button-text)" : "var(--orion-admin-text)",
|
|
4460
|
-
cursor: !canPublish || saving ? "not-allowed" : "pointer",
|
|
4461
|
-
fontWeight: 900,
|
|
4462
|
-
padding: "0.5rem 0.75rem"
|
|
4463
|
-
},
|
|
4464
|
-
type: "button",
|
|
4465
|
-
title: !canPublish ? "You do not have publish permissions." : void 0,
|
|
4466
|
-
children: saving === "published" ? "Publishing\u2026" : "Publish"
|
|
4467
|
-
}
|
|
4468
|
-
)
|
|
4469
|
-
] })
|
|
4470
|
-
]
|
|
4471
|
-
}
|
|
4472
|
-
),
|
|
4473
|
-
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4474
|
-
"iframe",
|
|
4475
|
-
{
|
|
4476
|
-
ref: iframeRef,
|
|
4477
|
-
src: `${builderBasePath.replace(/\/$/, "")}/${pageID}`,
|
|
4478
|
-
style: { border: "none", height: "100%", width: "100%" },
|
|
4479
|
-
title: "Page Builder",
|
|
4480
|
-
onLoad: () => {
|
|
4481
|
-
const iframe = iframeRef.current;
|
|
4482
|
-
if (!iframe?.contentWindow) return;
|
|
4483
|
-
iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type: "dirty-check-request" }, "*");
|
|
4484
|
-
iframe.contentWindow.postMessage({ source: "payload-visual-builder-parent", type: "history-check-request" }, "*");
|
|
4485
|
-
}
|
|
4486
|
-
}
|
|
4487
|
-
)
|
|
4488
|
-
] })
|
|
4328
|
+
/* @__PURE__ */ (0, import_jsx_runtime24.jsx)("div", { style: { height: "100dvh", overflow: "hidden" }, children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
|
|
4329
|
+
"iframe",
|
|
4330
|
+
{
|
|
4331
|
+
ref: iframeRef,
|
|
4332
|
+
src: `${builderBasePath.replace(/\/$/, "")}/${pageID}`,
|
|
4333
|
+
style: { border: "none", height: "100%", width: "100%" },
|
|
4334
|
+
title: "Page Builder"
|
|
4335
|
+
}
|
|
4336
|
+
) })
|
|
4489
4337
|
] }) });
|
|
4490
4338
|
}
|
|
4491
4339
|
|
|
4492
|
-
// src/admin/components/studio/
|
|
4493
|
-
var import_react19 = require("react");
|
|
4494
|
-
var import_ui7 = require("@payloadcms/ui");
|
|
4340
|
+
// src/admin/components/studio/AdminStudioPagesListView.tsx
|
|
4495
4341
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
4496
|
-
var
|
|
4342
|
+
var hasAdminAccess = (user) => {
|
|
4343
|
+
if (!user || typeof user !== "object") return false;
|
|
4344
|
+
const role = user.role;
|
|
4345
|
+
return typeof role === "string" && (role === "admin" || role === "developer");
|
|
4346
|
+
};
|
|
4497
4347
|
var getPropString5 = (props, key, fallback) => {
|
|
4498
4348
|
if (!props || typeof props !== "object") return fallback;
|
|
4499
4349
|
const direct = props[key];
|
|
@@ -4505,107 +4355,98 @@ var getPropString5 = (props, key, fallback) => {
|
|
|
4505
4355
|
}
|
|
4506
4356
|
return fallback;
|
|
4507
4357
|
};
|
|
4508
|
-
|
|
4509
|
-
if (!user || typeof user !== "object") return false;
|
|
4510
|
-
const role = user.role;
|
|
4511
|
-
return role === "admin" || role === "developer" || role === "editor";
|
|
4512
|
-
};
|
|
4513
|
-
var slugify = (value) => value.toLowerCase().trim().replace(/[^a-z0-9\s-]/g, "").replace(/\s+/g, "-").replace(/-+/g, "-");
|
|
4514
|
-
function AdminStudioNewPageView(props) {
|
|
4515
|
-
const { user } = (0, import_ui7.useAuth)();
|
|
4358
|
+
function AdminStudioPagesListView(props) {
|
|
4516
4359
|
const adminBasePath = useAdminBasePath();
|
|
4360
|
+
const pathname = (0, import_navigation3.usePathname)();
|
|
4361
|
+
const pagesPath = resolveAdminPath(adminBasePath, "/pages");
|
|
4362
|
+
const nestedPagePath = pathname && pathname.startsWith(`${pagesPath}/`) ? pathname.slice(`${pagesPath}/`.length).split("/")[0] : "";
|
|
4363
|
+
if (nestedPagePath === "new") {
|
|
4364
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AdminStudioNewPageView, { ...props });
|
|
4365
|
+
}
|
|
4366
|
+
if (nestedPagePath) {
|
|
4367
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AdminStudioPageEditView, { ...props });
|
|
4368
|
+
}
|
|
4369
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AdminStudioPagesIndexView, { ...props, adminBasePath });
|
|
4370
|
+
}
|
|
4371
|
+
function AdminStudioPagesIndexView({
|
|
4372
|
+
adminBasePath,
|
|
4373
|
+
...props
|
|
4374
|
+
}) {
|
|
4375
|
+
const { user } = (0, import_ui7.useAuth)();
|
|
4517
4376
|
const pagesCollectionSlug = getPropString5(props, "pagesCollectionSlug", "pages");
|
|
4518
|
-
const
|
|
4377
|
+
const newPagePath = resolveAdminPath(adminBasePath, "/pages/new");
|
|
4378
|
+
const [loading, setLoading] = (0, import_react19.useState)(true);
|
|
4519
4379
|
const [error, setError] = (0, import_react19.useState)(null);
|
|
4520
|
-
|
|
4521
|
-
|
|
4522
|
-
|
|
4523
|
-
|
|
4524
|
-
|
|
4525
|
-
|
|
4526
|
-
|
|
4527
|
-
|
|
4528
|
-
|
|
4529
|
-
|
|
4530
|
-
|
|
4531
|
-
|
|
4532
|
-
|
|
4533
|
-
|
|
4534
|
-
|
|
4535
|
-
|
|
4536
|
-
|
|
4537
|
-
|
|
4538
|
-
|
|
4539
|
-
|
|
4540
|
-
|
|
4541
|
-
|
|
4542
|
-
|
|
4543
|
-
|
|
4544
|
-
|
|
4545
|
-
|
|
4546
|
-
|
|
4547
|
-
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
slug,
|
|
4554
|
-
template,
|
|
4555
|
-
title
|
|
4556
|
-
}),
|
|
4557
|
-
credentials: "include",
|
|
4558
|
-
headers: {
|
|
4559
|
-
"Content-Type": "application/json"
|
|
4560
|
-
},
|
|
4561
|
-
method: "POST"
|
|
4562
|
-
});
|
|
4563
|
-
if (!response.ok) {
|
|
4564
|
-
throw new Error(`Failed to create page (${response.status}).`);
|
|
4565
|
-
}
|
|
4566
|
-
const payload = await response.json();
|
|
4567
|
-
const id = typeof payload.id === "string" || typeof payload.id === "number" ? String(payload.id) : "";
|
|
4568
|
-
if (!id) {
|
|
4569
|
-
throw new Error("Page created but no document ID was returned.");
|
|
4380
|
+
const [docs, setDocs] = (0, import_react19.useState)([]);
|
|
4381
|
+
const apiURL = (0, import_react19.useMemo)(() => {
|
|
4382
|
+
const params = new URLSearchParams({
|
|
4383
|
+
depth: "0",
|
|
4384
|
+
limit: "100",
|
|
4385
|
+
sort: "-updatedAt",
|
|
4386
|
+
draft: "true"
|
|
4387
|
+
});
|
|
4388
|
+
return `/api/${pagesCollectionSlug}?${params.toString()}`;
|
|
4389
|
+
}, [pagesCollectionSlug]);
|
|
4390
|
+
(0, import_react19.useEffect)(() => {
|
|
4391
|
+
let cancelled = false;
|
|
4392
|
+
const run = async () => {
|
|
4393
|
+
setLoading(true);
|
|
4394
|
+
setError(null);
|
|
4395
|
+
try {
|
|
4396
|
+
const res = await fetch(apiURL, { credentials: "include" });
|
|
4397
|
+
if (!res.ok) {
|
|
4398
|
+
const body = await res.text();
|
|
4399
|
+
throw new Error(body || "Failed to fetch pages");
|
|
4400
|
+
}
|
|
4401
|
+
const data = await res.json();
|
|
4402
|
+
if (!cancelled) {
|
|
4403
|
+
setDocs(Array.isArray(data.docs) ? data.docs : []);
|
|
4404
|
+
}
|
|
4405
|
+
} catch (err) {
|
|
4406
|
+
if (!cancelled) {
|
|
4407
|
+
setError(err instanceof Error ? err.message : "Failed to fetch pages");
|
|
4408
|
+
}
|
|
4409
|
+
} finally {
|
|
4410
|
+
if (!cancelled) {
|
|
4411
|
+
setLoading(false);
|
|
4412
|
+
}
|
|
4570
4413
|
}
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4574
|
-
|
|
4575
|
-
|
|
4576
|
-
|
|
4577
|
-
|
|
4578
|
-
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
|
|
4414
|
+
};
|
|
4415
|
+
void run();
|
|
4416
|
+
return () => {
|
|
4417
|
+
cancelled = true;
|
|
4418
|
+
};
|
|
4419
|
+
}, [apiURL]);
|
|
4420
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
|
|
4579
4421
|
AdminPage,
|
|
4580
4422
|
{
|
|
4423
|
+
actions: hasAdminAccess(user) ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_link2.default, { className: "orion-admin-action-button", href: newPagePath, children: "New Page" }) : null,
|
|
4581
4424
|
breadcrumbs: [
|
|
4582
4425
|
{ label: "Dashboard", href: adminBasePath },
|
|
4583
|
-
{ label: "Pages"
|
|
4584
|
-
{ label: "New Page" }
|
|
4426
|
+
{ label: "Pages" }
|
|
4585
4427
|
],
|
|
4586
|
-
description: "
|
|
4587
|
-
title: "
|
|
4588
|
-
children:
|
|
4428
|
+
description: "Open a page to edit it in the inline custom builder.",
|
|
4429
|
+
title: "Pages",
|
|
4430
|
+
children: [
|
|
4431
|
+
loading ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "orion-admin-list-meta", children: "Loading..." }) : null,
|
|
4589
4432
|
error ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { className: "orion-admin-error", children: error }) : null,
|
|
4590
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("
|
|
4591
|
-
"
|
|
4592
|
-
|
|
4593
|
-
|
|
4594
|
-
|
|
4595
|
-
|
|
4596
|
-
|
|
4597
|
-
|
|
4598
|
-
|
|
4599
|
-
|
|
4600
|
-
|
|
4601
|
-
|
|
4602
|
-
|
|
4603
|
-
|
|
4604
|
-
|
|
4605
|
-
|
|
4606
|
-
|
|
4607
|
-
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("button", { disabled: submitting, type: "submit", children: submitting ? "Creating..." : "Create Page" })
|
|
4608
|
-
] })
|
|
4433
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "orion-admin-list", children: [
|
|
4434
|
+
!loading && !error && docs.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "orion-admin-card", children: [
|
|
4435
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("strong", { children: "No pages yet" }),
|
|
4436
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { children: "Create the first page to start building content." })
|
|
4437
|
+
] }) : null,
|
|
4438
|
+
docs.map((doc) => {
|
|
4439
|
+
const id = typeof doc.id === "string" || typeof doc.id === "number" ? String(doc.id) : "";
|
|
4440
|
+
if (!id) return null;
|
|
4441
|
+
const title = typeof doc.title === "string" ? doc.title : "Untitled Page";
|
|
4442
|
+
const status = typeof doc._status === "string" ? doc._status : "draft";
|
|
4443
|
+
return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_link2.default, { className: "orion-admin-list-item", href: resolveAdminPath(adminBasePath, `/pages/${id}`), children: [
|
|
4444
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("div", { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("strong", { children: title }) }),
|
|
4445
|
+
/* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "orion-admin-pill", children: status })
|
|
4446
|
+
] }, id);
|
|
4447
|
+
})
|
|
4448
|
+
] })
|
|
4449
|
+
]
|
|
4609
4450
|
}
|
|
4610
4451
|
) });
|
|
4611
4452
|
}
|
|
@@ -6874,7 +6715,7 @@ function MediaListItem({
|
|
|
6874
6715
|
|
|
6875
6716
|
// src/admin-app/components/MediaUploadForm.tsx
|
|
6876
6717
|
var import_react27 = require("react");
|
|
6877
|
-
var
|
|
6718
|
+
var import_navigation4 = require("next/navigation");
|
|
6878
6719
|
|
|
6879
6720
|
// src/shared/clientImageUploadOptimization.ts
|
|
6880
6721
|
var MAX_DIRECT_UPLOAD_BYTES = 4e6;
|
|
@@ -7009,7 +6850,7 @@ var parseUploadError = async (response) => {
|
|
|
7009
6850
|
return fallback;
|
|
7010
6851
|
};
|
|
7011
6852
|
function MediaUploadForm() {
|
|
7012
|
-
const router = (0,
|
|
6853
|
+
const router = (0, import_navigation4.useRouter)();
|
|
7013
6854
|
const fileInputRef = (0, import_react27.useRef)(null);
|
|
7014
6855
|
const [alt, setAlt] = (0, import_react27.useState)("");
|
|
7015
6856
|
const [file, setFile] = (0, import_react27.useState)(null);
|
|
@@ -7544,17 +7385,17 @@ var FORM_TONE_OVERRIDES = {
|
|
|
7544
7385
|
var IDENTITY_KEYS = /* @__PURE__ */ new Set(["contactEmail", "email", "firstName", "lastName", "name"]);
|
|
7545
7386
|
var RESPONSE_FIELD_PREVIEW_LIMIT = 3;
|
|
7546
7387
|
var RESPONSE_SCROLL_THRESHOLD = 3;
|
|
7547
|
-
var
|
|
7388
|
+
var hasAdminAccess2 = (user) => {
|
|
7548
7389
|
if (!user || typeof user !== "object") return false;
|
|
7549
7390
|
const role = user.role;
|
|
7550
7391
|
return typeof role === "string" && (role === "admin" || role === "developer");
|
|
7551
7392
|
};
|
|
7552
|
-
var
|
|
7393
|
+
var isEditor = (user) => {
|
|
7553
7394
|
if (!user || typeof user !== "object") return false;
|
|
7554
7395
|
const role = user.role;
|
|
7555
7396
|
return typeof role === "string" && role === "editor";
|
|
7556
7397
|
};
|
|
7557
|
-
var canReviewForms2 = (user) =>
|
|
7398
|
+
var canReviewForms2 = (user) => hasAdminAccess2(user) || isEditor(user);
|
|
7558
7399
|
var getPropString13 = (props, key, fallback) => {
|
|
7559
7400
|
if (!props || typeof props !== "object") return fallback;
|
|
7560
7401
|
const direct = props[key];
|
|
@@ -8240,15 +8081,22 @@ var getFormTitle2 = (value) => {
|
|
|
8240
8081
|
// src/admin/components/studio/AdminStudioFormDetailView.tsx
|
|
8241
8082
|
var import_jsx_runtime41 = require("react/jsx-runtime");
|
|
8242
8083
|
var getNonEmptyText = (value, fallback = "") => typeof value === "string" && value.trim().length > 0 ? value : fallback;
|
|
8243
|
-
var
|
|
8084
|
+
var normalizeSteps = (value) => {
|
|
8244
8085
|
if (!Array.isArray(value)) {
|
|
8245
|
-
return
|
|
8086
|
+
return [];
|
|
8246
8087
|
}
|
|
8247
|
-
|
|
8248
|
-
|
|
8249
|
-
|
|
8250
|
-
|
|
8088
|
+
return value.map((step) => step && typeof step === "object" && !Array.isArray(step) ? step : {});
|
|
8089
|
+
};
|
|
8090
|
+
var normalizeFormResponse = (value) => {
|
|
8091
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
8092
|
+
return {};
|
|
8251
8093
|
}
|
|
8094
|
+
const record = value;
|
|
8095
|
+
const nestedDoc = record.doc;
|
|
8096
|
+
if (nestedDoc && typeof nestedDoc === "object" && !Array.isArray(nestedDoc)) {
|
|
8097
|
+
return nestedDoc;
|
|
8098
|
+
}
|
|
8099
|
+
return record;
|
|
8252
8100
|
};
|
|
8253
8101
|
var toEditorState = (doc) => {
|
|
8254
8102
|
const emails = doc.emails && typeof doc.emails === "object" ? doc.emails : null;
|
|
@@ -8264,7 +8112,7 @@ var toEditorState = (doc) => {
|
|
|
8264
8112
|
sendAdmin: emails?.sendAdmin !== false,
|
|
8265
8113
|
sendConfirmation: emails?.sendConfirmation !== false,
|
|
8266
8114
|
slug: getNonEmptyText(doc.slug),
|
|
8267
|
-
|
|
8115
|
+
steps: normalizeSteps(doc.steps),
|
|
8268
8116
|
submitLabel: getNonEmptyText(doc.submitLabel, "Submit"),
|
|
8269
8117
|
successMessage: getNonEmptyText(doc.successMessage),
|
|
8270
8118
|
title: getNonEmptyText(doc.title, "Untitled Form")
|
|
@@ -8275,25 +8123,72 @@ var checkboxLabelStyle = {
|
|
|
8275
8123
|
display: "flex",
|
|
8276
8124
|
gap: "0.6rem"
|
|
8277
8125
|
};
|
|
8278
|
-
var codeStyle = {
|
|
8279
|
-
background: "color-mix(in srgb, var(--orion-admin-card-bg) 82%, black)",
|
|
8280
|
-
border: "1px solid var(--orion-admin-card-border)",
|
|
8281
|
-
borderRadius: "var(--orion-admin-radius-sm)",
|
|
8282
|
-
color: "var(--orion-admin-text)",
|
|
8283
|
-
fontFamily: "ui-monospace, SFMono-Regular, SFMono-Regular, Menlo, monospace",
|
|
8284
|
-
fontSize: "0.86rem",
|
|
8285
|
-
lineHeight: 1.55,
|
|
8286
|
-
margin: 0,
|
|
8287
|
-
maxHeight: "28rem",
|
|
8288
|
-
overflow: "auto",
|
|
8289
|
-
padding: "0.9rem",
|
|
8290
|
-
whiteSpace: "pre-wrap"
|
|
8291
|
-
};
|
|
8292
8126
|
var sectionGridStyle = {
|
|
8293
8127
|
display: "grid",
|
|
8294
8128
|
gap: "1rem",
|
|
8295
8129
|
gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))"
|
|
8296
8130
|
};
|
|
8131
|
+
var fieldTypeOptions = [
|
|
8132
|
+
"text",
|
|
8133
|
+
"textarea",
|
|
8134
|
+
"email",
|
|
8135
|
+
"phone",
|
|
8136
|
+
"url",
|
|
8137
|
+
"select",
|
|
8138
|
+
"radio",
|
|
8139
|
+
"checkbox",
|
|
8140
|
+
"checkbox-group",
|
|
8141
|
+
"date",
|
|
8142
|
+
"file"
|
|
8143
|
+
];
|
|
8144
|
+
var getFields = (step) => Array.isArray(step.fields) ? step.fields.map(
|
|
8145
|
+
(field) => field && typeof field === "object" && !Array.isArray(field) ? field : {}
|
|
8146
|
+
) : [];
|
|
8147
|
+
var toOptionsText = (value) => Array.isArray(value) ? value.map((entry) => {
|
|
8148
|
+
if (entry && typeof entry === "object" && !Array.isArray(entry)) {
|
|
8149
|
+
const record = entry;
|
|
8150
|
+
const label = typeof record.label === "string" ? record.label : "";
|
|
8151
|
+
const optionValue = typeof record.value === "string" ? record.value : label;
|
|
8152
|
+
return label && optionValue && label !== optionValue ? `${label} | ${optionValue}` : label || optionValue;
|
|
8153
|
+
}
|
|
8154
|
+
return typeof entry === "string" ? entry : "";
|
|
8155
|
+
}).filter(Boolean).join("\n") : "";
|
|
8156
|
+
var fromOptionsText = (value) => value.split("\n").map((entry) => entry.trim()).filter(Boolean).map((entry) => {
|
|
8157
|
+
const [label, optionValue] = entry.split("|").map((part) => part.trim());
|
|
8158
|
+
return {
|
|
8159
|
+
label,
|
|
8160
|
+
value: optionValue || label
|
|
8161
|
+
};
|
|
8162
|
+
});
|
|
8163
|
+
var slugifyFieldName = (value) => value.trim().replace(/[^a-z0-9]+/gi, " ").trim().replace(/\s+([a-z0-9])/gi, (_, char) => char.toUpperCase()).replace(/^./, (char) => char.toLowerCase());
|
|
8164
|
+
var blankField = () => ({
|
|
8165
|
+
label: "New field",
|
|
8166
|
+
name: "newField",
|
|
8167
|
+
required: false,
|
|
8168
|
+
type: "text"
|
|
8169
|
+
});
|
|
8170
|
+
var blankStep = () => ({
|
|
8171
|
+
fields: [blankField()],
|
|
8172
|
+
title: "New step"
|
|
8173
|
+
});
|
|
8174
|
+
var getStepTitle = (step, stepIndex) => getNonEmptyText(step.title, `Step ${stepIndex + 1}`);
|
|
8175
|
+
var getFieldLabel = (field, fieldIndex) => getNonEmptyText(field.label, getNonEmptyText(field.name, `Field ${fieldIndex + 1}`));
|
|
8176
|
+
var formatFieldTypeLabel = (value) => getNonEmptyText(value, "text").replace(/-/g, " ").replace(/^./, (char) => char.toUpperCase());
|
|
8177
|
+
var getStepDestination = (stepIndex, stepCount) => {
|
|
8178
|
+
if (stepIndex < stepCount - 1) {
|
|
8179
|
+
return `Next: Step ${stepIndex + 2}`;
|
|
8180
|
+
}
|
|
8181
|
+
return "Then: Submit form";
|
|
8182
|
+
};
|
|
8183
|
+
var moveItem = (items, fromIndex, toIndex) => {
|
|
8184
|
+
if (toIndex < 0 || toIndex >= items.length) {
|
|
8185
|
+
return items;
|
|
8186
|
+
}
|
|
8187
|
+
const nextItems = [...items];
|
|
8188
|
+
const [item] = nextItems.splice(fromIndex, 1);
|
|
8189
|
+
nextItems.splice(toIndex, 0, item);
|
|
8190
|
+
return nextItems;
|
|
8191
|
+
};
|
|
8297
8192
|
function getFormIDFromPathname(pathname) {
|
|
8298
8193
|
const marker = "/forms/";
|
|
8299
8194
|
const raw = getIDFromPathname(pathname, marker);
|
|
@@ -8356,7 +8251,7 @@ function AdminStudioFormDetailView(props) {
|
|
|
8356
8251
|
if (!submissionsResponse.ok) {
|
|
8357
8252
|
throw new Error(`Failed to load submissions (${submissionsResponse.status}).`);
|
|
8358
8253
|
}
|
|
8359
|
-
const nextDoc = await formResponse.json();
|
|
8254
|
+
const nextDoc = normalizeFormResponse(await formResponse.json());
|
|
8360
8255
|
const submissionsPayload = await submissionsResponse.json();
|
|
8361
8256
|
const nextSubmissions = Array.isArray(submissionsPayload.docs) ? submissionsPayload.docs : [];
|
|
8362
8257
|
setDoc(nextDoc);
|
|
@@ -8386,10 +8281,6 @@ function AdminStudioFormDetailView(props) {
|
|
|
8386
8281
|
setError(null);
|
|
8387
8282
|
setSavedMessage(null);
|
|
8388
8283
|
try {
|
|
8389
|
-
const parsedSteps = JSON.parse(editorState.stepsText);
|
|
8390
|
-
if (!Array.isArray(parsedSteps)) {
|
|
8391
|
-
throw new Error("Structure JSON must be an array of steps.");
|
|
8392
|
-
}
|
|
8393
8284
|
const payload = {
|
|
8394
8285
|
emails: {
|
|
8395
8286
|
adminRecipients: editorState.adminRecipientsText.split("\n").map((value) => value.trim()).filter(Boolean).map((email) => ({ email })),
|
|
@@ -8401,7 +8292,7 @@ function AdminStudioFormDetailView(props) {
|
|
|
8401
8292
|
sendConfirmation: editorState.sendConfirmation
|
|
8402
8293
|
},
|
|
8403
8294
|
slug: editorState.slug.trim(),
|
|
8404
|
-
steps:
|
|
8295
|
+
steps: editorState.steps,
|
|
8405
8296
|
submitLabel: editorState.submitLabel.trim(),
|
|
8406
8297
|
successMessage: editorState.successMessage,
|
|
8407
8298
|
title: editorState.title.trim()
|
|
@@ -8417,7 +8308,7 @@ function AdminStudioFormDetailView(props) {
|
|
|
8417
8308
|
if (!response.ok) {
|
|
8418
8309
|
throw new Error(`Failed to save form (${response.status}).`);
|
|
8419
8310
|
}
|
|
8420
|
-
const nextDoc = await response.json();
|
|
8311
|
+
const nextDoc = normalizeFormResponse(await response.json());
|
|
8421
8312
|
setDoc(nextDoc);
|
|
8422
8313
|
setEditorState(toEditorState(nextDoc));
|
|
8423
8314
|
setSavedMessage("Saved.");
|
|
@@ -8447,8 +8338,52 @@ function AdminStudioFormDetailView(props) {
|
|
|
8447
8338
|
const toneStyle = getFormToneStyle2(slug, title || formID || "form");
|
|
8448
8339
|
const fieldLabels = doc ? buildFieldLabelMap2(doc) : /* @__PURE__ */ new Map();
|
|
8449
8340
|
const latestSubmission = submissions[0];
|
|
8450
|
-
const stepCount =
|
|
8451
|
-
const fieldCount = doc ? getFieldCount2(doc) : 0;
|
|
8341
|
+
const stepCount = editorState?.steps.length || 0;
|
|
8342
|
+
const fieldCount = editorState ? editorState.steps.reduce((count, step) => count + getFields(step).length, 0) : doc ? getFieldCount2(doc) : 0;
|
|
8343
|
+
const updateStep = (stepIndex, patch) => {
|
|
8344
|
+
setEditorState(
|
|
8345
|
+
(current) => current ? {
|
|
8346
|
+
...current,
|
|
8347
|
+
steps: current.steps.map(
|
|
8348
|
+
(step, index) => index === stepIndex ? { ...step, ...patch } : step
|
|
8349
|
+
)
|
|
8350
|
+
} : current
|
|
8351
|
+
);
|
|
8352
|
+
};
|
|
8353
|
+
const updateField = (stepIndex, fieldIndex, patch) => {
|
|
8354
|
+
setEditorState((current) => {
|
|
8355
|
+
if (!current) return current;
|
|
8356
|
+
return {
|
|
8357
|
+
...current,
|
|
8358
|
+
steps: current.steps.map((step, index) => {
|
|
8359
|
+
if (index !== stepIndex) return step;
|
|
8360
|
+
const fields = getFields(step).map(
|
|
8361
|
+
(field, currentFieldIndex) => currentFieldIndex === fieldIndex ? { ...field, ...patch } : field
|
|
8362
|
+
);
|
|
8363
|
+
return { ...step, fields };
|
|
8364
|
+
})
|
|
8365
|
+
};
|
|
8366
|
+
});
|
|
8367
|
+
};
|
|
8368
|
+
const moveStep = (stepIndex, direction) => {
|
|
8369
|
+
setEditorState(
|
|
8370
|
+
(current) => current ? {
|
|
8371
|
+
...current,
|
|
8372
|
+
steps: moveItem(current.steps, stepIndex, stepIndex + direction)
|
|
8373
|
+
} : current
|
|
8374
|
+
);
|
|
8375
|
+
};
|
|
8376
|
+
const moveField = (stepIndex, fieldIndex, direction) => {
|
|
8377
|
+
setEditorState((current) => {
|
|
8378
|
+
if (!current) return current;
|
|
8379
|
+
return {
|
|
8380
|
+
...current,
|
|
8381
|
+
steps: current.steps.map(
|
|
8382
|
+
(step, index) => index === stepIndex ? { ...step, fields: moveItem(getFields(step), fieldIndex, fieldIndex + direction) } : step
|
|
8383
|
+
)
|
|
8384
|
+
};
|
|
8385
|
+
});
|
|
8386
|
+
};
|
|
8452
8387
|
return /* @__PURE__ */ (0, import_jsx_runtime41.jsx)(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)(
|
|
8453
8388
|
AdminPage,
|
|
8454
8389
|
{
|
|
@@ -8527,10 +8462,9 @@ function AdminStudioFormDetailView(props) {
|
|
|
8527
8462
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { style: { display: "grid", gap: "1rem" }, children: [
|
|
8528
8463
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-card", children: [
|
|
8529
8464
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("strong", { children: "Step preview" }),
|
|
8530
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: "Review the
|
|
8531
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { style: { display: "grid", gap: "0.85rem", marginTop: "1rem" }, children:
|
|
8532
|
-
const
|
|
8533
|
-
const fields = Array.isArray(record?.fields) ? record.fields : [];
|
|
8465
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: "Review the public workflow as visitors will move through it." }),
|
|
8466
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { style: { display: "grid", gap: "0.85rem", marginTop: "1rem" }, children: editorState.steps.length > 0 ? editorState.steps.map((record, stepIndex) => {
|
|
8467
|
+
const fields = getFields(record);
|
|
8534
8468
|
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-form", children: [
|
|
8535
8469
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { children: [
|
|
8536
8470
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("strong", { children: [
|
|
@@ -8582,7 +8516,7 @@ function AdminStudioFormDetailView(props) {
|
|
|
8582
8516
|
] }, `step-${stepIndex}`);
|
|
8583
8517
|
}) : /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-empty-state", children: [
|
|
8584
8518
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("strong", { children: "No steps configured" }),
|
|
8585
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: "Add at least one step in
|
|
8519
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: "Add at least one step in Form settings to publish this form." })
|
|
8586
8520
|
] }) })
|
|
8587
8521
|
] }),
|
|
8588
8522
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-card", children: [
|
|
@@ -8764,32 +8698,296 @@ function AdminStudioFormDetailView(props) {
|
|
|
8764
8698
|
] })
|
|
8765
8699
|
] })
|
|
8766
8700
|
] }),
|
|
8767
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("
|
|
8768
|
-
"
|
|
8769
|
-
|
|
8770
|
-
|
|
8771
|
-
|
|
8772
|
-
|
|
8773
|
-
|
|
8774
|
-
|
|
8775
|
-
|
|
8776
|
-
|
|
8777
|
-
|
|
8778
|
-
|
|
8779
|
-
|
|
8780
|
-
|
|
8781
|
-
|
|
8782
|
-
|
|
8783
|
-
|
|
8701
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-card orion-admin-workflow-editor", children: [
|
|
8702
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-workflow-editor-header", children: [
|
|
8703
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { children: [
|
|
8704
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("strong", { children: "Form steps" }),
|
|
8705
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: "Build the visitor flow, then edit each step's fields below." })
|
|
8706
|
+
] }),
|
|
8707
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8708
|
+
"button",
|
|
8709
|
+
{
|
|
8710
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
8711
|
+
onClick: () => setEditorState(
|
|
8712
|
+
(current) => current ? { ...current, steps: [...current.steps, blankStep()] } : current
|
|
8713
|
+
),
|
|
8714
|
+
type: "button",
|
|
8715
|
+
children: "Add step"
|
|
8716
|
+
}
|
|
8717
|
+
)
|
|
8718
|
+
] }),
|
|
8719
|
+
editorState.steps.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-empty-state", children: [
|
|
8720
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("strong", { children: "No steps configured" }),
|
|
8721
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: "Add a first step to start building the public form flow." })
|
|
8722
|
+
] }) : null,
|
|
8723
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "orion-admin-step-editor-list", children: editorState.steps.map((step, stepIndex) => {
|
|
8724
|
+
const fields = getFields(step);
|
|
8725
|
+
const requiredCount = fields.filter((field) => field.required === true).length;
|
|
8726
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("details", { className: "orion-admin-step-editor", open: true, children: [
|
|
8727
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("summary", { className: "orion-admin-step-editor-summary", children: [
|
|
8728
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "orion-admin-workflow-node-number", children: stepIndex + 1 }),
|
|
8729
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "orion-admin-step-editor-title", children: getStepTitle(step, stepIndex) }),
|
|
8730
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { className: "orion-admin-step-editor-meta", children: [
|
|
8731
|
+
fields.length,
|
|
8732
|
+
" field",
|
|
8733
|
+
fields.length === 1 ? "" : "s",
|
|
8734
|
+
requiredCount > 0 ? ` \xB7 ${requiredCount} required` : ""
|
|
8735
|
+
] }),
|
|
8736
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "orion-admin-workflow-node-destination", children: getStepDestination(stepIndex, editorState.steps.length) })
|
|
8737
|
+
] }),
|
|
8738
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-step-editor-body", children: [
|
|
8739
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-step-editor-actions", children: [
|
|
8740
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8741
|
+
"button",
|
|
8742
|
+
{
|
|
8743
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
8744
|
+
disabled: stepIndex === 0,
|
|
8745
|
+
onClick: () => moveStep(stepIndex, -1),
|
|
8746
|
+
type: "button",
|
|
8747
|
+
children: "Move up"
|
|
8748
|
+
}
|
|
8749
|
+
),
|
|
8750
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8751
|
+
"button",
|
|
8752
|
+
{
|
|
8753
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
8754
|
+
disabled: stepIndex === editorState.steps.length - 1,
|
|
8755
|
+
onClick: () => moveStep(stepIndex, 1),
|
|
8756
|
+
type: "button",
|
|
8757
|
+
children: "Move down"
|
|
8758
|
+
}
|
|
8759
|
+
),
|
|
8760
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8761
|
+
"button",
|
|
8762
|
+
{
|
|
8763
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
8764
|
+
onClick: () => setEditorState(
|
|
8765
|
+
(current) => current ? {
|
|
8766
|
+
...current,
|
|
8767
|
+
steps: current.steps.filter((_, index) => index !== stepIndex)
|
|
8768
|
+
} : current
|
|
8769
|
+
),
|
|
8770
|
+
type: "button",
|
|
8771
|
+
children: "Remove step"
|
|
8772
|
+
}
|
|
8773
|
+
)
|
|
8774
|
+
] }),
|
|
8775
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-step-settings-grid", children: [
|
|
8776
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { children: [
|
|
8777
|
+
"Step title",
|
|
8778
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8779
|
+
"input",
|
|
8780
|
+
{
|
|
8781
|
+
onChange: (event) => updateStep(stepIndex, { title: event.target.value }),
|
|
8782
|
+
type: "text",
|
|
8783
|
+
value: getNonEmptyText(step.title)
|
|
8784
|
+
}
|
|
8785
|
+
)
|
|
8786
|
+
] }),
|
|
8787
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { children: [
|
|
8788
|
+
"Next button label",
|
|
8789
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8790
|
+
"input",
|
|
8791
|
+
{
|
|
8792
|
+
onChange: (event) => updateStep(stepIndex, { nextLabel: event.target.value }),
|
|
8793
|
+
placeholder: "Next",
|
|
8794
|
+
type: "text",
|
|
8795
|
+
value: getNonEmptyText(step.nextLabel)
|
|
8796
|
+
}
|
|
8797
|
+
)
|
|
8798
|
+
] })
|
|
8799
|
+
] }),
|
|
8800
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { children: [
|
|
8801
|
+
"Step intro text",
|
|
8802
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8803
|
+
"textarea",
|
|
8804
|
+
{
|
|
8805
|
+
onChange: (event) => updateStep(stepIndex, { subtitle: event.target.value }),
|
|
8806
|
+
rows: 3,
|
|
8807
|
+
value: getNonEmptyText(step.subtitle)
|
|
8808
|
+
}
|
|
8809
|
+
)
|
|
8810
|
+
] }),
|
|
8811
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { style: checkboxLabelStyle, children: [
|
|
8812
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8813
|
+
"input",
|
|
8814
|
+
{
|
|
8815
|
+
checked: step.allowSkip === true,
|
|
8816
|
+
onChange: (event) => updateStep(stepIndex, { allowSkip: event.target.checked }),
|
|
8817
|
+
type: "checkbox"
|
|
8818
|
+
}
|
|
8819
|
+
),
|
|
8820
|
+
"Allow visitors to skip this step"
|
|
8821
|
+
] }),
|
|
8822
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-field-list-header", children: [
|
|
8823
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { children: [
|
|
8824
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("strong", { children: "Fields in this step" }),
|
|
8825
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: "These appear together before the visitor moves to the next step." })
|
|
8826
|
+
] }),
|
|
8827
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8828
|
+
"button",
|
|
8829
|
+
{
|
|
8830
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
8831
|
+
onClick: () => setEditorState(
|
|
8832
|
+
(current) => current ? {
|
|
8833
|
+
...current,
|
|
8834
|
+
steps: current.steps.map(
|
|
8835
|
+
(currentStep, index) => index === stepIndex ? { ...currentStep, fields: [...getFields(currentStep), blankField()] } : currentStep
|
|
8836
|
+
)
|
|
8837
|
+
} : current
|
|
8838
|
+
),
|
|
8839
|
+
type: "button",
|
|
8840
|
+
children: "Add field"
|
|
8841
|
+
}
|
|
8842
|
+
)
|
|
8843
|
+
] }),
|
|
8844
|
+
fields.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("div", { className: "orion-admin-field-editor-list", children: fields.map((field, fieldIndex) => {
|
|
8845
|
+
const label = getFieldLabel(field, fieldIndex);
|
|
8846
|
+
const fieldType = getNonEmptyText(field.type, "text");
|
|
8847
|
+
return /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("details", { className: "orion-admin-field-editor", children: [
|
|
8848
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("summary", { className: "orion-admin-field-editor-summary", children: [
|
|
8849
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "orion-admin-field-order", children: fieldIndex + 1 }),
|
|
8850
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { className: "orion-admin-field-editor-title", children: label }),
|
|
8851
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("span", { className: "orion-admin-field-editor-meta", children: [
|
|
8852
|
+
formatFieldTypeLabel(fieldType),
|
|
8853
|
+
field.required === true ? " \xB7 Required" : ""
|
|
8854
|
+
] })
|
|
8855
|
+
] }),
|
|
8856
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-field-editor-body", children: [
|
|
8857
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-step-editor-actions", children: [
|
|
8858
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8859
|
+
"button",
|
|
8860
|
+
{
|
|
8861
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
8862
|
+
disabled: fieldIndex === 0,
|
|
8863
|
+
onClick: () => moveField(stepIndex, fieldIndex, -1),
|
|
8864
|
+
type: "button",
|
|
8865
|
+
children: "Move up"
|
|
8866
|
+
}
|
|
8867
|
+
),
|
|
8868
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8869
|
+
"button",
|
|
8870
|
+
{
|
|
8871
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
8872
|
+
disabled: fieldIndex === fields.length - 1,
|
|
8873
|
+
onClick: () => moveField(stepIndex, fieldIndex, 1),
|
|
8874
|
+
type: "button",
|
|
8875
|
+
children: "Move down"
|
|
8876
|
+
}
|
|
8877
|
+
),
|
|
8878
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8879
|
+
"button",
|
|
8880
|
+
{
|
|
8881
|
+
className: "orion-admin-action-button orion-admin-action-button--ghost",
|
|
8882
|
+
onClick: () => setEditorState((current) => {
|
|
8883
|
+
if (!current) return current;
|
|
8884
|
+
return {
|
|
8885
|
+
...current,
|
|
8886
|
+
steps: current.steps.map(
|
|
8887
|
+
(currentStep, index) => index === stepIndex ? {
|
|
8888
|
+
...currentStep,
|
|
8889
|
+
fields: getFields(currentStep).filter(
|
|
8890
|
+
(_, currentFieldIndex) => currentFieldIndex !== fieldIndex
|
|
8891
|
+
)
|
|
8892
|
+
} : currentStep
|
|
8893
|
+
)
|
|
8894
|
+
};
|
|
8895
|
+
}),
|
|
8896
|
+
type: "button",
|
|
8897
|
+
children: "Remove field"
|
|
8898
|
+
}
|
|
8899
|
+
)
|
|
8900
|
+
] }),
|
|
8901
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-step-settings-grid", children: [
|
|
8902
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { children: [
|
|
8903
|
+
"Field label",
|
|
8904
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8905
|
+
"input",
|
|
8906
|
+
{
|
|
8907
|
+
onChange: (event) => {
|
|
8908
|
+
const nextLabel = event.target.value;
|
|
8909
|
+
const currentName = getNonEmptyText(field.name);
|
|
8910
|
+
updateField(stepIndex, fieldIndex, {
|
|
8911
|
+
label: nextLabel,
|
|
8912
|
+
name: currentName || slugifyFieldName(nextLabel)
|
|
8913
|
+
});
|
|
8914
|
+
},
|
|
8915
|
+
type: "text",
|
|
8916
|
+
value: label
|
|
8917
|
+
}
|
|
8918
|
+
)
|
|
8919
|
+
] }),
|
|
8920
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { children: [
|
|
8921
|
+
"Field type",
|
|
8922
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8923
|
+
"select",
|
|
8924
|
+
{
|
|
8925
|
+
onChange: (event) => updateField(stepIndex, fieldIndex, { type: event.target.value }),
|
|
8926
|
+
value: fieldType,
|
|
8927
|
+
children: fieldTypeOptions.map((option) => /* @__PURE__ */ (0, import_jsx_runtime41.jsx)("option", { value: option, children: formatFieldTypeLabel(option) }, option))
|
|
8928
|
+
}
|
|
8929
|
+
)
|
|
8930
|
+
] })
|
|
8931
|
+
] }),
|
|
8932
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { children: [
|
|
8933
|
+
"Field key",
|
|
8934
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8935
|
+
"input",
|
|
8936
|
+
{
|
|
8937
|
+
onChange: (event) => updateField(stepIndex, fieldIndex, { name: event.target.value }),
|
|
8938
|
+
type: "text",
|
|
8939
|
+
value: getNonEmptyText(field.name)
|
|
8940
|
+
}
|
|
8941
|
+
)
|
|
8942
|
+
] }),
|
|
8943
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { style: checkboxLabelStyle, children: [
|
|
8944
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8945
|
+
"input",
|
|
8946
|
+
{
|
|
8947
|
+
checked: field.required === true,
|
|
8948
|
+
onChange: (event) => updateField(stepIndex, fieldIndex, { required: event.target.checked }),
|
|
8949
|
+
type: "checkbox"
|
|
8950
|
+
}
|
|
8951
|
+
),
|
|
8952
|
+
"Required"
|
|
8953
|
+
] }),
|
|
8954
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { children: [
|
|
8955
|
+
"Help text",
|
|
8956
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8957
|
+
"textarea",
|
|
8958
|
+
{
|
|
8959
|
+
onChange: (event) => updateField(stepIndex, fieldIndex, { helpText: event.target.value }),
|
|
8960
|
+
rows: 2,
|
|
8961
|
+
value: getNonEmptyText(field.helpText)
|
|
8962
|
+
}
|
|
8963
|
+
)
|
|
8964
|
+
] }),
|
|
8965
|
+
["select", "radio", "checkbox-group"].includes(fieldType) ? /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("label", { children: [
|
|
8966
|
+
"Options",
|
|
8967
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)(
|
|
8968
|
+
"textarea",
|
|
8969
|
+
{
|
|
8970
|
+
onChange: (event) => updateField(stepIndex, fieldIndex, {
|
|
8971
|
+
options: fromOptionsText(event.target.value)
|
|
8972
|
+
}),
|
|
8973
|
+
placeholder: "Option one\nOption two",
|
|
8974
|
+
rows: 4,
|
|
8975
|
+
value: toOptionsText(field.options)
|
|
8976
|
+
}
|
|
8977
|
+
)
|
|
8978
|
+
] }) : null
|
|
8979
|
+
] })
|
|
8980
|
+
] }, `edit-field-${stepIndex}-${fieldIndex}`);
|
|
8981
|
+
}) }) : /* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-empty-state", children: [
|
|
8982
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("strong", { children: "No fields in this step" }),
|
|
8983
|
+
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: "Add a field so visitors have something to answer here." })
|
|
8984
|
+
] })
|
|
8985
|
+
] })
|
|
8986
|
+
] }, `edit-step-${stepIndex}`);
|
|
8987
|
+
}) })
|
|
8784
8988
|
] }),
|
|
8785
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("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." }),
|
|
8786
8989
|
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("button", { disabled: saving, type: "submit", children: saving ? "Saving..." : "Save Form" })
|
|
8787
8990
|
] })
|
|
8788
|
-
] }),
|
|
8789
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsxs)("div", { className: "orion-admin-card", children: [
|
|
8790
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("strong", { children: "Current structure payload" }),
|
|
8791
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("span", { children: "Reference snapshot of the form steps that will be written back on save." }),
|
|
8792
|
-
/* @__PURE__ */ (0, import_jsx_runtime41.jsx)("pre", { style: { ...codeStyle, marginTop: "1rem" }, children: editorState.stepsText })
|
|
8793
8991
|
] })
|
|
8794
8992
|
] }) : null
|
|
8795
8993
|
]
|
|
@@ -8801,25 +8999,17 @@ function AdminStudioFormDetailView(props) {
|
|
|
8801
8999
|
var import_link5 = __toESM(require("next/link"));
|
|
8802
9000
|
var import_react33 = require("react");
|
|
8803
9001
|
var import_jsx_runtime42 = require("react/jsx-runtime");
|
|
8804
|
-
var codeStyle2 = {
|
|
8805
|
-
background: "color-mix(in srgb, var(--orion-admin-card-bg) 82%, black)",
|
|
8806
|
-
border: "1px solid var(--orion-admin-card-border)",
|
|
8807
|
-
borderRadius: "var(--orion-admin-radius-sm)",
|
|
8808
|
-
color: "var(--orion-admin-text)",
|
|
8809
|
-
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
8810
|
-
fontSize: "0.86rem",
|
|
8811
|
-
lineHeight: 1.55,
|
|
8812
|
-
margin: 0,
|
|
8813
|
-
maxHeight: "28rem",
|
|
8814
|
-
overflow: "auto",
|
|
8815
|
-
padding: "0.9rem",
|
|
8816
|
-
whiteSpace: "pre-wrap"
|
|
8817
|
-
};
|
|
8818
9002
|
var sectionGridStyle2 = {
|
|
8819
9003
|
display: "grid",
|
|
8820
9004
|
gap: "1rem",
|
|
8821
9005
|
gridTemplateColumns: "repeat(auto-fit, minmax(320px, 1fr))"
|
|
8822
9006
|
};
|
|
9007
|
+
var nestedListStyle = {
|
|
9008
|
+
display: "grid",
|
|
9009
|
+
gap: "0.45rem",
|
|
9010
|
+
margin: 0,
|
|
9011
|
+
padding: 0
|
|
9012
|
+
};
|
|
8823
9013
|
var renderFieldValue = (value) => {
|
|
8824
9014
|
if (value === null || value === void 0) {
|
|
8825
9015
|
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "orion-admin-list-meta", children: "No value" });
|
|
@@ -8833,7 +9023,26 @@ var renderFieldValue = (value) => {
|
|
|
8833
9023
|
if (typeof value === "string") {
|
|
8834
9024
|
return value.trim().length > 0 ? value : /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "orion-admin-list-meta", children: "No value" });
|
|
8835
9025
|
}
|
|
8836
|
-
|
|
9026
|
+
if (Array.isArray(value)) {
|
|
9027
|
+
const entries = value.filter((entry) => entry !== null && entry !== void 0 && entry !== "");
|
|
9028
|
+
if (entries.length === 0) {
|
|
9029
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "orion-admin-list-meta", children: "No value" });
|
|
9030
|
+
}
|
|
9031
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("ul", { style: nestedListStyle, children: entries.map((entry, index) => /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("li", { children: renderFieldValue(entry) }, index)) });
|
|
9032
|
+
}
|
|
9033
|
+
if (typeof value === "object") {
|
|
9034
|
+
const entries = Object.entries(value).filter(
|
|
9035
|
+
([, entryValue]) => entryValue !== null && entryValue !== void 0 && entryValue !== ""
|
|
9036
|
+
);
|
|
9037
|
+
if (entries.length === 0) {
|
|
9038
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "orion-admin-list-meta", children: "No value" });
|
|
9039
|
+
}
|
|
9040
|
+
return /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { style: { display: "grid", gap: "0.65rem" }, children: entries.map(([key, entryValue]) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "orion-admin-meta-row", children: [
|
|
9041
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "orion-admin-meta-label", children: humanizeKey2(key) }),
|
|
9042
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "orion-admin-meta-value", children: renderFieldValue(entryValue) })
|
|
9043
|
+
] }, key)) });
|
|
9044
|
+
}
|
|
9045
|
+
return String(value);
|
|
8837
9046
|
};
|
|
8838
9047
|
function getSubmissionIDFromPathname(pathname) {
|
|
8839
9048
|
return getIDFromPathname(pathname, "/forms/submissions/");
|
|
@@ -8985,31 +9194,24 @@ function AdminStudioFormSubmissionView(props) {
|
|
|
8985
9194
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("article", { className: "orion-admin-overview-stat", children: [
|
|
8986
9195
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { className: "orion-admin-overview-stat-label", children: "Highlighted answers" }),
|
|
8987
9196
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("strong", { children: previewFields.length }),
|
|
8988
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { children: "Readable answer previews
|
|
9197
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("p", { children: "Readable answer previews from this response." })
|
|
8989
9198
|
] })
|
|
8990
9199
|
] }),
|
|
8991
9200
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { style: sectionGridStyle2, children: [
|
|
8992
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.
|
|
8993
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.
|
|
8994
|
-
|
|
8995
|
-
|
|
8996
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.
|
|
8997
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.
|
|
8998
|
-
|
|
8999
|
-
|
|
9000
|
-
|
|
9001
|
-
|
|
9002
|
-
|
|
9003
|
-
|
|
9004
|
-
|
|
9005
|
-
|
|
9006
|
-
] }),
|
|
9007
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "orion-admin-card", children: [
|
|
9008
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("strong", { children: "Raw payload" }),
|
|
9009
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "Verbatim submission data for troubleshooting or export checks." }),
|
|
9010
|
-
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("pre", { style: { ...codeStyle2, marginTop: "1rem" }, children: JSON.stringify(doc.data ?? {}, null, 2) })
|
|
9011
|
-
] })
|
|
9012
|
-
] }),
|
|
9201
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { style: { display: "grid", gap: "1rem" }, children: /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "orion-admin-card", children: [
|
|
9202
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("strong", { children: "Response details" }),
|
|
9203
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "Formatted answers using the current form field labels when available." }),
|
|
9204
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { style: { display: "grid", gap: "0.85rem", marginTop: "1rem" }, children: answerEntries.length > 0 ? answerEntries.map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "orion-admin-form", children: [
|
|
9205
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { children: [
|
|
9206
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("strong", { children: fieldLabels.get(key) || humanizeKey2(key) }),
|
|
9207
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { className: "orion-admin-list-meta", children: key })
|
|
9208
|
+
] }),
|
|
9209
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { children: renderFieldValue(value) })
|
|
9210
|
+
] }, key)) : /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "orion-admin-empty-state", children: [
|
|
9211
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("strong", { children: "No answers available" }),
|
|
9212
|
+
/* @__PURE__ */ (0, import_jsx_runtime42.jsx)("span", { children: "This submission does not contain visible response details." })
|
|
9213
|
+
] }) })
|
|
9214
|
+
] }) }),
|
|
9013
9215
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { style: { display: "grid", gap: "1rem" }, children: [
|
|
9014
9216
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "orion-admin-card orion-admin-meta-table", children: [
|
|
9015
9217
|
/* @__PURE__ */ (0, import_jsx_runtime42.jsxs)("div", { className: "orion-admin-meta-row", children: [
|
|
@@ -9299,7 +9501,7 @@ var import_react35 = require("react");
|
|
|
9299
9501
|
var import_ui12 = require("@payloadcms/ui");
|
|
9300
9502
|
var import_jsx_runtime44 = require("react/jsx-runtime");
|
|
9301
9503
|
var userRoles = ["admin", "developer", "editor", "client"];
|
|
9302
|
-
var
|
|
9504
|
+
var hasAdminAccess3 = (user) => {
|
|
9303
9505
|
if (!user || typeof user !== "object") return false;
|
|
9304
9506
|
const role = user.role;
|
|
9305
9507
|
return typeof role === "string" && (role === "admin" || role === "developer");
|
|
@@ -9314,7 +9516,7 @@ function AdminStudioToolsView(props) {
|
|
|
9314
9516
|
const [savedMessage, setSavedMessage] = (0, import_react35.useState)(null);
|
|
9315
9517
|
const [createSubmitting, setCreateSubmitting] = (0, import_react35.useState)(false);
|
|
9316
9518
|
const [updatingUserID, setUpdatingUserID] = (0, import_react35.useState)(null);
|
|
9317
|
-
if (!
|
|
9519
|
+
if (!hasAdminAccess3(user)) {
|
|
9318
9520
|
return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(StudioSectionLayout, { navProps: props, children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
|
|
9319
9521
|
AdminPage,
|
|
9320
9522
|
{
|