@emdash-cms/admin 0.7.0 → 1.0.0
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/{LocaleDirectionProvider-CI7U6BBr.js → LocaleDirectionProvider-B43-InGI.js} +20 -14
- package/dist/LocaleDirectionProvider-B43-InGI.js.map +1 -0
- package/dist/{config-D8i8U4bV.d.ts → config-h7tWQRka.d.ts} +1 -1
- package/dist/{config-D8i8U4bV.d.ts.map → config-h7tWQRka.d.ts.map} +1 -1
- package/dist/index.d.ts +82 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +843 -380
- package/dist/index.js.map +1 -1
- package/dist/locales/ar/messages.mjs +1 -1
- package/dist/locales/de/messages.mjs +1 -1
- package/dist/locales/en/messages.mjs +1 -1
- package/dist/locales/es-419/messages.mjs +1 -1
- package/dist/locales/eu/messages.mjs +1 -1
- package/dist/locales/fa/messages.mjs +1 -1
- package/dist/locales/fr/messages.mjs +1 -1
- package/dist/locales/index.d.ts +1 -1
- package/dist/locales/index.js +1 -1
- package/dist/locales/ja/messages.mjs +1 -1
- package/dist/locales/ko/messages.mjs +1 -1
- package/dist/locales/pl/messages.mjs +1 -0
- package/dist/locales/pseudo/messages.mjs +1 -1
- package/dist/locales/pt-BR/messages.mjs +1 -1
- package/dist/locales/zh-CN/messages.mjs +1 -1
- package/dist/locales/zh-TW/messages.mjs +1 -1
- package/dist/messages-B6ZguVfS.js +6 -0
- package/dist/messages-B6ZguVfS.js.map +1 -0
- package/dist/messages-BOnMi1Vb.js +6 -0
- package/dist/messages-BOnMi1Vb.js.map +1 -0
- package/dist/messages-BZuRVH-D.js +6 -0
- package/dist/messages-BZuRVH-D.js.map +1 -0
- package/dist/messages-Bc_PDiKw.js +6 -0
- package/dist/messages-Bc_PDiKw.js.map +1 -0
- package/dist/messages-Bddg68eH.js +6 -0
- package/dist/messages-Bddg68eH.js.map +1 -0
- package/dist/messages-BoP-RHEG.js +6 -0
- package/dist/messages-BoP-RHEG.js.map +1 -0
- package/dist/messages-C4hNtyU5.js +6 -0
- package/dist/messages-C4hNtyU5.js.map +1 -0
- package/dist/messages-CMwt5Gv-.js +6 -0
- package/dist/messages-CMwt5Gv-.js.map +1 -0
- package/dist/messages-CnliZpid.js +6 -0
- package/dist/messages-CnliZpid.js.map +1 -0
- package/dist/messages-CseAZVO2.js +6 -0
- package/dist/messages-CseAZVO2.js.map +1 -0
- package/dist/messages-DRyNt1qC.js +6 -0
- package/dist/messages-DRyNt1qC.js.map +1 -0
- package/dist/messages-DTehFUkD.js +6 -0
- package/dist/messages-DTehFUkD.js.map +1 -0
- package/dist/messages-DeQMOYvT.js +6 -0
- package/dist/messages-DeQMOYvT.js.map +1 -0
- package/dist/messages-Do3BokvI.js +6 -0
- package/dist/messages-Do3BokvI.js.map +1 -0
- package/dist/{plugins-XhZqfegd.js → plugins-DUJY_8HN.js} +9 -2
- package/dist/{plugins-XhZqfegd.js.map → plugins-DUJY_8HN.js.map} +1 -1
- package/dist/styles.css +1 -1
- package/package.json +2 -2
- package/dist/LocaleDirectionProvider-CI7U6BBr.js.map +0 -1
- package/dist/messages-57qx1FXa.js +0 -6
- package/dist/messages-57qx1FXa.js.map +0 -1
- package/dist/messages-8uPA5VDB.js +0 -6
- package/dist/messages-8uPA5VDB.js.map +0 -1
- package/dist/messages-Bc3iE3Xx.js +0 -6
- package/dist/messages-Bc3iE3Xx.js.map +0 -1
- package/dist/messages-BudiTpRZ.js +0 -6
- package/dist/messages-BudiTpRZ.js.map +0 -1
- package/dist/messages-CLJeZfc0.js +0 -6
- package/dist/messages-CLJeZfc0.js.map +0 -1
- package/dist/messages-CXyBDum7.js +0 -6
- package/dist/messages-CXyBDum7.js.map +0 -1
- package/dist/messages-DFXk1gAB.js +0 -6
- package/dist/messages-DFXk1gAB.js.map +0 -1
- package/dist/messages-DHg9t0ML.js +0 -6
- package/dist/messages-DHg9t0ML.js.map +0 -1
- package/dist/messages-DT-_3Gqh.js +0 -6
- package/dist/messages-DT-_3Gqh.js.map +0 -1
- package/dist/messages-DYWnQ-qc.js +0 -6
- package/dist/messages-DYWnQ-qc.js.map +0 -1
- package/dist/messages-DrHBJ5Tm.js +0 -6
- package/dist/messages-DrHBJ5Tm.js.map +0 -1
- package/dist/messages-TukFV9EF.js +0 -6
- package/dist/messages-TukFV9EF.js.map +0 -1
- package/dist/messages-cadUq4Pc.js +0 -6
- package/dist/messages-cadUq4Pc.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { c as
|
|
2
|
-
import { a as SUPPORTED_LOCALES, i as DEFAULT_LOCALE, l as resolveLocale, n as useLocale, o as SUPPORTED_LOCALE_CODES, t as LocaleDirectionProvider } from "./LocaleDirectionProvider-
|
|
1
|
+
import { c as fetchAuthMode, d as throwResponseError, i as fetchPlugins, l as fetchManifest, n as enablePlugin, o as API_BASE, r as fetchPlugin, s as apiFetch, t as disablePlugin, u as parseApiResponse } from "./plugins-DUJY_8HN.js";
|
|
2
|
+
import { a as SUPPORTED_LOCALES, i as DEFAULT_LOCALE, l as resolveLocale, n as useLocale, o as SUPPORTED_LOCALE_CODES, t as LocaleDirectionProvider } from "./LocaleDirectionProvider-B43-InGI.js";
|
|
3
3
|
import "./locales/index.js";
|
|
4
4
|
import { Badge, Button, Checkbox, CommandPalette, Dialog, Input, InputArea, Label, LinkButton, Loader, Popover, Select, Sidebar as KumoSidebar, Switch, Tabs, Toast, Toasty, Tooltip, buttonVariants, useSidebar } from "@cloudflare/kumo";
|
|
5
5
|
import { i18n } from "@lingui/core";
|
|
@@ -10,7 +10,7 @@ import * as React from "react";
|
|
|
10
10
|
import { createContext, useCallback, useContext, useEffect, useState } from "react";
|
|
11
11
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
12
12
|
import { Dialog as Dialog$1 } from "@cloudflare/kumo/primitives";
|
|
13
|
-
import { ArrowCounterClockwise, ArrowLeft, ArrowRight, ArrowSquareOut, ArrowUUpLeft, ArrowUUpRight, ArrowsClockwise, ArrowsInSimple, ArrowsLeftRight, ArrowsOutSimple, BracketsCurly, Calendar, CalendarBlank, CaretDown, CaretLeft, CaretRight, CaretUp, ChatCircle, Check, CheckCircle, CircleDashed, CircleNotch, ClockCounterClockwise, Cloud, Code, CodeBlock, Copy, Cube, Database, DeviceMobile, DotsSixVertical, DownloadSimple, Envelope, EnvelopeSimple, Eye, EyeSlash, File, FileArrowDown, FileText, FloppyDisk, FolderOpen, Gear, GithubLogo, Globe, GlobeSimple, GridFour, HardDrive, Hash, Image as Image$1, ImageSquare, Info, Key, Link as Link$2, LinkBreak, LinkSimple, List, ListBullets, ListChecks, ListNumbers, MagnifyingGlass, Minus, Monitor, Moon, Palette, PaperPlaneTilt, Paragraph, Pencil, PencilSimple, PlugsConnected, Plus, Prohibit, PuzzlePiece, Quotes, Rows, Ruler, ShareNetwork, Shield, ShieldCheck, ShieldWarning, SignOut, SlidersHorizontal, Sparkle, SquaresFour, Stack, Storefront, Sun, TextAlignCenter, TextAlignLeft, TextAlignRight, TextB, TextHOne, TextHThree, TextHTwo, TextItalic, TextStrikethrough, TextT, TextUnderline, ToggleLeft, Trash, Upload, User, UserCircle, UserPlus, Users, Warning, WarningCircle, WebhooksLogo, X, YoutubeLogo } from "@phosphor-icons/react";
|
|
13
|
+
import { ArrowCounterClockwise, ArrowLeft, ArrowRight, ArrowSquareOut, ArrowUUpLeft, ArrowUUpRight, ArrowsClockwise, ArrowsInSimple, ArrowsLeftRight, ArrowsOutSimple, BracketsCurly, Calendar, CalendarBlank, CaretDown, CaretLeft, CaretRight, CaretUp, CaretUpDown, ChatCircle, Check, CheckCircle, CircleDashed, CircleNotch, ClockCounterClockwise, Cloud, Code, CodeBlock, Copy, Cube, Database, DeviceMobile, DotsSixVertical, DownloadSimple, Envelope, EnvelopeSimple, Eye, EyeSlash, File, FileArrowDown, FileText, FloppyDisk, FolderOpen, Gear, GithubLogo, Globe, GlobeSimple, GridFour, HardDrive, Hash, Image as Image$1, ImageSquare, Info, Key, Link as Link$2, LinkBreak, LinkSimple, List, ListBullets, ListChecks, ListNumbers, MagnifyingGlass, Minus, Monitor, Moon, Palette, PaperPlaneTilt, Paragraph, Pencil, PencilSimple, PlugsConnected, Plus, Prohibit, PuzzlePiece, Quotes, Rows, Ruler, ShareNetwork, Shield, ShieldCheck, ShieldWarning, SignOut, SlidersHorizontal, Sparkle, SquaresFour, Stack, Storefront, Sun, TextAlignCenter, TextAlignLeft, TextAlignRight, TextB, TextHOne, TextHThree, TextHTwo, TextItalic, TextStrikethrough, TextT, TextUnderline, ToggleLeft, Trash, Upload, User, UserCircle, UserPlus, Users, Warning, WarningCircle, WebhooksLogo, X, YoutubeLogo } from "@phosphor-icons/react";
|
|
14
14
|
import { clsx } from "clsx";
|
|
15
15
|
import { twMerge } from "tailwind-merge";
|
|
16
16
|
import { DndContext, DragOverlay, KeyboardSensor, PointerSensor, closestCenter, rectIntersection, useDraggable, useDroppable, useSensor, useSensors } from "@dnd-kit/core";
|
|
@@ -100,6 +100,34 @@ function useTheme() {
|
|
|
100
100
|
return context;
|
|
101
101
|
}
|
|
102
102
|
|
|
103
|
+
//#endregion
|
|
104
|
+
//#region src/lib/auth-provider-context.tsx
|
|
105
|
+
const AuthProviderContext = createContext({});
|
|
106
|
+
/**
|
|
107
|
+
* Provider that makes auth provider components available to all descendants
|
|
108
|
+
*/
|
|
109
|
+
function AuthProviderProvider({ children, authProviders }) {
|
|
110
|
+
return /* @__PURE__ */ jsx(AuthProviderContext.Provider, {
|
|
111
|
+
value: authProviders,
|
|
112
|
+
children
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Get all auth provider modules
|
|
117
|
+
*/
|
|
118
|
+
function useAuthProviders() {
|
|
119
|
+
return useContext(AuthProviderContext);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Get auth providers as an ordered array (buttons first, then forms)
|
|
123
|
+
*/
|
|
124
|
+
function useAuthProviderList() {
|
|
125
|
+
const providers = useContext(AuthProviderContext);
|
|
126
|
+
return Object.values(providers).toSorted((a, b) => {
|
|
127
|
+
return (a.LoginForm ? 1 : 0) - (b.LoginForm ? 1 : 0);
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
103
131
|
//#endregion
|
|
104
132
|
//#region src/lib/plugin-context.tsx
|
|
105
133
|
const PluginAdminContext = createContext({});
|
|
@@ -1105,6 +1133,8 @@ async function fetchContentList(collection, options) {
|
|
|
1105
1133
|
if (options?.limit) params.set("limit", String(options.limit));
|
|
1106
1134
|
if (options?.status) params.set("status", options.status);
|
|
1107
1135
|
if (options?.locale) params.set("locale", options.locale);
|
|
1136
|
+
if (options?.orderBy) params.set("orderBy", options.orderBy);
|
|
1137
|
+
if (options?.order) params.set("order", options.order);
|
|
1108
1138
|
return parseApiResponse(await apiFetch(`${API_BASE}/content/${collection}${params.toString() ? `?${params}` : ""}`), "Failed to fetch content");
|
|
1109
1139
|
}
|
|
1110
1140
|
/**
|
|
@@ -2261,6 +2291,10 @@ const API_TOKEN_SCOPES = {
|
|
|
2261
2291
|
MediaWrite: "media:write",
|
|
2262
2292
|
SchemaRead: "schema:read",
|
|
2263
2293
|
SchemaWrite: "schema:write",
|
|
2294
|
+
TaxonomiesManage: "taxonomies:manage",
|
|
2295
|
+
MenusManage: "menus:manage",
|
|
2296
|
+
SettingsRead: "settings:read",
|
|
2297
|
+
SettingsManage: "settings:manage",
|
|
2264
2298
|
Admin: "admin"
|
|
2265
2299
|
};
|
|
2266
2300
|
/**
|
|
@@ -2921,7 +2955,7 @@ var PluginFieldErrorBoundary = class extends React.Component {
|
|
|
2921
2955
|
* Each item is a collapsible card containing the defined sub-fields.
|
|
2922
2956
|
* Items can be added, removed, and reordered via drag-and-drop.
|
|
2923
2957
|
*/
|
|
2924
|
-
function ensureKeys(items) {
|
|
2958
|
+
function ensureKeys$1(items) {
|
|
2925
2959
|
return items.map((item, i) => {
|
|
2926
2960
|
const obj = typeof item === "object" && item !== null ? item : {};
|
|
2927
2961
|
return {
|
|
@@ -2930,13 +2964,13 @@ function ensureKeys(items) {
|
|
|
2930
2964
|
};
|
|
2931
2965
|
});
|
|
2932
2966
|
}
|
|
2933
|
-
function stripKeys(items) {
|
|
2967
|
+
function stripKeys$1(items) {
|
|
2934
2968
|
return items.map(({ _key, ...rest }) => rest);
|
|
2935
2969
|
}
|
|
2936
2970
|
function RepeaterField({ label, id, value, onChange, subFields, minItems = 0, maxItems }) {
|
|
2937
2971
|
const { _: _t } = useLingui();
|
|
2938
2972
|
const rawItems = Array.isArray(value) ? value : [];
|
|
2939
|
-
const [items, setItems] = React.useState(() => ensureKeys(rawItems));
|
|
2973
|
+
const [items, setItems] = React.useState(() => ensureKeys$1(rawItems));
|
|
2940
2974
|
const [collapsedItems, setCollapsedItems] = React.useState(/* @__PURE__ */ new Set());
|
|
2941
2975
|
React.useEffect(() => {
|
|
2942
2976
|
const incoming = Array.isArray(value) ? value : [];
|
|
@@ -2951,7 +2985,7 @@ function RepeaterField({ label, id, value, onChange, subFields, minItems = 0, ma
|
|
|
2951
2985
|
}, [value]);
|
|
2952
2986
|
const emitChange = (updated) => {
|
|
2953
2987
|
setItems(updated);
|
|
2954
|
-
onChange(stripKeys(updated));
|
|
2988
|
+
onChange(stripKeys$1(updated));
|
|
2955
2989
|
};
|
|
2956
2990
|
const handleAdd = () => {
|
|
2957
2991
|
if (maxItems && items.length >= maxItems) return;
|
|
@@ -3117,14 +3151,16 @@ function SubFieldInput({ subField, value, onChange }) {
|
|
|
3117
3151
|
label: subField.label,
|
|
3118
3152
|
value: typeof value === "string" ? value : "",
|
|
3119
3153
|
onChange: (e) => onChange(e.target.value),
|
|
3120
|
-
required: subField.required
|
|
3154
|
+
required: subField.required,
|
|
3155
|
+
dir: "auto"
|
|
3121
3156
|
});
|
|
3122
3157
|
case "text": return /* @__PURE__ */ jsx(InputArea, {
|
|
3123
3158
|
label: subField.label,
|
|
3124
3159
|
value: typeof value === "string" ? value : "",
|
|
3125
3160
|
onChange: (e) => onChange(e.target.value),
|
|
3126
3161
|
required: subField.required,
|
|
3127
|
-
rows: 3
|
|
3162
|
+
rows: 3,
|
|
3163
|
+
dir: "auto"
|
|
3128
3164
|
});
|
|
3129
3165
|
case "number":
|
|
3130
3166
|
case "integer": return /* @__PURE__ */ jsx(Input, {
|
|
@@ -6638,6 +6674,24 @@ function SlashCommandMenu({ state, onCommand, onClose: _onClose, setSelectedInde
|
|
|
6638
6674
|
}, item.id))
|
|
6639
6675
|
}), document.body);
|
|
6640
6676
|
}
|
|
6677
|
+
function getPluginBlockDefaultValues(fields) {
|
|
6678
|
+
const defaults = {};
|
|
6679
|
+
for (const field of fields ?? []) {
|
|
6680
|
+
const initialValue = "initial_value" in field ? field.initial_value : void 0;
|
|
6681
|
+
if (initialValue !== void 0) defaults[field.action_id] = initialValue;
|
|
6682
|
+
}
|
|
6683
|
+
return defaults;
|
|
6684
|
+
}
|
|
6685
|
+
function buildPluginBlockFormValues(block, initialValues) {
|
|
6686
|
+
const defaults = getPluginBlockDefaultValues(block?.fields);
|
|
6687
|
+
return initialValues ? {
|
|
6688
|
+
...defaults,
|
|
6689
|
+
...initialValues
|
|
6690
|
+
} : defaults;
|
|
6691
|
+
}
|
|
6692
|
+
function hasPluginBlockFormData(values) {
|
|
6693
|
+
return Object.values(values).some((value) => value !== void 0 && value !== null && value !== "");
|
|
6694
|
+
}
|
|
6641
6695
|
/**
|
|
6642
6696
|
* Plugin block insertion/editing modal.
|
|
6643
6697
|
* When the block has `fields`, renders Block Kit elements.
|
|
@@ -6648,8 +6702,7 @@ function PluginBlockModal({ block, initialValues, onClose, onInsert }) {
|
|
|
6648
6702
|
const inputRef = React.useRef(null);
|
|
6649
6703
|
React.useEffect(() => {
|
|
6650
6704
|
if (block) {
|
|
6651
|
-
|
|
6652
|
-
else setFormValues({});
|
|
6705
|
+
setFormValues(buildPluginBlockFormValues(block, initialValues));
|
|
6653
6706
|
if (!block.fields || block.fields.length === 0) setTimeout(() => inputRef.current?.focus(), 0);
|
|
6654
6707
|
}
|
|
6655
6708
|
}, [block, initialValues]);
|
|
@@ -6669,7 +6722,7 @@ function PluginBlockModal({ block, initialValues, onClose, onInsert }) {
|
|
|
6669
6722
|
};
|
|
6670
6723
|
const isEditing = !!initialValues;
|
|
6671
6724
|
const hasFields = block?.fields && block.fields.length > 0;
|
|
6672
|
-
const canSubmit = hasFields ?
|
|
6725
|
+
const canSubmit = hasFields ? hasPluginBlockFormData(formValues) : typeof formValues.id === "string" && formValues.id.trim().length > 0;
|
|
6673
6726
|
return /* @__PURE__ */ jsx(Dialog.Root, {
|
|
6674
6727
|
open: !!block,
|
|
6675
6728
|
onOpenChange: (open) => !open && onClose(),
|
|
@@ -6702,7 +6755,7 @@ function PluginBlockModal({ block, initialValues, onClose, onInsert }) {
|
|
|
6702
6755
|
}), /* @__PURE__ */ jsxs("form", {
|
|
6703
6756
|
onSubmit: handleSubmit,
|
|
6704
6757
|
children: [/* @__PURE__ */ jsx("div", {
|
|
6705
|
-
className: "py-4 space-y-4",
|
|
6758
|
+
className: "py-4 space-y-4 max-h-[70vh] overflow-y-auto -mx-1 px-1",
|
|
6706
6759
|
children: hasFields ? block.fields.map((field) => /* @__PURE__ */ jsx(BlockKitField, {
|
|
6707
6760
|
field,
|
|
6708
6761
|
pluginId: block.pluginId,
|
|
@@ -6789,12 +6842,244 @@ function BlockKitField({ field, pluginId, value, onChange }) {
|
|
|
6789
6842
|
children: field.label
|
|
6790
6843
|
})]
|
|
6791
6844
|
});
|
|
6845
|
+
case "repeater": return /* @__PURE__ */ jsx(BlockKitRepeater, {
|
|
6846
|
+
field,
|
|
6847
|
+
pluginId,
|
|
6848
|
+
value,
|
|
6849
|
+
onChange
|
|
6850
|
+
});
|
|
6792
6851
|
default: return /* @__PURE__ */ jsxs("div", {
|
|
6793
6852
|
className: "text-sm text-kumo-subtle",
|
|
6794
6853
|
children: ["Unknown field type: ", field.type]
|
|
6795
6854
|
});
|
|
6796
6855
|
}
|
|
6797
6856
|
}
|
|
6857
|
+
function ensureKeys(items) {
|
|
6858
|
+
return items.map((item, i) => {
|
|
6859
|
+
const obj = typeof item === "object" && item !== null ? item : {};
|
|
6860
|
+
return {
|
|
6861
|
+
...obj,
|
|
6862
|
+
_key: obj._key || `item-${i}-${Date.now()}`
|
|
6863
|
+
};
|
|
6864
|
+
});
|
|
6865
|
+
}
|
|
6866
|
+
function stripKeys(items) {
|
|
6867
|
+
return items.map(({ _key, ...rest }) => rest);
|
|
6868
|
+
}
|
|
6869
|
+
function BlockKitRepeater({ field, pluginId, value, onChange }) {
|
|
6870
|
+
const { _: _t2 } = useLingui();
|
|
6871
|
+
const rawItems = React.useMemo(() => Array.isArray(value) ? value : [], [value]);
|
|
6872
|
+
const [items, setItems] = React.useState(() => ensureKeys(rawItems));
|
|
6873
|
+
const [expanded, setExpanded] = React.useState(/* @__PURE__ */ new Set());
|
|
6874
|
+
const sensors = useSensors(useSensor(PointerSensor), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }));
|
|
6875
|
+
const lastEmittedRef = React.useRef(null);
|
|
6876
|
+
React.useEffect(() => {
|
|
6877
|
+
if (lastEmittedRef.current === rawItems) return;
|
|
6878
|
+
setItems((prev) => rawItems.map((item, i) => {
|
|
6879
|
+
const obj = typeof item === "object" && item !== null ? item : {};
|
|
6880
|
+
const existingKey = obj._key || prev[i]?._key;
|
|
6881
|
+
return {
|
|
6882
|
+
...obj,
|
|
6883
|
+
_key: existingKey || `item-${i}-${Date.now()}`
|
|
6884
|
+
};
|
|
6885
|
+
}));
|
|
6886
|
+
}, [rawItems]);
|
|
6887
|
+
const minItems = field.min_items ?? 0;
|
|
6888
|
+
const maxItems = field.max_items;
|
|
6889
|
+
const canAdd = maxItems === void 0 || items.length < maxItems;
|
|
6890
|
+
const canRemove = items.length > minItems;
|
|
6891
|
+
const addButtonLabel = field.item_label ? _t2({
|
|
6892
|
+
id: "3nLdaX",
|
|
6893
|
+
message: "Add {0}",
|
|
6894
|
+
values: { 0: field.item_label }
|
|
6895
|
+
}) : _t2({
|
|
6896
|
+
id: "NQ8llq",
|
|
6897
|
+
message: "Add item"
|
|
6898
|
+
});
|
|
6899
|
+
const emit = (next) => {
|
|
6900
|
+
setItems(next);
|
|
6901
|
+
const stripped = stripKeys(next);
|
|
6902
|
+
lastEmittedRef.current = stripped;
|
|
6903
|
+
onChange(field.action_id, stripped);
|
|
6904
|
+
};
|
|
6905
|
+
const handleAdd = () => {
|
|
6906
|
+
if (!canAdd) return;
|
|
6907
|
+
const newItem = { _key: `item-${Date.now()}-${Math.random().toString(36).slice(2, 7)}` };
|
|
6908
|
+
for (const sf of field.fields) switch (sf.type) {
|
|
6909
|
+
case "toggle":
|
|
6910
|
+
newItem[sf.action_id] = false;
|
|
6911
|
+
break;
|
|
6912
|
+
case "number_input":
|
|
6913
|
+
newItem[sf.action_id] = void 0;
|
|
6914
|
+
break;
|
|
6915
|
+
default: newItem[sf.action_id] = "";
|
|
6916
|
+
}
|
|
6917
|
+
setExpanded((prev) => {
|
|
6918
|
+
const next = new Set(prev);
|
|
6919
|
+
next.add(newItem._key);
|
|
6920
|
+
return next;
|
|
6921
|
+
});
|
|
6922
|
+
emit([...items, newItem]);
|
|
6923
|
+
};
|
|
6924
|
+
const handleRemove = (key) => {
|
|
6925
|
+
if (!canRemove) return;
|
|
6926
|
+
setExpanded((prev) => {
|
|
6927
|
+
if (!prev.has(key)) return prev;
|
|
6928
|
+
const next = new Set(prev);
|
|
6929
|
+
next.delete(key);
|
|
6930
|
+
return next;
|
|
6931
|
+
});
|
|
6932
|
+
emit(items.filter((it) => it._key !== key));
|
|
6933
|
+
};
|
|
6934
|
+
const handleItemChange = (key, subActionId, subValue) => {
|
|
6935
|
+
emit(items.map((it) => it._key === key ? {
|
|
6936
|
+
...it,
|
|
6937
|
+
[subActionId]: subValue
|
|
6938
|
+
} : it));
|
|
6939
|
+
};
|
|
6940
|
+
const handleDragEnd = (event) => {
|
|
6941
|
+
const { active, over } = event;
|
|
6942
|
+
if (!over || active.id === over.id) return;
|
|
6943
|
+
const oldIndex = items.findIndex((it) => it._key === active.id);
|
|
6944
|
+
const newIndex = items.findIndex((it) => it._key === over.id);
|
|
6945
|
+
if (oldIndex === -1 || newIndex === -1) return;
|
|
6946
|
+
emit(arrayMove(items, oldIndex, newIndex));
|
|
6947
|
+
};
|
|
6948
|
+
const toggleExpanded = (key) => {
|
|
6949
|
+
setExpanded((prev) => {
|
|
6950
|
+
const next = new Set(prev);
|
|
6951
|
+
if (next.has(key)) next.delete(key);
|
|
6952
|
+
else next.add(key);
|
|
6953
|
+
return next;
|
|
6954
|
+
});
|
|
6955
|
+
};
|
|
6956
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
6957
|
+
className: "space-y-2",
|
|
6958
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
6959
|
+
className: "flex items-center justify-between",
|
|
6960
|
+
children: [/* @__PURE__ */ jsxs("label", {
|
|
6961
|
+
className: "text-sm font-medium",
|
|
6962
|
+
children: [field.label, items.length > 0 && /* @__PURE__ */ jsxs("span", {
|
|
6963
|
+
className: "ms-2 text-kumo-subtle font-normal",
|
|
6964
|
+
children: [
|
|
6965
|
+
"(",
|
|
6966
|
+
items.length,
|
|
6967
|
+
")"
|
|
6968
|
+
]
|
|
6969
|
+
})]
|
|
6970
|
+
}), canAdd && /* @__PURE__ */ jsx(Button, {
|
|
6971
|
+
variant: "outline",
|
|
6972
|
+
size: "sm",
|
|
6973
|
+
icon: /* @__PURE__ */ jsx(Plus, {}),
|
|
6974
|
+
onClick: handleAdd,
|
|
6975
|
+
type: "button",
|
|
6976
|
+
children: addButtonLabel
|
|
6977
|
+
})]
|
|
6978
|
+
}), items.length === 0 ? /* @__PURE__ */ jsxs("div", {
|
|
6979
|
+
className: "border-2 border-dashed rounded-lg p-6 text-center text-kumo-subtle",
|
|
6980
|
+
children: [/* @__PURE__ */ jsx("p", {
|
|
6981
|
+
className: "text-sm",
|
|
6982
|
+
children: _t2({
|
|
6983
|
+
id: "bWmJ0A",
|
|
6984
|
+
message: "No items yet"
|
|
6985
|
+
})
|
|
6986
|
+
}), canAdd && /* @__PURE__ */ jsx(Button, {
|
|
6987
|
+
variant: "outline",
|
|
6988
|
+
size: "sm",
|
|
6989
|
+
className: "mt-2",
|
|
6990
|
+
icon: /* @__PURE__ */ jsx(Plus, {}),
|
|
6991
|
+
onClick: handleAdd,
|
|
6992
|
+
type: "button",
|
|
6993
|
+
children: addButtonLabel
|
|
6994
|
+
})]
|
|
6995
|
+
}) : /* @__PURE__ */ jsx(DndContext, {
|
|
6996
|
+
sensors,
|
|
6997
|
+
collisionDetection: closestCenter,
|
|
6998
|
+
onDragEnd: handleDragEnd,
|
|
6999
|
+
children: /* @__PURE__ */ jsx(SortableContext, {
|
|
7000
|
+
items: items.map((it) => it._key),
|
|
7001
|
+
strategy: verticalListSortingStrategy,
|
|
7002
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
7003
|
+
className: "space-y-2",
|
|
7004
|
+
children: items.map((item, index) => /* @__PURE__ */ jsx(BlockKitRepeaterItem, {
|
|
7005
|
+
item,
|
|
7006
|
+
index,
|
|
7007
|
+
fields: field.fields,
|
|
7008
|
+
pluginId,
|
|
7009
|
+
isCollapsed: !expanded.has(item._key),
|
|
7010
|
+
onToggleCollapse: () => toggleExpanded(item._key),
|
|
7011
|
+
onRemove: canRemove ? () => handleRemove(item._key) : void 0,
|
|
7012
|
+
onChange: (subActionId, v) => handleItemChange(item._key, subActionId, v)
|
|
7013
|
+
}, item._key))
|
|
7014
|
+
})
|
|
7015
|
+
})
|
|
7016
|
+
})]
|
|
7017
|
+
});
|
|
7018
|
+
}
|
|
7019
|
+
function BlockKitRepeaterItem({ item, index, fields, pluginId, isCollapsed, onToggleCollapse, onRemove, onChange }) {
|
|
7020
|
+
const { _: _t3 } = useLingui();
|
|
7021
|
+
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: item._key });
|
|
7022
|
+
const style = {
|
|
7023
|
+
transform: CSS.Transform.toString(transform),
|
|
7024
|
+
transition
|
|
7025
|
+
};
|
|
7026
|
+
const summaryField = fields.find((f) => f.type === "text_input");
|
|
7027
|
+
const summaryLabel = (summaryField && typeof item[summaryField.action_id] === "string" ? item[summaryField.action_id] : "").trim() || _t3({
|
|
7028
|
+
id: "y/5CE8",
|
|
7029
|
+
message: "Item {0}",
|
|
7030
|
+
values: { 0: index + 1 }
|
|
7031
|
+
});
|
|
7032
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
7033
|
+
ref: setNodeRef,
|
|
7034
|
+
style,
|
|
7035
|
+
className: cn("border border-kumo-line rounded-lg bg-kumo-base", isDragging && "opacity-50 ring-2 ring-kumo-brand"),
|
|
7036
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
7037
|
+
className: "flex items-center gap-2 px-3 py-2 border-b border-kumo-line",
|
|
7038
|
+
children: [
|
|
7039
|
+
/* @__PURE__ */ jsx("span", {
|
|
7040
|
+
className: "inline-flex h-4 w-4 text-kumo-subtle cursor-grab shrink-0",
|
|
7041
|
+
"aria-label": _t3({
|
|
7042
|
+
id: "KGi3u9",
|
|
7043
|
+
message: "Drag to reorder"
|
|
7044
|
+
}),
|
|
7045
|
+
...attributes,
|
|
7046
|
+
...listeners,
|
|
7047
|
+
children: /* @__PURE__ */ jsx(DotsSixVertical, { className: "h-4 w-4" })
|
|
7048
|
+
}),
|
|
7049
|
+
/* @__PURE__ */ jsxs("button", {
|
|
7050
|
+
type: "button",
|
|
7051
|
+
className: "flex items-center gap-2 flex-1 min-w-0 text-left cursor-pointer",
|
|
7052
|
+
onClick: onToggleCollapse,
|
|
7053
|
+
"aria-expanded": !isCollapsed,
|
|
7054
|
+
children: [isCollapsed ? /* @__PURE__ */ jsx(CaretRight, { className: "h-4 w-4 text-kumo-subtle shrink-0" }) : /* @__PURE__ */ jsx(CaretDown, { className: "h-4 w-4 text-kumo-subtle shrink-0" }), /* @__PURE__ */ jsx("span", {
|
|
7055
|
+
className: "text-sm font-medium flex-1 truncate",
|
|
7056
|
+
children: summaryLabel
|
|
7057
|
+
})]
|
|
7058
|
+
}),
|
|
7059
|
+
onRemove && /* @__PURE__ */ jsx(Button, {
|
|
7060
|
+
variant: "ghost",
|
|
7061
|
+
shape: "square",
|
|
7062
|
+
type: "button",
|
|
7063
|
+
onClick: onRemove,
|
|
7064
|
+
"aria-label": _t3({
|
|
7065
|
+
id: "mU3j1b",
|
|
7066
|
+
message: "Remove item {0}",
|
|
7067
|
+
values: { 0: index + 1 }
|
|
7068
|
+
}),
|
|
7069
|
+
children: /* @__PURE__ */ jsx(Trash, { className: "h-3.5 w-3.5 text-kumo-danger" })
|
|
7070
|
+
})
|
|
7071
|
+
]
|
|
7072
|
+
}), !isCollapsed && /* @__PURE__ */ jsx("div", {
|
|
7073
|
+
className: "p-3 space-y-3",
|
|
7074
|
+
children: fields.map((sf) => /* @__PURE__ */ jsx(BlockKitField, {
|
|
7075
|
+
field: sf,
|
|
7076
|
+
pluginId,
|
|
7077
|
+
value: item[sf.action_id],
|
|
7078
|
+
onChange: (actionId, v) => onChange(actionId, v)
|
|
7079
|
+
}, sf.action_id))
|
|
7080
|
+
})]
|
|
7081
|
+
});
|
|
7082
|
+
}
|
|
6798
7083
|
/**
|
|
6799
7084
|
* Select field that supports loading options dynamically via `optionsRoute`.
|
|
6800
7085
|
* When `optionsRoute` is set, fetches `{ items: [{ id, name }] }` from the plugin route.
|
|
@@ -6893,7 +7178,7 @@ function EditorFooter({ editor }) {
|
|
|
6893
7178
|
* Portable Text Editor Component
|
|
6894
7179
|
*/
|
|
6895
7180
|
function PortableTextEditor({ value, onChange, placeholder = "Start writing...", className, editable = true, "aria-labelledby": ariaLabelledby, pluginBlocks = [], focusMode: controlledFocusMode, onFocusModeChange, onEditorReady, minimal = false, onBlockSidebarOpen, onBlockSidebarClose }) {
|
|
6896
|
-
const { _:
|
|
7181
|
+
const { _: _t4 } = useLingui();
|
|
6897
7182
|
const onChangeRef = React.useRef(onChange);
|
|
6898
7183
|
React.useEffect(() => {
|
|
6899
7184
|
onChangeRef.current = onChange;
|
|
@@ -6977,7 +7262,7 @@ function PortableTextEditor({ value, onChange, placeholder = "Start writing...",
|
|
|
6977
7262
|
for (const block of pluginBlocks) cmds.push({
|
|
6978
7263
|
id: `plugin-${block.pluginId}-${block.type}`,
|
|
6979
7264
|
title: block.label,
|
|
6980
|
-
description: block.description ??
|
|
7265
|
+
description: block.description ?? _t4({
|
|
6981
7266
|
id: "g0zqOw",
|
|
6982
7267
|
message: "Embed a {0}",
|
|
6983
7268
|
values: { 0: block.label }
|
|
@@ -6994,7 +7279,7 @@ function PortableTextEditor({ value, onChange, placeholder = "Start writing...",
|
|
|
6994
7279
|
}
|
|
6995
7280
|
});
|
|
6996
7281
|
return cmds;
|
|
6997
|
-
}, [pluginBlocks,
|
|
7282
|
+
}, [pluginBlocks, _t4]);
|
|
6998
7283
|
const filterCommandsRef = React.useRef((_q) => []);
|
|
6999
7284
|
filterCommandsRef.current = (query) => {
|
|
7000
7285
|
if (!query) return slashCommands;
|
|
@@ -7002,8 +7287,8 @@ function PortableTextEditor({ value, onChange, placeholder = "Start writing...",
|
|
|
7002
7287
|
const titleMatches = [];
|
|
7003
7288
|
const otherMatches = [];
|
|
7004
7289
|
for (const item of slashCommands) {
|
|
7005
|
-
const titleStr = typeof item.title === "string" ? item.title :
|
|
7006
|
-
const descStr = typeof item.description === "string" ? item.description :
|
|
7290
|
+
const titleStr = typeof item.title === "string" ? item.title : _t4(item.title);
|
|
7291
|
+
const descStr = typeof item.description === "string" ? item.description : _t4(item.description);
|
|
7007
7292
|
if (titleStr.toLowerCase().includes(searchText)) titleMatches.push(item);
|
|
7008
7293
|
else if (descStr.toLowerCase().includes(searchText) || item.aliases?.some((alias) => alias.toLowerCase().includes(searchText))) otherMatches.push(item);
|
|
7009
7294
|
}
|
|
@@ -7055,7 +7340,10 @@ function PortableTextEditor({ value, onChange, placeholder = "Start writing...",
|
|
|
7055
7340
|
content: initialContent,
|
|
7056
7341
|
editable,
|
|
7057
7342
|
immediatelyRender: true,
|
|
7058
|
-
editorProps: React.useMemo(() => ({ attributes: {
|
|
7343
|
+
editorProps: React.useMemo(() => ({ attributes: {
|
|
7344
|
+
class: "prose prose-sm sm:prose-base dark:prose-invert max-w-none focus:outline-none min-h-[200px] p-4",
|
|
7345
|
+
dir: "auto"
|
|
7346
|
+
} }), []),
|
|
7059
7347
|
onUpdate: ({ editor: updatedEditor }) => {
|
|
7060
7348
|
const cb = onChangeRef.current;
|
|
7061
7349
|
if (cb) cb(prosemirrorToPortableText(updatedEditor.getJSON()));
|
|
@@ -8406,7 +8694,8 @@ function SeoPanel({ contentKey, seo, onChange }) {
|
|
|
8406
8694
|
value: draft.title,
|
|
8407
8695
|
onChange: (e) => {
|
|
8408
8696
|
updateDraft({ title: e.target.value });
|
|
8409
|
-
}
|
|
8697
|
+
},
|
|
8698
|
+
dir: "auto"
|
|
8410
8699
|
}),
|
|
8411
8700
|
/* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(InputArea, {
|
|
8412
8701
|
label: _t({
|
|
@@ -8425,7 +8714,8 @@ function SeoPanel({ contentKey, seo, onChange }) {
|
|
|
8425
8714
|
onChange: (e) => {
|
|
8426
8715
|
updateDraft({ description: e.target.value });
|
|
8427
8716
|
},
|
|
8428
|
-
rows: 3
|
|
8717
|
+
rows: 3,
|
|
8718
|
+
dir: "auto"
|
|
8429
8719
|
}) }),
|
|
8430
8720
|
/* @__PURE__ */ jsx(Input, {
|
|
8431
8721
|
label: _t({
|
|
@@ -8567,7 +8857,7 @@ function CategoryCheckboxTree({ term, level = 0, selectedIds, onToggle }) {
|
|
|
8567
8857
|
const isChecked = selectedIds.has(term.id);
|
|
8568
8858
|
return /* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsxs("label", {
|
|
8569
8859
|
className: "flex items-center py-1 cursor-pointer hover:bg-kumo-tint/50 rounded px-2",
|
|
8570
|
-
style: {
|
|
8860
|
+
style: { marginInlineStart: `${level}rem` },
|
|
8571
8861
|
children: [/* @__PURE__ */ jsx("input", {
|
|
8572
8862
|
type: "checkbox",
|
|
8573
8863
|
checked: isChecked,
|
|
@@ -8917,13 +9207,6 @@ function ContentEditor({ collection, collectionLabel, item, fields, isNew, isSav
|
|
|
8917
9207
|
roleLabel: entry.roleLabel
|
|
8918
9208
|
})) ?? []);
|
|
8919
9209
|
const [portableTextEditor, setPortableTextEditor] = React.useState(null);
|
|
8920
|
-
const ptEditorClaimedRef = React.useRef(false);
|
|
8921
|
-
React.useCallback((editor) => {
|
|
8922
|
-
if (!ptEditorClaimedRef.current) {
|
|
8923
|
-
ptEditorClaimedRef.current = true;
|
|
8924
|
-
setPortableTextEditor(editor);
|
|
8925
|
-
}
|
|
8926
|
-
}, []);
|
|
8927
9210
|
const [blockSidebarPanel, setBlockSidebarPanel] = React.useState(null);
|
|
8928
9211
|
const handleBlockSidebarOpen = React.useCallback((panel) => {
|
|
8929
9212
|
setBlockSidebarPanel(panel);
|
|
@@ -9751,6 +10034,7 @@ function FieldRenderer({ name, field, value, onChange, onEditorReady, minimal, p
|
|
|
9751
10034
|
value: typeof value === "string" ? value : "",
|
|
9752
10035
|
onChange: (e) => handleChange(e.target.value),
|
|
9753
10036
|
required: field.required,
|
|
10037
|
+
dir: "auto",
|
|
9754
10038
|
className: minimal ? "border-0 bg-transparent px-0 text-lg font-medium focus-visible:ring-0 focus-visible:ring-offset-0" : void 0
|
|
9755
10039
|
});
|
|
9756
10040
|
case "number": return /* @__PURE__ */ jsx(Input, {
|
|
@@ -9801,6 +10085,7 @@ function FieldRenderer({ name, field, value, onChange, onEditorReady, minimal, p
|
|
|
9801
10085
|
value: typeof value === "string" ? value : "",
|
|
9802
10086
|
onChange: (e) => handleChange(e.target.value),
|
|
9803
10087
|
rows: 10,
|
|
10088
|
+
dir: "auto",
|
|
9804
10089
|
placeholder: _t2({
|
|
9805
10090
|
id: "dPFFy+",
|
|
9806
10091
|
message: "Enter markdown content..."
|
|
@@ -9897,7 +10182,8 @@ function FieldRenderer({ name, field, value, onChange, onEditorReady, minimal, p
|
|
|
9897
10182
|
id,
|
|
9898
10183
|
value: typeof value === "string" ? value : "",
|
|
9899
10184
|
onChange: (e) => handleChange(e.target.value),
|
|
9900
|
-
required: field.required
|
|
10185
|
+
required: field.required,
|
|
10186
|
+
dir: "auto"
|
|
9901
10187
|
});
|
|
9902
10188
|
}
|
|
9903
10189
|
}
|
|
@@ -10537,7 +10823,7 @@ function getItemTitle$1(item) {
|
|
|
10537
10823
|
/**
|
|
10538
10824
|
* Content list view with table display and trash tab
|
|
10539
10825
|
*/
|
|
10540
|
-
function ContentList({ collection, collectionLabel, items, trashedItems = [], isLoading, isTrashedLoading, onDelete, onDuplicate, onRestore, onPermanentDelete, onLoadMore, onLoadMoreTrashed, hasMore, hasMoreTrashed, trashedCount = 0, i18n: i18n$1, activeLocale, onLocaleChange, urlPattern }) {
|
|
10826
|
+
function ContentList({ collection, collectionLabel, items, trashedItems = [], isLoading, isTrashedLoading, onDelete, onDuplicate, onRestore, onPermanentDelete, onLoadMore, onLoadMoreTrashed, hasMore, hasMoreTrashed, trashedCount = 0, i18n: i18n$1, activeLocale, onLocaleChange, urlPattern, sort, onSortChange }) {
|
|
10541
10827
|
const { _: _t } = useLingui();
|
|
10542
10828
|
const [activeTab, setActiveTab] = React.useState("all");
|
|
10543
10829
|
const [searchQuery, setSearchQuery] = React.useState("");
|
|
@@ -10653,34 +10939,38 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
|
|
|
10653
10939
|
children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", {
|
|
10654
10940
|
className: "border-b bg-kumo-tint/50",
|
|
10655
10941
|
children: [
|
|
10656
|
-
/* @__PURE__ */ jsx(
|
|
10657
|
-
|
|
10658
|
-
|
|
10659
|
-
|
|
10942
|
+
/* @__PURE__ */ jsx(SortableTh, {
|
|
10943
|
+
field: "title",
|
|
10944
|
+
sort,
|
|
10945
|
+
onSortChange,
|
|
10946
|
+
label: _t({
|
|
10660
10947
|
id: "MHrjPM",
|
|
10661
10948
|
message: "Title"
|
|
10662
10949
|
})
|
|
10663
10950
|
}),
|
|
10664
|
-
/* @__PURE__ */ jsx(
|
|
10665
|
-
|
|
10666
|
-
|
|
10667
|
-
|
|
10951
|
+
/* @__PURE__ */ jsx(SortableTh, {
|
|
10952
|
+
field: "status",
|
|
10953
|
+
sort,
|
|
10954
|
+
onSortChange,
|
|
10955
|
+
label: _t({
|
|
10668
10956
|
id: "uAQUqI",
|
|
10669
10957
|
message: "Status"
|
|
10670
10958
|
})
|
|
10671
10959
|
}),
|
|
10672
|
-
i18n$1 && /* @__PURE__ */ jsx(
|
|
10673
|
-
|
|
10674
|
-
|
|
10675
|
-
|
|
10960
|
+
i18n$1 && /* @__PURE__ */ jsx(SortableTh, {
|
|
10961
|
+
field: "locale",
|
|
10962
|
+
sort,
|
|
10963
|
+
onSortChange,
|
|
10964
|
+
label: _t({
|
|
10676
10965
|
id: "8NbHF7",
|
|
10677
10966
|
message: "Locale"
|
|
10678
10967
|
})
|
|
10679
10968
|
}),
|
|
10680
|
-
/* @__PURE__ */ jsx(
|
|
10681
|
-
|
|
10682
|
-
|
|
10683
|
-
|
|
10969
|
+
/* @__PURE__ */ jsx(SortableTh, {
|
|
10970
|
+
field: "updatedAt",
|
|
10971
|
+
sort,
|
|
10972
|
+
onSortChange,
|
|
10973
|
+
label: _t({
|
|
10684
10974
|
id: "mYGY3B",
|
|
10685
10975
|
message: "Date"
|
|
10686
10976
|
})
|
|
@@ -10873,6 +11163,52 @@ function ContentList({ collection, collectionLabel, items, trashedItems = [], is
|
|
|
10873
11163
|
]
|
|
10874
11164
|
});
|
|
10875
11165
|
}
|
|
11166
|
+
/**
|
|
11167
|
+
* Table header that doubles as a sort control when the parent opted in by
|
|
11168
|
+
* passing `onSortChange`. When no callback is provided we fall back to a
|
|
11169
|
+
* plain `<th>` so legacy callers (and screen readers) see exactly the same
|
|
11170
|
+
* markup as before this change.
|
|
11171
|
+
*
|
|
11172
|
+
* The button's accessible name is just the column label — the sort state
|
|
11173
|
+
* is conveyed via `aria-sort` on the <th>, which screen readers announce
|
|
11174
|
+
* automatically. Adding a verbose aria-label would make each header re-read
|
|
11175
|
+
* the sort instruction on every focus, which is noisy.
|
|
11176
|
+
*/
|
|
11177
|
+
function SortableTh({ field, sort, onSortChange, label }) {
|
|
11178
|
+
const isActive = sort?.field === field;
|
|
11179
|
+
const direction = isActive ? sort?.direction : void 0;
|
|
11180
|
+
if (!onSortChange) return /* @__PURE__ */ jsx("th", {
|
|
11181
|
+
scope: "col",
|
|
11182
|
+
className: "px-4 py-3 text-start text-sm font-medium",
|
|
11183
|
+
children: label
|
|
11184
|
+
});
|
|
11185
|
+
const ariaSort = isActive ? direction === "asc" ? "ascending" : "descending" : "none";
|
|
11186
|
+
const handleClick = () => {
|
|
11187
|
+
if (isActive) onSortChange({
|
|
11188
|
+
field,
|
|
11189
|
+
direction: direction === "asc" ? "desc" : "asc"
|
|
11190
|
+
});
|
|
11191
|
+
else onSortChange({
|
|
11192
|
+
field,
|
|
11193
|
+
direction: "desc"
|
|
11194
|
+
});
|
|
11195
|
+
};
|
|
11196
|
+
const Icon = isActive ? direction === "asc" ? CaretUp : CaretDown : CaretUpDown;
|
|
11197
|
+
return /* @__PURE__ */ jsx("th", {
|
|
11198
|
+
scope: "col",
|
|
11199
|
+
"aria-sort": ariaSort,
|
|
11200
|
+
className: "px-4 py-3 text-start text-sm font-medium",
|
|
11201
|
+
children: /* @__PURE__ */ jsxs("button", {
|
|
11202
|
+
type: "button",
|
|
11203
|
+
onClick: handleClick,
|
|
11204
|
+
className: cn("inline-flex items-center gap-1 rounded hover:text-kumo-brand", "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-kumo-brand", isActive ? "text-kumo-fg" : "text-kumo-subtle"),
|
|
11205
|
+
children: [/* @__PURE__ */ jsx("span", { children: label }), /* @__PURE__ */ jsx(Icon, {
|
|
11206
|
+
className: "h-3 w-3",
|
|
11207
|
+
"aria-hidden": "true"
|
|
11208
|
+
})]
|
|
11209
|
+
})
|
|
11210
|
+
});
|
|
11211
|
+
}
|
|
10876
11212
|
function ContentListItem({ item, collection, onDelete, onDuplicate, showLocale, urlPattern }) {
|
|
10877
11213
|
const { _: _t2 } = useLingui();
|
|
10878
11214
|
const title = getItemTitle$1(item);
|
|
@@ -12094,7 +12430,7 @@ function ContentTypeEditor({ collection, isNew, isSaving, onSave, onAddField, on
|
|
|
12094
12430
|
const [labelSingular, setLabelSingular] = React.useState(collection?.labelSingular ?? "");
|
|
12095
12431
|
const [description, setDescription] = React.useState(collection?.description ?? "");
|
|
12096
12432
|
const [urlPattern, setUrlPattern] = React.useState(collection?.urlPattern ?? "");
|
|
12097
|
-
const [supports, setSupports] = React.useState((collection?.supports ?? ["drafts"]).filter((s) => s !== "seo"));
|
|
12433
|
+
const [supports, setSupports] = React.useState((collection?.supports ?? ["drafts", "revisions"]).filter((s) => s !== "seo"));
|
|
12098
12434
|
const [hasSeo, setHasSeo] = React.useState(collection?.hasSeo ?? false);
|
|
12099
12435
|
const [commentsEnabled, setCommentsEnabled] = React.useState(collection?.commentsEnabled ?? false);
|
|
12100
12436
|
const [commentsModeration, setCommentsModeration] = React.useState(collection?.commentsModeration ?? "first_time");
|
|
@@ -14742,54 +15078,13 @@ function PasskeyLogin({ optionsEndpoint, verifyEndpoint, onSuccess, onError, sho
|
|
|
14742
15078
|
* It's a standalone page for authentication.
|
|
14743
15079
|
*
|
|
14744
15080
|
* Supports:
|
|
14745
|
-
* - Passkey authentication (
|
|
14746
|
-
* -
|
|
15081
|
+
* - Passkey authentication (always available)
|
|
15082
|
+
* - Pluggable auth providers (AT Protocol, GitHub, Google, etc.) when configured
|
|
14747
15083
|
* - Magic link (email) when configured
|
|
14748
15084
|
*
|
|
14749
15085
|
* When external auth (e.g., Cloudflare Access) is configured, this page
|
|
14750
15086
|
* redirects to the admin dashboard since authentication is handled externally.
|
|
14751
15087
|
*/
|
|
14752
|
-
function GitHubIcon({ className }) {
|
|
14753
|
-
return /* @__PURE__ */ jsx("svg", {
|
|
14754
|
-
className,
|
|
14755
|
-
viewBox: "0 0 24 24",
|
|
14756
|
-
fill: "currentColor",
|
|
14757
|
-
children: /* @__PURE__ */ jsx("path", { d: "M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z" })
|
|
14758
|
-
});
|
|
14759
|
-
}
|
|
14760
|
-
function GoogleIcon({ className }) {
|
|
14761
|
-
return /* @__PURE__ */ jsxs("svg", {
|
|
14762
|
-
className,
|
|
14763
|
-
viewBox: "0 0 24 24",
|
|
14764
|
-
children: [
|
|
14765
|
-
/* @__PURE__ */ jsx("path", {
|
|
14766
|
-
fill: "#4285F4",
|
|
14767
|
-
d: "M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92c-.26 1.37-1.04 2.53-2.21 3.31v2.77h3.57c2.08-1.92 3.28-4.74 3.28-8.09z"
|
|
14768
|
-
}),
|
|
14769
|
-
/* @__PURE__ */ jsx("path", {
|
|
14770
|
-
fill: "#34A853",
|
|
14771
|
-
d: "M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84C3.99 20.53 7.7 23 12 23z"
|
|
14772
|
-
}),
|
|
14773
|
-
/* @__PURE__ */ jsx("path", {
|
|
14774
|
-
fill: "#FBBC05",
|
|
14775
|
-
d: "M5.84 14.09c-.22-.66-.35-1.36-.35-2.09s.13-1.43.35-2.09V7.07H2.18C1.43 8.55 1 10.22 1 12s.43 3.45 1.18 4.93l2.85-2.22.81-.62z"
|
|
14776
|
-
}),
|
|
14777
|
-
/* @__PURE__ */ jsx("path", {
|
|
14778
|
-
fill: "#EA4335",
|
|
14779
|
-
d: "M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15C17.45 2.09 14.97 1 12 1 7.7 1 3.99 3.47 2.18 7.07l3.66 2.84c.87-2.6 3.3-4.53 6.16-4.53z"
|
|
14780
|
-
})
|
|
14781
|
-
]
|
|
14782
|
-
});
|
|
14783
|
-
}
|
|
14784
|
-
const OAUTH_PROVIDERS = [{
|
|
14785
|
-
id: "github",
|
|
14786
|
-
name: "GitHub",
|
|
14787
|
-
icon: /* @__PURE__ */ jsx(GitHubIcon, { className: "h-5 w-5" })
|
|
14788
|
-
}, {
|
|
14789
|
-
id: "google",
|
|
14790
|
-
name: "Google",
|
|
14791
|
-
icon: /* @__PURE__ */ jsx(GoogleIcon, { className: "h-5 w-5" })
|
|
14792
|
-
}];
|
|
14793
15088
|
function MagicLinkForm({ onBack }) {
|
|
14794
15089
|
const { _: _t } = useLingui();
|
|
14795
15090
|
const [email, setEmail] = React.useState("");
|
|
@@ -14930,22 +15225,21 @@ function MagicLinkForm({ onBack }) {
|
|
|
14930
15225
|
]
|
|
14931
15226
|
});
|
|
14932
15227
|
}
|
|
14933
|
-
function handleOAuthClick(providerId) {
|
|
14934
|
-
window.location.href = `/_emdash/api/auth/oauth/${providerId}`;
|
|
14935
|
-
}
|
|
14936
15228
|
function LoginPage({ redirectUrl = "/_emdash/admin" }) {
|
|
14937
15229
|
const safeRedirectUrl = sanitizeRedirectUrl(redirectUrl);
|
|
14938
15230
|
const { _: _t2 } = useLingui();
|
|
14939
15231
|
const { locale, setLocale } = useLocale();
|
|
14940
15232
|
const [method, setMethod] = React.useState("passkey");
|
|
14941
15233
|
const [urlError, setUrlError] = React.useState(null);
|
|
14942
|
-
const
|
|
14943
|
-
|
|
14944
|
-
|
|
15234
|
+
const [activeProvider, setActiveProvider] = React.useState(null);
|
|
15235
|
+
const authProviderList = useAuthProviderList();
|
|
15236
|
+
const { data: authInfo, isLoading: authModeLoading } = useQuery({
|
|
15237
|
+
queryKey: ["authMode"],
|
|
15238
|
+
queryFn: fetchAuthMode
|
|
14945
15239
|
});
|
|
14946
15240
|
React.useEffect(() => {
|
|
14947
|
-
if (
|
|
14948
|
-
}, [
|
|
15241
|
+
if (authInfo?.authMode && authInfo.authMode !== "passkey") window.location.href = safeRedirectUrl;
|
|
15242
|
+
}, [authInfo, safeRedirectUrl]);
|
|
14949
15243
|
React.useEffect(() => {
|
|
14950
15244
|
const params = new URLSearchParams(window.location.search);
|
|
14951
15245
|
const error = params.get("error");
|
|
@@ -14962,15 +15256,12 @@ function LoginPage({ redirectUrl = "/_emdash/admin" }) {
|
|
|
14962
15256
|
const handleSuccess = () => {
|
|
14963
15257
|
window.location.href = safeRedirectUrl;
|
|
14964
15258
|
};
|
|
14965
|
-
|
|
15259
|
+
const buttonProviders = authProviderList.filter((p) => p.LoginButton);
|
|
15260
|
+
if (authModeLoading || authInfo?.authMode && authInfo.authMode !== "passkey") return /* @__PURE__ */ jsx("div", {
|
|
14966
15261
|
className: "min-h-screen flex items-center justify-center bg-kumo-base p-4",
|
|
14967
15262
|
children: /* @__PURE__ */ jsxs("div", {
|
|
14968
15263
|
className: "flex flex-col items-center",
|
|
14969
|
-
children: [/* @__PURE__ */ jsx(BrandLogo, {
|
|
14970
|
-
logoUrl: manifest?.admin?.logo,
|
|
14971
|
-
siteName: manifest?.admin?.siteName,
|
|
14972
|
-
className: "h-10 mb-4"
|
|
14973
|
-
}), /* @__PURE__ */ jsx(Loader, {})]
|
|
15264
|
+
children: [/* @__PURE__ */ jsx(BrandLogo, { className: "h-10 mb-4" }), /* @__PURE__ */ jsx(Loader, {})]
|
|
14974
15265
|
})
|
|
14975
15266
|
});
|
|
14976
15267
|
return /* @__PURE__ */ jsx("div", {
|
|
@@ -14980,19 +15271,19 @@ function LoginPage({ redirectUrl = "/_emdash/admin" }) {
|
|
|
14980
15271
|
children: [
|
|
14981
15272
|
/* @__PURE__ */ jsxs("div", {
|
|
14982
15273
|
className: "text-center mb-8",
|
|
14983
|
-
children: [/* @__PURE__ */ jsx(BrandLogo, {
|
|
14984
|
-
logoUrl: manifest?.admin?.logo,
|
|
14985
|
-
siteName: manifest?.admin?.siteName,
|
|
14986
|
-
className: "h-10 mx-auto mb-2"
|
|
14987
|
-
}), /* @__PURE__ */ jsxs("h1", {
|
|
15274
|
+
children: [/* @__PURE__ */ jsx(BrandLogo, { className: "h-10 mx-auto mb-2" }), /* @__PURE__ */ jsx("h1", {
|
|
14988
15275
|
className: "text-2xl font-semibold text-kumo-default",
|
|
14989
|
-
children:
|
|
14990
|
-
id: "lE0wHD",
|
|
14991
|
-
message: "Sign in to your site"
|
|
14992
|
-
}), method === "magic-link" && _t2({
|
|
15276
|
+
children: method === "magic-link" ? _t2({
|
|
14993
15277
|
id: "me9L29",
|
|
14994
15278
|
message: "Sign in with email"
|
|
14995
|
-
})
|
|
15279
|
+
}) : activeProvider ? _t2({
|
|
15280
|
+
id: "e/ToF5",
|
|
15281
|
+
message: "Sign in with {0}",
|
|
15282
|
+
values: { 0: authProviderList.find((p) => p.id === activeProvider)?.label ?? activeProvider }
|
|
15283
|
+
}) : _t2({
|
|
15284
|
+
id: "lE0wHD",
|
|
15285
|
+
message: "Sign in to your site"
|
|
15286
|
+
})
|
|
14996
15287
|
})]
|
|
14997
15288
|
}),
|
|
14998
15289
|
urlError && /* @__PURE__ */ jsx("div", {
|
|
@@ -15001,71 +15292,94 @@ function LoginPage({ redirectUrl = "/_emdash/admin" }) {
|
|
|
15001
15292
|
}),
|
|
15002
15293
|
/* @__PURE__ */ jsxs("div", {
|
|
15003
15294
|
className: "bg-kumo-base border rounded-lg shadow-sm p-6",
|
|
15004
|
-
children: [
|
|
15005
|
-
|
|
15006
|
-
|
|
15007
|
-
|
|
15008
|
-
|
|
15009
|
-
|
|
15010
|
-
|
|
15011
|
-
|
|
15012
|
-
|
|
15013
|
-
|
|
15014
|
-
|
|
15015
|
-
|
|
15016
|
-
|
|
15017
|
-
|
|
15018
|
-
|
|
15019
|
-
|
|
15020
|
-
|
|
15021
|
-
|
|
15022
|
-
|
|
15023
|
-
|
|
15024
|
-
|
|
15025
|
-
|
|
15026
|
-
|
|
15027
|
-
|
|
15295
|
+
children: [
|
|
15296
|
+
method === "passkey" && !activeProvider && /* @__PURE__ */ jsxs("div", {
|
|
15297
|
+
className: "space-y-6",
|
|
15298
|
+
children: [
|
|
15299
|
+
/* @__PURE__ */ jsx(PasskeyLogin, {
|
|
15300
|
+
optionsEndpoint: "/_emdash/api/auth/passkey/options",
|
|
15301
|
+
verifyEndpoint: "/_emdash/api/auth/passkey/verify",
|
|
15302
|
+
onSuccess: handleSuccess,
|
|
15303
|
+
buttonText: _t2({
|
|
15304
|
+
id: "QjsOMP",
|
|
15305
|
+
message: "Sign in with Passkey"
|
|
15306
|
+
})
|
|
15307
|
+
}),
|
|
15308
|
+
/* @__PURE__ */ jsxs("div", {
|
|
15309
|
+
className: "relative",
|
|
15310
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
15311
|
+
className: "absolute inset-0 flex items-center",
|
|
15312
|
+
children: /* @__PURE__ */ jsx("span", { className: "w-full border-t" })
|
|
15313
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
15314
|
+
className: "relative flex justify-center text-xs uppercase",
|
|
15315
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
15316
|
+
className: "bg-kumo-base px-2 text-kumo-subtle",
|
|
15317
|
+
children: _t2({
|
|
15318
|
+
id: "zW+FpA",
|
|
15319
|
+
message: "Or continue with"
|
|
15320
|
+
})
|
|
15028
15321
|
})
|
|
15322
|
+
})]
|
|
15323
|
+
}),
|
|
15324
|
+
buttonProviders.length > 0 && /* @__PURE__ */ jsx("div", {
|
|
15325
|
+
className: `grid gap-3 ${buttonProviders.length === 1 ? "grid-cols-1" : "grid-cols-2"}`,
|
|
15326
|
+
children: buttonProviders.map((provider) => {
|
|
15327
|
+
const Btn = provider.LoginButton;
|
|
15328
|
+
const hasForm = !!provider.LoginForm;
|
|
15329
|
+
const selectProvider = () => setActiveProvider(provider.id);
|
|
15330
|
+
return /* @__PURE__ */ jsx("div", {
|
|
15331
|
+
onClick: hasForm ? selectProvider : void 0,
|
|
15332
|
+
children: /* @__PURE__ */ jsx(Btn, {})
|
|
15333
|
+
}, provider.id);
|
|
15029
15334
|
})
|
|
15030
|
-
})
|
|
15031
|
-
|
|
15032
|
-
|
|
15033
|
-
className: "grid grid-cols-2 gap-3",
|
|
15034
|
-
children: OAUTH_PROVIDERS.map((provider) => /* @__PURE__ */ jsxs(Button, {
|
|
15035
|
-
variant: "outline",
|
|
15036
|
-
type: "button",
|
|
15037
|
-
onClick: () => handleOAuthClick(provider.id),
|
|
15335
|
+
}),
|
|
15336
|
+
/* @__PURE__ */ jsx(Button, {
|
|
15337
|
+
variant: "ghost",
|
|
15038
15338
|
className: "w-full justify-center",
|
|
15039
|
-
|
|
15040
|
-
|
|
15041
|
-
|
|
15042
|
-
|
|
15043
|
-
|
|
15044
|
-
|
|
15045
|
-
/* @__PURE__ */ jsx(Button, {
|
|
15046
|
-
variant: "ghost",
|
|
15047
|
-
className: "w-full justify-center",
|
|
15048
|
-
type: "button",
|
|
15049
|
-
onClick: () => setMethod("magic-link"),
|
|
15050
|
-
children: _t2({
|
|
15051
|
-
id: "RxerEl",
|
|
15052
|
-
message: "Sign in with email link"
|
|
15339
|
+
type: "button",
|
|
15340
|
+
onClick: () => setMethod("magic-link"),
|
|
15341
|
+
children: _t2({
|
|
15342
|
+
id: "RxerEl",
|
|
15343
|
+
message: "Sign in with email link"
|
|
15344
|
+
})
|
|
15053
15345
|
})
|
|
15054
|
-
|
|
15055
|
-
|
|
15056
|
-
|
|
15346
|
+
]
|
|
15347
|
+
}),
|
|
15348
|
+
method === "passkey" && activeProvider && (() => {
|
|
15349
|
+
const provider = authProviderList.find((p) => p.id === activeProvider);
|
|
15350
|
+
if (!provider?.LoginForm) return null;
|
|
15351
|
+
const Form = provider.LoginForm;
|
|
15352
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
15353
|
+
className: "space-y-4",
|
|
15354
|
+
children: [/* @__PURE__ */ jsx(Form, {}), /* @__PURE__ */ jsx(Button, {
|
|
15355
|
+
type: "button",
|
|
15356
|
+
variant: "ghost",
|
|
15357
|
+
className: "w-full justify-center",
|
|
15358
|
+
onClick: () => setActiveProvider(null),
|
|
15359
|
+
children: _t2({
|
|
15360
|
+
id: "VCoEm+",
|
|
15361
|
+
message: "Back to login"
|
|
15362
|
+
})
|
|
15363
|
+
})]
|
|
15364
|
+
});
|
|
15365
|
+
})(),
|
|
15366
|
+
method === "magic-link" && /* @__PURE__ */ jsx(MagicLinkForm, { onBack: () => setMethod("passkey") })
|
|
15367
|
+
]
|
|
15057
15368
|
}),
|
|
15058
15369
|
/* @__PURE__ */ jsx("p", {
|
|
15059
15370
|
className: "text-center mt-6 text-sm text-kumo-subtle",
|
|
15060
|
-
children: method === "
|
|
15061
|
-
id: "+ET/av",
|
|
15062
|
-
message: "Use your registered passkey to sign in securely."
|
|
15063
|
-
}) : _t2({
|
|
15371
|
+
children: method === "magic-link" ? _t2({
|
|
15064
15372
|
id: "pv+wH3",
|
|
15065
15373
|
message: "We'll send you a link to sign in without a password."
|
|
15374
|
+
}) : activeProvider ? _t2({
|
|
15375
|
+
id: "TZGT4o",
|
|
15376
|
+
message: "Enter your handle to sign in."
|
|
15377
|
+
}) : _t2({
|
|
15378
|
+
id: "+ET/av",
|
|
15379
|
+
message: "Use your registered passkey to sign in securely."
|
|
15066
15380
|
})
|
|
15067
15381
|
}),
|
|
15068
|
-
|
|
15382
|
+
authInfo?.signupEnabled && /* @__PURE__ */ jsx("p", {
|
|
15069
15383
|
className: "text-center mt-4 text-sm text-kumo-subtle",
|
|
15070
15384
|
children: /* @__PURE__ */ jsx(Trans, {
|
|
15071
15385
|
id: "352VU2",
|
|
@@ -21459,6 +21773,50 @@ const API_TOKEN_SCOPE_VALUES = [
|
|
|
21459
21773
|
message: "Modify collection schemas"
|
|
21460
21774
|
}
|
|
21461
21775
|
},
|
|
21776
|
+
{
|
|
21777
|
+
scope: API_TOKEN_SCOPES.TaxonomiesManage,
|
|
21778
|
+
label: {
|
|
21779
|
+
id: "cfmuSI",
|
|
21780
|
+
message: "Taxonomies Manage"
|
|
21781
|
+
},
|
|
21782
|
+
description: {
|
|
21783
|
+
id: "mmBufY",
|
|
21784
|
+
message: "Create, update, and delete taxonomy terms"
|
|
21785
|
+
}
|
|
21786
|
+
},
|
|
21787
|
+
{
|
|
21788
|
+
scope: API_TOKEN_SCOPES.MenusManage,
|
|
21789
|
+
label: {
|
|
21790
|
+
id: "Wosws9",
|
|
21791
|
+
message: "Menus Manage"
|
|
21792
|
+
},
|
|
21793
|
+
description: {
|
|
21794
|
+
id: "DGhfmD",
|
|
21795
|
+
message: "Create, update, and delete navigation menus"
|
|
21796
|
+
}
|
|
21797
|
+
},
|
|
21798
|
+
{
|
|
21799
|
+
scope: API_TOKEN_SCOPES.SettingsRead,
|
|
21800
|
+
label: {
|
|
21801
|
+
id: "tYQSLw",
|
|
21802
|
+
message: "Settings Read"
|
|
21803
|
+
},
|
|
21804
|
+
description: {
|
|
21805
|
+
id: "fHKrk0",
|
|
21806
|
+
message: "Read site settings"
|
|
21807
|
+
}
|
|
21808
|
+
},
|
|
21809
|
+
{
|
|
21810
|
+
scope: API_TOKEN_SCOPES.SettingsManage,
|
|
21811
|
+
label: {
|
|
21812
|
+
id: "+K5A49",
|
|
21813
|
+
message: "Settings Manage"
|
|
21814
|
+
},
|
|
21815
|
+
description: {
|
|
21816
|
+
id: "RAXQwS",
|
|
21817
|
+
message: "Update site settings"
|
|
21818
|
+
}
|
|
21819
|
+
},
|
|
21462
21820
|
{
|
|
21463
21821
|
scope: API_TOKEN_SCOPES.Admin,
|
|
21464
21822
|
label: {
|
|
@@ -23516,8 +23874,9 @@ function SocialSettings() {
|
|
|
23516
23874
|
*
|
|
23517
23875
|
* Steps:
|
|
23518
23876
|
* 1. Site Configuration (title, tagline, sample content)
|
|
23519
|
-
* 2.
|
|
23520
|
-
*
|
|
23877
|
+
* 2. Create admin account — user picks any available auth method:
|
|
23878
|
+
* - Passkey (always available)
|
|
23879
|
+
* - Any configured auth provider (AT Protocol, GitHub, Google, etc.)
|
|
23521
23880
|
*/
|
|
23522
23881
|
async function fetchSetupStatus() {
|
|
23523
23882
|
return parseApiResponse(await apiFetch("/_emdash/api/setup/status"), "Failed to fetch setup status");
|
|
@@ -23538,8 +23897,8 @@ async function executeAdminSetup(data) {
|
|
|
23538
23897
|
}
|
|
23539
23898
|
function SiteStep({ seedInfo, onNext, isLoading, error }) {
|
|
23540
23899
|
const { _: _t } = useLingui();
|
|
23541
|
-
const [title, setTitle] = React.useState("");
|
|
23542
|
-
const [tagline, setTagline] = React.useState("");
|
|
23900
|
+
const [title, setTitle] = React.useState(seedInfo?.title ?? "");
|
|
23901
|
+
const [tagline, setTagline] = React.useState(seedInfo?.tagline ?? "");
|
|
23543
23902
|
const [includeContent, setIncludeContent] = React.useState(true);
|
|
23544
23903
|
const [errors, setErrors] = React.useState({});
|
|
23545
23904
|
const validate = () => {
|
|
@@ -23751,58 +24110,97 @@ function AdminStep({ onNext, onBack, isLoading, error }) {
|
|
|
23751
24110
|
]
|
|
23752
24111
|
});
|
|
23753
24112
|
}
|
|
23754
|
-
function
|
|
24113
|
+
function handleSetupSuccess() {
|
|
23755
24114
|
window.location.href = "/_emdash/admin";
|
|
23756
24115
|
}
|
|
23757
|
-
function
|
|
24116
|
+
function AuthMethodStep({ adminData, providers, onBack }) {
|
|
23758
24117
|
const { _: _t3 } = useLingui();
|
|
24118
|
+
const [activeProvider, setActiveProvider] = React.useState(null);
|
|
24119
|
+
const buttonProviders = providers.filter((p) => p.LoginButton);
|
|
24120
|
+
const hasProviders = buttonProviders.length > 0;
|
|
24121
|
+
if (activeProvider) {
|
|
24122
|
+
const provider = providers.find((p) => p.id === activeProvider);
|
|
24123
|
+
if (provider && (provider.SetupStep || provider.LoginForm)) return /* @__PURE__ */ jsxs("div", {
|
|
24124
|
+
className: "space-y-4",
|
|
24125
|
+
children: [
|
|
24126
|
+
/* @__PURE__ */ jsx("div", {
|
|
24127
|
+
className: "text-center mb-2",
|
|
24128
|
+
children: /* @__PURE__ */ jsx("h3", {
|
|
24129
|
+
className: "text-lg font-medium",
|
|
24130
|
+
children: _t3({
|
|
24131
|
+
id: "e/ToF5",
|
|
24132
|
+
message: "Sign in with {0}",
|
|
24133
|
+
values: { 0: provider.label }
|
|
24134
|
+
})
|
|
24135
|
+
})
|
|
24136
|
+
}),
|
|
24137
|
+
provider.SetupStep ? /* @__PURE__ */ jsx(provider.SetupStep, { onComplete: handleSetupSuccess }) : provider.LoginForm ? /* @__PURE__ */ jsx(provider.LoginForm, {}) : null,
|
|
24138
|
+
/* @__PURE__ */ jsx(Button, {
|
|
24139
|
+
type: "button",
|
|
24140
|
+
variant: "ghost",
|
|
24141
|
+
className: "w-full justify-center",
|
|
24142
|
+
onClick: () => setActiveProvider(null),
|
|
24143
|
+
children: _t3({
|
|
24144
|
+
id: "2ygf/L",
|
|
24145
|
+
message: "← Back"
|
|
24146
|
+
})
|
|
24147
|
+
})
|
|
24148
|
+
]
|
|
24149
|
+
});
|
|
24150
|
+
}
|
|
23759
24151
|
return /* @__PURE__ */ jsxs("div", {
|
|
23760
24152
|
className: "space-y-6",
|
|
23761
24153
|
children: [
|
|
23762
24154
|
/* @__PURE__ */ jsxs("div", {
|
|
23763
24155
|
className: "text-center",
|
|
23764
|
-
children: [
|
|
23765
|
-
|
|
23766
|
-
|
|
23767
|
-
|
|
23768
|
-
|
|
23769
|
-
fill: "none",
|
|
23770
|
-
stroke: "currentColor",
|
|
23771
|
-
viewBox: "0 0 24 24",
|
|
23772
|
-
children: /* @__PURE__ */ jsx("path", {
|
|
23773
|
-
strokeLinecap: "round",
|
|
23774
|
-
strokeLinejoin: "round",
|
|
23775
|
-
strokeWidth: 2,
|
|
23776
|
-
d: "M12 11c0 3.517-1.009 6.799-2.753 9.571m-3.44-2.04l.054-.09A13.916 13.916 0 008 11a4 4 0 118 0c0 1.017-.07 2.019-.203 3m-2.118 6.844A21.88 21.88 0 0015.171 17m3.839 1.132c.645-2.266.99-4.659.99-7.132A8 8 0 008 4.07M3 15.364c.64-1.319 1-2.8 1-4.364 0-1.457.39-2.823 1.07-4"
|
|
23777
|
-
})
|
|
23778
|
-
})
|
|
23779
|
-
}),
|
|
23780
|
-
/* @__PURE__ */ jsx("h3", {
|
|
23781
|
-
className: "text-lg font-medium",
|
|
23782
|
-
children: _t3({
|
|
23783
|
-
id: "fifQ8k",
|
|
23784
|
-
message: "Set up your passkey"
|
|
23785
|
-
})
|
|
23786
|
-
}),
|
|
23787
|
-
/* @__PURE__ */ jsx("p", {
|
|
23788
|
-
className: "text-sm text-kumo-subtle mt-1",
|
|
23789
|
-
children: _t3({
|
|
23790
|
-
id: "YdZ7D8",
|
|
23791
|
-
message: "Passkeys are more secure than passwords. You'll use your device's biometrics, PIN, or security key to sign in."
|
|
23792
|
-
})
|
|
24156
|
+
children: [/* @__PURE__ */ jsx("h3", {
|
|
24157
|
+
className: "text-lg font-medium",
|
|
24158
|
+
children: _t3({
|
|
24159
|
+
id: "HAV363",
|
|
24160
|
+
message: "Choose how to sign in"
|
|
23793
24161
|
})
|
|
23794
|
-
|
|
24162
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
24163
|
+
className: "text-sm text-kumo-subtle mt-1",
|
|
24164
|
+
children: _t3({
|
|
24165
|
+
id: "NH33Oi",
|
|
24166
|
+
message: "Pick any method to create your admin account."
|
|
24167
|
+
})
|
|
24168
|
+
})]
|
|
23795
24169
|
}),
|
|
23796
24170
|
/* @__PURE__ */ jsx(PasskeyRegistration, {
|
|
23797
24171
|
optionsEndpoint: "/_emdash/api/setup/admin",
|
|
23798
24172
|
verifyEndpoint: "/_emdash/api/setup/admin/verify",
|
|
23799
|
-
onSuccess:
|
|
24173
|
+
onSuccess: handleSetupSuccess,
|
|
23800
24174
|
buttonText: _t3({
|
|
23801
24175
|
id: "AKqzR1",
|
|
23802
24176
|
message: "Create Passkey"
|
|
23803
24177
|
}),
|
|
23804
24178
|
additionalData: { ...adminData }
|
|
23805
24179
|
}),
|
|
24180
|
+
hasProviders && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
|
|
24181
|
+
className: "relative",
|
|
24182
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
24183
|
+
className: "absolute inset-0 flex items-center",
|
|
24184
|
+
children: /* @__PURE__ */ jsx("span", { className: "w-full border-t" })
|
|
24185
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
24186
|
+
className: "relative flex justify-center text-xs uppercase",
|
|
24187
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
24188
|
+
className: "bg-kumo-base px-2 text-kumo-subtle",
|
|
24189
|
+
children: "Or continue with"
|
|
24190
|
+
})
|
|
24191
|
+
})]
|
|
24192
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
24193
|
+
className: `grid gap-3 ${buttonProviders.length === 1 ? "grid-cols-1" : "grid-cols-2"}`,
|
|
24194
|
+
children: buttonProviders.map((provider) => {
|
|
24195
|
+
const Btn = provider.LoginButton;
|
|
24196
|
+
const hasForm = !!provider.LoginForm || !!provider.SetupStep;
|
|
24197
|
+
const selectProvider = () => setActiveProvider(provider.id);
|
|
24198
|
+
return /* @__PURE__ */ jsx("div", {
|
|
24199
|
+
onClick: hasForm ? selectProvider : void 0,
|
|
24200
|
+
children: /* @__PURE__ */ jsx(Btn, {})
|
|
24201
|
+
}, provider.id);
|
|
24202
|
+
})
|
|
24203
|
+
})] }),
|
|
23806
24204
|
/* @__PURE__ */ jsx(Button, {
|
|
23807
24205
|
type: "button",
|
|
23808
24206
|
variant: "ghost",
|
|
@@ -23842,8 +24240,8 @@ function StepIndicator$1({ currentStep, useAccessAuth }) {
|
|
|
23842
24240
|
{
|
|
23843
24241
|
key: "passkey",
|
|
23844
24242
|
label: _t4({
|
|
23845
|
-
id: "
|
|
23846
|
-
message: "
|
|
24243
|
+
id: "n1ekoW",
|
|
24244
|
+
message: "Sign In"
|
|
23847
24245
|
})
|
|
23848
24246
|
}
|
|
23849
24247
|
];
|
|
@@ -23881,6 +24279,17 @@ function SetupWizard() {
|
|
|
23881
24279
|
const [_siteData, setSiteData] = React.useState(null);
|
|
23882
24280
|
const [adminData, setAdminData] = React.useState(null);
|
|
23883
24281
|
const [error, setError] = React.useState();
|
|
24282
|
+
const [urlError, setUrlError] = React.useState(null);
|
|
24283
|
+
const authProviderList = useAuthProviderList();
|
|
24284
|
+
React.useEffect(() => {
|
|
24285
|
+
const params = new URLSearchParams(window.location.search);
|
|
24286
|
+
const errorParam = params.get("error");
|
|
24287
|
+
const message = params.get("message");
|
|
24288
|
+
if (errorParam) {
|
|
24289
|
+
setUrlError(message || `Authentication error: ${errorParam}`);
|
|
24290
|
+
window.history.replaceState({}, "", window.location.pathname);
|
|
24291
|
+
}
|
|
24292
|
+
}, []);
|
|
23884
24293
|
const { data: status, isLoading: statusLoading, error: statusError } = useQuery({
|
|
23885
24294
|
queryKey: ["setup", "status"],
|
|
23886
24295
|
queryFn: fetchSetupStatus,
|
|
@@ -23999,6 +24408,10 @@ function SetupWizard() {
|
|
|
23999
24408
|
})
|
|
24000
24409
|
]
|
|
24001
24410
|
}),
|
|
24411
|
+
urlError && /* @__PURE__ */ jsx("div", {
|
|
24412
|
+
className: "mb-6 rounded-lg bg-kumo-danger/10 border border-kumo-danger/20 p-4 text-sm text-kumo-danger",
|
|
24413
|
+
children: urlError
|
|
24414
|
+
}),
|
|
24002
24415
|
/* @__PURE__ */ jsx(StepIndicator$1, {
|
|
24003
24416
|
currentStep,
|
|
24004
24417
|
useAccessAuth
|
|
@@ -24021,8 +24434,9 @@ function SetupWizard() {
|
|
|
24021
24434
|
isLoading: adminMutation.isPending,
|
|
24022
24435
|
error
|
|
24023
24436
|
}),
|
|
24024
|
-
currentStep === "passkey" && adminData && /* @__PURE__ */ jsx(
|
|
24437
|
+
currentStep === "passkey" && adminData && /* @__PURE__ */ jsx(AuthMethodStep, {
|
|
24025
24438
|
adminData,
|
|
24439
|
+
providers: authProviderList,
|
|
24026
24440
|
onBack: () => {
|
|
24027
24441
|
setError(void 0);
|
|
24028
24442
|
setCurrentStep("admin");
|
|
@@ -25788,7 +26202,7 @@ function TermRow({ term, level = 0, onEdit, onDelete }) {
|
|
|
25788
26202
|
className: "flex items-center gap-4 py-2 px-4 border-b hover:bg-kumo-tint/50",
|
|
25789
26203
|
children: [
|
|
25790
26204
|
/* @__PURE__ */ jsxs("div", {
|
|
25791
|
-
style: {
|
|
26205
|
+
style: { marginInlineStart: `${level * 1.5}rem` },
|
|
25792
26206
|
className: "flex-1",
|
|
25793
26207
|
children: [/* @__PURE__ */ jsx("span", {
|
|
25794
26208
|
className: "font-medium",
|
|
@@ -27132,7 +27546,20 @@ function Widgets() {
|
|
|
27132
27546
|
const [activeId, setActiveId] = React.useState(null);
|
|
27133
27547
|
const [activeDragData, setActiveDragData] = React.useState(null);
|
|
27134
27548
|
const [expandedWidgets, setExpandedWidgets] = React.useState(/* @__PURE__ */ new Set());
|
|
27549
|
+
const [blockSidebarPanel, setBlockSidebarPanel] = React.useState(null);
|
|
27135
27550
|
const draggingFromPaletteRef = React.useRef(false);
|
|
27551
|
+
const handleBlockSidebarOpen = React.useCallback((panel) => {
|
|
27552
|
+
setBlockSidebarPanel((prev) => {
|
|
27553
|
+
prev?.onClose();
|
|
27554
|
+
return panel;
|
|
27555
|
+
});
|
|
27556
|
+
}, []);
|
|
27557
|
+
const handleBlockSidebarClose = React.useCallback(() => {
|
|
27558
|
+
setBlockSidebarPanel((prev) => {
|
|
27559
|
+
prev?.onClose();
|
|
27560
|
+
return null;
|
|
27561
|
+
});
|
|
27562
|
+
}, []);
|
|
27136
27563
|
const { data: areas = [], isLoading } = useQuery({
|
|
27137
27564
|
queryKey: ["widget-areas"],
|
|
27138
27565
|
queryFn: fetchWidgetAreas
|
|
@@ -27270,174 +27697,189 @@ function Widgets() {
|
|
|
27270
27697
|
collisionDetection,
|
|
27271
27698
|
onDragStart: handleDragStart,
|
|
27272
27699
|
onDragEnd: handleDragEnd,
|
|
27273
|
-
children: [
|
|
27274
|
-
|
|
27275
|
-
|
|
27276
|
-
|
|
27277
|
-
|
|
27278
|
-
|
|
27279
|
-
|
|
27280
|
-
|
|
27281
|
-
|
|
27282
|
-
|
|
27283
|
-
|
|
27284
|
-
|
|
27285
|
-
|
|
27286
|
-
|
|
27287
|
-
|
|
27288
|
-
|
|
27289
|
-
|
|
27290
|
-
|
|
27291
|
-
|
|
27292
|
-
|
|
27293
|
-
|
|
27294
|
-
|
|
27295
|
-
|
|
27296
|
-
|
|
27297
|
-
|
|
27298
|
-
|
|
27299
|
-
|
|
27300
|
-
|
|
27301
|
-
|
|
27302
|
-
|
|
27303
|
-
render: (props) => /* @__PURE__ */ jsxs(Button, {
|
|
27304
|
-
...props,
|
|
27305
|
-
variant: "ghost",
|
|
27306
|
-
shape: "square",
|
|
27700
|
+
children: [
|
|
27701
|
+
/* @__PURE__ */ jsxs("div", {
|
|
27702
|
+
className: "space-y-6",
|
|
27703
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
27704
|
+
className: "flex items-center justify-between",
|
|
27705
|
+
children: [/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h1", {
|
|
27706
|
+
className: "text-3xl font-bold",
|
|
27707
|
+
children: "Widgets"
|
|
27708
|
+
}), /* @__PURE__ */ jsx("p", {
|
|
27709
|
+
className: "text-kumo-subtle",
|
|
27710
|
+
children: "Manage content widgets in your widget areas"
|
|
27711
|
+
})] }), /* @__PURE__ */ jsxs(Dialog.Root, {
|
|
27712
|
+
open: isCreateAreaOpen,
|
|
27713
|
+
onOpenChange: (open) => {
|
|
27714
|
+
setIsCreateAreaOpen(open);
|
|
27715
|
+
if (!open) setCreateAreaError(null);
|
|
27716
|
+
},
|
|
27717
|
+
children: [/* @__PURE__ */ jsx(Dialog.Trigger, { render: (props) => /* @__PURE__ */ jsx(Button, {
|
|
27718
|
+
...props,
|
|
27719
|
+
icon: /* @__PURE__ */ jsx(Plus, {}),
|
|
27720
|
+
children: "Add Widget Area"
|
|
27721
|
+
}) }), /* @__PURE__ */ jsxs(Dialog, {
|
|
27722
|
+
className: "p-6",
|
|
27723
|
+
size: "lg",
|
|
27724
|
+
children: [/* @__PURE__ */ jsxs("div", {
|
|
27725
|
+
className: "flex items-start justify-between gap-4 mb-4",
|
|
27726
|
+
children: [/* @__PURE__ */ jsx(Dialog.Title, {
|
|
27727
|
+
className: "text-lg font-semibold leading-none tracking-tight",
|
|
27728
|
+
children: "Create Widget Area"
|
|
27729
|
+
}), /* @__PURE__ */ jsx(Dialog.Close, {
|
|
27307
27730
|
"aria-label": "Close",
|
|
27308
|
-
|
|
27309
|
-
|
|
27310
|
-
|
|
27311
|
-
|
|
27312
|
-
|
|
27313
|
-
|
|
27731
|
+
render: (props) => /* @__PURE__ */ jsxs(Button, {
|
|
27732
|
+
...props,
|
|
27733
|
+
variant: "ghost",
|
|
27734
|
+
shape: "square",
|
|
27735
|
+
"aria-label": "Close",
|
|
27736
|
+
className: "absolute end-4 top-4",
|
|
27737
|
+
children: [/* @__PURE__ */ jsx(X, { className: "h-4 w-4" }), /* @__PURE__ */ jsx("span", {
|
|
27738
|
+
className: "sr-only",
|
|
27739
|
+
children: "Close"
|
|
27740
|
+
})]
|
|
27741
|
+
})
|
|
27742
|
+
})]
|
|
27743
|
+
}), /* @__PURE__ */ jsxs("form", {
|
|
27744
|
+
onSubmit: handleCreateArea,
|
|
27745
|
+
className: "space-y-4",
|
|
27746
|
+
children: [
|
|
27747
|
+
/* @__PURE__ */ jsx(Input, {
|
|
27748
|
+
label: "Name",
|
|
27749
|
+
name: "name",
|
|
27750
|
+
required: true,
|
|
27751
|
+
placeholder: "sidebar",
|
|
27752
|
+
pattern: "[a-z0-9-]+"
|
|
27753
|
+
}),
|
|
27754
|
+
/* @__PURE__ */ jsx(Input, {
|
|
27755
|
+
label: "Label",
|
|
27756
|
+
name: "label",
|
|
27757
|
+
required: true,
|
|
27758
|
+
placeholder: "Main Sidebar"
|
|
27759
|
+
}),
|
|
27760
|
+
/* @__PURE__ */ jsx(Input, {
|
|
27761
|
+
label: "Description",
|
|
27762
|
+
name: "description",
|
|
27763
|
+
placeholder: "Appears on posts and pages"
|
|
27764
|
+
}),
|
|
27765
|
+
/* @__PURE__ */ jsx(DialogError, { message: createAreaError || getMutationError(createAreaMutation.error) }),
|
|
27766
|
+
/* @__PURE__ */ jsxs("div", {
|
|
27767
|
+
className: "flex justify-end gap-2",
|
|
27768
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
27769
|
+
type: "button",
|
|
27770
|
+
variant: "outline",
|
|
27771
|
+
onClick: () => setIsCreateAreaOpen(false),
|
|
27772
|
+
children: "Cancel"
|
|
27773
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
27774
|
+
type: "submit",
|
|
27775
|
+
disabled: createAreaMutation.isPending,
|
|
27776
|
+
children: "Create"
|
|
27777
|
+
})]
|
|
27778
|
+
})
|
|
27779
|
+
]
|
|
27314
27780
|
})]
|
|
27315
|
-
})
|
|
27316
|
-
|
|
27317
|
-
|
|
27781
|
+
})]
|
|
27782
|
+
})]
|
|
27783
|
+
}), /* @__PURE__ */ jsxs("div", {
|
|
27784
|
+
className: "grid grid-cols-12 gap-6",
|
|
27785
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
27786
|
+
className: "col-span-4",
|
|
27787
|
+
children: /* @__PURE__ */ jsxs("div", {
|
|
27788
|
+
className: "rounded-lg border bg-kumo-base p-6 space-y-4",
|
|
27318
27789
|
children: [
|
|
27319
|
-
/* @__PURE__ */ jsx(
|
|
27320
|
-
|
|
27321
|
-
|
|
27322
|
-
required: true,
|
|
27323
|
-
placeholder: "sidebar",
|
|
27324
|
-
pattern: "[a-z0-9-]+"
|
|
27325
|
-
}),
|
|
27326
|
-
/* @__PURE__ */ jsx(Input, {
|
|
27327
|
-
label: "Label",
|
|
27328
|
-
name: "label",
|
|
27329
|
-
required: true,
|
|
27330
|
-
placeholder: "Main Sidebar"
|
|
27790
|
+
/* @__PURE__ */ jsx("h2", {
|
|
27791
|
+
className: "text-xl font-semibold",
|
|
27792
|
+
children: "Available Widgets"
|
|
27331
27793
|
}),
|
|
27332
|
-
/* @__PURE__ */ jsx(
|
|
27333
|
-
|
|
27334
|
-
|
|
27335
|
-
placeholder: "Appears on posts and pages"
|
|
27794
|
+
/* @__PURE__ */ jsx("p", {
|
|
27795
|
+
className: "text-sm text-kumo-subtle",
|
|
27796
|
+
children: "Drag widgets into an area to add them"
|
|
27336
27797
|
}),
|
|
27337
|
-
/* @__PURE__ */ jsx(DialogError, { message: createAreaError || getMutationError(createAreaMutation.error) }),
|
|
27338
27798
|
/* @__PURE__ */ jsxs("div", {
|
|
27339
|
-
className: "
|
|
27340
|
-
children: [/* @__PURE__ */ jsx(
|
|
27341
|
-
|
|
27342
|
-
|
|
27343
|
-
|
|
27344
|
-
|
|
27345
|
-
|
|
27346
|
-
|
|
27347
|
-
|
|
27348
|
-
|
|
27349
|
-
|
|
27799
|
+
className: "space-y-2",
|
|
27800
|
+
children: [BUILTIN_WIDGETS.map((item) => /* @__PURE__ */ jsx(DraggablePaletteItem, {
|
|
27801
|
+
id: item.id,
|
|
27802
|
+
label: _t(item.label),
|
|
27803
|
+
description: _t(item.description),
|
|
27804
|
+
widgetInput: {
|
|
27805
|
+
...item.input,
|
|
27806
|
+
title: _t(item.label)
|
|
27807
|
+
}
|
|
27808
|
+
}, item.id)), components.map((comp) => /* @__PURE__ */ jsx(DraggablePaletteItem, {
|
|
27809
|
+
id: `palette-comp-${comp.id}`,
|
|
27810
|
+
label: comp.label,
|
|
27811
|
+
description: comp.description,
|
|
27812
|
+
widgetInput: {
|
|
27813
|
+
type: "component",
|
|
27814
|
+
title: comp.label,
|
|
27815
|
+
componentId: comp.id
|
|
27816
|
+
}
|
|
27817
|
+
}, `palette-comp-${comp.id}`))]
|
|
27350
27818
|
})
|
|
27351
27819
|
]
|
|
27352
|
-
})
|
|
27820
|
+
})
|
|
27821
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
27822
|
+
className: "col-span-8 space-y-4",
|
|
27823
|
+
children: areas.length === 0 ? /* @__PURE__ */ jsx("div", {
|
|
27824
|
+
className: "rounded-lg border bg-kumo-base p-12 text-center",
|
|
27825
|
+
children: /* @__PURE__ */ jsx("p", {
|
|
27826
|
+
className: "text-kumo-subtle",
|
|
27827
|
+
children: "No widget areas yet. Create one to get started."
|
|
27828
|
+
})
|
|
27829
|
+
}) : areas.map((area) => /* @__PURE__ */ jsx(WidgetAreaPanel, {
|
|
27830
|
+
area,
|
|
27831
|
+
expandedWidgets,
|
|
27832
|
+
onToggleWidget: toggleWidget,
|
|
27833
|
+
isDraggingPalette: activeDragData !== null && isPaletteItem(activeDragData),
|
|
27834
|
+
components,
|
|
27835
|
+
pluginBlocks,
|
|
27836
|
+
onBlockSidebarOpen: handleBlockSidebarOpen,
|
|
27837
|
+
onBlockSidebarClose: handleBlockSidebarClose
|
|
27838
|
+
}, area.id))
|
|
27353
27839
|
})]
|
|
27354
27840
|
})]
|
|
27355
|
-
}),
|
|
27356
|
-
|
|
27357
|
-
|
|
27358
|
-
|
|
27841
|
+
}),
|
|
27842
|
+
/* @__PURE__ */ jsx(DragOverlay, {
|
|
27843
|
+
dropAnimation: draggingFromPaletteRef.current ? null : void 0,
|
|
27844
|
+
children: activePaletteLabel ? /* @__PURE__ */ jsx("div", {
|
|
27845
|
+
className: "rounded border bg-kumo-base p-3 shadow-lg opacity-90",
|
|
27846
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
27847
|
+
className: "font-medium",
|
|
27848
|
+
children: activePaletteLabel
|
|
27849
|
+
})
|
|
27850
|
+
}) : activeWidget ? /* @__PURE__ */ jsx("div", {
|
|
27851
|
+
className: "rounded border bg-kumo-base p-3 shadow-lg opacity-90",
|
|
27359
27852
|
children: /* @__PURE__ */ jsxs("div", {
|
|
27360
|
-
className: "
|
|
27853
|
+
className: "flex items-center gap-2",
|
|
27361
27854
|
children: [
|
|
27362
|
-
/* @__PURE__ */ jsx("
|
|
27363
|
-
|
|
27364
|
-
|
|
27365
|
-
|
|
27366
|
-
/* @__PURE__ */ jsx("p", {
|
|
27367
|
-
className: "text-sm text-kumo-subtle",
|
|
27368
|
-
children: "Drag widgets into an area to add them"
|
|
27855
|
+
/* @__PURE__ */ jsx(DotsSixVertical, { className: "h-4 w-4 text-kumo-subtle" }),
|
|
27856
|
+
/* @__PURE__ */ jsx("span", {
|
|
27857
|
+
className: "font-medium",
|
|
27858
|
+
children: activeWidget.title || "Untitled Widget"
|
|
27369
27859
|
}),
|
|
27370
|
-
/* @__PURE__ */ jsxs("
|
|
27371
|
-
className: "
|
|
27372
|
-
children: [
|
|
27373
|
-
|
|
27374
|
-
|
|
27375
|
-
|
|
27376
|
-
|
|
27377
|
-
...item.input,
|
|
27378
|
-
title: _t(item.label)
|
|
27379
|
-
}
|
|
27380
|
-
}, item.id)), components.map((comp) => /* @__PURE__ */ jsx(DraggablePaletteItem, {
|
|
27381
|
-
id: `palette-comp-${comp.id}`,
|
|
27382
|
-
label: comp.label,
|
|
27383
|
-
description: comp.description,
|
|
27384
|
-
widgetInput: {
|
|
27385
|
-
type: "component",
|
|
27386
|
-
title: comp.label,
|
|
27387
|
-
componentId: comp.id
|
|
27388
|
-
}
|
|
27389
|
-
}, `palette-comp-${comp.id}`))]
|
|
27860
|
+
/* @__PURE__ */ jsxs("span", {
|
|
27861
|
+
className: "text-xs text-kumo-subtle",
|
|
27862
|
+
children: [
|
|
27863
|
+
"(",
|
|
27864
|
+
activeWidget.type,
|
|
27865
|
+
")"
|
|
27866
|
+
]
|
|
27390
27867
|
})
|
|
27391
27868
|
]
|
|
27392
27869
|
})
|
|
27393
|
-
})
|
|
27394
|
-
|
|
27395
|
-
|
|
27396
|
-
|
|
27397
|
-
|
|
27398
|
-
|
|
27399
|
-
|
|
27400
|
-
|
|
27401
|
-
|
|
27402
|
-
|
|
27403
|
-
|
|
27404
|
-
|
|
27405
|
-
|
|
27406
|
-
components,
|
|
27407
|
-
pluginBlocks
|
|
27408
|
-
}, area.id))
|
|
27409
|
-
})]
|
|
27410
|
-
})]
|
|
27411
|
-
}), /* @__PURE__ */ jsx(DragOverlay, {
|
|
27412
|
-
dropAnimation: draggingFromPaletteRef.current ? null : void 0,
|
|
27413
|
-
children: activePaletteLabel ? /* @__PURE__ */ jsx("div", {
|
|
27414
|
-
className: "rounded border bg-kumo-base p-3 shadow-lg opacity-90",
|
|
27415
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
27416
|
-
className: "font-medium",
|
|
27417
|
-
children: activePaletteLabel
|
|
27418
|
-
})
|
|
27419
|
-
}) : activeWidget ? /* @__PURE__ */ jsx("div", {
|
|
27420
|
-
className: "rounded border bg-kumo-base p-3 shadow-lg opacity-90",
|
|
27421
|
-
children: /* @__PURE__ */ jsxs("div", {
|
|
27422
|
-
className: "flex items-center gap-2",
|
|
27423
|
-
children: [
|
|
27424
|
-
/* @__PURE__ */ jsx(DotsSixVertical, { className: "h-4 w-4 text-kumo-subtle" }),
|
|
27425
|
-
/* @__PURE__ */ jsx("span", {
|
|
27426
|
-
className: "font-medium",
|
|
27427
|
-
children: activeWidget.title || "Untitled Widget"
|
|
27428
|
-
}),
|
|
27429
|
-
/* @__PURE__ */ jsxs("span", {
|
|
27430
|
-
className: "text-xs text-kumo-subtle",
|
|
27431
|
-
children: [
|
|
27432
|
-
"(",
|
|
27433
|
-
activeWidget.type,
|
|
27434
|
-
")"
|
|
27435
|
-
]
|
|
27436
|
-
})
|
|
27437
|
-
]
|
|
27438
|
-
})
|
|
27439
|
-
}) : null
|
|
27440
|
-
})]
|
|
27870
|
+
}) : null
|
|
27871
|
+
}),
|
|
27872
|
+
blockSidebarPanel?.type === "image" && /* @__PURE__ */ jsx(ImageDetailPanel, {
|
|
27873
|
+
attributes: blockSidebarPanel.attrs,
|
|
27874
|
+
onUpdate: (attrs) => blockSidebarPanel.onUpdate(attrs),
|
|
27875
|
+
onReplace: (attrs) => blockSidebarPanel.onReplace(attrs),
|
|
27876
|
+
onDelete: () => {
|
|
27877
|
+
blockSidebarPanel.onDelete();
|
|
27878
|
+
setBlockSidebarPanel(null);
|
|
27879
|
+
},
|
|
27880
|
+
onClose: handleBlockSidebarClose
|
|
27881
|
+
})
|
|
27882
|
+
]
|
|
27441
27883
|
});
|
|
27442
27884
|
}
|
|
27443
27885
|
/** A draggable item in the available widgets palette */
|
|
@@ -27464,7 +27906,7 @@ function DraggablePaletteItem({ id, label, description, widgetInput }) {
|
|
|
27464
27906
|
})]
|
|
27465
27907
|
});
|
|
27466
27908
|
}
|
|
27467
|
-
function WidgetAreaPanel({ area, expandedWidgets, onToggleWidget, isDraggingPalette, components, pluginBlocks }) {
|
|
27909
|
+
function WidgetAreaPanel({ area, expandedWidgets, onToggleWidget, isDraggingPalette, components, pluginBlocks, onBlockSidebarOpen, onBlockSidebarClose }) {
|
|
27468
27910
|
const queryClient = useQueryClient();
|
|
27469
27911
|
const toastManager = Toast.useToastManager();
|
|
27470
27912
|
const [deleteAreaName, setDeleteAreaName] = React.useState(null);
|
|
@@ -27510,7 +27952,9 @@ function WidgetAreaPanel({ area, expandedWidgets, onToggleWidget, isDraggingPale
|
|
|
27510
27952
|
isExpanded: expandedWidgets.has(widget.id),
|
|
27511
27953
|
onToggle: () => onToggleWidget(widget.id),
|
|
27512
27954
|
components,
|
|
27513
|
-
pluginBlocks
|
|
27955
|
+
pluginBlocks,
|
|
27956
|
+
onBlockSidebarOpen,
|
|
27957
|
+
onBlockSidebarClose
|
|
27514
27958
|
}, widget.id))
|
|
27515
27959
|
}) : null,
|
|
27516
27960
|
isDraggingPalette && /* @__PURE__ */ jsx("div", {
|
|
@@ -27540,7 +27984,7 @@ function WidgetAreaPanel({ area, expandedWidgets, onToggleWidget, isDraggingPale
|
|
|
27540
27984
|
]
|
|
27541
27985
|
});
|
|
27542
27986
|
}
|
|
27543
|
-
function WidgetItem({ widget, areaName, isExpanded, onToggle, components, pluginBlocks }) {
|
|
27987
|
+
function WidgetItem({ widget, areaName, isExpanded, onToggle, components, pluginBlocks, onBlockSidebarOpen, onBlockSidebarClose }) {
|
|
27544
27988
|
const queryClient = useQueryClient();
|
|
27545
27989
|
const toastManager = Toast.useToastManager();
|
|
27546
27990
|
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({
|
|
@@ -27632,12 +28076,14 @@ function WidgetItem({ widget, areaName, isExpanded, onToggle, components, plugin
|
|
|
27632
28076
|
components,
|
|
27633
28077
|
pluginBlocks,
|
|
27634
28078
|
onSave: (input) => updateMutation.mutate(input),
|
|
27635
|
-
isSaving: updateMutation.isPending
|
|
28079
|
+
isSaving: updateMutation.isPending,
|
|
28080
|
+
onBlockSidebarOpen,
|
|
28081
|
+
onBlockSidebarClose
|
|
27636
28082
|
})]
|
|
27637
28083
|
});
|
|
27638
28084
|
}
|
|
27639
28085
|
/** Inline editor form for a widget, rendered when the widget is expanded */
|
|
27640
|
-
function WidgetEditor({ widget, components, pluginBlocks, onSave, isSaving }) {
|
|
28086
|
+
function WidgetEditor({ widget, components, pluginBlocks, onSave, isSaving, onBlockSidebarOpen, onBlockSidebarClose }) {
|
|
27641
28087
|
const [title, setTitle] = React.useState(widget.title ?? "");
|
|
27642
28088
|
const [content, setContent] = React.useState(Array.isArray(widget.content) ? widget.content : []);
|
|
27643
28089
|
const [menuName, setMenuName] = React.useState(widget.menuName ?? "");
|
|
@@ -27676,7 +28122,9 @@ function WidgetEditor({ widget, components, pluginBlocks, onSave, isSaving }) {
|
|
|
27676
28122
|
onChange: (value) => setContent(value),
|
|
27677
28123
|
minimal: true,
|
|
27678
28124
|
placeholder: "Write widget content...",
|
|
27679
|
-
pluginBlocks
|
|
28125
|
+
pluginBlocks,
|
|
28126
|
+
onBlockSidebarOpen,
|
|
28127
|
+
onBlockSidebarClose
|
|
27680
28128
|
})] }),
|
|
27681
28129
|
widget.type === "menu" && /* @__PURE__ */ jsxs(Select, {
|
|
27682
28130
|
label: "Menu",
|
|
@@ -31894,16 +32342,25 @@ function ContentListPage() {
|
|
|
31894
32342
|
});
|
|
31895
32343
|
const i18n = manifest?.i18n;
|
|
31896
32344
|
const activeLocale = i18n ? localeParam ?? i18n.defaultLocale : void 0;
|
|
32345
|
+
const [sort, setSort] = React.useState({
|
|
32346
|
+
field: "updatedAt",
|
|
32347
|
+
direction: "desc"
|
|
32348
|
+
});
|
|
31897
32349
|
const { data, fetchNextPage, hasNextPage, isFetchingNextPage, isLoading, error } = useInfiniteQuery({
|
|
31898
32350
|
queryKey: [
|
|
31899
32351
|
"content",
|
|
31900
32352
|
collection,
|
|
31901
|
-
{
|
|
32353
|
+
{
|
|
32354
|
+
locale: activeLocale,
|
|
32355
|
+
sort
|
|
32356
|
+
}
|
|
31902
32357
|
],
|
|
31903
32358
|
queryFn: ({ pageParam }) => fetchContentList(collection, {
|
|
31904
32359
|
locale: activeLocale,
|
|
31905
32360
|
cursor: pageParam,
|
|
31906
|
-
limit: 100
|
|
32361
|
+
limit: 100,
|
|
32362
|
+
orderBy: sort.field,
|
|
32363
|
+
order: sort.direction
|
|
31907
32364
|
}),
|
|
31908
32365
|
initialPageParam: void 0,
|
|
31909
32366
|
getNextPageParam: (lastPage) => lastPage.nextCursor,
|
|
@@ -32014,7 +32471,9 @@ function ContentListPage() {
|
|
|
32014
32471
|
i18n,
|
|
32015
32472
|
activeLocale,
|
|
32016
32473
|
onLocaleChange: handleLocaleChange,
|
|
32017
|
-
urlPattern: collectionConfig.urlPattern
|
|
32474
|
+
urlPattern: collectionConfig.urlPattern,
|
|
32475
|
+
sort,
|
|
32476
|
+
onSortChange: setSort
|
|
32018
32477
|
});
|
|
32019
32478
|
}
|
|
32020
32479
|
const contentNewRoute = createRoute({
|
|
@@ -32734,7 +33193,7 @@ function MarketplaceBrowsePage() {
|
|
|
32734
33193
|
const { data: plugins } = useQuery({
|
|
32735
33194
|
queryKey: ["plugins"],
|
|
32736
33195
|
queryFn: async () => {
|
|
32737
|
-
const { fetchPlugins } = await import("./plugins-
|
|
33196
|
+
const { fetchPlugins } = await import("./plugins-DUJY_8HN.js").then((n) => n.a);
|
|
32738
33197
|
return fetchPlugins();
|
|
32739
33198
|
}
|
|
32740
33199
|
});
|
|
@@ -32753,7 +33212,7 @@ function MarketplaceDetailPage() {
|
|
|
32753
33212
|
const { data: plugins } = useQuery({
|
|
32754
33213
|
queryKey: ["plugins"],
|
|
32755
33214
|
queryFn: async () => {
|
|
32756
|
-
const { fetchPlugins } = await import("./plugins-
|
|
33215
|
+
const { fetchPlugins } = await import("./plugins-DUJY_8HN.js").then((n) => n.a);
|
|
32757
33216
|
return fetchPlugins();
|
|
32758
33217
|
}
|
|
32759
33218
|
});
|
|
@@ -33166,7 +33625,8 @@ const router = createAdminRouter(queryClient);
|
|
|
33166
33625
|
* Main Admin Application
|
|
33167
33626
|
*/
|
|
33168
33627
|
const EMPTY_PLUGINS = {};
|
|
33169
|
-
|
|
33628
|
+
const EMPTY_AUTH_PROVIDERS = {};
|
|
33629
|
+
function AdminApp({ pluginAdmins = EMPTY_PLUGINS, authProviders = EMPTY_AUTH_PROVIDERS, locale = "en", messages = {} }) {
|
|
33170
33630
|
React.useEffect(() => {
|
|
33171
33631
|
document.getElementById("emdash-boot-loader")?.remove();
|
|
33172
33632
|
}, []);
|
|
@@ -33180,16 +33640,19 @@ function AdminApp({ pluginAdmins = EMPTY_PLUGINS, locale = "en", messages = {} }
|
|
|
33180
33640
|
}
|
|
33181
33641
|
return /* @__PURE__ */ jsx(ThemeProvider, { children: /* @__PURE__ */ jsx(I18nProvider, {
|
|
33182
33642
|
i18n,
|
|
33183
|
-
children: /* @__PURE__ */ jsx(LocaleDirectionProvider, { children: /* @__PURE__ */ jsx(Toasty, { children: /* @__PURE__ */ jsx(
|
|
33184
|
-
|
|
33185
|
-
children: /* @__PURE__ */ jsx(
|
|
33186
|
-
|
|
33187
|
-
children: /* @__PURE__ */ jsx(
|
|
33643
|
+
children: /* @__PURE__ */ jsx(LocaleDirectionProvider, { children: /* @__PURE__ */ jsx(Toasty, { children: /* @__PURE__ */ jsx(AuthProviderProvider, {
|
|
33644
|
+
authProviders,
|
|
33645
|
+
children: /* @__PURE__ */ jsx(PluginAdminProvider, {
|
|
33646
|
+
pluginAdmins,
|
|
33647
|
+
children: /* @__PURE__ */ jsx(QueryClientProvider, {
|
|
33648
|
+
client: queryClient,
|
|
33649
|
+
children: /* @__PURE__ */ jsx(RouterProvider, { router })
|
|
33650
|
+
})
|
|
33188
33651
|
})
|
|
33189
33652
|
}) }) })
|
|
33190
33653
|
}) });
|
|
33191
33654
|
}
|
|
33192
33655
|
|
|
33193
33656
|
//#endregion
|
|
33194
|
-
export { API_BASE, API_TOKEN_SCOPES, AdminApp, AdminApp as App, CAPABILITY_LABELS, ContentEditor, ContentList, DEFAULT_LOCALE, Dashboard, Header, Link, LoginPage, MediaLibrary, MediaPickerModal, PasskeyLogin, PasskeyRegistration, PluginAdminProvider, PortableTextEditor, SUPPORTED_LOCALES, SUPPORTED_LOCALE_CODES, SaveButton, Settings, SetupWizard, Shell, KumoSidebar as Sidebar, SidebarNav, analyzeWpPluginSite, analyzeWxr, apiFetch, bulkCommentAction, checkPluginUpdates, cn, compareRevisions, completeSignup, createAdminRouter, createAllowedDomain, createApiToken, createByline, createCollection, createContent, createField, createMenu, createMenuItem, createRedirect, createSection, createTaxonomy, createTerm, createWidget, createWidgetArea, deleteAllowedDomain, deleteByline, deleteCollection, deleteComment, deleteContent, deleteField, deleteFromProvider, deleteMedia, deleteMenu, deleteMenuItem, deletePasskey, deleteRedirect, deleteSection, deleteTerm, deleteWidget, deleteWidgetArea, describeCapability, disablePlugin, disableUser, discardDraft, duplicateContent, enablePlugin, enableUser, executeWpPluginImport, executeWxrImport, fetch404Summary, fetchAllowedDomains, fetchApiTokens, fetchByline, fetchBylines, fetchCollection, fetchCollections, fetchComment, fetchCommentCounts, fetchComments, fetchContent, fetchContentList, fetchDashboardStats, fetchEmailSettings, fetchFields, fetchManifest, fetchMarketplacePlugin, fetchMediaList, fetchMediaProviders, fetchMenu, fetchMenus, fetchOrphanedTables, fetchPasskeys, fetchPlugin, fetchPlugins, fetchProviderMedia, fetchRedirects, fetchRevision, fetchRevisions, fetchSection, fetchSections, fetchSettings, fetchTaxonomyDef, fetchTaxonomyDefs, fetchTerms, fetchTheme, fetchTranslations, fetchTrashedContent, fetchUser, fetchUsers, fetchWidgetArea, fetchWidgetAreas, fetchWidgetComponents, generatePreviewUrl, getDraftStatus, getPreviewUrl, hasAllowedDomains, importWxrMedia, installMarketplacePlugin, inviteUser, parseApiResponse, permanentDeleteContent, prepareWxrImport, probeImportUrl, publishContent, registerOrphanedTable, renamePasskey, reorderFields, reorderMenuItems, reorderWidgets, requestSignup, resolveLocale, restoreContent, restoreRevision, revokeApiToken, rewriteContentUrls, scheduleContent, searchMarketplace, searchThemes, sendRecoveryLink, sendTestEmail, setSearchEnabled, throwResponseError, uninstallMarketplacePlugin, unpublishContent, unscheduleContent, updateAllowedDomain, updateByline, updateCollection, updateCommentStatus, updateContent, updateField, updateMarketplacePlugin, updateMedia, updateMenu, updateMenuItem, updateRedirect, updateSection, updateSettings, updateTerm, updateUser, updateWidget, uploadMedia, uploadToProvider, useCurrentUser, useLocale, useNavigate, useParams, usePluginAdmins, usePluginField, usePluginHasPages, usePluginHasWidgets, usePluginPage, usePluginWidget, validateInviteToken, verifySignupToken };
|
|
33657
|
+
export { API_BASE, API_TOKEN_SCOPES, AdminApp, AdminApp as App, AuthProviderProvider, CAPABILITY_LABELS, ContentEditor, ContentList, DEFAULT_LOCALE, Dashboard, Header, Link, LoginPage, MediaLibrary, MediaPickerModal, PasskeyLogin, PasskeyRegistration, PluginAdminProvider, PortableTextEditor, SUPPORTED_LOCALES, SUPPORTED_LOCALE_CODES, SaveButton, Settings, SetupWizard, Shell, KumoSidebar as Sidebar, SidebarNav, analyzeWpPluginSite, analyzeWxr, apiFetch, bulkCommentAction, checkPluginUpdates, cn, compareRevisions, completeSignup, createAdminRouter, createAllowedDomain, createApiToken, createByline, createCollection, createContent, createField, createMenu, createMenuItem, createRedirect, createSection, createTaxonomy, createTerm, createWidget, createWidgetArea, deleteAllowedDomain, deleteByline, deleteCollection, deleteComment, deleteContent, deleteField, deleteFromProvider, deleteMedia, deleteMenu, deleteMenuItem, deletePasskey, deleteRedirect, deleteSection, deleteTerm, deleteWidget, deleteWidgetArea, describeCapability, disablePlugin, disableUser, discardDraft, duplicateContent, enablePlugin, enableUser, executeWpPluginImport, executeWxrImport, fetch404Summary, fetchAllowedDomains, fetchApiTokens, fetchAuthMode, fetchByline, fetchBylines, fetchCollection, fetchCollections, fetchComment, fetchCommentCounts, fetchComments, fetchContent, fetchContentList, fetchDashboardStats, fetchEmailSettings, fetchFields, fetchManifest, fetchMarketplacePlugin, fetchMediaList, fetchMediaProviders, fetchMenu, fetchMenus, fetchOrphanedTables, fetchPasskeys, fetchPlugin, fetchPlugins, fetchProviderMedia, fetchRedirects, fetchRevision, fetchRevisions, fetchSection, fetchSections, fetchSettings, fetchTaxonomyDef, fetchTaxonomyDefs, fetchTerms, fetchTheme, fetchTranslations, fetchTrashedContent, fetchUser, fetchUsers, fetchWidgetArea, fetchWidgetAreas, fetchWidgetComponents, generatePreviewUrl, getDraftStatus, getPreviewUrl, hasAllowedDomains, importWxrMedia, installMarketplacePlugin, inviteUser, parseApiResponse, permanentDeleteContent, prepareWxrImport, probeImportUrl, publishContent, registerOrphanedTable, renamePasskey, reorderFields, reorderMenuItems, reorderWidgets, requestSignup, resolveLocale, restoreContent, restoreRevision, revokeApiToken, rewriteContentUrls, scheduleContent, searchMarketplace, searchThemes, sendRecoveryLink, sendTestEmail, setSearchEnabled, throwResponseError, uninstallMarketplacePlugin, unpublishContent, unscheduleContent, updateAllowedDomain, updateByline, updateCollection, updateCommentStatus, updateContent, updateField, updateMarketplacePlugin, updateMedia, updateMenu, updateMenuItem, updateRedirect, updateSection, updateSettings, updateTerm, updateUser, updateWidget, uploadMedia, uploadToProvider, useAuthProviderList, useAuthProviders, useCurrentUser, useLocale, useNavigate, useParams, usePluginAdmins, usePluginField, usePluginHasPages, usePluginHasWidgets, usePluginPage, usePluginWidget, validateInviteToken, verifySignupToken };
|
|
33195
33658
|
//# sourceMappingURL=index.js.map
|