@orion-studios/payload-studio 0.5.0-beta.97 → 0.5.0-beta.99
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/README.md +1 -1
- package/dist/admin/client.js +164 -43
- package/dist/admin/client.mjs +164 -43
- package/dist/admin/index.d.mts +2 -2
- package/dist/admin/index.d.ts +2 -2
- package/dist/admin/index.js +147 -11
- package/dist/admin/index.mjs +2 -2
- package/dist/{chunk-YJPNN3O3.mjs → chunk-74XFAVXU.mjs} +124 -4
- package/dist/{chunk-CKEUQCDC.mjs → chunk-XHWQJUX5.mjs} +1 -1
- package/dist/{chunk-ZFJJQ4YK.mjs → chunk-ZTXJG4K5.mjs} +24 -8
- package/dist/{index-D8RxRIh3.d.ts → index-BnoqmQDP.d.mts} +44 -3
- package/dist/{index-CodQ-io_.d.mts → index-CTpik6fR.d.ts} +44 -3
- package/dist/{index-CW02UDzl.d.mts → index-D8BNfUJb.d.mts} +1 -1
- package/dist/{index-BBUjXVqQ.d.ts → index-DD_E2UfJ.d.ts} +1 -1
- package/dist/index.d.mts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +166 -30
- package/dist/index.mjs +3 -3
- package/dist/nextjs/index.d.mts +2 -2
- package/dist/nextjs/index.d.ts +2 -2
- package/dist/nextjs/index.js +24 -8
- package/dist/nextjs/index.mjs +2 -2
- package/dist/{socialMedia-CXaTwojP.d.mts → socialMedia-C05Iy-SV.d.mts} +2 -2
- package/dist/{socialMedia-CXaTwojP.d.ts → socialMedia-C05Iy-SV.d.ts} +2 -2
- package/package.json +10 -2
package/README.md
CHANGED
|
@@ -69,7 +69,7 @@ export const globals = [
|
|
|
69
69
|
|
|
70
70
|
- Major platforms (Facebook, Instagram, X, LinkedIn, YouTube, TikTok, Pinterest, Snapchat)
|
|
71
71
|
- URL field for each platform
|
|
72
|
-
-
|
|
72
|
+
- Four icon choices per platform (`Simple Icons`, `Font Awesome Brands`, `Tabler Brands`, `Remix Icons`)
|
|
73
73
|
|
|
74
74
|
You can fetch and normalize these links in Next.js:
|
|
75
75
|
|
package/dist/admin/client.js
CHANGED
|
@@ -2280,6 +2280,81 @@ function WelcomeHeader({
|
|
|
2280
2280
|
// src/admin/components/studio/AdminStudioDashboard.tsx
|
|
2281
2281
|
var import_ui3 = require("@payloadcms/ui");
|
|
2282
2282
|
|
|
2283
|
+
// src/shared/studioSections.ts
|
|
2284
|
+
var studioRoles = /* @__PURE__ */ new Set(["admin", "editor", "client"]);
|
|
2285
|
+
var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
2286
|
+
var isAbsoluteExternalURL = (value) => /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(value) || value.startsWith("//");
|
|
2287
|
+
var normalizePathLikeValue = (value) => {
|
|
2288
|
+
const trimmed = value.trim();
|
|
2289
|
+
if (!trimmed) {
|
|
2290
|
+
return "";
|
|
2291
|
+
}
|
|
2292
|
+
if (isAbsoluteExternalURL(trimmed)) {
|
|
2293
|
+
return trimmed;
|
|
2294
|
+
}
|
|
2295
|
+
const withLeadingSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
2296
|
+
const normalized = withLeadingSlash.replace(/\/+$/, "");
|
|
2297
|
+
return normalized || "/";
|
|
2298
|
+
};
|
|
2299
|
+
var normalizeStringArray = (value) => {
|
|
2300
|
+
if (!Array.isArray(value)) {
|
|
2301
|
+
return [];
|
|
2302
|
+
}
|
|
2303
|
+
return value.filter((entry) => typeof entry === "string").map((entry) => normalizePathLikeValue(entry)).filter((entry) => entry.length > 0);
|
|
2304
|
+
};
|
|
2305
|
+
var normalizeRoles = (value) => {
|
|
2306
|
+
if (!Array.isArray(value)) {
|
|
2307
|
+
return void 0;
|
|
2308
|
+
}
|
|
2309
|
+
const roles = value.filter((entry) => typeof entry === "string" && studioRoles.has(entry));
|
|
2310
|
+
return roles.length > 0 ? roles : void 0;
|
|
2311
|
+
};
|
|
2312
|
+
var normalizeCard = (value) => {
|
|
2313
|
+
if (!isRecord(value) || typeof value.title !== "string") {
|
|
2314
|
+
return void 0;
|
|
2315
|
+
}
|
|
2316
|
+
const title = value.title.trim();
|
|
2317
|
+
if (!title) {
|
|
2318
|
+
return void 0;
|
|
2319
|
+
}
|
|
2320
|
+
return {
|
|
2321
|
+
title,
|
|
2322
|
+
...typeof value.description === "string" && value.description.trim().length > 0 ? { description: value.description.trim() } : {}
|
|
2323
|
+
};
|
|
2324
|
+
};
|
|
2325
|
+
var resolveStudioSections = (value) => {
|
|
2326
|
+
if (!Array.isArray(value)) {
|
|
2327
|
+
return [];
|
|
2328
|
+
}
|
|
2329
|
+
const sections = [];
|
|
2330
|
+
const seen = /* @__PURE__ */ new Set();
|
|
2331
|
+
for (const entry of value) {
|
|
2332
|
+
if (!isRecord(entry) || typeof entry.id !== "string" || typeof entry.label !== "string") {
|
|
2333
|
+
continue;
|
|
2334
|
+
}
|
|
2335
|
+
const id = entry.id.trim();
|
|
2336
|
+
const label = entry.label.trim();
|
|
2337
|
+
if (!id || !label || seen.has(id)) {
|
|
2338
|
+
continue;
|
|
2339
|
+
}
|
|
2340
|
+
const href = typeof entry.href === "string" && entry.href.trim().length > 0 ? normalizePathLikeValue(entry.href) : isRecord(entry.view) && typeof entry.view.path === "string" ? normalizePathLikeValue(entry.view.path) : "";
|
|
2341
|
+
if (!href) {
|
|
2342
|
+
continue;
|
|
2343
|
+
}
|
|
2344
|
+
const matchPrefixes = Array.from(/* @__PURE__ */ new Set([href, ...normalizeStringArray(entry.matchPrefixes)]));
|
|
2345
|
+
sections.push({
|
|
2346
|
+
id,
|
|
2347
|
+
label,
|
|
2348
|
+
href,
|
|
2349
|
+
matchPrefixes,
|
|
2350
|
+
...normalizeRoles(entry.roles) ? { roles: normalizeRoles(entry.roles) } : {},
|
|
2351
|
+
...normalizeCard(entry.card) ? { card: normalizeCard(entry.card) } : {}
|
|
2352
|
+
});
|
|
2353
|
+
seen.add(id);
|
|
2354
|
+
}
|
|
2355
|
+
return sections;
|
|
2356
|
+
};
|
|
2357
|
+
|
|
2283
2358
|
// src/admin/components/studio/adminPathUtils.ts
|
|
2284
2359
|
var import_react11 = require("react");
|
|
2285
2360
|
var DEFAULT_ADMIN_BASE_PATH = "/admin";
|
|
@@ -2322,10 +2397,10 @@ var detectAdminBasePath = (pathname, fallback = DEFAULT_ADMIN_BASE_PATH) => {
|
|
|
2322
2397
|
}
|
|
2323
2398
|
return normalizedFallback;
|
|
2324
2399
|
};
|
|
2325
|
-
var
|
|
2400
|
+
var isAbsoluteExternalURL2 = (value) => /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(value) || value.startsWith("//");
|
|
2326
2401
|
var resolveAdminPath = (adminBasePath, targetPath) => {
|
|
2327
2402
|
if (!targetPath) return adminBasePath;
|
|
2328
|
-
if (
|
|
2403
|
+
if (isAbsoluteExternalURL2(targetPath)) return targetPath;
|
|
2329
2404
|
const normalizedBasePath = normalizeAdminBasePath(adminBasePath);
|
|
2330
2405
|
const normalizedTargetPath = normalizePath(targetPath);
|
|
2331
2406
|
if (normalizedTargetPath === "/admin") {
|
|
@@ -2376,14 +2451,30 @@ var getPropString = (props, key, fallback) => {
|
|
|
2376
2451
|
}
|
|
2377
2452
|
return fallback;
|
|
2378
2453
|
};
|
|
2454
|
+
var getPropSections = (props, key) => {
|
|
2455
|
+
if (!props || typeof props !== "object") return [];
|
|
2456
|
+
const direct = resolveStudioSections(props[key]);
|
|
2457
|
+
if (direct.length > 0) return direct;
|
|
2458
|
+
const clientProps = props.clientProps;
|
|
2459
|
+
if (clientProps && typeof clientProps === "object") {
|
|
2460
|
+
return resolveStudioSections(clientProps[key]);
|
|
2461
|
+
}
|
|
2462
|
+
return [];
|
|
2463
|
+
};
|
|
2379
2464
|
function AdminStudioDashboard(props) {
|
|
2380
2465
|
const pagesCollectionSlug = getPropString(props, "pagesCollectionSlug", "pages");
|
|
2381
2466
|
const mediaCollectionSlug = getPropString(props, "mediaCollectionSlug", "media");
|
|
2382
2467
|
const globalsBasePath = getPropString(props, "globalsBasePath", "/studio-globals");
|
|
2468
|
+
const sections = getPropSections(props, "sections");
|
|
2383
2469
|
const adminBasePath = useAdminBasePath();
|
|
2384
2470
|
const resolvedGlobalsBasePath = resolveAdminPath(adminBasePath, globalsBasePath);
|
|
2385
2471
|
const pagesPath = resolveAdminPath(adminBasePath, `/collections/${pagesCollectionSlug}`);
|
|
2386
2472
|
const mediaPath = resolveAdminPath(adminBasePath, `/collections/${mediaCollectionSlug}`);
|
|
2473
|
+
const extensionCards = sections.filter((section) => section.card).map((section) => ({
|
|
2474
|
+
href: resolveAdminPath(adminBasePath, section.href),
|
|
2475
|
+
title: section.card?.title || section.label,
|
|
2476
|
+
description: section.card?.description || ""
|
|
2477
|
+
}));
|
|
2387
2478
|
return /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { style: { padding: "1.2rem 1.2rem 2.5rem" }, children: [
|
|
2388
2479
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_ui3.SetStepNav, { nav: [{ label: "Dashboard", url: adminBasePath }] }),
|
|
2389
2480
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("h1", { style: { fontSize: "1.6rem", margin: 0 }, children: "Studio" }),
|
|
@@ -2409,7 +2500,11 @@ function AdminStudioDashboard(props) {
|
|
|
2409
2500
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("a", { href: mediaPath, style: cardStyle, children: [
|
|
2410
2501
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontWeight: 900 }, children: "Media" }),
|
|
2411
2502
|
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { color: "var(--theme-elevation-600)", marginTop: "0.25rem" }, children: "Upload and manage images and files." })
|
|
2412
|
-
] })
|
|
2503
|
+
] }),
|
|
2504
|
+
extensionCards.map((card) => /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("a", { href: card.href, style: cardStyle, children: [
|
|
2505
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { fontWeight: 900 }, children: card.title }),
|
|
2506
|
+
/* @__PURE__ */ (0, import_jsx_runtime14.jsx)("div", { style: { color: "var(--theme-elevation-600)", marginTop: "0.25rem" }, children: card.description })
|
|
2507
|
+
] }, card.href))
|
|
2413
2508
|
]
|
|
2414
2509
|
}
|
|
2415
2510
|
)
|
|
@@ -2420,11 +2515,6 @@ function AdminStudioDashboard(props) {
|
|
|
2420
2515
|
var import_react12 = require("react");
|
|
2421
2516
|
var import_ui4 = require("@payloadcms/ui");
|
|
2422
2517
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
2423
|
-
var isAdmin = (user) => {
|
|
2424
|
-
if (!user || typeof user !== "object") return false;
|
|
2425
|
-
const role = user.role;
|
|
2426
|
-
return typeof role === "string" && role === "admin";
|
|
2427
|
-
};
|
|
2428
2518
|
var getPropString2 = (props, key, fallback) => {
|
|
2429
2519
|
if (!props || typeof props !== "object") return fallback;
|
|
2430
2520
|
const direct = props[key];
|
|
@@ -2459,6 +2549,32 @@ var getPropStringArray = (props, key, fallback) => {
|
|
|
2459
2549
|
}
|
|
2460
2550
|
return fallback;
|
|
2461
2551
|
};
|
|
2552
|
+
var getPropSections2 = (props, key) => {
|
|
2553
|
+
if (!props || typeof props !== "object") return [];
|
|
2554
|
+
const direct = resolveStudioSections(props[key]);
|
|
2555
|
+
if (direct.length > 0) return direct;
|
|
2556
|
+
const clientProps = props.clientProps;
|
|
2557
|
+
if (clientProps && typeof clientProps === "object") {
|
|
2558
|
+
return resolveStudioSections(clientProps[key]);
|
|
2559
|
+
}
|
|
2560
|
+
return [];
|
|
2561
|
+
};
|
|
2562
|
+
var roleCanAccessSection = (role, section) => {
|
|
2563
|
+
if (!section.roles || section.roles.length === 0) {
|
|
2564
|
+
return true;
|
|
2565
|
+
}
|
|
2566
|
+
if (!role) {
|
|
2567
|
+
return false;
|
|
2568
|
+
}
|
|
2569
|
+
return section.roles.includes(role);
|
|
2570
|
+
};
|
|
2571
|
+
var readUserRole = (user) => {
|
|
2572
|
+
if (!user || typeof user !== "object") {
|
|
2573
|
+
return void 0;
|
|
2574
|
+
}
|
|
2575
|
+
const role = user.role;
|
|
2576
|
+
return typeof role === "string" ? role : void 0;
|
|
2577
|
+
};
|
|
2462
2578
|
function AdminStudioNav(props) {
|
|
2463
2579
|
const { user } = (0, import_ui4.useAuth)();
|
|
2464
2580
|
const brandName = getPropString2(props, "brandName", "Orion Studio");
|
|
@@ -2467,6 +2583,7 @@ function AdminStudioNav(props) {
|
|
|
2467
2583
|
const mediaCollectionSlug = getPropString2(props, "mediaCollectionSlug", "media");
|
|
2468
2584
|
const globalsBasePath = getPropString2(props, "globalsBasePath", "/studio-globals");
|
|
2469
2585
|
const globalsExtraMatchPrefixes = getPropStringArray(props, "globalsExtraMatchPrefixes", []);
|
|
2586
|
+
const sections = getPropSections2(props, "sections");
|
|
2470
2587
|
const compact = getPropBoolean(props, "compact", false);
|
|
2471
2588
|
const adminBasePath = useAdminBasePath();
|
|
2472
2589
|
const branding = useSiteBranding(brandName, logoUrl || void 0);
|
|
@@ -2486,35 +2603,38 @@ function AdminStudioNav(props) {
|
|
|
2486
2603
|
(prefix) => resolveAdminPath(adminBasePath, prefix)
|
|
2487
2604
|
);
|
|
2488
2605
|
const dashboardPath = adminBasePath;
|
|
2606
|
+
const userRole = readUserRole(user);
|
|
2489
2607
|
const links = (0, import_react12.useMemo)(
|
|
2490
|
-
() =>
|
|
2491
|
-
|
|
2492
|
-
|
|
2493
|
-
href: pagesPath,
|
|
2494
|
-
|
|
2495
|
-
|
|
2496
|
-
|
|
2497
|
-
|
|
2498
|
-
|
|
2499
|
-
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
]
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
|
|
2512
|
-
|
|
2513
|
-
|
|
2514
|
-
|
|
2515
|
-
|
|
2516
|
-
|
|
2517
|
-
|
|
2608
|
+
() => {
|
|
2609
|
+
const defaultSections = [
|
|
2610
|
+
{ id: "dashboard", href: dashboardPath, label: "Dashboard", matchPrefixes: [dashboardPath] },
|
|
2611
|
+
{ id: "pages", href: pagesPath, label: "Pages", matchPrefixes: [pagesPath] },
|
|
2612
|
+
{
|
|
2613
|
+
id: "globals",
|
|
2614
|
+
href: resolvedGlobalsBasePath,
|
|
2615
|
+
label: "Globals",
|
|
2616
|
+
matchPrefixes: [
|
|
2617
|
+
resolvedGlobalsBasePath,
|
|
2618
|
+
resolveAdminPath(adminBasePath, "/globals"),
|
|
2619
|
+
...resolvedGlobalsExtraMatchPrefixes
|
|
2620
|
+
]
|
|
2621
|
+
},
|
|
2622
|
+
{ id: "media", href: mediaPath, label: "Media", matchPrefixes: [mediaPath] },
|
|
2623
|
+
{
|
|
2624
|
+
id: "admin-tools",
|
|
2625
|
+
href: usersPath,
|
|
2626
|
+
label: "Admin Tools",
|
|
2627
|
+
matchPrefixes: [usersPath],
|
|
2628
|
+
roles: ["admin"]
|
|
2629
|
+
}
|
|
2630
|
+
];
|
|
2631
|
+
const extensionSections = sections.map((section) => ({
|
|
2632
|
+
...section,
|
|
2633
|
+
href: resolveAdminPath(adminBasePath, section.href),
|
|
2634
|
+
matchPrefixes: section.matchPrefixes.map((prefix) => resolveAdminPath(adminBasePath, prefix))
|
|
2635
|
+
}));
|
|
2636
|
+
return [...defaultSections, ...extensionSections];
|
|
2637
|
+
},
|
|
2518
2638
|
[
|
|
2519
2639
|
adminBasePath,
|
|
2520
2640
|
dashboardPath,
|
|
@@ -2522,6 +2642,7 @@ function AdminStudioNav(props) {
|
|
|
2522
2642
|
pagesPath,
|
|
2523
2643
|
resolvedGlobalsBasePath,
|
|
2524
2644
|
resolvedGlobalsExtraMatchPrefixes,
|
|
2645
|
+
sections,
|
|
2525
2646
|
usersPath
|
|
2526
2647
|
]
|
|
2527
2648
|
);
|
|
@@ -2580,7 +2701,7 @@ function AdminStudioNav(props) {
|
|
|
2580
2701
|
),
|
|
2581
2702
|
!compact ? /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.85rem" }, children: "Studio" }) : null
|
|
2582
2703
|
] }),
|
|
2583
|
-
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("nav", { style: { display: "grid", gap: "0.25rem" }, children: links.filter((link) =>
|
|
2704
|
+
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)("nav", { style: { display: "grid", gap: "0.25rem" }, children: links.filter((link) => roleCanAccessSection(userRole, link)).map((link) => {
|
|
2584
2705
|
const active = link.href === dashboardPath ? pathname === dashboardPath : link.matchPrefixes.some((prefix) => pathname.startsWith(prefix));
|
|
2585
2706
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsx)("a", { href: link.href, style: linkStyle(active), title: link.label, children: compact ? link.label.slice(0, 1) : link.label }, link.href);
|
|
2586
2707
|
}) }),
|
|
@@ -2611,7 +2732,7 @@ function AdminStudioNav(props) {
|
|
|
2611
2732
|
var import_react13 = require("react");
|
|
2612
2733
|
var import_ui5 = require("@payloadcms/ui");
|
|
2613
2734
|
var import_jsx_runtime16 = require("react/jsx-runtime");
|
|
2614
|
-
var
|
|
2735
|
+
var isAdmin = (user) => {
|
|
2615
2736
|
if (!user || typeof user !== "object") return false;
|
|
2616
2737
|
const role = user.role;
|
|
2617
2738
|
return typeof role === "string" && role === "admin";
|
|
@@ -2677,7 +2798,7 @@ function AdminStudioPagesListView(props) {
|
|
|
2677
2798
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("h1", { style: { margin: 0 }, children: "Pages" }),
|
|
2678
2799
|
/* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Open a page to edit it in the custom editor." })
|
|
2679
2800
|
] }),
|
|
2680
|
-
|
|
2801
|
+
isAdmin(user) ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
|
|
2681
2802
|
"a",
|
|
2682
2803
|
{
|
|
2683
2804
|
href: `${rawPagesCollectionPath}/create`,
|
|
@@ -2787,7 +2908,7 @@ function AdminStudioPagesListView(props) {
|
|
|
2787
2908
|
var import_react14 = require("react");
|
|
2788
2909
|
var import_ui6 = require("@payloadcms/ui");
|
|
2789
2910
|
var import_jsx_runtime17 = require("react/jsx-runtime");
|
|
2790
|
-
var
|
|
2911
|
+
var isAdmin2 = (user) => {
|
|
2791
2912
|
if (!user || typeof user !== "object") return false;
|
|
2792
2913
|
const role = user.role;
|
|
2793
2914
|
return typeof role === "string" && role === "admin";
|
|
@@ -2848,7 +2969,7 @@ function AdminStudioPageEditView(props) {
|
|
|
2848
2969
|
}
|
|
2849
2970
|
setDidResolvePathFallback(true);
|
|
2850
2971
|
}, [pageIDFromParams]);
|
|
2851
|
-
const canPublish =
|
|
2972
|
+
const canPublish = isAdmin2(user) || isEditor(user);
|
|
2852
2973
|
const refreshUnpublishedState = async (id) => {
|
|
2853
2974
|
try {
|
|
2854
2975
|
const response = await fetch(
|
|
@@ -3570,7 +3691,7 @@ function AdminStudioMediaView(props) {
|
|
|
3570
3691
|
// src/admin/components/studio/AdminStudioToolsView.tsx
|
|
3571
3692
|
var import_ui10 = require("@payloadcms/ui");
|
|
3572
3693
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
3573
|
-
var
|
|
3694
|
+
var isAdmin3 = (user) => {
|
|
3574
3695
|
if (!user || typeof user !== "object") return false;
|
|
3575
3696
|
const role = user.role;
|
|
3576
3697
|
return typeof role === "string" && role === "admin";
|
|
@@ -3590,7 +3711,7 @@ function AdminStudioToolsView(props) {
|
|
|
3590
3711
|
const { user } = (0, import_ui10.useAuth)();
|
|
3591
3712
|
const adminBasePath = useAdminBasePath();
|
|
3592
3713
|
const toolsPath = resolveAdminPath(adminBasePath, "/tools");
|
|
3593
|
-
if (!
|
|
3714
|
+
if (!isAdmin3(user)) {
|
|
3594
3715
|
return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(import_jsx_runtime21.Fragment, { children: [
|
|
3595
3716
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_ui10.SetStepNav, { nav: [{ label: "Admin Tools", url: toolsPath }] }),
|
|
3596
3717
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("h1", { style: { margin: 0 }, children: "Admin Tools" }),
|
package/dist/admin/client.mjs
CHANGED
|
@@ -1097,6 +1097,81 @@ function WelcomeHeader({
|
|
|
1097
1097
|
// src/admin/components/studio/AdminStudioDashboard.tsx
|
|
1098
1098
|
import { SetStepNav } from "@payloadcms/ui";
|
|
1099
1099
|
|
|
1100
|
+
// src/shared/studioSections.ts
|
|
1101
|
+
var studioRoles = /* @__PURE__ */ new Set(["admin", "editor", "client"]);
|
|
1102
|
+
var isRecord = (value) => Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
1103
|
+
var isAbsoluteExternalURL = (value) => /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(value) || value.startsWith("//");
|
|
1104
|
+
var normalizePathLikeValue = (value) => {
|
|
1105
|
+
const trimmed = value.trim();
|
|
1106
|
+
if (!trimmed) {
|
|
1107
|
+
return "";
|
|
1108
|
+
}
|
|
1109
|
+
if (isAbsoluteExternalURL(trimmed)) {
|
|
1110
|
+
return trimmed;
|
|
1111
|
+
}
|
|
1112
|
+
const withLeadingSlash = trimmed.startsWith("/") ? trimmed : `/${trimmed}`;
|
|
1113
|
+
const normalized = withLeadingSlash.replace(/\/+$/, "");
|
|
1114
|
+
return normalized || "/";
|
|
1115
|
+
};
|
|
1116
|
+
var normalizeStringArray = (value) => {
|
|
1117
|
+
if (!Array.isArray(value)) {
|
|
1118
|
+
return [];
|
|
1119
|
+
}
|
|
1120
|
+
return value.filter((entry) => typeof entry === "string").map((entry) => normalizePathLikeValue(entry)).filter((entry) => entry.length > 0);
|
|
1121
|
+
};
|
|
1122
|
+
var normalizeRoles = (value) => {
|
|
1123
|
+
if (!Array.isArray(value)) {
|
|
1124
|
+
return void 0;
|
|
1125
|
+
}
|
|
1126
|
+
const roles = value.filter((entry) => typeof entry === "string" && studioRoles.has(entry));
|
|
1127
|
+
return roles.length > 0 ? roles : void 0;
|
|
1128
|
+
};
|
|
1129
|
+
var normalizeCard = (value) => {
|
|
1130
|
+
if (!isRecord(value) || typeof value.title !== "string") {
|
|
1131
|
+
return void 0;
|
|
1132
|
+
}
|
|
1133
|
+
const title = value.title.trim();
|
|
1134
|
+
if (!title) {
|
|
1135
|
+
return void 0;
|
|
1136
|
+
}
|
|
1137
|
+
return {
|
|
1138
|
+
title,
|
|
1139
|
+
...typeof value.description === "string" && value.description.trim().length > 0 ? { description: value.description.trim() } : {}
|
|
1140
|
+
};
|
|
1141
|
+
};
|
|
1142
|
+
var resolveStudioSections = (value) => {
|
|
1143
|
+
if (!Array.isArray(value)) {
|
|
1144
|
+
return [];
|
|
1145
|
+
}
|
|
1146
|
+
const sections = [];
|
|
1147
|
+
const seen = /* @__PURE__ */ new Set();
|
|
1148
|
+
for (const entry of value) {
|
|
1149
|
+
if (!isRecord(entry) || typeof entry.id !== "string" || typeof entry.label !== "string") {
|
|
1150
|
+
continue;
|
|
1151
|
+
}
|
|
1152
|
+
const id = entry.id.trim();
|
|
1153
|
+
const label = entry.label.trim();
|
|
1154
|
+
if (!id || !label || seen.has(id)) {
|
|
1155
|
+
continue;
|
|
1156
|
+
}
|
|
1157
|
+
const href = typeof entry.href === "string" && entry.href.trim().length > 0 ? normalizePathLikeValue(entry.href) : isRecord(entry.view) && typeof entry.view.path === "string" ? normalizePathLikeValue(entry.view.path) : "";
|
|
1158
|
+
if (!href) {
|
|
1159
|
+
continue;
|
|
1160
|
+
}
|
|
1161
|
+
const matchPrefixes = Array.from(/* @__PURE__ */ new Set([href, ...normalizeStringArray(entry.matchPrefixes)]));
|
|
1162
|
+
sections.push({
|
|
1163
|
+
id,
|
|
1164
|
+
label,
|
|
1165
|
+
href,
|
|
1166
|
+
matchPrefixes,
|
|
1167
|
+
...normalizeRoles(entry.roles) ? { roles: normalizeRoles(entry.roles) } : {},
|
|
1168
|
+
...normalizeCard(entry.card) ? { card: normalizeCard(entry.card) } : {}
|
|
1169
|
+
});
|
|
1170
|
+
seen.add(id);
|
|
1171
|
+
}
|
|
1172
|
+
return sections;
|
|
1173
|
+
};
|
|
1174
|
+
|
|
1100
1175
|
// src/admin/components/studio/adminPathUtils.ts
|
|
1101
1176
|
import { useEffect as useEffect6, useState as useState5 } from "react";
|
|
1102
1177
|
var DEFAULT_ADMIN_BASE_PATH = "/admin";
|
|
@@ -1139,10 +1214,10 @@ var detectAdminBasePath = (pathname, fallback = DEFAULT_ADMIN_BASE_PATH) => {
|
|
|
1139
1214
|
}
|
|
1140
1215
|
return normalizedFallback;
|
|
1141
1216
|
};
|
|
1142
|
-
var
|
|
1217
|
+
var isAbsoluteExternalURL2 = (value) => /^[a-zA-Z][a-zA-Z\d+\-.]*:/.test(value) || value.startsWith("//");
|
|
1143
1218
|
var resolveAdminPath = (adminBasePath, targetPath) => {
|
|
1144
1219
|
if (!targetPath) return adminBasePath;
|
|
1145
|
-
if (
|
|
1220
|
+
if (isAbsoluteExternalURL2(targetPath)) return targetPath;
|
|
1146
1221
|
const normalizedBasePath = normalizeAdminBasePath(adminBasePath);
|
|
1147
1222
|
const normalizedTargetPath = normalizePath(targetPath);
|
|
1148
1223
|
if (normalizedTargetPath === "/admin") {
|
|
@@ -1193,14 +1268,30 @@ var getPropString = (props, key, fallback) => {
|
|
|
1193
1268
|
}
|
|
1194
1269
|
return fallback;
|
|
1195
1270
|
};
|
|
1271
|
+
var getPropSections = (props, key) => {
|
|
1272
|
+
if (!props || typeof props !== "object") return [];
|
|
1273
|
+
const direct = resolveStudioSections(props[key]);
|
|
1274
|
+
if (direct.length > 0) return direct;
|
|
1275
|
+
const clientProps = props.clientProps;
|
|
1276
|
+
if (clientProps && typeof clientProps === "object") {
|
|
1277
|
+
return resolveStudioSections(clientProps[key]);
|
|
1278
|
+
}
|
|
1279
|
+
return [];
|
|
1280
|
+
};
|
|
1196
1281
|
function AdminStudioDashboard(props) {
|
|
1197
1282
|
const pagesCollectionSlug = getPropString(props, "pagesCollectionSlug", "pages");
|
|
1198
1283
|
const mediaCollectionSlug = getPropString(props, "mediaCollectionSlug", "media");
|
|
1199
1284
|
const globalsBasePath = getPropString(props, "globalsBasePath", "/studio-globals");
|
|
1285
|
+
const sections = getPropSections(props, "sections");
|
|
1200
1286
|
const adminBasePath = useAdminBasePath();
|
|
1201
1287
|
const resolvedGlobalsBasePath = resolveAdminPath(adminBasePath, globalsBasePath);
|
|
1202
1288
|
const pagesPath = resolveAdminPath(adminBasePath, `/collections/${pagesCollectionSlug}`);
|
|
1203
1289
|
const mediaPath = resolveAdminPath(adminBasePath, `/collections/${mediaCollectionSlug}`);
|
|
1290
|
+
const extensionCards = sections.filter((section) => section.card).map((section) => ({
|
|
1291
|
+
href: resolveAdminPath(adminBasePath, section.href),
|
|
1292
|
+
title: section.card?.title || section.label,
|
|
1293
|
+
description: section.card?.description || ""
|
|
1294
|
+
}));
|
|
1204
1295
|
return /* @__PURE__ */ jsxs9("div", { style: { padding: "1.2rem 1.2rem 2.5rem" }, children: [
|
|
1205
1296
|
/* @__PURE__ */ jsx10(SetStepNav, { nav: [{ label: "Dashboard", url: adminBasePath }] }),
|
|
1206
1297
|
/* @__PURE__ */ jsx10("h1", { style: { fontSize: "1.6rem", margin: 0 }, children: "Studio" }),
|
|
@@ -1226,7 +1317,11 @@ function AdminStudioDashboard(props) {
|
|
|
1226
1317
|
/* @__PURE__ */ jsxs9("a", { href: mediaPath, style: cardStyle, children: [
|
|
1227
1318
|
/* @__PURE__ */ jsx10("div", { style: { fontWeight: 900 }, children: "Media" }),
|
|
1228
1319
|
/* @__PURE__ */ jsx10("div", { style: { color: "var(--theme-elevation-600)", marginTop: "0.25rem" }, children: "Upload and manage images and files." })
|
|
1229
|
-
] })
|
|
1320
|
+
] }),
|
|
1321
|
+
extensionCards.map((card) => /* @__PURE__ */ jsxs9("a", { href: card.href, style: cardStyle, children: [
|
|
1322
|
+
/* @__PURE__ */ jsx10("div", { style: { fontWeight: 900 }, children: card.title }),
|
|
1323
|
+
/* @__PURE__ */ jsx10("div", { style: { color: "var(--theme-elevation-600)", marginTop: "0.25rem" }, children: card.description })
|
|
1324
|
+
] }, card.href))
|
|
1230
1325
|
]
|
|
1231
1326
|
}
|
|
1232
1327
|
)
|
|
@@ -1237,11 +1332,6 @@ function AdminStudioDashboard(props) {
|
|
|
1237
1332
|
import { useEffect as useEffect7, useMemo, useState as useState6 } from "react";
|
|
1238
1333
|
import { Logout, useAuth } from "@payloadcms/ui";
|
|
1239
1334
|
import { Fragment as Fragment2, jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1240
|
-
var isAdmin = (user) => {
|
|
1241
|
-
if (!user || typeof user !== "object") return false;
|
|
1242
|
-
const role = user.role;
|
|
1243
|
-
return typeof role === "string" && role === "admin";
|
|
1244
|
-
};
|
|
1245
1335
|
var getPropString2 = (props, key, fallback) => {
|
|
1246
1336
|
if (!props || typeof props !== "object") return fallback;
|
|
1247
1337
|
const direct = props[key];
|
|
@@ -1276,6 +1366,32 @@ var getPropStringArray = (props, key, fallback) => {
|
|
|
1276
1366
|
}
|
|
1277
1367
|
return fallback;
|
|
1278
1368
|
};
|
|
1369
|
+
var getPropSections2 = (props, key) => {
|
|
1370
|
+
if (!props || typeof props !== "object") return [];
|
|
1371
|
+
const direct = resolveStudioSections(props[key]);
|
|
1372
|
+
if (direct.length > 0) return direct;
|
|
1373
|
+
const clientProps = props.clientProps;
|
|
1374
|
+
if (clientProps && typeof clientProps === "object") {
|
|
1375
|
+
return resolveStudioSections(clientProps[key]);
|
|
1376
|
+
}
|
|
1377
|
+
return [];
|
|
1378
|
+
};
|
|
1379
|
+
var roleCanAccessSection = (role, section) => {
|
|
1380
|
+
if (!section.roles || section.roles.length === 0) {
|
|
1381
|
+
return true;
|
|
1382
|
+
}
|
|
1383
|
+
if (!role) {
|
|
1384
|
+
return false;
|
|
1385
|
+
}
|
|
1386
|
+
return section.roles.includes(role);
|
|
1387
|
+
};
|
|
1388
|
+
var readUserRole = (user) => {
|
|
1389
|
+
if (!user || typeof user !== "object") {
|
|
1390
|
+
return void 0;
|
|
1391
|
+
}
|
|
1392
|
+
const role = user.role;
|
|
1393
|
+
return typeof role === "string" ? role : void 0;
|
|
1394
|
+
};
|
|
1279
1395
|
function AdminStudioNav(props) {
|
|
1280
1396
|
const { user } = useAuth();
|
|
1281
1397
|
const brandName = getPropString2(props, "brandName", "Orion Studio");
|
|
@@ -1284,6 +1400,7 @@ function AdminStudioNav(props) {
|
|
|
1284
1400
|
const mediaCollectionSlug = getPropString2(props, "mediaCollectionSlug", "media");
|
|
1285
1401
|
const globalsBasePath = getPropString2(props, "globalsBasePath", "/studio-globals");
|
|
1286
1402
|
const globalsExtraMatchPrefixes = getPropStringArray(props, "globalsExtraMatchPrefixes", []);
|
|
1403
|
+
const sections = getPropSections2(props, "sections");
|
|
1287
1404
|
const compact = getPropBoolean(props, "compact", false);
|
|
1288
1405
|
const adminBasePath = useAdminBasePath();
|
|
1289
1406
|
const branding = useSiteBranding(brandName, logoUrl || void 0);
|
|
@@ -1303,35 +1420,38 @@ function AdminStudioNav(props) {
|
|
|
1303
1420
|
(prefix) => resolveAdminPath(adminBasePath, prefix)
|
|
1304
1421
|
);
|
|
1305
1422
|
const dashboardPath = adminBasePath;
|
|
1423
|
+
const userRole = readUserRole(user);
|
|
1306
1424
|
const links = useMemo(
|
|
1307
|
-
() =>
|
|
1308
|
-
|
|
1309
|
-
|
|
1310
|
-
href: pagesPath,
|
|
1311
|
-
|
|
1312
|
-
|
|
1313
|
-
|
|
1314
|
-
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
]
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1425
|
+
() => {
|
|
1426
|
+
const defaultSections = [
|
|
1427
|
+
{ id: "dashboard", href: dashboardPath, label: "Dashboard", matchPrefixes: [dashboardPath] },
|
|
1428
|
+
{ id: "pages", href: pagesPath, label: "Pages", matchPrefixes: [pagesPath] },
|
|
1429
|
+
{
|
|
1430
|
+
id: "globals",
|
|
1431
|
+
href: resolvedGlobalsBasePath,
|
|
1432
|
+
label: "Globals",
|
|
1433
|
+
matchPrefixes: [
|
|
1434
|
+
resolvedGlobalsBasePath,
|
|
1435
|
+
resolveAdminPath(adminBasePath, "/globals"),
|
|
1436
|
+
...resolvedGlobalsExtraMatchPrefixes
|
|
1437
|
+
]
|
|
1438
|
+
},
|
|
1439
|
+
{ id: "media", href: mediaPath, label: "Media", matchPrefixes: [mediaPath] },
|
|
1440
|
+
{
|
|
1441
|
+
id: "admin-tools",
|
|
1442
|
+
href: usersPath,
|
|
1443
|
+
label: "Admin Tools",
|
|
1444
|
+
matchPrefixes: [usersPath],
|
|
1445
|
+
roles: ["admin"]
|
|
1446
|
+
}
|
|
1447
|
+
];
|
|
1448
|
+
const extensionSections = sections.map((section) => ({
|
|
1449
|
+
...section,
|
|
1450
|
+
href: resolveAdminPath(adminBasePath, section.href),
|
|
1451
|
+
matchPrefixes: section.matchPrefixes.map((prefix) => resolveAdminPath(adminBasePath, prefix))
|
|
1452
|
+
}));
|
|
1453
|
+
return [...defaultSections, ...extensionSections];
|
|
1454
|
+
},
|
|
1335
1455
|
[
|
|
1336
1456
|
adminBasePath,
|
|
1337
1457
|
dashboardPath,
|
|
@@ -1339,6 +1459,7 @@ function AdminStudioNav(props) {
|
|
|
1339
1459
|
pagesPath,
|
|
1340
1460
|
resolvedGlobalsBasePath,
|
|
1341
1461
|
resolvedGlobalsExtraMatchPrefixes,
|
|
1462
|
+
sections,
|
|
1342
1463
|
usersPath
|
|
1343
1464
|
]
|
|
1344
1465
|
);
|
|
@@ -1397,7 +1518,7 @@ function AdminStudioNav(props) {
|
|
|
1397
1518
|
),
|
|
1398
1519
|
!compact ? /* @__PURE__ */ jsx11("div", { style: { color: "var(--theme-elevation-600)", fontSize: "0.85rem" }, children: "Studio" }) : null
|
|
1399
1520
|
] }),
|
|
1400
|
-
/* @__PURE__ */ jsx11("nav", { style: { display: "grid", gap: "0.25rem" }, children: links.filter((link) =>
|
|
1521
|
+
/* @__PURE__ */ jsx11("nav", { style: { display: "grid", gap: "0.25rem" }, children: links.filter((link) => roleCanAccessSection(userRole, link)).map((link) => {
|
|
1401
1522
|
const active = link.href === dashboardPath ? pathname === dashboardPath : link.matchPrefixes.some((prefix) => pathname.startsWith(prefix));
|
|
1402
1523
|
return /* @__PURE__ */ jsx11("a", { href: link.href, style: linkStyle(active), title: link.label, children: compact ? link.label.slice(0, 1) : link.label }, link.href);
|
|
1403
1524
|
}) }),
|
|
@@ -1428,7 +1549,7 @@ function AdminStudioNav(props) {
|
|
|
1428
1549
|
import { useEffect as useEffect8, useMemo as useMemo2, useState as useState7 } from "react";
|
|
1429
1550
|
import { SetStepNav as SetStepNav2, useAuth as useAuth2 } from "@payloadcms/ui";
|
|
1430
1551
|
import { Fragment as Fragment3, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
1431
|
-
var
|
|
1552
|
+
var isAdmin = (user) => {
|
|
1432
1553
|
if (!user || typeof user !== "object") return false;
|
|
1433
1554
|
const role = user.role;
|
|
1434
1555
|
return typeof role === "string" && role === "admin";
|
|
@@ -1494,7 +1615,7 @@ function AdminStudioPagesListView(props) {
|
|
|
1494
1615
|
/* @__PURE__ */ jsx12("h1", { style: { margin: 0 }, children: "Pages" }),
|
|
1495
1616
|
/* @__PURE__ */ jsx12("p", { style: { color: "var(--theme-elevation-600)", marginTop: "0.35rem" }, children: "Open a page to edit it in the custom editor." })
|
|
1496
1617
|
] }),
|
|
1497
|
-
|
|
1618
|
+
isAdmin(user) ? /* @__PURE__ */ jsx12(
|
|
1498
1619
|
"a",
|
|
1499
1620
|
{
|
|
1500
1621
|
href: `${rawPagesCollectionPath}/create`,
|
|
@@ -1604,7 +1725,7 @@ function AdminStudioPagesListView(props) {
|
|
|
1604
1725
|
import { useEffect as useEffect9, useMemo as useMemo3, useRef as useRef3, useState as useState8 } from "react";
|
|
1605
1726
|
import { SetStepNav as SetStepNav3, toast, useAuth as useAuth3 } from "@payloadcms/ui";
|
|
1606
1727
|
import { Fragment as Fragment4, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
|
|
1607
|
-
var
|
|
1728
|
+
var isAdmin2 = (user) => {
|
|
1608
1729
|
if (!user || typeof user !== "object") return false;
|
|
1609
1730
|
const role = user.role;
|
|
1610
1731
|
return typeof role === "string" && role === "admin";
|
|
@@ -1665,7 +1786,7 @@ function AdminStudioPageEditView(props) {
|
|
|
1665
1786
|
}
|
|
1666
1787
|
setDidResolvePathFallback(true);
|
|
1667
1788
|
}, [pageIDFromParams]);
|
|
1668
|
-
const canPublish =
|
|
1789
|
+
const canPublish = isAdmin2(user) || isEditor(user);
|
|
1669
1790
|
const refreshUnpublishedState = async (id) => {
|
|
1670
1791
|
try {
|
|
1671
1792
|
const response = await fetch(
|
|
@@ -2387,7 +2508,7 @@ function AdminStudioMediaView(props) {
|
|
|
2387
2508
|
// src/admin/components/studio/AdminStudioToolsView.tsx
|
|
2388
2509
|
import { SetStepNav as SetStepNav7, useAuth as useAuth4 } from "@payloadcms/ui";
|
|
2389
2510
|
import { Fragment as Fragment7, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
|
|
2390
|
-
var
|
|
2511
|
+
var isAdmin3 = (user) => {
|
|
2391
2512
|
if (!user || typeof user !== "object") return false;
|
|
2392
2513
|
const role = user.role;
|
|
2393
2514
|
return typeof role === "string" && role === "admin";
|
|
@@ -2407,7 +2528,7 @@ function AdminStudioToolsView(props) {
|
|
|
2407
2528
|
const { user } = useAuth4();
|
|
2408
2529
|
const adminBasePath = useAdminBasePath();
|
|
2409
2530
|
const toolsPath = resolveAdminPath(adminBasePath, "/tools");
|
|
2410
|
-
if (!
|
|
2531
|
+
if (!isAdmin3(user)) {
|
|
2411
2532
|
return /* @__PURE__ */ jsxs16(Fragment7, { children: [
|
|
2412
2533
|
/* @__PURE__ */ jsx17(SetStepNav7, { nav: [{ label: "Admin Tools", url: toolsPath }] }),
|
|
2413
2534
|
/* @__PURE__ */ jsx17("h1", { style: { margin: 0 }, children: "Admin Tools" }),
|