@emdash-cms/admin 0.32.0 → 0.33.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-5U1vW9Op.js → LocaleDirectionProvider-C41G0UML.js} +39 -27
- package/dist/LocaleDirectionProvider-C41G0UML.js.map +1 -0
- package/dist/{config-BAgt8Ary.d.ts → config-fchhTOsm.d.ts} +1 -1
- package/dist/{config-BAgt8Ary.d.ts.map → config-fchhTOsm.d.ts.map} +1 -1
- package/dist/index.d.ts +22 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1107 -218
- package/dist/index.js.map +1 -1
- package/dist/locales/ar/messages.mjs +1 -1
- package/dist/locales/ca/messages.mjs +1 -1
- package/dist/locales/cs/messages.mjs +1 -0
- package/dist/locales/de/messages.mjs +1 -1
- package/dist/locales/en/messages.mjs +1 -1
- package/dist/locales/en-GB/messages.mjs +1 -1
- package/dist/locales/es-419/messages.mjs +1 -1
- package/dist/locales/es-ES/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/hi/messages.mjs +1 -0
- package/dist/locales/hu/messages.mjs +1 -1
- package/dist/locales/id/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/nb/messages.mjs +1 -1
- package/dist/locales/nl/messages.mjs +1 -1
- package/dist/locales/pl/messages.mjs +1 -1
- package/dist/locales/pseudo/messages.mjs +1 -1
- package/dist/locales/pt-BR/messages.mjs +1 -1
- package/dist/locales/sr-Latn/messages.mjs +1 -1
- package/dist/locales/sv/messages.mjs +1 -1
- package/dist/locales/th/messages.mjs +1 -1
- package/dist/locales/tr/messages.mjs +1 -1
- package/dist/locales/uk/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-2nITy6cb.js +6 -0
- package/dist/messages-2nITy6cb.js.map +1 -0
- package/dist/messages-B-s-GKf5.js +6 -0
- package/dist/messages-B-s-GKf5.js.map +1 -0
- package/dist/messages-BAIA7DfO.js +6 -0
- package/dist/messages-BAIA7DfO.js.map +1 -0
- package/dist/messages-BIe0Ym8X.js +6 -0
- package/dist/messages-BIe0Ym8X.js.map +1 -0
- package/dist/messages-BYdRq2w6.js +6 -0
- package/dist/messages-BYdRq2w6.js.map +1 -0
- package/dist/messages-BbP6qRzA.js +6 -0
- package/dist/messages-BbP6qRzA.js.map +1 -0
- package/dist/messages-BbypDsgO.js +6 -0
- package/dist/messages-BbypDsgO.js.map +1 -0
- package/dist/messages-BiQssJrA.js +6 -0
- package/dist/messages-BiQssJrA.js.map +1 -0
- package/dist/messages-BmjGFwEW.js +6 -0
- package/dist/messages-BmjGFwEW.js.map +1 -0
- package/dist/messages-BoMzEid6.js +6 -0
- package/dist/messages-BoMzEid6.js.map +1 -0
- package/dist/messages-Bq54RVtg.js +6 -0
- package/dist/messages-Bq54RVtg.js.map +1 -0
- package/dist/messages-Bqz9_4l0.js +6 -0
- package/dist/messages-Bqz9_4l0.js.map +1 -0
- package/dist/messages-BzV83X48.js +6 -0
- package/dist/messages-BzV83X48.js.map +1 -0
- package/dist/messages-CBfedvAL.js +6 -0
- package/dist/messages-CBfedvAL.js.map +1 -0
- package/dist/messages-CPe95E0E.js +6 -0
- package/dist/messages-CPe95E0E.js.map +1 -0
- package/dist/messages-CSnpmRJn.js +6 -0
- package/dist/messages-CSnpmRJn.js.map +1 -0
- package/dist/messages-CToObMDq.js +6 -0
- package/dist/messages-CToObMDq.js.map +1 -0
- package/dist/messages-C_VLhjAp.js +6 -0
- package/dist/messages-C_VLhjAp.js.map +1 -0
- package/dist/messages-C_zI4Kow.js +6 -0
- package/dist/messages-C_zI4Kow.js.map +1 -0
- package/dist/messages-Ci8G1wyr.js +6 -0
- package/dist/messages-Ci8G1wyr.js.map +1 -0
- package/dist/messages-CkcmC2uj.js +6 -0
- package/dist/messages-CkcmC2uj.js.map +1 -0
- package/dist/messages-ClIrJnnx.js +6 -0
- package/dist/messages-ClIrJnnx.js.map +1 -0
- package/dist/messages-D1BPX5RB.js +6 -0
- package/dist/messages-D1BPX5RB.js.map +1 -0
- package/dist/messages-D2Px_N2E.js +6 -0
- package/dist/messages-D2Px_N2E.js.map +1 -0
- package/dist/messages-D3et4y9E.js +6 -0
- package/dist/messages-D3et4y9E.js.map +1 -0
- package/dist/messages-DBQIDoWi.js +6 -0
- package/dist/messages-DBQIDoWi.js.map +1 -0
- package/dist/messages-EB4nBbR-.js +6 -0
- package/dist/messages-EB4nBbR-.js.map +1 -0
- package/dist/messages-wzeERbqn.js +6 -0
- package/dist/messages-wzeERbqn.js.map +1 -0
- package/dist/plugins-CQAV8Ap0.js.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +3 -2
- package/dist/LocaleDirectionProvider-5U1vW9Op.js.map +0 -1
- package/dist/messages-4Xvqxc1Y.js +0 -6
- package/dist/messages-4Xvqxc1Y.js.map +0 -1
- package/dist/messages-BEM_otIY.js +0 -6
- package/dist/messages-BEM_otIY.js.map +0 -1
- package/dist/messages-BGMVnYg4.js +0 -6
- package/dist/messages-BGMVnYg4.js.map +0 -1
- package/dist/messages-BclRCIJA.js +0 -6
- package/dist/messages-BclRCIJA.js.map +0 -1
- package/dist/messages-C1ze9eQE.js +0 -6
- package/dist/messages-C1ze9eQE.js.map +0 -1
- package/dist/messages-C4H363zG.js +0 -6
- package/dist/messages-C4H363zG.js.map +0 -1
- package/dist/messages-C6OGaloG.js +0 -6
- package/dist/messages-C6OGaloG.js.map +0 -1
- package/dist/messages-C8wqmrr8.js +0 -6
- package/dist/messages-C8wqmrr8.js.map +0 -1
- package/dist/messages-CA8wH0UZ.js +0 -6
- package/dist/messages-CA8wH0UZ.js.map +0 -1
- package/dist/messages-CIJnESHn.js +0 -6
- package/dist/messages-CIJnESHn.js.map +0 -1
- package/dist/messages-CM58Ca_k.js +0 -6
- package/dist/messages-CM58Ca_k.js.map +0 -1
- package/dist/messages-C_GxB5z5.js +0 -6
- package/dist/messages-C_GxB5z5.js.map +0 -1
- package/dist/messages-CyfnTXoj.js +0 -6
- package/dist/messages-CyfnTXoj.js.map +0 -1
- package/dist/messages-D0s7hcHS.js +0 -6
- package/dist/messages-D0s7hcHS.js.map +0 -1
- package/dist/messages-D1x_ybt3.js +0 -6
- package/dist/messages-D1x_ybt3.js.map +0 -1
- package/dist/messages-DGwx2Tk0.js +0 -6
- package/dist/messages-DGwx2Tk0.js.map +0 -1
- package/dist/messages-DK0nSPWb.js +0 -6
- package/dist/messages-DK0nSPWb.js.map +0 -1
- package/dist/messages-DN4lsll0.js +0 -6
- package/dist/messages-DN4lsll0.js.map +0 -1
- package/dist/messages-DTFf1KbO.js +0 -6
- package/dist/messages-DTFf1KbO.js.map +0 -1
- package/dist/messages-DbGMdPqR.js +0 -6
- package/dist/messages-DbGMdPqR.js.map +0 -1
- package/dist/messages-DhWQ6ntN.js +0 -6
- package/dist/messages-DhWQ6ntN.js.map +0 -1
- package/dist/messages-TIxLB_zK.js +0 -6
- package/dist/messages-TIxLB_zK.js.map +0 -1
- package/dist/messages-jmWwv5I9.js +0 -6
- package/dist/messages-jmWwv5I9.js.map +0 -1
- package/dist/messages-n5KSdGIR.js +0 -6
- package/dist/messages-n5KSdGIR.js.map +0 -1
- package/dist/messages-qZU4N886.js +0 -6
- package/dist/messages-qZU4N886.js.map +0 -1
- package/dist/messages-z8DCjl2v.js +0 -6
- package/dist/messages-z8DCjl2v.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { a as fetchPlugins, c as updatePluginSettings, d as fetchAuthMode, f as fetchManifest, i as fetchPluginSettings, l as API_BASE, m as throwResponseError, n as enablePlugin, p as parseApiResponse, r as fetchPlugin, s as setPluginMcpEnabled, t as disablePlugin, u as apiFetch } from "./plugins-CQAV8Ap0.js";
|
|
2
|
-
import { a as SUPPORTED_LOCALES, i as DEFAULT_LOCALE, l as resolveLocale, n as useLocale, o as SUPPORTED_LOCALE_CODES, s as getLocaleDir, t as LocaleDirectionProvider } from "./LocaleDirectionProvider-
|
|
2
|
+
import { a as SUPPORTED_LOCALES, i as DEFAULT_LOCALE, l as resolveLocale, n as useLocale, o as SUPPORTED_LOCALE_CODES, s as getLocaleDir, t as LocaleDirectionProvider } from "./LocaleDirectionProvider-C41G0UML.js";
|
|
3
3
|
import "./locales/index.js";
|
|
4
4
|
import { Autocomplete, Badge, Banner, Button, Checkbox, ClipboardText, Collapsible, Combobox, CommandPalette, Dialog, DropdownMenu, Field, Input, InputArea, Label, LayerCard, LinkButton, LinkProvider, Loader, Popover, Select, Sidebar, Sidebar as KumoSidebar, SkeletonLine, Switch, Tabs, Text, Toast, Toasty, Tooltip, TooltipProvider, buttonVariants, inputVariants, useKumoToastManager, useSidebar, useSidebar as useSidebar$1 } from "@cloudflare/kumo";
|
|
5
5
|
import { i18n } from "@lingui/core";
|
|
@@ -18,7 +18,7 @@ import { SortableContext, arrayMove, rectSortingStrategy, sortableKeyboardCoordi
|
|
|
18
18
|
import { CSS } from "@dnd-kit/utilities";
|
|
19
19
|
import { EditorContent, Node as Node$1, NodeViewContent, NodeViewWrapper, ReactNodeViewRenderer, mergeAttributes, useEditor, useEditorState } from "@tiptap/react";
|
|
20
20
|
import { Popover as Popover$1 } from "@cloudflare/kumo/primitives/popover";
|
|
21
|
-
import { Extension, InputRule, Node as Node$2, PasteRule, escapeForRegEx, mergeAttributes as mergeAttributes$1 } from "@tiptap/core";
|
|
21
|
+
import { Extension, InputRule, Node as Node$2, PasteRule, escapeForRegEx, mergeAttributes as mergeAttributes$1, wrappingInputRule } from "@tiptap/core";
|
|
22
22
|
import CharacterCount from "@tiptap/extension-character-count";
|
|
23
23
|
import Focus from "@tiptap/extension-focus";
|
|
24
24
|
import Placeholder from "@tiptap/extension-placeholder";
|
|
@@ -30,7 +30,7 @@ import { TableHeader } from "@tiptap/extension-table-header";
|
|
|
30
30
|
import { TableRow } from "@tiptap/extension-table-row";
|
|
31
31
|
import TextAlign from "@tiptap/extension-text-align";
|
|
32
32
|
import Typography from "@tiptap/extension-typography";
|
|
33
|
-
import { AllSelection, NodeSelection, Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
|
|
33
|
+
import { AllSelection, NodeSelection, Plugin, PluginKey, Selection, TextSelection } from "@tiptap/pm/state";
|
|
34
34
|
import { CellSelection } from "@tiptap/pm/tables";
|
|
35
35
|
import { BubbleMenu } from "@tiptap/react/menus";
|
|
36
36
|
import StarterKit from "@tiptap/starter-kit";
|
|
@@ -40,6 +40,9 @@ import Code$1 from "@tiptap/extension-code";
|
|
|
40
40
|
import { offset } from "@floating-ui/react";
|
|
41
41
|
import { DragHandle } from "@tiptap/extension-drag-handle-react";
|
|
42
42
|
import { isAllowedUri } from "@tiptap/extension-link";
|
|
43
|
+
import { OrderedList } from "@tiptap/extension-list";
|
|
44
|
+
import { Fragment as Fragment$1, Slice } from "@tiptap/pm/model";
|
|
45
|
+
import { canJoin, dropPoint } from "@tiptap/pm/transform";
|
|
43
46
|
import { BlockRenderer } from "@emdash-cms/blocks";
|
|
44
47
|
import DOMPurify from "dompurify";
|
|
45
48
|
import { Marked, Renderer } from "marked";
|
|
@@ -1882,6 +1885,24 @@ async function reorderFields(collectionSlug, fieldSlugs) {
|
|
|
1882
1885
|
}));
|
|
1883
1886
|
}
|
|
1884
1887
|
/**
|
|
1888
|
+
* Reorder collections in the admin sidebar.
|
|
1889
|
+
*
|
|
1890
|
+
* `slugs` is the full desired order — collections left out lose their
|
|
1891
|
+
* explicit position and fall back to alphabetical order after the ordered
|
|
1892
|
+
* ones.
|
|
1893
|
+
*/
|
|
1894
|
+
async function reorderCollections(slugs) {
|
|
1895
|
+
const response = await apiFetch(`${API_BASE}/schema/collections/reorder`, {
|
|
1896
|
+
method: "POST",
|
|
1897
|
+
headers: { "Content-Type": "application/json" },
|
|
1898
|
+
body: JSON.stringify({ slugs })
|
|
1899
|
+
});
|
|
1900
|
+
if (!response.ok) await throwResponseError(response, i18n._({
|
|
1901
|
+
id: "VLe0JL",
|
|
1902
|
+
message: "Failed to reorder content types"
|
|
1903
|
+
}));
|
|
1904
|
+
}
|
|
1905
|
+
/**
|
|
1885
1906
|
* Fetch orphaned content tables
|
|
1886
1907
|
*/
|
|
1887
1908
|
async function fetchOrphanedTables() {
|
|
@@ -2626,6 +2647,21 @@ async function updateTerm(taxonomyName, slug, input, options = {}) {
|
|
|
2626
2647
|
}), "Failed to update term")).term;
|
|
2627
2648
|
}
|
|
2628
2649
|
/**
|
|
2650
|
+
* Set the manual order of one sibling group.
|
|
2651
|
+
*
|
|
2652
|
+
* `ids` and `parentId` are translation groups: a term holds one position across
|
|
2653
|
+
* every locale, so there is no locale to pass. `ids` may name only the terms
|
|
2654
|
+
* this locale renders — the server permutes them within the positions they
|
|
2655
|
+
* already occupy and leaves untranslated members where they are.
|
|
2656
|
+
*/
|
|
2657
|
+
async function reorderTerms(taxonomyName, input) {
|
|
2658
|
+
await parseApiResponse(await apiFetch(`${API_BASE}/taxonomies/${taxonomyName}/reorder`, {
|
|
2659
|
+
method: "POST",
|
|
2660
|
+
headers: { "Content-Type": "application/json" },
|
|
2661
|
+
body: JSON.stringify(input)
|
|
2662
|
+
}), "Failed to reorder terms");
|
|
2663
|
+
}
|
|
2664
|
+
/**
|
|
2629
2665
|
* Delete a term
|
|
2630
2666
|
*/
|
|
2631
2667
|
async function deleteTerm(taxonomyName, slug, options = {}) {
|
|
@@ -4755,8 +4791,8 @@ function useContentStatusLabel(state) {
|
|
|
4755
4791
|
const { _: _t } = useLingui();
|
|
4756
4792
|
switch (state) {
|
|
4757
4793
|
case "published": return _t({
|
|
4758
|
-
id: "
|
|
4759
|
-
message: "
|
|
4794
|
+
id: "u3wRF+",
|
|
4795
|
+
message: "Published"
|
|
4760
4796
|
});
|
|
4761
4797
|
case "draft": return _t({
|
|
4762
4798
|
id: "eneWvv",
|
|
@@ -6940,7 +6976,7 @@ function toInput(draft) {
|
|
|
6940
6976
|
function serializeDraft(draft) {
|
|
6941
6977
|
return JSON.stringify(draft);
|
|
6942
6978
|
}
|
|
6943
|
-
function SeoPanel({ contentKey, seo, onChange }) {
|
|
6979
|
+
function SeoPanel({ contentKey, seo, onChange, defaultTitle, defaultDescription }) {
|
|
6944
6980
|
const { _: _t } = useLingui();
|
|
6945
6981
|
const titleId = React$1.useId();
|
|
6946
6982
|
const descriptionId = React$1.useId();
|
|
@@ -7064,6 +7100,7 @@ function SeoPanel({ contentKey, seo, onChange }) {
|
|
|
7064
7100
|
}),
|
|
7065
7101
|
className: "w-full",
|
|
7066
7102
|
value: draft.title,
|
|
7103
|
+
placeholder: defaultTitle ?? void 0,
|
|
7067
7104
|
onChange: (e) => {
|
|
7068
7105
|
updateDraft({ title: e.target.value });
|
|
7069
7106
|
},
|
|
@@ -7099,6 +7136,7 @@ function SeoPanel({ contentKey, seo, onChange }) {
|
|
|
7099
7136
|
values: { 0: draft.description.length }
|
|
7100
7137
|
}) : void 0,
|
|
7101
7138
|
value: draft.description,
|
|
7139
|
+
placeholder: defaultDescription ?? void 0,
|
|
7102
7140
|
onChange: (e) => {
|
|
7103
7141
|
updateDraft({ description: e.target.value });
|
|
7104
7142
|
},
|
|
@@ -8443,7 +8481,9 @@ const ContentSettingsPanel = React$1.memo(function ContentSettingsPanel({ collec
|
|
|
8443
8481
|
}), /* @__PURE__ */ jsx(SeoPanel, {
|
|
8444
8482
|
contentKey: item?.id ?? `new:${collection}`,
|
|
8445
8483
|
seo: item?.seo,
|
|
8446
|
-
onChange: onSeoChange
|
|
8484
|
+
onChange: onSeoChange,
|
|
8485
|
+
defaultTitle: typeof item?.data?.title === "string" ? item.data.title : null,
|
|
8486
|
+
defaultDescription: typeof item?.data?.excerpt === "string" ? item.data.excerpt : null
|
|
8447
8487
|
})]
|
|
8448
8488
|
})
|
|
8449
8489
|
}),
|
|
@@ -11387,6 +11427,401 @@ const MarkdownLinkExtension = Extension.create({
|
|
|
11387
11427
|
}
|
|
11388
11428
|
});
|
|
11389
11429
|
|
|
11430
|
+
//#endregion
|
|
11431
|
+
//#region src/components/editor/ordered-list.ts
|
|
11432
|
+
const ORDERED_LIST_INPUT_REGEX = /^(\d+)\.\s$/;
|
|
11433
|
+
const MAX_START = 2147483647;
|
|
11434
|
+
const normalizeId = (value) => {
|
|
11435
|
+
if (typeof value !== "string") return void 0;
|
|
11436
|
+
const id = value.trim();
|
|
11437
|
+
return id.length > 0 && id.length <= 128 ? id : void 0;
|
|
11438
|
+
};
|
|
11439
|
+
const normalizeStart = (value) => typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= MAX_START ? value : void 0;
|
|
11440
|
+
const legacyId = (seed) => {
|
|
11441
|
+
const readable = `legacy:${seed}`;
|
|
11442
|
+
if (readable.length <= 128) return readable;
|
|
11443
|
+
let hash = 2166136261;
|
|
11444
|
+
for (let i = 0; i < seed.length; i++) {
|
|
11445
|
+
hash ^= seed.charCodeAt(i);
|
|
11446
|
+
hash = Math.imul(hash, 16777619);
|
|
11447
|
+
}
|
|
11448
|
+
return `legacy:${seed.slice(0, 96)}:${(hash >>> 0).toString(36)}:${seed.length.toString(36)}`;
|
|
11449
|
+
};
|
|
11450
|
+
const createId = () => globalThis.crypto?.randomUUID?.() ?? `list-${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
|
|
11451
|
+
const createRepairId = (sourceId, scope, attempt) => {
|
|
11452
|
+
const base = legacyId(`repair:${sourceId}:${scope}`);
|
|
11453
|
+
const suffix = `:${attempt.toString(36)}`;
|
|
11454
|
+
return `${base.slice(0, 128 - suffix.length)}${suffix}`;
|
|
11455
|
+
};
|
|
11456
|
+
function collectLists(doc) {
|
|
11457
|
+
const lists = [];
|
|
11458
|
+
doc.descendants((node, pos) => {
|
|
11459
|
+
if (node.type.name !== "orderedList") return;
|
|
11460
|
+
const resolved = doc.resolve(pos);
|
|
11461
|
+
let context = "root";
|
|
11462
|
+
let contextPos = null;
|
|
11463
|
+
for (let depth = resolved.depth; depth > 0; depth--) if (resolved.node(depth).type.name === "listItem") {
|
|
11464
|
+
contextPos = resolved.before(depth);
|
|
11465
|
+
context = `listItem:${contextPos}`;
|
|
11466
|
+
break;
|
|
11467
|
+
}
|
|
11468
|
+
if (contextPos === null && resolved.depth > 0) {
|
|
11469
|
+
contextPos = resolved.before(resolved.depth);
|
|
11470
|
+
context = `${resolved.node(resolved.depth).type.name}:${contextPos}`;
|
|
11471
|
+
}
|
|
11472
|
+
lists.push({
|
|
11473
|
+
node,
|
|
11474
|
+
pos,
|
|
11475
|
+
depth: resolved.depth,
|
|
11476
|
+
context,
|
|
11477
|
+
contextPos
|
|
11478
|
+
});
|
|
11479
|
+
});
|
|
11480
|
+
return lists;
|
|
11481
|
+
}
|
|
11482
|
+
function normalizeOrderedListDocument(doc) {
|
|
11483
|
+
const canonicalBySourceScope = /* @__PURE__ */ new Map();
|
|
11484
|
+
const assignedCanonicalIds = /* @__PURE__ */ new Set();
|
|
11485
|
+
const lists = collectLists(doc).map((list) => {
|
|
11486
|
+
const sourceId = normalizeId(list.node.attrs.listId) ?? legacyId(`pm:${list.pos}:${list.depth}:${list.context}`);
|
|
11487
|
+
const scope = JSON.stringify([list.depth, list.context]);
|
|
11488
|
+
const sourceScope = JSON.stringify([sourceId, scope]);
|
|
11489
|
+
let listId = canonicalBySourceScope.get(sourceScope);
|
|
11490
|
+
if (!listId) {
|
|
11491
|
+
if (!assignedCanonicalIds.has(sourceId)) listId = sourceId;
|
|
11492
|
+
else {
|
|
11493
|
+
let attempt = 0;
|
|
11494
|
+
do
|
|
11495
|
+
listId = createRepairId(sourceId, scope, attempt++);
|
|
11496
|
+
while (assignedCanonicalIds.has(listId));
|
|
11497
|
+
}
|
|
11498
|
+
canonicalBySourceScope.set(sourceScope, listId);
|
|
11499
|
+
assignedCanonicalIds.add(listId);
|
|
11500
|
+
}
|
|
11501
|
+
return {
|
|
11502
|
+
...list,
|
|
11503
|
+
listId,
|
|
11504
|
+
scopeKey: JSON.stringify([
|
|
11505
|
+
listId,
|
|
11506
|
+
list.depth,
|
|
11507
|
+
list.context
|
|
11508
|
+
])
|
|
11509
|
+
};
|
|
11510
|
+
});
|
|
11511
|
+
const bases = /* @__PURE__ */ new Map();
|
|
11512
|
+
for (const list of lists) {
|
|
11513
|
+
const start = normalizeStart(list.node.attrs.listStart);
|
|
11514
|
+
if (start !== void 0 && !bases.has(list.scopeKey)) bases.set(list.scopeKey, start);
|
|
11515
|
+
}
|
|
11516
|
+
for (const list of lists) if (!bases.has(list.scopeKey)) bases.set(list.scopeKey, normalizeStart(list.node.attrs.start) ?? 1);
|
|
11517
|
+
const counts = /* @__PURE__ */ new Map();
|
|
11518
|
+
const changes = [];
|
|
11519
|
+
for (const list of lists) {
|
|
11520
|
+
const listStart = bases.get(list.scopeKey);
|
|
11521
|
+
const count = counts.get(list.scopeKey) ?? 0;
|
|
11522
|
+
const start = normalizeStart(listStart + count) ?? 1;
|
|
11523
|
+
counts.set(list.scopeKey, count + list.node.childCount);
|
|
11524
|
+
if (list.node.attrs.listId !== list.listId || list.node.attrs.listStart !== listStart || list.node.attrs.start !== start) changes.push({
|
|
11525
|
+
pos: list.pos,
|
|
11526
|
+
attrs: {
|
|
11527
|
+
...list.node.attrs,
|
|
11528
|
+
listId: list.listId,
|
|
11529
|
+
listStart,
|
|
11530
|
+
start
|
|
11531
|
+
}
|
|
11532
|
+
});
|
|
11533
|
+
}
|
|
11534
|
+
return changes;
|
|
11535
|
+
}
|
|
11536
|
+
function normalizeTransaction(state) {
|
|
11537
|
+
const changes = normalizeOrderedListDocument(state.doc);
|
|
11538
|
+
if (changes.length === 0) {
|
|
11539
|
+
const lists = collectLists(state.doc);
|
|
11540
|
+
if (!lists.some((list, index) => {
|
|
11541
|
+
const next = lists[index + 1];
|
|
11542
|
+
return next !== void 0 && next.pos === list.pos + list.node.nodeSize && next.depth === list.depth && next.context === list.context && normalizeId(next.node.attrs.listId) === normalizeId(list.node.attrs.listId) && normalizeStart(next.node.attrs.listStart) === normalizeStart(list.node.attrs.listStart);
|
|
11543
|
+
})) return null;
|
|
11544
|
+
}
|
|
11545
|
+
const transaction = state.tr;
|
|
11546
|
+
for (const change of changes) transaction.setNodeMarkup(change.pos, void 0, change.attrs);
|
|
11547
|
+
const normalizedLists = collectLists(transaction.doc);
|
|
11548
|
+
const joinPositions = normalizedLists.flatMap((list, index) => {
|
|
11549
|
+
const next = normalizedLists[index + 1];
|
|
11550
|
+
return next !== void 0 && next.pos === list.pos + list.node.nodeSize && next.depth === list.depth && next.context === list.context && normalizeId(next.node.attrs.listId) === normalizeId(list.node.attrs.listId) && normalizeStart(next.node.attrs.listStart) === normalizeStart(list.node.attrs.listStart) ? [next.pos] : [];
|
|
11551
|
+
});
|
|
11552
|
+
for (const pos of joinPositions.toReversed()) if (canJoin(transaction.doc, pos)) transaction.join(pos);
|
|
11553
|
+
if (!transaction.docChanged) return null;
|
|
11554
|
+
return transaction;
|
|
11555
|
+
}
|
|
11556
|
+
function remapPaste(slice) {
|
|
11557
|
+
const identities = /* @__PURE__ */ new Map();
|
|
11558
|
+
let missingIndex = 0;
|
|
11559
|
+
const mapFragment = (fragment, depth, parentContext) => {
|
|
11560
|
+
const children = [];
|
|
11561
|
+
fragment.forEach((node, _offset, index) => {
|
|
11562
|
+
const childContext = node.type.name === "listItem" ? `${parentContext}/listItem:${index}` : parentContext;
|
|
11563
|
+
const content = mapFragment(node.content, depth + 1, childContext);
|
|
11564
|
+
if (node.type.name !== "orderedList") {
|
|
11565
|
+
children.push(node.copy(content));
|
|
11566
|
+
return;
|
|
11567
|
+
}
|
|
11568
|
+
const sourceId = normalizeId(node.attrs.listId) ?? `missing:${missingIndex++}`;
|
|
11569
|
+
const scope = JSON.stringify([
|
|
11570
|
+
sourceId,
|
|
11571
|
+
depth,
|
|
11572
|
+
parentContext
|
|
11573
|
+
]);
|
|
11574
|
+
let identity = identities.get(scope);
|
|
11575
|
+
if (!identity) {
|
|
11576
|
+
identity = {
|
|
11577
|
+
listId: createId(),
|
|
11578
|
+
listStart: normalizeStart(node.attrs.start) ?? normalizeStart(node.attrs.listStart) ?? 1
|
|
11579
|
+
};
|
|
11580
|
+
identities.set(scope, identity);
|
|
11581
|
+
}
|
|
11582
|
+
children.push(node.type.create({
|
|
11583
|
+
...node.attrs,
|
|
11584
|
+
...identity,
|
|
11585
|
+
start: identity.listStart
|
|
11586
|
+
}, content, node.marks));
|
|
11587
|
+
});
|
|
11588
|
+
return Fragment$1.fromArray(children);
|
|
11589
|
+
};
|
|
11590
|
+
return new Slice(mapFragment(slice.content, 0, "root"), slice.openStart, slice.openEnd);
|
|
11591
|
+
}
|
|
11592
|
+
function sliceHasOrderedList(slice) {
|
|
11593
|
+
let found = false;
|
|
11594
|
+
slice.content.descendants((node) => {
|
|
11595
|
+
if (node.type.name !== "orderedList") return true;
|
|
11596
|
+
found = true;
|
|
11597
|
+
return false;
|
|
11598
|
+
});
|
|
11599
|
+
return found;
|
|
11600
|
+
}
|
|
11601
|
+
function displayedStartAtSelection(state) {
|
|
11602
|
+
const current = collectLists(state.doc).findLast((list) => state.selection.from >= list.pos && state.selection.from <= list.pos + list.node.nodeSize);
|
|
11603
|
+
if (!current) return null;
|
|
11604
|
+
const listId = normalizeId(current.node.attrs.listId);
|
|
11605
|
+
const start = normalizeStart(current.node.attrs.start);
|
|
11606
|
+
if (!listId || start === void 0) return null;
|
|
11607
|
+
let precedingItems = 0;
|
|
11608
|
+
current.node.forEach((child, offset) => {
|
|
11609
|
+
if (current.pos + 1 + offset + child.nodeSize <= state.selection.from) precedingItems++;
|
|
11610
|
+
});
|
|
11611
|
+
return {
|
|
11612
|
+
listId,
|
|
11613
|
+
listStart: normalizeStart(start + precedingItems) ?? 1
|
|
11614
|
+
};
|
|
11615
|
+
}
|
|
11616
|
+
function rewriteSliceIdentity(slice, sourceId, listId, listStart) {
|
|
11617
|
+
const mapFragment = (fragment) => {
|
|
11618
|
+
const children = [];
|
|
11619
|
+
fragment.forEach((node) => {
|
|
11620
|
+
const content = mapFragment(node.content);
|
|
11621
|
+
children.push(node.type.name === "orderedList" && normalizeId(node.attrs.listId) === sourceId ? node.type.create({
|
|
11622
|
+
...node.attrs,
|
|
11623
|
+
listId,
|
|
11624
|
+
listStart,
|
|
11625
|
+
start: listStart
|
|
11626
|
+
}, content, node.marks) : node.copy(content));
|
|
11627
|
+
});
|
|
11628
|
+
return Fragment$1.fromArray(children);
|
|
11629
|
+
};
|
|
11630
|
+
return new Slice(mapFragment(slice.content), slice.openStart, slice.openEnd);
|
|
11631
|
+
}
|
|
11632
|
+
function prepareCopy(slice, state) {
|
|
11633
|
+
const selected = displayedStartAtSelection(state);
|
|
11634
|
+
if (!selected) return slice;
|
|
11635
|
+
let updated = false;
|
|
11636
|
+
const mapFragment = (fragment) => {
|
|
11637
|
+
const children = [];
|
|
11638
|
+
fragment.forEach((node) => {
|
|
11639
|
+
const isFirstSelectedList = !updated && node.type.name === "orderedList" && normalizeId(node.attrs.listId) === selected.listId;
|
|
11640
|
+
if (isFirstSelectedList) updated = true;
|
|
11641
|
+
const content = mapFragment(node.content);
|
|
11642
|
+
if (isFirstSelectedList) children.push(node.type.create({
|
|
11643
|
+
...node.attrs,
|
|
11644
|
+
start: selected.listStart
|
|
11645
|
+
}, content, node.marks));
|
|
11646
|
+
else children.push(node.copy(content));
|
|
11647
|
+
});
|
|
11648
|
+
return Fragment$1.fromArray(children);
|
|
11649
|
+
};
|
|
11650
|
+
return new Slice(mapFragment(slice.content), slice.openStart, slice.openEnd);
|
|
11651
|
+
}
|
|
11652
|
+
function remapMove(slice, state) {
|
|
11653
|
+
const selected = displayedStartAtSelection(state);
|
|
11654
|
+
if (!selected) return slice;
|
|
11655
|
+
return rewriteSliceIdentity(slice, selected.listId, createId(), selected.listStart);
|
|
11656
|
+
}
|
|
11657
|
+
function selectedList(state) {
|
|
11658
|
+
const lists = collectLists(state.doc);
|
|
11659
|
+
const current = lists.findLast((list) => state.selection.from >= list.pos && state.selection.to <= list.pos + list.node.nodeSize);
|
|
11660
|
+
if (!current) return null;
|
|
11661
|
+
return lists.filter((list) => list.depth === current.depth && list.context === current.context && state.selection.from < list.pos + list.node.nodeSize && state.selection.to > list.pos).length === 1 ? {
|
|
11662
|
+
current,
|
|
11663
|
+
lists
|
|
11664
|
+
} : null;
|
|
11665
|
+
}
|
|
11666
|
+
function rewriteTail(state, dispatch, mode) {
|
|
11667
|
+
const selected = selectedList(state);
|
|
11668
|
+
if (!selected) return false;
|
|
11669
|
+
const { current, lists } = selected;
|
|
11670
|
+
const currentId = normalizeId(current.node.attrs.listId);
|
|
11671
|
+
if (!currentId) return false;
|
|
11672
|
+
const compatible = lists.filter((list) => list.depth === current.depth && list.context === current.context);
|
|
11673
|
+
const predecessor = compatible.findLast((list) => list.pos < current.pos);
|
|
11674
|
+
const predecessorId = predecessor ? normalizeId(predecessor.node.attrs.listId) : void 0;
|
|
11675
|
+
if (mode === "continue" && (!predecessorId || predecessorId === currentId)) return false;
|
|
11676
|
+
if (!dispatch) return true;
|
|
11677
|
+
const listId = mode === "continue" ? predecessorId : createId();
|
|
11678
|
+
const listStart = mode === "continue" ? normalizeStart(predecessor.node.attrs.listStart) ?? 1 : 1;
|
|
11679
|
+
const transaction = state.tr;
|
|
11680
|
+
for (const list of compatible) {
|
|
11681
|
+
if (list.pos < current.pos || normalizeId(list.node.attrs.listId) !== currentId) continue;
|
|
11682
|
+
transaction.setNodeMarkup(list.pos, void 0, {
|
|
11683
|
+
...list.node.attrs,
|
|
11684
|
+
listId,
|
|
11685
|
+
listStart
|
|
11686
|
+
});
|
|
11687
|
+
}
|
|
11688
|
+
dispatch(transaction);
|
|
11689
|
+
return true;
|
|
11690
|
+
}
|
|
11691
|
+
function buildDropTransaction(state, slice, insertPos, deleteSource) {
|
|
11692
|
+
const transaction = state.tr;
|
|
11693
|
+
if (deleteSource) transaction.deleteSelection();
|
|
11694
|
+
const from = transaction.mapping.map(insertPos);
|
|
11695
|
+
const beforeInsert = transaction.doc;
|
|
11696
|
+
transaction.replaceRange(from, from, slice);
|
|
11697
|
+
if (transaction.doc.eq(beforeInsert)) return null;
|
|
11698
|
+
let to = from;
|
|
11699
|
+
transaction.mapping.maps.at(-1)?.forEach((_oldFrom, _oldTo, _newFrom, newTo) => {
|
|
11700
|
+
to = Math.max(to, newTo);
|
|
11701
|
+
});
|
|
11702
|
+
return {
|
|
11703
|
+
transaction,
|
|
11704
|
+
from,
|
|
11705
|
+
to
|
|
11706
|
+
};
|
|
11707
|
+
}
|
|
11708
|
+
function handleMovedDrop(view, event, slice, moved) {
|
|
11709
|
+
if (!sliceHasOrderedList(slice)) return false;
|
|
11710
|
+
const eventPos = view.posAtCoords({
|
|
11711
|
+
left: event.clientX,
|
|
11712
|
+
top: event.clientY
|
|
11713
|
+
});
|
|
11714
|
+
if (!eventPos) return false;
|
|
11715
|
+
const insertPos = dropPoint(view.state.doc, eventPos.pos, slice) ?? eventPos.pos;
|
|
11716
|
+
if (!moved) {
|
|
11717
|
+
const dropped = buildDropTransaction(view.state, remapPaste(slice), insertPos, false);
|
|
11718
|
+
if (!dropped) return false;
|
|
11719
|
+
const selectionPos = Math.min(dropped.to, dropped.transaction.doc.content.size);
|
|
11720
|
+
dropped.transaction.setSelection(Selection.near(dropped.transaction.doc.resolve(selectionPos), -1));
|
|
11721
|
+
view.focus();
|
|
11722
|
+
view.dispatch(dropped.transaction.setMeta("uiEvent", "drop").scrollIntoView());
|
|
11723
|
+
return true;
|
|
11724
|
+
}
|
|
11725
|
+
const selected = selectedList(view.state);
|
|
11726
|
+
if (!selected) return false;
|
|
11727
|
+
const preview = buildDropTransaction(view.state, slice, insertPos, true);
|
|
11728
|
+
if (!preview) return false;
|
|
11729
|
+
const sourceContextPos = selected.current.contextPos;
|
|
11730
|
+
const mappedSourceContextPos = sourceContextPos === null ? null : preview.transaction.mapping.map(sourceContextPos, 1);
|
|
11731
|
+
if (collectLists(preview.transaction.doc).some((list) => list.pos < preview.to && list.pos + list.node.nodeSize > preview.from && list.depth === selected.current.depth && list.contextPos === mappedSourceContextPos)) return false;
|
|
11732
|
+
const remapped = remapMove(slice, view.state);
|
|
11733
|
+
if (remapped === slice) return false;
|
|
11734
|
+
const dropped = buildDropTransaction(view.state, remapped, insertPos, true);
|
|
11735
|
+
if (!dropped) return false;
|
|
11736
|
+
const selectionPos = Math.min(dropped.to, dropped.transaction.doc.content.size);
|
|
11737
|
+
dropped.transaction.setSelection(Selection.near(dropped.transaction.doc.resolve(selectionPos), -1));
|
|
11738
|
+
view.focus();
|
|
11739
|
+
view.dispatch(dropped.transaction.setMeta("uiEvent", "drop").scrollIntoView());
|
|
11740
|
+
return true;
|
|
11741
|
+
}
|
|
11742
|
+
const EmDashOrderedList = OrderedList.extend({
|
|
11743
|
+
addAttributes() {
|
|
11744
|
+
const parent = this.parent?.() ?? {};
|
|
11745
|
+
return {
|
|
11746
|
+
...parent,
|
|
11747
|
+
start: {
|
|
11748
|
+
...parent.start,
|
|
11749
|
+
parseHTML: (element) => normalizeStart(Number(element.dataset.emdashListFirst)) ?? normalizeStart(Number(element.getAttribute("start"))) ?? 1
|
|
11750
|
+
},
|
|
11751
|
+
listId: {
|
|
11752
|
+
default: null,
|
|
11753
|
+
parseHTML: (element) => normalizeId(element.dataset.emdashListId) ?? null,
|
|
11754
|
+
rendered: false
|
|
11755
|
+
},
|
|
11756
|
+
listStart: {
|
|
11757
|
+
default: null,
|
|
11758
|
+
parseHTML: (element) => normalizeStart(Number(element.dataset.emdashListStart)) ?? null,
|
|
11759
|
+
rendered: false
|
|
11760
|
+
}
|
|
11761
|
+
};
|
|
11762
|
+
},
|
|
11763
|
+
renderHTML({ HTMLAttributes, node }) {
|
|
11764
|
+
const { start: _start, ...withoutStart } = HTMLAttributes;
|
|
11765
|
+
const start = normalizeStart(node.attrs.start) ?? 1;
|
|
11766
|
+
const continuity = {
|
|
11767
|
+
"data-emdash-list-id": normalizeId(node.attrs.listId),
|
|
11768
|
+
"data-emdash-list-start": normalizeStart(node.attrs.listStart),
|
|
11769
|
+
"data-emdash-list-first": start
|
|
11770
|
+
};
|
|
11771
|
+
return start === 1 ? [
|
|
11772
|
+
"ol",
|
|
11773
|
+
mergeAttributes$1(this.options.HTMLAttributes, withoutStart, continuity),
|
|
11774
|
+
0
|
|
11775
|
+
] : [
|
|
11776
|
+
"ol",
|
|
11777
|
+
mergeAttributes$1(this.options.HTMLAttributes, {
|
|
11778
|
+
...withoutStart,
|
|
11779
|
+
start
|
|
11780
|
+
}, continuity),
|
|
11781
|
+
0
|
|
11782
|
+
];
|
|
11783
|
+
},
|
|
11784
|
+
addCommands() {
|
|
11785
|
+
return {
|
|
11786
|
+
toggleOrderedList: () => ({ commands, chain }) => this.editor.isActive(this.name) ? commands.toggleList(this.name, this.options.itemTypeName, this.options.keepMarks) : chain().toggleList(this.name, this.options.itemTypeName, this.options.keepMarks).updateAttributes(this.name, {
|
|
11787
|
+
listId: createId(),
|
|
11788
|
+
listStart: 1
|
|
11789
|
+
}).run(),
|
|
11790
|
+
continueOrderedList: () => ({ state, dispatch }) => rewriteTail(state, dispatch, "continue"),
|
|
11791
|
+
restartOrderedList: () => ({ state, dispatch }) => rewriteTail(state, dispatch, "restart")
|
|
11792
|
+
};
|
|
11793
|
+
},
|
|
11794
|
+
addInputRules() {
|
|
11795
|
+
return [wrappingInputRule({
|
|
11796
|
+
find: ORDERED_LIST_INPUT_REGEX,
|
|
11797
|
+
type: this.type,
|
|
11798
|
+
getAttributes: (match) => {
|
|
11799
|
+
const listStart = normalizeStart(Number(match[1])) ?? 1;
|
|
11800
|
+
return {
|
|
11801
|
+
start: listStart,
|
|
11802
|
+
listStart,
|
|
11803
|
+
listId: createId()
|
|
11804
|
+
};
|
|
11805
|
+
},
|
|
11806
|
+
joinPredicate: () => false
|
|
11807
|
+
})];
|
|
11808
|
+
},
|
|
11809
|
+
addProseMirrorPlugins() {
|
|
11810
|
+
return [new Plugin({
|
|
11811
|
+
appendTransaction: (_transactions, _oldState, newState) => normalizeTransaction(newState),
|
|
11812
|
+
props: {
|
|
11813
|
+
transformCopied: (slice, view) => prepareCopy(slice, view.state),
|
|
11814
|
+
handleDrop: handleMovedDrop,
|
|
11815
|
+
handlePaste(view, _event, slice) {
|
|
11816
|
+
if (!sliceHasOrderedList(slice)) return false;
|
|
11817
|
+
view.dispatch(view.state.tr.replaceSelection(remapPaste(slice)).setMeta("paste", true).setMeta("uiEvent", "paste").scrollIntoView());
|
|
11818
|
+
return true;
|
|
11819
|
+
}
|
|
11820
|
+
}
|
|
11821
|
+
})];
|
|
11822
|
+
}
|
|
11823
|
+
});
|
|
11824
|
+
|
|
11390
11825
|
//#endregion
|
|
11391
11826
|
//#region src/components/editor/PluginBlockNode.tsx
|
|
11392
11827
|
/**
|
|
@@ -11973,17 +12408,124 @@ function sanitizeGalleryImages(value, withKeys = false) {
|
|
|
11973
12408
|
}
|
|
11974
12409
|
const attrStr = (v) => typeof v === "string" && v ? v : void 0;
|
|
11975
12410
|
const attrNum = (v) => typeof v === "number" && v ? v : void 0;
|
|
12411
|
+
const MAX_ORDERED_LIST_START = 2147483647;
|
|
12412
|
+
function normalizeListId(value) {
|
|
12413
|
+
if (typeof value !== "string") return void 0;
|
|
12414
|
+
const normalized = value.trim();
|
|
12415
|
+
return normalized.length > 0 && normalized.length <= 128 ? normalized : void 0;
|
|
12416
|
+
}
|
|
12417
|
+
function normalizeListStart(value) {
|
|
12418
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 1 && value <= MAX_ORDERED_LIST_START ? value : void 0;
|
|
12419
|
+
}
|
|
12420
|
+
function deriveLegacyListId(seed) {
|
|
12421
|
+
const readable = `legacy:${seed}`;
|
|
12422
|
+
if (readable.length <= 128) return readable;
|
|
12423
|
+
let hash = 2166136261;
|
|
12424
|
+
for (let i = 0; i < seed.length; i++) {
|
|
12425
|
+
hash ^= seed.charCodeAt(i);
|
|
12426
|
+
hash = Math.imul(hash, 16777619);
|
|
12427
|
+
}
|
|
12428
|
+
return `legacy:${seed.slice(0, 96)}:${(hash >>> 0).toString(36)}:${seed.length.toString(36)}`;
|
|
12429
|
+
}
|
|
12430
|
+
function readOrderedListMetadata(attrs, fallbackId) {
|
|
12431
|
+
return {
|
|
12432
|
+
listId: normalizeListId(attrs?.listId) ?? deriveLegacyListId(fallbackId),
|
|
12433
|
+
listStart: normalizeListStart(attrs?.listStart) ?? normalizeListStart(attrs?.start) ?? 1
|
|
12434
|
+
};
|
|
12435
|
+
}
|
|
12436
|
+
function clonePortableTextProseMirrorNode(node) {
|
|
12437
|
+
return {
|
|
12438
|
+
...node,
|
|
12439
|
+
attrs: node.attrs ? { ...node.attrs } : void 0,
|
|
12440
|
+
content: node.content?.map(clonePortableTextProseMirrorNode),
|
|
12441
|
+
marks: node.marks?.map((mark) => ({
|
|
12442
|
+
...mark,
|
|
12443
|
+
attrs: mark.attrs ? { ...mark.attrs } : void 0
|
|
12444
|
+
}))
|
|
12445
|
+
};
|
|
12446
|
+
}
|
|
12447
|
+
function normalizeOrderedListJson(doc) {
|
|
12448
|
+
const normalized = {
|
|
12449
|
+
...doc,
|
|
12450
|
+
content: doc.content.map(clonePortableTextProseMirrorNode)
|
|
12451
|
+
};
|
|
12452
|
+
const lists = [];
|
|
12453
|
+
const visit = (node, path, depth, context) => {
|
|
12454
|
+
if (node.type === "orderedList") lists.push({
|
|
12455
|
+
node,
|
|
12456
|
+
path,
|
|
12457
|
+
depth,
|
|
12458
|
+
context
|
|
12459
|
+
});
|
|
12460
|
+
for (const [index, child] of (node.content ?? []).entries()) {
|
|
12461
|
+
const childPath = `${path}:${index}`;
|
|
12462
|
+
visit(child, childPath, depth + 1, child.type === "listItem" ? `listItem:${childPath}` : context);
|
|
12463
|
+
}
|
|
12464
|
+
};
|
|
12465
|
+
for (const [index, node] of normalized.content.entries()) visit(node, `root:${index}`, 0, "root");
|
|
12466
|
+
const canonicalBySourceScope = /* @__PURE__ */ new Map();
|
|
12467
|
+
const assignedIds = /* @__PURE__ */ new Set();
|
|
12468
|
+
const descriptors = lists.map((list) => {
|
|
12469
|
+
const sourceId = normalizeListId(list.node.attrs?.listId) ?? deriveLegacyListId(`pm-json:${list.path}:${list.depth}:${list.context}`);
|
|
12470
|
+
const scope = JSON.stringify([list.depth, list.context]);
|
|
12471
|
+
const sourceScope = JSON.stringify([sourceId, scope]);
|
|
12472
|
+
let listId = canonicalBySourceScope.get(sourceScope);
|
|
12473
|
+
if (!listId) {
|
|
12474
|
+
if (!assignedIds.has(sourceId)) listId = sourceId;
|
|
12475
|
+
else {
|
|
12476
|
+
let attempt = 0;
|
|
12477
|
+
do {
|
|
12478
|
+
const suffix = `:${attempt.toString(36)}`;
|
|
12479
|
+
listId = `${deriveLegacyListId(`repair:${sourceId}:${scope}`).slice(0, 128 - suffix.length)}${suffix}`;
|
|
12480
|
+
attempt++;
|
|
12481
|
+
} while (assignedIds.has(listId));
|
|
12482
|
+
}
|
|
12483
|
+
canonicalBySourceScope.set(sourceScope, listId);
|
|
12484
|
+
assignedIds.add(listId);
|
|
12485
|
+
}
|
|
12486
|
+
return {
|
|
12487
|
+
...list,
|
|
12488
|
+
listId,
|
|
12489
|
+
scopeKey: JSON.stringify([
|
|
12490
|
+
listId,
|
|
12491
|
+
list.depth,
|
|
12492
|
+
list.context
|
|
12493
|
+
])
|
|
12494
|
+
};
|
|
12495
|
+
});
|
|
12496
|
+
const bases = /* @__PURE__ */ new Map();
|
|
12497
|
+
for (const list of descriptors) {
|
|
12498
|
+
const listStart = normalizeListStart(list.node.attrs?.listStart);
|
|
12499
|
+
if (listStart !== void 0 && !bases.has(list.scopeKey)) bases.set(list.scopeKey, listStart);
|
|
12500
|
+
}
|
|
12501
|
+
for (const list of descriptors) if (!bases.has(list.scopeKey)) bases.set(list.scopeKey, normalizeListStart(list.node.attrs?.start) ?? 1);
|
|
12502
|
+
const counts = /* @__PURE__ */ new Map();
|
|
12503
|
+
for (const list of descriptors) {
|
|
12504
|
+
const listStart = bases.get(list.scopeKey);
|
|
12505
|
+
const count = counts.get(list.scopeKey) ?? 0;
|
|
12506
|
+
const start = normalizeListStart(listStart + count) ?? 1;
|
|
12507
|
+
const directItemCount = list.node.content?.filter((node) => node.type === "listItem").length ?? 0;
|
|
12508
|
+
counts.set(list.scopeKey, count + directItemCount);
|
|
12509
|
+
list.node.attrs = {
|
|
12510
|
+
...list.node.attrs,
|
|
12511
|
+
listId: list.listId,
|
|
12512
|
+
listStart,
|
|
12513
|
+
start
|
|
12514
|
+
};
|
|
12515
|
+
}
|
|
12516
|
+
return normalized;
|
|
12517
|
+
}
|
|
11976
12518
|
function prosemirrorToPortableText(doc) {
|
|
11977
12519
|
if (!doc || doc.type !== "doc" || !doc.content) return [];
|
|
11978
12520
|
const blocks = [];
|
|
11979
|
-
for (
|
|
11980
|
-
const converted = convertPMNode(
|
|
12521
|
+
for (let i = 0; i < doc.content.length; i++) {
|
|
12522
|
+
const converted = convertPMNode(doc.content[i], `root:${i}`);
|
|
11981
12523
|
if (converted) if (Array.isArray(converted)) blocks.push(...converted);
|
|
11982
12524
|
else blocks.push(converted);
|
|
11983
12525
|
}
|
|
11984
12526
|
return blocks;
|
|
11985
12527
|
}
|
|
11986
|
-
function convertPMNode(node) {
|
|
12528
|
+
function convertPMNode(node, path) {
|
|
11987
12529
|
switch (node.type) {
|
|
11988
12530
|
case "paragraph": {
|
|
11989
12531
|
const { children, markDefs } = convertInlineContent(node.content || []);
|
|
@@ -12016,8 +12558,8 @@ function convertPMNode(node) {
|
|
|
12016
12558
|
...textAlign ? { textAlign } : {}
|
|
12017
12559
|
};
|
|
12018
12560
|
}
|
|
12019
|
-
case "bulletList": return convertList(node.content || [], "bullet");
|
|
12020
|
-
case "orderedList": return convertList(node.content || [], "number");
|
|
12561
|
+
case "bulletList": return convertList(node.content || [], "bullet", 1, node.attrs, path);
|
|
12562
|
+
case "orderedList": return convertList(node.content || [], "number", 1, node.attrs, path);
|
|
12021
12563
|
case "blockquote": {
|
|
12022
12564
|
const blocks = [];
|
|
12023
12565
|
const blockquoteContent = node.content || [];
|
|
@@ -12141,24 +12683,32 @@ function convertPMNode(node) {
|
|
|
12141
12683
|
default: return null;
|
|
12142
12684
|
}
|
|
12143
12685
|
}
|
|
12144
|
-
function convertList(items, listItem, level = 1) {
|
|
12686
|
+
function convertList(items, listItem, level = 1, attrs, path = `list:${level}`) {
|
|
12145
12687
|
const blocks = [];
|
|
12146
12688
|
const typedItems = items;
|
|
12147
|
-
|
|
12148
|
-
|
|
12149
|
-
|
|
12150
|
-
|
|
12151
|
-
|
|
12152
|
-
|
|
12153
|
-
|
|
12154
|
-
|
|
12155
|
-
|
|
12156
|
-
|
|
12157
|
-
|
|
12158
|
-
|
|
12159
|
-
|
|
12160
|
-
|
|
12161
|
-
|
|
12689
|
+
const metadata = listItem === "number" ? readOrderedListMetadata(attrs, path) : void 0;
|
|
12690
|
+
for (let itemIndex = 0; itemIndex < typedItems.length; itemIndex++) {
|
|
12691
|
+
const item = typedItems[itemIndex];
|
|
12692
|
+
if (item.type === "listItem") {
|
|
12693
|
+
const listItemContent = item.content || [];
|
|
12694
|
+
for (let childIndex = 0; childIndex < listItemContent.length; childIndex++) {
|
|
12695
|
+
const child = listItemContent[childIndex];
|
|
12696
|
+
if (child.type === "paragraph") {
|
|
12697
|
+
const { children, markDefs } = convertInlineContent(child.content || []);
|
|
12698
|
+
if (children.length > 0) blocks.push({
|
|
12699
|
+
_type: "block",
|
|
12700
|
+
_key: generateKey(),
|
|
12701
|
+
style: "normal",
|
|
12702
|
+
listItem,
|
|
12703
|
+
level,
|
|
12704
|
+
...metadata,
|
|
12705
|
+
children,
|
|
12706
|
+
markDefs: markDefs.length > 0 ? markDefs : void 0
|
|
12707
|
+
});
|
|
12708
|
+
} else if (child.type === "bulletList") blocks.push(...convertList(child.content || [], "bullet", level + 1, child.attrs, `${path}:${itemIndex}:${childIndex}`));
|
|
12709
|
+
else if (child.type === "orderedList") blocks.push(...convertList(child.content || [], "number", level + 1, child.attrs, `${path}:${itemIndex}:${childIndex}`));
|
|
12710
|
+
}
|
|
12711
|
+
}
|
|
12162
12712
|
}
|
|
12163
12713
|
return blocks;
|
|
12164
12714
|
}
|
|
@@ -12245,26 +12795,46 @@ function portableTextToProsemirror(blocks) {
|
|
|
12245
12795
|
if (isTextBlock(block) && block.listItem) {
|
|
12246
12796
|
const listBlocks = [];
|
|
12247
12797
|
const listType = block.listItem;
|
|
12798
|
+
const runStart = i;
|
|
12799
|
+
const rootId = listType === "number" ? normalizeListId(block.listId) : void 0;
|
|
12248
12800
|
while (i < blocks.length) {
|
|
12249
12801
|
const current = blocks[i];
|
|
12250
12802
|
if (!isTextBlock(current) || !current.listItem) break;
|
|
12251
|
-
|
|
12803
|
+
const level = current.level || 1;
|
|
12804
|
+
const currentId = current.listItem === "number" ? normalizeListId(current.listId) : void 0;
|
|
12805
|
+
const sameRootIdentity = listType !== "number" || level > 1 || (rootId ? currentId === rootId : currentId === void 0);
|
|
12806
|
+
if (level > 1 || current.listItem === listType && sameRootIdentity) {
|
|
12252
12807
|
listBlocks.push(current);
|
|
12253
12808
|
i++;
|
|
12254
12809
|
} else break;
|
|
12255
12810
|
}
|
|
12256
|
-
content.push(convertPTList(listBlocks, listType));
|
|
12811
|
+
content.push(convertPTList(listBlocks, listType, `root:${runStart}`));
|
|
12257
12812
|
} else {
|
|
12258
12813
|
const converted = convertPTBlock(block);
|
|
12259
12814
|
if (converted) content.push(converted);
|
|
12260
12815
|
i++;
|
|
12261
12816
|
}
|
|
12262
12817
|
}
|
|
12263
|
-
return {
|
|
12818
|
+
return normalizeOrderedListJson({
|
|
12264
12819
|
type: "doc",
|
|
12265
12820
|
content: content.length > 0 ? content : [{ type: "paragraph" }]
|
|
12821
|
+
});
|
|
12822
|
+
}
|
|
12823
|
+
function getListMetadata(item, fallbackSeed) {
|
|
12824
|
+
const listId = normalizeListId(item.listId) ?? deriveLegacyListId(fallbackSeed);
|
|
12825
|
+
const listStart = normalizeListStart(item.listStart);
|
|
12826
|
+
return {
|
|
12827
|
+
listId,
|
|
12828
|
+
...listStart === void 0 ? {} : { listStart }
|
|
12266
12829
|
};
|
|
12267
12830
|
}
|
|
12831
|
+
function belongsToNestedGroup(item, minLevel, parentListType, anchorType, anchorId) {
|
|
12832
|
+
if ((item.level || 2) > minLevel) return true;
|
|
12833
|
+
if ((item.listItem || parentListType) !== anchorType) return false;
|
|
12834
|
+
if (anchorType !== "number") return true;
|
|
12835
|
+
const itemId = normalizeListId(item.listId);
|
|
12836
|
+
return anchorId ? itemId === anchorId : itemId === void 0;
|
|
12837
|
+
}
|
|
12268
12838
|
function convertPTBlock(block) {
|
|
12269
12839
|
switch (block._type) {
|
|
12270
12840
|
case "block": {
|
|
@@ -12407,7 +12977,7 @@ function convertPTBlock(block) {
|
|
|
12407
12977
|
}
|
|
12408
12978
|
}
|
|
12409
12979
|
}
|
|
12410
|
-
function convertPTList(items, listType) {
|
|
12980
|
+
function convertPTList(items, listType, context) {
|
|
12411
12981
|
const rootItems = [];
|
|
12412
12982
|
let i = 0;
|
|
12413
12983
|
while (i < items.length) {
|
|
@@ -12419,18 +12989,24 @@ function convertPTList(items, listType) {
|
|
|
12419
12989
|
nestedItems.push(items[i]);
|
|
12420
12990
|
i++;
|
|
12421
12991
|
}
|
|
12422
|
-
rootItems.push(convertPTListItem(item, nestedItems, listType));
|
|
12992
|
+
rootItems.push(convertPTListItem(item, nestedItems, listType, `${context}:${rootItems.length}`));
|
|
12423
12993
|
} else {
|
|
12424
|
-
rootItems.push(convertPTListItem(item, [], listType));
|
|
12994
|
+
rootItems.push(convertPTListItem(item, [], listType, `${context}:${rootItems.length}`));
|
|
12425
12995
|
i++;
|
|
12426
12996
|
}
|
|
12427
12997
|
}
|
|
12998
|
+
const firstItem = items[0];
|
|
12999
|
+
const metadata = listType === "number" ? getListMetadata(firstItem, `${context}:${firstItem._key}`) : void 0;
|
|
12428
13000
|
return {
|
|
12429
13001
|
type: listType === "bullet" ? "bulletList" : "orderedList",
|
|
13002
|
+
attrs: metadata ? {
|
|
13003
|
+
...metadata,
|
|
13004
|
+
start: metadata.listStart ?? 1
|
|
13005
|
+
} : void 0,
|
|
12430
13006
|
content: rootItems
|
|
12431
13007
|
};
|
|
12432
13008
|
}
|
|
12433
|
-
function convertPTListItem(item, nestedItems, parentListType) {
|
|
13009
|
+
function convertPTListItem(item, nestedItems, parentListType, context) {
|
|
12434
13010
|
const content = [];
|
|
12435
13011
|
const pmContent = convertPTSpans(item.children, item.markDefs || []);
|
|
12436
13012
|
content.push({
|
|
@@ -12446,17 +13022,18 @@ function convertPTListItem(item, nestedItems, parentListType) {
|
|
|
12446
13022
|
let j = 0;
|
|
12447
13023
|
while (j < nestedItems.length) {
|
|
12448
13024
|
const anchorType = nestedItems[j].listItem || parentListType;
|
|
13025
|
+
const anchorId = anchorType === "number" ? normalizeListId(nestedItems[j].listId) : void 0;
|
|
12449
13026
|
const nestedGroup = [];
|
|
12450
13027
|
do {
|
|
12451
13028
|
nestedGroup.push(nestedItems[j]);
|
|
12452
13029
|
j++;
|
|
12453
|
-
} while (j < nestedItems.length && (
|
|
13030
|
+
} while (j < nestedItems.length && belongsToNestedGroup(nestedItems[j], minLevel, parentListType, anchorType, anchorId));
|
|
12454
13031
|
if (nestedGroup.length > 0) {
|
|
12455
13032
|
const adjustedGroup = nestedGroup.map((ni) => ({
|
|
12456
13033
|
...ni,
|
|
12457
13034
|
level: (ni.level || 2) - 1
|
|
12458
13035
|
}));
|
|
12459
|
-
content.push(convertPTList(adjustedGroup, anchorType));
|
|
13036
|
+
content.push(convertPTList(adjustedGroup, anchorType, `${context}:nested:${j - nestedGroup.length}`));
|
|
12460
13037
|
}
|
|
12461
13038
|
}
|
|
12462
13039
|
}
|
|
@@ -13731,6 +14308,7 @@ function PortableTextEditor({ value, onChange, placeholder, className, editable
|
|
|
13731
14308
|
},
|
|
13732
14309
|
codeBlock: false,
|
|
13733
14310
|
code: false,
|
|
14311
|
+
orderedList: false,
|
|
13734
14312
|
link: {
|
|
13735
14313
|
openOnClick: false,
|
|
13736
14314
|
enableClickSelection: true,
|
|
@@ -13738,6 +14316,7 @@ function PortableTextEditor({ value, onChange, placeholder, className, editable
|
|
|
13738
14316
|
},
|
|
13739
14317
|
underline: {}
|
|
13740
14318
|
}),
|
|
14319
|
+
EmDashOrderedList,
|
|
13741
14320
|
CodeMarkExtension,
|
|
13742
14321
|
CodeBlockExtension,
|
|
13743
14322
|
HtmlBlockExtension,
|
|
@@ -14587,6 +15166,7 @@ function EditorToolbar({ toolbarRef, editor, focusMode, onFocusModeChange, onIns
|
|
|
14587
15166
|
editor,
|
|
14588
15167
|
selector: (ctx) => {
|
|
14589
15168
|
const textAlignment = getSelectionTextAlignment(ctx.editor);
|
|
15169
|
+
const isOrderedList = ctx.editor.isActive("orderedList");
|
|
14590
15170
|
return {
|
|
14591
15171
|
isBold: ctx.editor.isActive("bold"),
|
|
14592
15172
|
isItalic: ctx.editor.isActive("italic"),
|
|
@@ -14596,7 +15176,9 @@ function EditorToolbar({ toolbarRef, editor, focusMode, onFocusModeChange, onIns
|
|
|
14596
15176
|
isSuperscript: ctx.editor.isActive("superscript"),
|
|
14597
15177
|
isCode: ctx.editor.isActive("code"),
|
|
14598
15178
|
isBulletList: ctx.editor.isActive("bulletList"),
|
|
14599
|
-
isOrderedList
|
|
15179
|
+
isOrderedList,
|
|
15180
|
+
canContinueOrderedList: isOrderedList && ctx.editor.can().continueOrderedList(),
|
|
15181
|
+
canRestartOrderedList: isOrderedList && ctx.editor.can().restartOrderedList(),
|
|
14600
15182
|
isBlockquote: ctx.editor.isActive("blockquote"),
|
|
14601
15183
|
isCodeBlock: ctx.editor.isActive("codeBlock"),
|
|
14602
15184
|
isAlignLeft: textAlignment === "left",
|
|
@@ -14818,6 +15400,29 @@ function EditorToolbar({ toolbarRef, editor, focusMode, onFocusModeChange, onIns
|
|
|
14818
15400
|
"aria-hidden": "true"
|
|
14819
15401
|
})
|
|
14820
15402
|
}),
|
|
15403
|
+
editorState.isOrderedList && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ToolbarButton, {
|
|
15404
|
+
onClick: () => editor.chain().focus().continueOrderedList().run(),
|
|
15405
|
+
disabled: !editorState.canContinueOrderedList,
|
|
15406
|
+
title: _t9({
|
|
15407
|
+
id: "AEfArz",
|
|
15408
|
+
message: "Continue numbering"
|
|
15409
|
+
}),
|
|
15410
|
+
children: /* @__PURE__ */ jsx(ArrowUUpRight, {
|
|
15411
|
+
className: "h-4 w-4 rtl:-scale-x-100",
|
|
15412
|
+
"aria-hidden": "true"
|
|
15413
|
+
})
|
|
15414
|
+
}), /* @__PURE__ */ jsx(ToolbarButton, {
|
|
15415
|
+
onClick: () => editor.chain().focus().restartOrderedList().run(),
|
|
15416
|
+
disabled: !editorState.canRestartOrderedList,
|
|
15417
|
+
title: _t9({
|
|
15418
|
+
id: "knExCm",
|
|
15419
|
+
message: "Restart numbering"
|
|
15420
|
+
}),
|
|
15421
|
+
children: /* @__PURE__ */ jsx(ArrowUUpLeft, {
|
|
15422
|
+
className: "h-4 w-4 rtl:-scale-x-100",
|
|
15423
|
+
"aria-hidden": "true"
|
|
15424
|
+
})
|
|
15425
|
+
})] }),
|
|
14821
15426
|
/* @__PURE__ */ jsx(ToolbarButton, {
|
|
14822
15427
|
onClick: () => editor.chain().focus().toggleBlockquote().run(),
|
|
14823
15428
|
active: editorState.isBlockquote,
|
|
@@ -16805,8 +17410,8 @@ function FilterBar({ statusFilter, onStatusFilterChange, authors, authorFilter,
|
|
|
16805
17410
|
message: "All statuses"
|
|
16806
17411
|
}),
|
|
16807
17412
|
published: _t2({
|
|
16808
|
-
id: "
|
|
16809
|
-
message: "
|
|
17413
|
+
id: "u3wRF+",
|
|
17414
|
+
message: "Published"
|
|
16810
17415
|
}),
|
|
16811
17416
|
draft: _t2({
|
|
16812
17417
|
id: "eneWvv",
|
|
@@ -19157,12 +19762,45 @@ function SystemFieldRow({ field }) {
|
|
|
19157
19762
|
//#endregion
|
|
19158
19763
|
//#region src/components/ContentTypeList.tsx
|
|
19159
19764
|
/**
|
|
19765
|
+
* Apply a drag-and-drop move to the collection order. Returns the input array
|
|
19766
|
+
* unchanged when the move is a no-op.
|
|
19767
|
+
*/
|
|
19768
|
+
function moveCollection(slugs, activeSlug, overSlug) {
|
|
19769
|
+
const from = slugs.indexOf(activeSlug);
|
|
19770
|
+
const to = slugs.indexOf(overSlug);
|
|
19771
|
+
if (from === -1 || to === -1 || from === to) return slugs;
|
|
19772
|
+
const next = [...slugs];
|
|
19773
|
+
next.splice(to, 0, next.splice(from, 1)[0]);
|
|
19774
|
+
return next;
|
|
19775
|
+
}
|
|
19776
|
+
/**
|
|
19160
19777
|
* Content Type list view - shows all collections in the schema registry
|
|
19161
19778
|
*/
|
|
19162
|
-
function ContentTypeList({ collections, orphanedTables, isLoading, onDelete, onRegisterOrphan }) {
|
|
19779
|
+
function ContentTypeList({ collections, orphanedTables, isLoading, onDelete, onRegisterOrphan, onReorder }) {
|
|
19163
19780
|
const { _: _t } = useLingui();
|
|
19164
19781
|
const [deleteTarget, setDeleteTarget] = React$1.useState(null);
|
|
19165
19782
|
const hasOrphans = orphanedTables && orphanedTables.length > 0;
|
|
19783
|
+
const [order, setOrder] = React$1.useState(null);
|
|
19784
|
+
const serverOrder = React$1.useMemo(() => collections.map((c) => c.slug), [collections]);
|
|
19785
|
+
const orderedSlugs = order ?? serverOrder;
|
|
19786
|
+
React$1.useEffect(() => {
|
|
19787
|
+
setOrder(null);
|
|
19788
|
+
}, [serverOrder]);
|
|
19789
|
+
const orderedCollections = React$1.useMemo(() => {
|
|
19790
|
+
const bySlug = new Map(collections.map((c) => [c.slug, c]));
|
|
19791
|
+
return orderedSlugs.map((slug) => bySlug.get(slug)).filter((c) => c !== void 0);
|
|
19792
|
+
}, [collections, orderedSlugs]);
|
|
19793
|
+
const canReorder = !!onReorder && collections.length > 1;
|
|
19794
|
+
const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 8 } }), useSensor(KeyboardSensor, { coordinateGetter: sortableKeyboardCoordinates }));
|
|
19795
|
+
const columnCount = canReorder ? 6 : 5;
|
|
19796
|
+
const handleDragEnd = (event) => {
|
|
19797
|
+
const { active, over } = event;
|
|
19798
|
+
if (!over || active.id === over.id) return;
|
|
19799
|
+
const next = moveCollection(orderedSlugs, String(active.id), String(over.id));
|
|
19800
|
+
if (next === orderedSlugs) return;
|
|
19801
|
+
setOrder(next);
|
|
19802
|
+
onReorder?.(next);
|
|
19803
|
+
};
|
|
19166
19804
|
return /* @__PURE__ */ jsxs("div", {
|
|
19167
19805
|
className: "space-y-4",
|
|
19168
19806
|
children: [
|
|
@@ -19240,86 +19878,107 @@ function ContentTypeList({ collections, orphanedTables, isLoading, onDelete, onR
|
|
|
19240
19878
|
})]
|
|
19241
19879
|
})
|
|
19242
19880
|
}),
|
|
19243
|
-
/* @__PURE__ */ jsx(
|
|
19244
|
-
|
|
19245
|
-
|
|
19246
|
-
|
|
19247
|
-
|
|
19248
|
-
|
|
19249
|
-
|
|
19250
|
-
|
|
19251
|
-
|
|
19252
|
-
|
|
19253
|
-
children: _t({
|
|
19254
|
-
id: "6YtxFj",
|
|
19255
|
-
message: "Name"
|
|
19256
|
-
})
|
|
19257
|
-
}),
|
|
19258
|
-
/* @__PURE__ */ jsx("th", {
|
|
19259
|
-
scope: "col",
|
|
19260
|
-
className: "px-4 py-3 text-start text-sm font-medium",
|
|
19261
|
-
children: _t({
|
|
19262
|
-
id: "L85WcV",
|
|
19263
|
-
message: "Slug"
|
|
19264
|
-
})
|
|
19265
|
-
}),
|
|
19266
|
-
/* @__PURE__ */ jsx("th", {
|
|
19267
|
-
scope: "col",
|
|
19268
|
-
className: "px-4 py-3 text-start text-sm font-medium",
|
|
19269
|
-
children: _t({
|
|
19270
|
-
id: "wdxz7K",
|
|
19271
|
-
message: "Source"
|
|
19272
|
-
})
|
|
19273
|
-
}),
|
|
19274
|
-
/* @__PURE__ */ jsx("th", {
|
|
19275
|
-
scope: "col",
|
|
19276
|
-
className: "px-4 py-3 text-start text-sm font-medium",
|
|
19277
|
-
children: _t({
|
|
19278
|
-
id: "PpZkda",
|
|
19279
|
-
message: "Features"
|
|
19280
|
-
})
|
|
19281
|
-
}),
|
|
19282
|
-
/* @__PURE__ */ jsx("th", {
|
|
19283
|
-
scope: "col",
|
|
19284
|
-
className: "px-4 py-3 text-end text-sm font-medium",
|
|
19285
|
-
children: _t({
|
|
19286
|
-
id: "7L01XJ",
|
|
19287
|
-
message: "Actions"
|
|
19288
|
-
})
|
|
19289
|
-
})
|
|
19290
|
-
]
|
|
19291
|
-
}) }), /* @__PURE__ */ jsx("tbody", {
|
|
19292
|
-
className: "divide-y divide-kumo-line",
|
|
19293
|
-
children: isLoading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", {
|
|
19294
|
-
colSpan: 5,
|
|
19295
|
-
className: "px-4 py-8 text-center text-kumo-subtle",
|
|
19296
|
-
children: _t({
|
|
19297
|
-
id: "y+JWgj",
|
|
19298
|
-
message: "Loading collections..."
|
|
19299
|
-
})
|
|
19300
|
-
}) }) : collections.length === 0 && !hasOrphans ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsxs("td", {
|
|
19301
|
-
colSpan: 5,
|
|
19302
|
-
className: "px-4 py-8 text-center text-kumo-subtle",
|
|
19881
|
+
/* @__PURE__ */ jsx(DndContext, {
|
|
19882
|
+
sensors,
|
|
19883
|
+
collisionDetection: closestCenter,
|
|
19884
|
+
onDragEnd: handleDragEnd,
|
|
19885
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
19886
|
+
className: "rounded-md border bg-kumo-base overflow-x-auto",
|
|
19887
|
+
children: /* @__PURE__ */ jsxs("table", {
|
|
19888
|
+
className: "w-full",
|
|
19889
|
+
children: [/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsxs("tr", {
|
|
19890
|
+
className: "border-b bg-kumo-tint/50",
|
|
19303
19891
|
children: [
|
|
19304
|
-
|
|
19305
|
-
|
|
19306
|
-
|
|
19892
|
+
canReorder && /* @__PURE__ */ jsx("th", {
|
|
19893
|
+
scope: "col",
|
|
19894
|
+
className: "w-10 px-2 py-3",
|
|
19895
|
+
children: /* @__PURE__ */ jsx("span", {
|
|
19896
|
+
className: "sr-only",
|
|
19897
|
+
children: _t({
|
|
19898
|
+
id: "toJdZA",
|
|
19899
|
+
message: "Reorder"
|
|
19900
|
+
})
|
|
19901
|
+
})
|
|
19307
19902
|
}),
|
|
19308
|
-
|
|
19309
|
-
|
|
19310
|
-
|
|
19311
|
-
|
|
19903
|
+
/* @__PURE__ */ jsx("th", {
|
|
19904
|
+
scope: "col",
|
|
19905
|
+
className: "px-4 py-3 text-start text-sm font-medium",
|
|
19906
|
+
children: _t({
|
|
19907
|
+
id: "6YtxFj",
|
|
19908
|
+
message: "Name"
|
|
19909
|
+
})
|
|
19910
|
+
}),
|
|
19911
|
+
/* @__PURE__ */ jsx("th", {
|
|
19912
|
+
scope: "col",
|
|
19913
|
+
className: "px-4 py-3 text-start text-sm font-medium",
|
|
19914
|
+
children: _t({
|
|
19915
|
+
id: "L85WcV",
|
|
19916
|
+
message: "Slug"
|
|
19917
|
+
})
|
|
19918
|
+
}),
|
|
19919
|
+
/* @__PURE__ */ jsx("th", {
|
|
19920
|
+
scope: "col",
|
|
19921
|
+
className: "px-4 py-3 text-start text-sm font-medium",
|
|
19922
|
+
children: _t({
|
|
19923
|
+
id: "wdxz7K",
|
|
19924
|
+
message: "Source"
|
|
19925
|
+
})
|
|
19926
|
+
}),
|
|
19927
|
+
/* @__PURE__ */ jsx("th", {
|
|
19928
|
+
scope: "col",
|
|
19929
|
+
className: "px-4 py-3 text-start text-sm font-medium",
|
|
19312
19930
|
children: _t({
|
|
19313
|
-
id: "
|
|
19314
|
-
message: "
|
|
19931
|
+
id: "PpZkda",
|
|
19932
|
+
message: "Features"
|
|
19933
|
+
})
|
|
19934
|
+
}),
|
|
19935
|
+
/* @__PURE__ */ jsx("th", {
|
|
19936
|
+
scope: "col",
|
|
19937
|
+
className: "px-4 py-3 text-end text-sm font-medium",
|
|
19938
|
+
children: _t({
|
|
19939
|
+
id: "7L01XJ",
|
|
19940
|
+
message: "Actions"
|
|
19315
19941
|
})
|
|
19316
19942
|
})
|
|
19317
19943
|
]
|
|
19318
|
-
}) })
|
|
19319
|
-
|
|
19320
|
-
|
|
19321
|
-
|
|
19322
|
-
|
|
19944
|
+
}) }), /* @__PURE__ */ jsx("tbody", {
|
|
19945
|
+
className: "divide-y divide-kumo-line",
|
|
19946
|
+
children: isLoading ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsx("td", {
|
|
19947
|
+
colSpan: columnCount,
|
|
19948
|
+
className: "px-4 py-8 text-center text-kumo-subtle",
|
|
19949
|
+
children: _t({
|
|
19950
|
+
id: "y+JWgj",
|
|
19951
|
+
message: "Loading collections..."
|
|
19952
|
+
})
|
|
19953
|
+
}) }) : collections.length === 0 && !hasOrphans ? /* @__PURE__ */ jsx("tr", { children: /* @__PURE__ */ jsxs("td", {
|
|
19954
|
+
colSpan: columnCount,
|
|
19955
|
+
className: "px-4 py-8 text-center text-kumo-subtle",
|
|
19956
|
+
children: [
|
|
19957
|
+
_t({
|
|
19958
|
+
id: "T1ePSQ",
|
|
19959
|
+
message: "No content types yet."
|
|
19960
|
+
}),
|
|
19961
|
+
" ",
|
|
19962
|
+
/* @__PURE__ */ jsx(Link$1, {
|
|
19963
|
+
to: "/content-types/new",
|
|
19964
|
+
className: "text-kumo-link underline",
|
|
19965
|
+
children: _t({
|
|
19966
|
+
id: "+bjdyB",
|
|
19967
|
+
message: "Create your first one"
|
|
19968
|
+
})
|
|
19969
|
+
})
|
|
19970
|
+
]
|
|
19971
|
+
}) }) : /* @__PURE__ */ jsx(SortableContext, {
|
|
19972
|
+
items: orderedSlugs,
|
|
19973
|
+
strategy: verticalListSortingStrategy,
|
|
19974
|
+
children: orderedCollections.map((collection) => /* @__PURE__ */ jsx(ContentTypeRow, {
|
|
19975
|
+
collection,
|
|
19976
|
+
canReorder,
|
|
19977
|
+
onRequestDelete: setDeleteTarget
|
|
19978
|
+
}, collection.id))
|
|
19979
|
+
})
|
|
19980
|
+
})]
|
|
19981
|
+
})
|
|
19323
19982
|
})
|
|
19324
19983
|
}),
|
|
19325
19984
|
/* @__PURE__ */ jsx(ConfirmDialog, {
|
|
@@ -19354,12 +20013,36 @@ function ContentTypeList({ collections, orphanedTables, isLoading, onDelete, onR
|
|
|
19354
20013
|
]
|
|
19355
20014
|
});
|
|
19356
20015
|
}
|
|
19357
|
-
function ContentTypeRow({ collection, onRequestDelete }) {
|
|
20016
|
+
function ContentTypeRow({ collection, canReorder, onRequestDelete }) {
|
|
19358
20017
|
const { _: _t2 } = useLingui();
|
|
19359
20018
|
const isFromCode = collection.source === "code";
|
|
20019
|
+
const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: collection.slug });
|
|
19360
20020
|
return /* @__PURE__ */ jsxs("tr", {
|
|
19361
|
-
|
|
20021
|
+
ref: setNodeRef,
|
|
20022
|
+
style: {
|
|
20023
|
+
transform: CSS.Transform.toString(transform),
|
|
20024
|
+
transition
|
|
20025
|
+
},
|
|
20026
|
+
className: cn("hover:bg-kumo-tint/25", isDragging && "relative z-10 bg-kumo-base shadow-sm"),
|
|
19362
20027
|
children: [
|
|
20028
|
+
canReorder && /* @__PURE__ */ jsx("td", {
|
|
20029
|
+
className: "w-10 px-2 py-3",
|
|
20030
|
+
children: /* @__PURE__ */ jsx("button", {
|
|
20031
|
+
type: "button",
|
|
20032
|
+
...attributes,
|
|
20033
|
+
...listeners,
|
|
20034
|
+
"aria-label": _t2({
|
|
20035
|
+
id: "2BPVq8",
|
|
20036
|
+
message: "Reorder {0}",
|
|
20037
|
+
values: { 0: collection.label }
|
|
20038
|
+
}),
|
|
20039
|
+
className: "flex h-8 w-8 cursor-grab items-center justify-center rounded-md text-kumo-subtle hover:bg-kumo-tint focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-kumo-focus active:cursor-grabbing",
|
|
20040
|
+
children: /* @__PURE__ */ jsx(DotsSixVertical, {
|
|
20041
|
+
className: "h-4 w-4",
|
|
20042
|
+
"aria-hidden": "true"
|
|
20043
|
+
})
|
|
20044
|
+
})
|
|
20045
|
+
}),
|
|
19363
20046
|
/* @__PURE__ */ jsx("td", {
|
|
19364
20047
|
className: "px-4 py-3",
|
|
19365
20048
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -19745,8 +20428,8 @@ function CollectionList({ collections, manifest, loading }) {
|
|
|
19745
20428
|
count: col.published,
|
|
19746
20429
|
variant: "success",
|
|
19747
20430
|
label: _t4({
|
|
19748
|
-
id: "
|
|
19749
|
-
message: "
|
|
20431
|
+
id: "u3wRF+",
|
|
20432
|
+
message: "Published"
|
|
19750
20433
|
})
|
|
19751
20434
|
}),
|
|
19752
20435
|
/* @__PURE__ */ jsx(CountBadge, {
|
|
@@ -27359,14 +28042,14 @@ function RedirectFormDialog({ open, onClose, redirect, defaultSource }) {
|
|
|
27359
28042
|
const createMutation = useMutation({
|
|
27360
28043
|
mutationFn: (input) => createRedirect(input),
|
|
27361
28044
|
onSuccess: () => {
|
|
27362
|
-
queryClient.
|
|
28045
|
+
queryClient.resetQueries({ queryKey: ["redirects"] });
|
|
27363
28046
|
onClose();
|
|
27364
28047
|
}
|
|
27365
28048
|
});
|
|
27366
28049
|
const updateMutation = useMutation({
|
|
27367
28050
|
mutationFn: (input) => updateRedirect(redirect.id, input),
|
|
27368
28051
|
onSuccess: () => {
|
|
27369
|
-
queryClient.
|
|
28052
|
+
queryClient.resetQueries({ queryKey: ["redirects"] });
|
|
27370
28053
|
onClose();
|
|
27371
28054
|
}
|
|
27372
28055
|
});
|
|
@@ -27659,19 +28342,22 @@ function Redirects() {
|
|
|
27659
28342
|
const [prefillSource, setPrefillSource] = useState("");
|
|
27660
28343
|
const enabledFilter = filterEnabled === "all" ? void 0 : filterEnabled === "true";
|
|
27661
28344
|
const autoFilter = filterAuto === "all" ? void 0 : filterAuto === "true";
|
|
27662
|
-
const redirectsQuery =
|
|
28345
|
+
const redirectsQuery = useInfiniteQuery({
|
|
27663
28346
|
queryKey: [
|
|
27664
28347
|
"redirects",
|
|
27665
28348
|
debouncedSearch,
|
|
27666
28349
|
enabledFilter,
|
|
27667
28350
|
autoFilter
|
|
27668
28351
|
],
|
|
27669
|
-
queryFn: () => fetchRedirects({
|
|
28352
|
+
queryFn: ({ pageParam }) => fetchRedirects({
|
|
27670
28353
|
search: debouncedSearch || void 0,
|
|
27671
28354
|
enabled: enabledFilter,
|
|
27672
28355
|
auto: autoFilter,
|
|
28356
|
+
cursor: pageParam,
|
|
27673
28357
|
limit: 100
|
|
27674
|
-
})
|
|
28358
|
+
}),
|
|
28359
|
+
initialPageParam: void 0,
|
|
28360
|
+
getNextPageParam: (lastPage) => lastPage.nextCursor
|
|
27675
28361
|
});
|
|
27676
28362
|
const notFoundQuery = useQuery({
|
|
27677
28363
|
queryKey: ["redirects", "404-summary"],
|
|
@@ -27681,17 +28367,17 @@ function Redirects() {
|
|
|
27681
28367
|
const deleteMutation = useMutation({
|
|
27682
28368
|
mutationFn: (id) => deleteRedirect(id),
|
|
27683
28369
|
onSuccess: () => {
|
|
27684
|
-
queryClient.
|
|
28370
|
+
queryClient.resetQueries({ queryKey: ["redirects"] });
|
|
27685
28371
|
setDeleteId(null);
|
|
27686
28372
|
}
|
|
27687
28373
|
});
|
|
27688
28374
|
const toggleMutation = useMutation({
|
|
27689
28375
|
mutationFn: ({ id, enabled }) => updateRedirect(id, { enabled }),
|
|
27690
28376
|
onSuccess: () => {
|
|
27691
|
-
queryClient.
|
|
28377
|
+
queryClient.resetQueries({ queryKey: ["redirects"] });
|
|
27692
28378
|
},
|
|
27693
28379
|
onError: () => {
|
|
27694
|
-
queryClient.
|
|
28380
|
+
queryClient.resetQueries({ queryKey: ["redirects"] });
|
|
27695
28381
|
}
|
|
27696
28382
|
});
|
|
27697
28383
|
const markGoneMutation = useMutation({
|
|
@@ -27702,7 +28388,7 @@ function Redirects() {
|
|
|
27702
28388
|
enabled: true
|
|
27703
28389
|
}),
|
|
27704
28390
|
onSuccess: () => {
|
|
27705
|
-
queryClient.
|
|
28391
|
+
queryClient.resetQueries({ queryKey: ["redirects"] });
|
|
27706
28392
|
}
|
|
27707
28393
|
});
|
|
27708
28394
|
function handleCreateFrom404(path) {
|
|
@@ -27710,8 +28396,8 @@ function Redirects() {
|
|
|
27710
28396
|
setShowCreate(true);
|
|
27711
28397
|
setTab("redirects");
|
|
27712
28398
|
}
|
|
27713
|
-
const redirects = redirectsQuery.data?.items ?? [];
|
|
27714
|
-
const loopRedirectIds = new Set(redirectsQuery.data?.loopRedirectIds ?? []);
|
|
28399
|
+
const redirects = redirectsQuery.data?.pages.flatMap((page) => page.items) ?? [];
|
|
28400
|
+
const loopRedirectIds = new Set(redirectsQuery.data?.pages.flatMap((page) => page.loopRedirectIds ?? []) ?? []);
|
|
27715
28401
|
return /* @__PURE__ */ jsxs("div", {
|
|
27716
28402
|
className: "space-y-6",
|
|
27717
28403
|
children: [
|
|
@@ -27749,7 +28435,7 @@ function Redirects() {
|
|
|
27749
28435
|
}), redirectsQuery.data && /* @__PURE__ */ jsxs(Badge, {
|
|
27750
28436
|
variant: "secondary",
|
|
27751
28437
|
className: "ms-2",
|
|
27752
|
-
children: [
|
|
28438
|
+
children: [redirects.length, redirectsQuery.hasNextPage ? "+" : ""]
|
|
27753
28439
|
})]
|
|
27754
28440
|
}), /* @__PURE__ */ jsx("button", {
|
|
27755
28441
|
onClick: () => setTab("404s"),
|
|
@@ -27883,7 +28569,7 @@ function Redirects() {
|
|
|
27883
28569
|
})
|
|
27884
28570
|
})
|
|
27885
28571
|
]
|
|
27886
|
-
}) : /* @__PURE__ */ jsxs("div", {
|
|
28572
|
+
}) : /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
|
|
27887
28573
|
className: "border rounded-lg",
|
|
27888
28574
|
children: [/* @__PURE__ */ jsxs("div", {
|
|
27889
28575
|
className: "flex items-center gap-4 py-2 px-4 border-b bg-kumo-tint/50 text-sm font-medium text-kumo-subtle",
|
|
@@ -28031,7 +28717,21 @@ function Redirects() {
|
|
|
28031
28717
|
})
|
|
28032
28718
|
]
|
|
28033
28719
|
}, r.id))]
|
|
28034
|
-
})
|
|
28720
|
+
}), redirectsQuery.hasNextPage && /* @__PURE__ */ jsx("div", {
|
|
28721
|
+
className: "flex justify-center",
|
|
28722
|
+
children: /* @__PURE__ */ jsx(Button, {
|
|
28723
|
+
variant: "outline",
|
|
28724
|
+
onClick: () => void redirectsQuery.fetchNextPage(),
|
|
28725
|
+
disabled: redirectsQuery.isFetchingNextPage,
|
|
28726
|
+
children: redirectsQuery.isFetchingNextPage ? _t3({
|
|
28727
|
+
id: "Z3FXyt",
|
|
28728
|
+
message: "Loading..."
|
|
28729
|
+
}) : _t3({
|
|
28730
|
+
id: "yQ2kGp",
|
|
28731
|
+
message: "Load more"
|
|
28732
|
+
})
|
|
28733
|
+
})
|
|
28734
|
+
})] })
|
|
28035
28735
|
] }),
|
|
28036
28736
|
tab === "404s" && /* @__PURE__ */ jsx(NotFoundPanel, {
|
|
28037
28737
|
items: notFoundQuery.data ?? [],
|
|
@@ -34443,6 +35143,18 @@ function filterNavItemsByRole(items, userRole) {
|
|
|
34443
35143
|
return items.filter((item) => !item.minRole || userRole >= item.minRole);
|
|
34444
35144
|
}
|
|
34445
35145
|
/**
|
|
35146
|
+
* Manifest collections that get an auto-generated sidebar entry, in manifest
|
|
35147
|
+
* order. Pure function — exported so tests can pin the `hidden` contract
|
|
35148
|
+
* without rendering the sidebar.
|
|
35149
|
+
*
|
|
35150
|
+
* A hidden collection is still shipped in the manifest and stays fully
|
|
35151
|
+
* routable at `/content/:collection`; it only loses its nav link, so a plugin
|
|
35152
|
+
* that owns the collection end to end can steer editors to its own admin UI.
|
|
35153
|
+
*/
|
|
35154
|
+
function visibleCollectionEntries(collections) {
|
|
35155
|
+
return Object.entries(collections).filter(([, config]) => !config.hidden);
|
|
35156
|
+
}
|
|
35157
|
+
/**
|
|
34446
35158
|
* Navigation item rendered with Kumo's native Sidebar.MenuButton. Kumo's
|
|
34447
35159
|
* LinkProvider maps the href to TanStack Router for client-side navigation.
|
|
34448
35160
|
*/
|
|
@@ -34524,7 +35236,7 @@ function SidebarNav({ manifest }) {
|
|
|
34524
35236
|
}),
|
|
34525
35237
|
icon: ADMIN_NAV_ICONS.dashboard
|
|
34526
35238
|
}];
|
|
34527
|
-
for (const [name, config] of
|
|
35239
|
+
for (const [name, config] of visibleCollectionEntries(manifest.collections)) contentItems.push({
|
|
34528
35240
|
to: "/content/$collection",
|
|
34529
35241
|
label: config.label,
|
|
34530
35242
|
icon: getCollectionNavIcon(name),
|
|
@@ -36143,11 +36855,90 @@ function getAvailableParentTerms(terms, currentTerm) {
|
|
|
36143
36855
|
const excludedIds = new Set([currentTerm.id, ...flattenTerms(currentTerm.children).map((term) => term.id)]);
|
|
36144
36856
|
return flatTerms.filter((term) => !excludedIds.has(term.id));
|
|
36145
36857
|
}
|
|
36858
|
+
/** The translation group a term belongs to — what `parentId` and reorder ids hold. */
|
|
36859
|
+
function termGroup(term) {
|
|
36860
|
+
return term.translationGroup ?? term.id;
|
|
36861
|
+
}
|
|
36862
|
+
/**
|
|
36863
|
+
* Whether a term is rendered in a group it isn't a member of.
|
|
36864
|
+
*
|
|
36865
|
+
* A child whose parent has no row in this locale is listed at the top level so
|
|
36866
|
+
* it isn't lost, but its position belongs to its parent's group. It can't be
|
|
36867
|
+
* moved from here, and it can't be named in a reorder of the group it's drawn in.
|
|
36868
|
+
*/
|
|
36869
|
+
function isStranded(term, parentId) {
|
|
36870
|
+
return parentId === null && !!term.parentId;
|
|
36871
|
+
}
|
|
36872
|
+
/**
|
|
36873
|
+
* Permute `movable` into the slots those same terms occupy in `rendered`,
|
|
36874
|
+
* leaving everything else where it is.
|
|
36875
|
+
*
|
|
36876
|
+
* Mirrors what the reorder endpoint does with the ids it's given, so the
|
|
36877
|
+
* optimistic list matches what comes back.
|
|
36878
|
+
*/
|
|
36879
|
+
function reorderWithinSlots(rendered, movable, permuted) {
|
|
36880
|
+
const inGroup = new Set(movable);
|
|
36881
|
+
const next = [...rendered];
|
|
36882
|
+
let slot = 0;
|
|
36883
|
+
for (const [index, term] of rendered.entries()) {
|
|
36884
|
+
if (!inGroup.has(term)) continue;
|
|
36885
|
+
const replacement = permuted[slot++];
|
|
36886
|
+
if (replacement) next[index] = replacement;
|
|
36887
|
+
}
|
|
36888
|
+
return next;
|
|
36889
|
+
}
|
|
36890
|
+
/**
|
|
36891
|
+
* Replace one sibling group in a term tree with a reordered copy of itself.
|
|
36892
|
+
*
|
|
36893
|
+
* `parentId` is a translation group (what `term.parentId` holds), so it matches
|
|
36894
|
+
* the parent in whichever locale is on screen. `null` replaces the roots.
|
|
36895
|
+
*/
|
|
36896
|
+
function replaceSiblingGroup(terms, parentId, ordered) {
|
|
36897
|
+
if (parentId === null) return ordered;
|
|
36898
|
+
return terms.map((term) => termGroup(term) === parentId ? {
|
|
36899
|
+
...term,
|
|
36900
|
+
children: ordered
|
|
36901
|
+
} : {
|
|
36902
|
+
...term,
|
|
36903
|
+
children: replaceSiblingGroup(term.children, parentId, ordered)
|
|
36904
|
+
});
|
|
36905
|
+
}
|
|
36906
|
+
/**
|
|
36907
|
+
* One sibling group's rows, in display order.
|
|
36908
|
+
*
|
|
36909
|
+
* The movable subset is worked out once for the whole group: each row needs it
|
|
36910
|
+
* to know whether its carets are live, and a move needs the same list to build
|
|
36911
|
+
* the order it sends.
|
|
36912
|
+
*/
|
|
36913
|
+
function TermGroup({ siblings, parentId, level = 0, ...callbacks }) {
|
|
36914
|
+
const movable = siblings.filter((sibling) => !isStranded(sibling, parentId));
|
|
36915
|
+
const places = new Map(movable.map((term, index) => [term, index]));
|
|
36916
|
+
return /* @__PURE__ */ jsx(Fragment, { children: siblings.map((term) => /* @__PURE__ */ jsx(TermRow, {
|
|
36917
|
+
term,
|
|
36918
|
+
siblings,
|
|
36919
|
+
movable,
|
|
36920
|
+
place: places.get(term) ?? -1,
|
|
36921
|
+
parentId,
|
|
36922
|
+
level,
|
|
36923
|
+
...callbacks
|
|
36924
|
+
}, term.id)) });
|
|
36925
|
+
}
|
|
36146
36926
|
/**
|
|
36147
36927
|
* Term row component (recursive for hierarchy)
|
|
36928
|
+
*
|
|
36929
|
+
* `siblings` is the group the term is rendered from, in display order, and
|
|
36930
|
+
* `parentId` is that group's parent. Moving a term reorders that group and
|
|
36931
|
+
* never changes its parent.
|
|
36932
|
+
*
|
|
36933
|
+
* A term whose parent has no row in this locale is rendered at the top level so
|
|
36934
|
+
* it isn't lost, but it belongs to its parent's group — a group this locale
|
|
36935
|
+
* can't show. Its move buttons are disabled rather than silently addressing the
|
|
36936
|
+
* wrong group, and `place` is -1 because it holds no slot in the group it is
|
|
36937
|
+
* drawn in.
|
|
36148
36938
|
*/
|
|
36149
|
-
function TermRow({ term, level = 0, onEdit, onDelete, onTranslate, canTranslate }) {
|
|
36939
|
+
function TermRow({ term, siblings, movable, place, parentId, level = 0, onEdit, onDelete, onMove, onTranslate, canTranslate }) {
|
|
36150
36940
|
const { _: _t } = useLingui();
|
|
36941
|
+
const stranded = isStranded(term, parentId);
|
|
36151
36942
|
return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
|
|
36152
36943
|
className: "flex items-center gap-4 py-2 px-4 hover:bg-kumo-tint/50",
|
|
36153
36944
|
children: [
|
|
@@ -36173,6 +36964,45 @@ function TermRow({ term, level = 0, onEdit, onDelete, onTranslate, canTranslate
|
|
|
36173
36964
|
/* @__PURE__ */ jsxs("div", {
|
|
36174
36965
|
className: "flex gap-2",
|
|
36175
36966
|
children: [
|
|
36967
|
+
/* @__PURE__ */ jsxs("span", {
|
|
36968
|
+
className: "flex gap-2",
|
|
36969
|
+
title: stranded ? _t({
|
|
36970
|
+
id: "+L2ab9",
|
|
36971
|
+
message: "{0} can't be moved here — its parent has no translation in this locale, so this list isn't the group it belongs to.",
|
|
36972
|
+
values: { 0: term.label }
|
|
36973
|
+
}) : void 0,
|
|
36974
|
+
children: [/* @__PURE__ */ jsx(Button, {
|
|
36975
|
+
variant: "ghost",
|
|
36976
|
+
size: "sm",
|
|
36977
|
+
"aria-label": stranded ? _t({
|
|
36978
|
+
id: "WtMC7E",
|
|
36979
|
+
message: "Move {0} up — unavailable, its parent has no translation in this locale",
|
|
36980
|
+
values: { 0: term.label }
|
|
36981
|
+
}) : _t({
|
|
36982
|
+
id: "GtRAA3",
|
|
36983
|
+
message: "Move {0} up",
|
|
36984
|
+
values: { 0: term.label }
|
|
36985
|
+
}),
|
|
36986
|
+
disabled: stranded || place <= 0,
|
|
36987
|
+
onClick: () => onMove(parentId, siblings, movable, term, -1),
|
|
36988
|
+
children: /* @__PURE__ */ jsx(CaretUp, { className: "w-4 h-4" })
|
|
36989
|
+
}), /* @__PURE__ */ jsx(Button, {
|
|
36990
|
+
variant: "ghost",
|
|
36991
|
+
size: "sm",
|
|
36992
|
+
"aria-label": stranded ? _t({
|
|
36993
|
+
id: "aeS7hl",
|
|
36994
|
+
message: "Move {0} down — unavailable, its parent has no translation in this locale",
|
|
36995
|
+
values: { 0: term.label }
|
|
36996
|
+
}) : _t({
|
|
36997
|
+
id: "tspiKT",
|
|
36998
|
+
message: "Move {0} down",
|
|
36999
|
+
values: { 0: term.label }
|
|
37000
|
+
}),
|
|
37001
|
+
disabled: stranded || place >= movable.length - 1,
|
|
37002
|
+
onClick: () => onMove(parentId, siblings, movable, term, 1),
|
|
37003
|
+
children: /* @__PURE__ */ jsx(CaretDown, { className: "w-4 h-4" })
|
|
37004
|
+
})]
|
|
37005
|
+
}),
|
|
36176
37006
|
canTranslate && onTranslate ? /* @__PURE__ */ jsx(Button, {
|
|
36177
37007
|
variant: "ghost",
|
|
36178
37008
|
size: "sm",
|
|
@@ -36212,14 +37042,16 @@ function TermRow({ term, level = 0, onEdit, onDelete, onTranslate, canTranslate
|
|
|
36212
37042
|
]
|
|
36213
37043
|
})
|
|
36214
37044
|
]
|
|
36215
|
-
}),
|
|
36216
|
-
|
|
37045
|
+
}), /* @__PURE__ */ jsx(TermGroup, {
|
|
37046
|
+
siblings: term.children,
|
|
37047
|
+
parentId: termGroup(term),
|
|
36217
37048
|
level: level + 1,
|
|
36218
37049
|
onEdit,
|
|
36219
37050
|
onDelete,
|
|
37051
|
+
onMove,
|
|
36220
37052
|
onTranslate,
|
|
36221
37053
|
canTranslate
|
|
36222
|
-
}
|
|
37054
|
+
})] });
|
|
36223
37055
|
}
|
|
36224
37056
|
/**
|
|
36225
37057
|
* Dialog to pick a target locale for creating a term translation.
|
|
@@ -36860,13 +37692,14 @@ function TaxonomyManager({ taxonomyName }) {
|
|
|
36860
37692
|
queryKey: ["taxonomy-def", taxonomyName],
|
|
36861
37693
|
queryFn: () => fetchTaxonomyDef(taxonomyName)
|
|
36862
37694
|
});
|
|
37695
|
+
const termsQueryKey = [
|
|
37696
|
+
"taxonomy-terms",
|
|
37697
|
+
taxonomyName,
|
|
37698
|
+
activeLocale,
|
|
37699
|
+
{ includeCounts: true }
|
|
37700
|
+
];
|
|
36863
37701
|
const { data: terms = [], isLoading: termsLoading } = useQuery({
|
|
36864
|
-
queryKey:
|
|
36865
|
-
"taxonomy-terms",
|
|
36866
|
-
taxonomyName,
|
|
36867
|
-
activeLocale,
|
|
36868
|
-
{ includeCounts: true }
|
|
36869
|
-
],
|
|
37702
|
+
queryKey: termsQueryKey,
|
|
36870
37703
|
queryFn: () => fetchTerms(taxonomyName, { locale: activeLocale })
|
|
36871
37704
|
});
|
|
36872
37705
|
const deleteMutation = useMutation({
|
|
@@ -36880,6 +37713,43 @@ function TaxonomyManager({ taxonomyName }) {
|
|
|
36880
37713
|
}) });
|
|
36881
37714
|
}
|
|
36882
37715
|
});
|
|
37716
|
+
const reorderMutationKey = ["taxonomy-terms-reorder", taxonomyName];
|
|
37717
|
+
const reorderMutation = useMutation({
|
|
37718
|
+
mutationKey: reorderMutationKey,
|
|
37719
|
+
scope: { id: `taxonomy-reorder:${taxonomyName}` },
|
|
37720
|
+
mutationFn: ({ parentId, ids }) => reorderTerms(taxonomyName, {
|
|
37721
|
+
parentId,
|
|
37722
|
+
ids
|
|
37723
|
+
}),
|
|
37724
|
+
onError: (error) => {
|
|
37725
|
+
toastManager.add({
|
|
37726
|
+
title: _t5({
|
|
37727
|
+
id: "SlfejT",
|
|
37728
|
+
message: "Error"
|
|
37729
|
+
}),
|
|
37730
|
+
description: error.message,
|
|
37731
|
+
type: "error"
|
|
37732
|
+
});
|
|
37733
|
+
},
|
|
37734
|
+
onSettled: () => {
|
|
37735
|
+
if (queryClient.isMutating({ mutationKey: reorderMutationKey }) > 1) return;
|
|
37736
|
+
queryClient.invalidateQueries({ queryKey: ["taxonomy-terms", taxonomyName] });
|
|
37737
|
+
}
|
|
37738
|
+
});
|
|
37739
|
+
const handleMove = (parentId, siblings, movable, term, direction) => {
|
|
37740
|
+
const from = movable.indexOf(term);
|
|
37741
|
+
const to = from + direction;
|
|
37742
|
+
const moving = movable[from];
|
|
37743
|
+
const displaced = movable[to];
|
|
37744
|
+
if (!moving || !displaced) return;
|
|
37745
|
+
const permuted = movable.map((sibling, index) => index === from ? displaced : index === to ? moving : sibling);
|
|
37746
|
+
const reordered = reorderWithinSlots(siblings, movable, permuted);
|
|
37747
|
+
queryClient.setQueryData(termsQueryKey, (current) => current ? replaceSiblingGroup(current, parentId, reordered) : current);
|
|
37748
|
+
reorderMutation.mutate({
|
|
37749
|
+
parentId,
|
|
37750
|
+
ids: permuted.map(termGroup)
|
|
37751
|
+
});
|
|
37752
|
+
};
|
|
36883
37753
|
const translateMutation = useMutation({
|
|
36884
37754
|
mutationFn: ({ term, locale }) => createTermTranslation(taxonomyName, term.slug, {
|
|
36885
37755
|
locale,
|
|
@@ -37022,13 +37892,15 @@ function TaxonomyManager({ taxonomyName }) {
|
|
|
37022
37892
|
})
|
|
37023
37893
|
}) : /* @__PURE__ */ jsx("div", {
|
|
37024
37894
|
className: "divide-y divide-kumo-line",
|
|
37025
|
-
children:
|
|
37026
|
-
|
|
37895
|
+
children: /* @__PURE__ */ jsx(TermGroup, {
|
|
37896
|
+
siblings: terms,
|
|
37897
|
+
parentId: null,
|
|
37027
37898
|
onEdit: handleEdit,
|
|
37028
37899
|
onDelete: handleDelete,
|
|
37900
|
+
onMove: handleMove,
|
|
37029
37901
|
onTranslate: setTranslateTarget,
|
|
37030
37902
|
canTranslate: !!i18n && !!activeLocale && i18n.locales.length > 1
|
|
37031
|
-
}
|
|
37903
|
+
})
|
|
37032
37904
|
})]
|
|
37033
37905
|
}),
|
|
37034
37906
|
/* @__PURE__ */ jsx(TermFormDialog, {
|
|
@@ -44331,7 +45203,7 @@ function UsersPage() {
|
|
|
44331
45203
|
* Defines all admin routes and their components.
|
|
44332
45204
|
*/
|
|
44333
45205
|
function patchAutosaveQueries(queryClient, params) {
|
|
44334
|
-
const { collection, id, savedItem, payload
|
|
45206
|
+
const { collection, id, savedItem, payload } = params;
|
|
44335
45207
|
const draftRevisionId = savedItem.draftRevisionId;
|
|
44336
45208
|
if (draftRevisionId) queryClient.setQueryData(["revision", draftRevisionId], (existing) => {
|
|
44337
45209
|
const nextData = {
|
|
@@ -44348,16 +45220,11 @@ function patchAutosaveQueries(queryClient, params) {
|
|
|
44348
45220
|
createdAt: existing?.createdAt ?? savedItem.updatedAt
|
|
44349
45221
|
};
|
|
44350
45222
|
});
|
|
44351
|
-
queryClient.
|
|
44352
|
-
"content",
|
|
44353
|
-
collection,
|
|
44354
|
-
id,
|
|
44355
|
-
{ locale }
|
|
44356
|
-
] : [
|
|
45223
|
+
queryClient.setQueriesData({ queryKey: [
|
|
44357
45224
|
"content",
|
|
44358
45225
|
collection,
|
|
44359
45226
|
id
|
|
44360
|
-
], savedItem);
|
|
45227
|
+
] }, savedItem);
|
|
44361
45228
|
}
|
|
44362
45229
|
const baseRootRoute = createRootRouteWithContext()({ component: () => /* @__PURE__ */ jsx(Outlet, {}) });
|
|
44363
45230
|
const setupRoute = createRoute({
|
|
@@ -44775,6 +45642,8 @@ function ContentNewPage() {
|
|
|
44775
45642
|
const { locale } = useSearch({ from: "/_admin/content/$collection/new" });
|
|
44776
45643
|
const navigate = useNavigate();
|
|
44777
45644
|
const queryClient = useQueryClient();
|
|
45645
|
+
const { _: _t3 } = useLingui();
|
|
45646
|
+
const toastManager = useKumoToastManager();
|
|
44778
45647
|
const [selectedBylines, setSelectedBylines] = React$1.useState([]);
|
|
44779
45648
|
const { data: manifest } = useQuery({
|
|
44780
45649
|
queryKey: ["manifest"],
|
|
@@ -44796,6 +45665,19 @@ function ContentNewPage() {
|
|
|
44796
45665
|
},
|
|
44797
45666
|
search: { locale: result.locale }
|
|
44798
45667
|
});
|
|
45668
|
+
},
|
|
45669
|
+
onError: (error) => {
|
|
45670
|
+
toastManager.add({
|
|
45671
|
+
title: _t3({
|
|
45672
|
+
id: "+Ya+b9",
|
|
45673
|
+
message: "Failed to save"
|
|
45674
|
+
}),
|
|
45675
|
+
description: error instanceof Error ? error.message : _t3({
|
|
45676
|
+
id: "Vw8l6h",
|
|
45677
|
+
message: "An error occurred"
|
|
45678
|
+
}),
|
|
45679
|
+
variant: "error"
|
|
45680
|
+
});
|
|
44799
45681
|
}
|
|
44800
45682
|
});
|
|
44801
45683
|
const pluginBlocks = React$1.useMemo(() => manifest ? getPluginBlocks(manifest) : [], [manifest]);
|
|
@@ -44872,7 +45754,7 @@ const contentEditRoute = createRoute({
|
|
|
44872
45754
|
});
|
|
44873
45755
|
const ROLE_EDITOR = 40;
|
|
44874
45756
|
function ContentEditPage() {
|
|
44875
|
-
const { _:
|
|
45757
|
+
const { _: _t4 } = useLingui();
|
|
44876
45758
|
const { collection, id } = useParams({ from: "/_admin/content/$collection/$id" });
|
|
44877
45759
|
const searchParams = useSearch({ from: "/_admin/content/$collection/$id" });
|
|
44878
45760
|
const queryClient = useQueryClient();
|
|
@@ -44949,7 +45831,7 @@ function ContentEditPage() {
|
|
|
44949
45831
|
const { data: currentUser } = useQuery({
|
|
44950
45832
|
queryKey: ["currentUser"],
|
|
44951
45833
|
queryFn: async () => {
|
|
44952
|
-
return parseApiResponse(await apiFetch("/_emdash/api/auth/me"),
|
|
45834
|
+
return parseApiResponse(await apiFetch("/_emdash/api/auth/me"), _t4({
|
|
44953
45835
|
id: "z7Mflq",
|
|
44954
45836
|
message: "Failed to fetch user"
|
|
44955
45837
|
}));
|
|
@@ -45035,17 +45917,17 @@ function ContentEditPage() {
|
|
|
45035
45917
|
]);
|
|
45036
45918
|
const handleContentUpdateError = React$1.useCallback((error) => {
|
|
45037
45919
|
toastManager.add({
|
|
45038
|
-
title:
|
|
45920
|
+
title: _t4({
|
|
45039
45921
|
id: "+Ya+b9",
|
|
45040
45922
|
message: "Failed to save"
|
|
45041
45923
|
}),
|
|
45042
|
-
description: error instanceof Error ? error.message :
|
|
45924
|
+
description: error instanceof Error ? error.message : _t4({
|
|
45043
45925
|
id: "Vw8l6h",
|
|
45044
45926
|
message: "An error occurred"
|
|
45045
45927
|
}),
|
|
45046
45928
|
type: "error"
|
|
45047
45929
|
});
|
|
45048
|
-
}, [
|
|
45930
|
+
}, [_t4, toastManager]);
|
|
45049
45931
|
const updateMutation = useMutation({
|
|
45050
45932
|
mutationFn: ({ targetId, targetLocale, changes }) => updateContent(collection, targetId, changes, { locale: targetLocale }),
|
|
45051
45933
|
onMutate: (variables) => {
|
|
@@ -45080,17 +45962,16 @@ function ContentEditPage() {
|
|
|
45080
45962
|
payload: {
|
|
45081
45963
|
data: variables.changes.data,
|
|
45082
45964
|
slug: variables.changes.slug
|
|
45083
|
-
}
|
|
45084
|
-
locale: variables.targetLocale
|
|
45965
|
+
}
|
|
45085
45966
|
});
|
|
45086
45967
|
},
|
|
45087
45968
|
onError: (err) => {
|
|
45088
45969
|
toastManager.add({
|
|
45089
|
-
title:
|
|
45970
|
+
title: _t4({
|
|
45090
45971
|
id: "dnqStT",
|
|
45091
45972
|
message: "Autosave failed"
|
|
45092
45973
|
}),
|
|
45093
|
-
description: err instanceof Error ? err.message :
|
|
45974
|
+
description: err instanceof Error ? err.message : _t4({
|
|
45094
45975
|
id: "Vw8l6h",
|
|
45095
45976
|
message: "An error occurred"
|
|
45096
45977
|
}),
|
|
@@ -45112,11 +45993,11 @@ function ContentEditPage() {
|
|
|
45112
45993
|
id
|
|
45113
45994
|
] });
|
|
45114
45995
|
toastManager.add({
|
|
45115
|
-
title:
|
|
45996
|
+
title: _t4({
|
|
45116
45997
|
id: "u3wRF+",
|
|
45117
45998
|
message: "Published"
|
|
45118
45999
|
}),
|
|
45119
|
-
description:
|
|
46000
|
+
description: _t4({
|
|
45120
46001
|
id: "SM5lo+",
|
|
45121
46002
|
message: "Content is now live"
|
|
45122
46003
|
})
|
|
@@ -45124,11 +46005,11 @@ function ContentEditPage() {
|
|
|
45124
46005
|
},
|
|
45125
46006
|
onError: (error) => {
|
|
45126
46007
|
toastManager.add({
|
|
45127
|
-
title:
|
|
46008
|
+
title: _t4({
|
|
45128
46009
|
id: "pxQAFW",
|
|
45129
46010
|
message: "Failed to publish"
|
|
45130
46011
|
}),
|
|
45131
|
-
description: error instanceof Error ? error.message :
|
|
46012
|
+
description: error instanceof Error ? error.message : _t4({
|
|
45132
46013
|
id: "Vw8l6h",
|
|
45133
46014
|
message: "An error occurred"
|
|
45134
46015
|
}),
|
|
@@ -45150,11 +46031,11 @@ function ContentEditPage() {
|
|
|
45150
46031
|
id
|
|
45151
46032
|
] });
|
|
45152
46033
|
toastManager.add({
|
|
45153
|
-
title:
|
|
46034
|
+
title: _t4({
|
|
45154
46035
|
id: "ejZKhw",
|
|
45155
46036
|
message: "Unpublished"
|
|
45156
46037
|
}),
|
|
45157
|
-
description:
|
|
46038
|
+
description: _t4({
|
|
45158
46039
|
id: "WWp6Cy",
|
|
45159
46040
|
message: "Content removed from public view"
|
|
45160
46041
|
})
|
|
@@ -45162,11 +46043,11 @@ function ContentEditPage() {
|
|
|
45162
46043
|
},
|
|
45163
46044
|
onError: (error) => {
|
|
45164
46045
|
toastManager.add({
|
|
45165
|
-
title:
|
|
46046
|
+
title: _t4({
|
|
45166
46047
|
id: "l0S9au",
|
|
45167
46048
|
message: "Failed to unpublish"
|
|
45168
46049
|
}),
|
|
45169
|
-
description: error instanceof Error ? error.message :
|
|
46050
|
+
description: error instanceof Error ? error.message : _t4({
|
|
45170
46051
|
id: "Vw8l6h",
|
|
45171
46052
|
message: "An error occurred"
|
|
45172
46053
|
}),
|
|
@@ -45188,11 +46069,11 @@ function ContentEditPage() {
|
|
|
45188
46069
|
id
|
|
45189
46070
|
] });
|
|
45190
46071
|
toastManager.add({
|
|
45191
|
-
title:
|
|
46072
|
+
title: _t4({
|
|
45192
46073
|
id: "Uy0jGI",
|
|
45193
46074
|
message: "Changes discarded"
|
|
45194
46075
|
}),
|
|
45195
|
-
description:
|
|
46076
|
+
description: _t4({
|
|
45196
46077
|
id: "26Nir7",
|
|
45197
46078
|
message: "Reverted to published version"
|
|
45198
46079
|
})
|
|
@@ -45200,11 +46081,11 @@ function ContentEditPage() {
|
|
|
45200
46081
|
},
|
|
45201
46082
|
onError: (error) => {
|
|
45202
46083
|
toastManager.add({
|
|
45203
|
-
title:
|
|
46084
|
+
title: _t4({
|
|
45204
46085
|
id: "7tFjEI",
|
|
45205
46086
|
message: "Failed to discard changes"
|
|
45206
46087
|
}),
|
|
45207
|
-
description: error instanceof Error ? error.message :
|
|
46088
|
+
description: error instanceof Error ? error.message : _t4({
|
|
45208
46089
|
id: "Vw8l6h",
|
|
45209
46090
|
message: "An error occurred"
|
|
45210
46091
|
}),
|
|
@@ -45221,11 +46102,11 @@ function ContentEditPage() {
|
|
|
45221
46102
|
id
|
|
45222
46103
|
] });
|
|
45223
46104
|
toastManager.add({
|
|
45224
|
-
title:
|
|
46105
|
+
title: _t4({
|
|
45225
46106
|
id: "4ba0NE",
|
|
45226
46107
|
message: "Scheduled"
|
|
45227
46108
|
}),
|
|
45228
|
-
description:
|
|
46109
|
+
description: _t4({
|
|
45229
46110
|
id: "wZIOmQ",
|
|
45230
46111
|
message: "Content has been scheduled for publishing"
|
|
45231
46112
|
})
|
|
@@ -45233,11 +46114,11 @@ function ContentEditPage() {
|
|
|
45233
46114
|
},
|
|
45234
46115
|
onError: (error) => {
|
|
45235
46116
|
toastManager.add({
|
|
45236
|
-
title:
|
|
46117
|
+
title: _t4({
|
|
45237
46118
|
id: "gOH5Xh",
|
|
45238
46119
|
message: "Failed to schedule"
|
|
45239
46120
|
}),
|
|
45240
|
-
description: error instanceof Error ? error.message :
|
|
46121
|
+
description: error instanceof Error ? error.message : _t4({
|
|
45241
46122
|
id: "Vw8l6h",
|
|
45242
46123
|
message: "An error occurred"
|
|
45243
46124
|
}),
|
|
@@ -45254,11 +46135,11 @@ function ContentEditPage() {
|
|
|
45254
46135
|
id
|
|
45255
46136
|
] });
|
|
45256
46137
|
toastManager.add({
|
|
45257
|
-
title:
|
|
46138
|
+
title: _t4({
|
|
45258
46139
|
id: "cJ44lA",
|
|
45259
46140
|
message: "Unscheduled"
|
|
45260
46141
|
}),
|
|
45261
|
-
description:
|
|
46142
|
+
description: _t4({
|
|
45262
46143
|
id: "XhvaX7",
|
|
45263
46144
|
message: "Content reverted to draft"
|
|
45264
46145
|
})
|
|
@@ -45266,11 +46147,11 @@ function ContentEditPage() {
|
|
|
45266
46147
|
},
|
|
45267
46148
|
onError: (error) => {
|
|
45268
46149
|
toastManager.add({
|
|
45269
|
-
title:
|
|
46150
|
+
title: _t4({
|
|
45270
46151
|
id: "fjtI07",
|
|
45271
46152
|
message: "Failed to unschedule"
|
|
45272
46153
|
}),
|
|
45273
|
-
description: error instanceof Error ? error.message :
|
|
46154
|
+
description: error instanceof Error ? error.message : _t4({
|
|
45274
46155
|
id: "Vw8l6h",
|
|
45275
46156
|
message: "An error occurred"
|
|
45276
46157
|
}),
|
|
@@ -45301,14 +46182,14 @@ function ContentEditPage() {
|
|
|
45301
46182
|
search: { locale: result.locale }
|
|
45302
46183
|
});
|
|
45303
46184
|
toastManager.add({
|
|
45304
|
-
title:
|
|
46185
|
+
title: _t4({
|
|
45305
46186
|
id: "pBdGCu",
|
|
45306
46187
|
message: "Translation created"
|
|
45307
46188
|
}),
|
|
45308
|
-
description:
|
|
46189
|
+
description: _t4({
|
|
45309
46190
|
id: "JtUYuE",
|
|
45310
46191
|
message: "Created {0} translation",
|
|
45311
|
-
values: { 0: result.locale?.toUpperCase() ??
|
|
46192
|
+
values: { 0: result.locale?.toUpperCase() ?? _t4({
|
|
45312
46193
|
id: "Oz0N9s",
|
|
45313
46194
|
message: "new"
|
|
45314
46195
|
}) }
|
|
@@ -45317,11 +46198,11 @@ function ContentEditPage() {
|
|
|
45317
46198
|
},
|
|
45318
46199
|
onError: (error) => {
|
|
45319
46200
|
toastManager.add({
|
|
45320
|
-
title:
|
|
46201
|
+
title: _t4({
|
|
45321
46202
|
id: "q0N9jk",
|
|
45322
46203
|
message: "Failed to create translation"
|
|
45323
46204
|
}),
|
|
45324
|
-
description: error instanceof Error ? error.message :
|
|
46205
|
+
description: error instanceof Error ? error.message : _t4({
|
|
45325
46206
|
id: "Vw8l6h",
|
|
45326
46207
|
message: "An error occurred"
|
|
45327
46208
|
}),
|
|
@@ -45346,11 +46227,11 @@ function ContentEditPage() {
|
|
|
45346
46227
|
},
|
|
45347
46228
|
onError: (error) => {
|
|
45348
46229
|
toastManager.add({
|
|
45349
|
-
title:
|
|
46230
|
+
title: _t4({
|
|
45350
46231
|
id: "92o1+U",
|
|
45351
46232
|
message: "Failed to delete"
|
|
45352
46233
|
}),
|
|
45353
|
-
description: error instanceof Error ? error.message :
|
|
46234
|
+
description: error instanceof Error ? error.message : _t4({
|
|
45354
46235
|
id: "Vw8l6h",
|
|
45355
46236
|
message: "An error occurred"
|
|
45356
46237
|
}),
|
|
@@ -45522,7 +46403,7 @@ const commentsRoute = createRoute({
|
|
|
45522
46403
|
});
|
|
45523
46404
|
const ROLE_ADMIN = 50;
|
|
45524
46405
|
function CommentsPage() {
|
|
45525
|
-
const { _:
|
|
46406
|
+
const { _: _t5 } = useLingui();
|
|
45526
46407
|
const queryClient = useQueryClient();
|
|
45527
46408
|
const toastManager = Toast.useToastManager();
|
|
45528
46409
|
const { data: manifest } = useQuery({
|
|
@@ -45532,7 +46413,7 @@ function CommentsPage() {
|
|
|
45532
46413
|
const { data: currentUser } = useQuery({
|
|
45533
46414
|
queryKey: ["currentUser"],
|
|
45534
46415
|
queryFn: async () => {
|
|
45535
|
-
return parseApiResponse(await apiFetch("/_emdash/api/auth/me"),
|
|
46416
|
+
return parseApiResponse(await apiFetch("/_emdash/api/auth/me"), _t5({
|
|
45536
46417
|
id: "z7Mflq",
|
|
45537
46418
|
message: "Failed to fetch user"
|
|
45538
46419
|
}));
|
|
@@ -45576,11 +46457,11 @@ function CommentsPage() {
|
|
|
45576
46457
|
},
|
|
45577
46458
|
onError: (error) => {
|
|
45578
46459
|
toastManager.add({
|
|
45579
|
-
title:
|
|
46460
|
+
title: _t5({
|
|
45580
46461
|
id: "/gQXGv",
|
|
45581
46462
|
message: "Failed to update status"
|
|
45582
46463
|
}),
|
|
45583
|
-
description: error instanceof Error ? error.message :
|
|
46464
|
+
description: error instanceof Error ? error.message : _t5({
|
|
45584
46465
|
id: "Vw8l6h",
|
|
45585
46466
|
message: "An error occurred"
|
|
45586
46467
|
}),
|
|
@@ -45596,11 +46477,11 @@ function CommentsPage() {
|
|
|
45596
46477
|
},
|
|
45597
46478
|
onError: (error) => {
|
|
45598
46479
|
toastManager.add({
|
|
45599
|
-
title:
|
|
46480
|
+
title: _t5({
|
|
45600
46481
|
id: "YpwXI2",
|
|
45601
46482
|
message: "Failed to delete comment"
|
|
45602
46483
|
}),
|
|
45603
|
-
description: error instanceof Error ? error.message :
|
|
46484
|
+
description: error instanceof Error ? error.message : _t5({
|
|
45604
46485
|
id: "Vw8l6h",
|
|
45605
46486
|
message: "An error occurred"
|
|
45606
46487
|
}),
|
|
@@ -45621,11 +46502,11 @@ function CommentsPage() {
|
|
|
45621
46502
|
},
|
|
45622
46503
|
onError: (error) => {
|
|
45623
46504
|
toastManager.add({
|
|
45624
|
-
title:
|
|
46505
|
+
title: _t5({
|
|
45625
46506
|
id: "QposE2",
|
|
45626
46507
|
message: "Failed to perform bulk action"
|
|
45627
46508
|
}),
|
|
45628
|
-
description: error instanceof Error ? error.message :
|
|
46509
|
+
description: error instanceof Error ? error.message : _t5({
|
|
45629
46510
|
id: "Vw8l6h",
|
|
45630
46511
|
message: "An error occurred"
|
|
45631
46512
|
}),
|
|
@@ -45641,13 +46522,13 @@ function CommentsPage() {
|
|
|
45641
46522
|
className: "text-center",
|
|
45642
46523
|
children: [/* @__PURE__ */ jsx("h1", {
|
|
45643
46524
|
className: "text-2xl font-semibold leading-tight",
|
|
45644
|
-
children:
|
|
46525
|
+
children: _t5({
|
|
45645
46526
|
id: "VTfZPy",
|
|
45646
46527
|
message: "Access Denied"
|
|
45647
46528
|
})
|
|
45648
46529
|
}), /* @__PURE__ */ jsx("p", {
|
|
45649
46530
|
className: "mt-2 text-sm text-kumo-subtle",
|
|
45650
|
-
children:
|
|
46531
|
+
children: _t5({
|
|
45651
46532
|
id: "xbYfFQ",
|
|
45652
46533
|
message: "You need Editor permissions to moderate comments."
|
|
45653
46534
|
})
|
|
@@ -45919,6 +46800,13 @@ function ContentTypesListPage() {
|
|
|
45919
46800
|
queryClient.invalidateQueries({ queryKey: ["manifest"] });
|
|
45920
46801
|
}
|
|
45921
46802
|
});
|
|
46803
|
+
const reorderMutation = useMutation({
|
|
46804
|
+
mutationFn: (slugs) => reorderCollections(slugs),
|
|
46805
|
+
onSettled: () => {
|
|
46806
|
+
queryClient.invalidateQueries({ queryKey: ["schema", "collections"] });
|
|
46807
|
+
queryClient.invalidateQueries({ queryKey: ["manifest"] });
|
|
46808
|
+
}
|
|
46809
|
+
});
|
|
45922
46810
|
const error = collectionsError || orphansError;
|
|
45923
46811
|
if (error) return /* @__PURE__ */ jsx(ErrorScreen, { error: error.message });
|
|
45924
46812
|
return /* @__PURE__ */ jsx(ContentTypeList, {
|
|
@@ -45926,7 +46814,8 @@ function ContentTypesListPage() {
|
|
|
45926
46814
|
orphanedTables,
|
|
45927
46815
|
isLoading: collectionsLoading || orphansLoading,
|
|
45928
46816
|
onDelete: (slug) => deleteMutation.mutate(slug),
|
|
45929
|
-
onRegisterOrphan: (slug) => registerOrphanMutation.mutate(slug)
|
|
46817
|
+
onRegisterOrphan: (slug) => registerOrphanMutation.mutate(slug),
|
|
46818
|
+
onReorder: (slugs) => reorderMutation.mutate(slugs)
|
|
45930
46819
|
});
|
|
45931
46820
|
}
|
|
45932
46821
|
const contentTypesNewRoute = createRoute({
|
|
@@ -45965,7 +46854,7 @@ function ContentTypesEditPage() {
|
|
|
45965
46854
|
const { slug } = useParams({ from: "/_admin/content-types/$slug" });
|
|
45966
46855
|
const queryClient = useQueryClient();
|
|
45967
46856
|
const toastManager = Toast.useToastManager();
|
|
45968
|
-
const { _:
|
|
46857
|
+
const { _: _t6 } = useLingui();
|
|
45969
46858
|
const { data: collection, isLoading, error } = useQuery({
|
|
45970
46859
|
queryKey: [
|
|
45971
46860
|
"schema",
|
|
@@ -45999,11 +46888,11 @@ function ContentTypesEditPage() {
|
|
|
45999
46888
|
},
|
|
46000
46889
|
onError: (mutationError) => {
|
|
46001
46890
|
toastManager.add({
|
|
46002
|
-
title:
|
|
46891
|
+
title: _t6({
|
|
46003
46892
|
id: "+Ya+b9",
|
|
46004
46893
|
message: "Failed to save"
|
|
46005
46894
|
}),
|
|
46006
|
-
description: mutationError instanceof Error ? mutationError.message :
|
|
46895
|
+
description: mutationError instanceof Error ? mutationError.message : _t6({
|
|
46007
46896
|
id: "Vw8l6h",
|
|
46008
46897
|
message: "An error occurred"
|
|
46009
46898
|
}),
|
|
@@ -46156,7 +47045,7 @@ function createAdminRouter(queryClient) {
|
|
|
46156
47045
|
});
|
|
46157
47046
|
}
|
|
46158
47047
|
function ConfigurationLoadingScreen() {
|
|
46159
|
-
const { _:
|
|
47048
|
+
const { _: _t7 } = useLingui();
|
|
46160
47049
|
return /* @__PURE__ */ jsx("div", {
|
|
46161
47050
|
className: "emdash-configuration-loader",
|
|
46162
47051
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -46164,13 +47053,13 @@ function ConfigurationLoadingScreen() {
|
|
|
46164
47053
|
children: [/* @__PURE__ */ jsx("div", {
|
|
46165
47054
|
className: "spinner emdash-configuration-spinner",
|
|
46166
47055
|
role: "status",
|
|
46167
|
-
"aria-label":
|
|
47056
|
+
"aria-label": _t7({
|
|
46168
47057
|
id: "yQE2r9",
|
|
46169
47058
|
message: "Loading"
|
|
46170
47059
|
})
|
|
46171
47060
|
}), /* @__PURE__ */ jsx("p", {
|
|
46172
47061
|
className: "emdash-configuration-label",
|
|
46173
|
-
children:
|
|
47062
|
+
children: _t7({
|
|
46174
47063
|
id: "I6/uPI",
|
|
46175
47064
|
message: "Loading configuration..."
|
|
46176
47065
|
})
|
|
@@ -46179,14 +47068,14 @@ function ConfigurationLoadingScreen() {
|
|
|
46179
47068
|
});
|
|
46180
47069
|
}
|
|
46181
47070
|
function LoadingScreen() {
|
|
46182
|
-
const { _:
|
|
47071
|
+
const { _: _t8 } = useLingui();
|
|
46183
47072
|
return /* @__PURE__ */ jsx("div", {
|
|
46184
47073
|
className: "flex items-center justify-center min-h-screen",
|
|
46185
47074
|
children: /* @__PURE__ */ jsxs("div", {
|
|
46186
47075
|
className: "text-center",
|
|
46187
47076
|
children: [/* @__PURE__ */ jsx(Loader, {}), /* @__PURE__ */ jsx("p", {
|
|
46188
47077
|
className: "mt-4 text-kumo-subtle",
|
|
46189
|
-
children:
|
|
47078
|
+
children: _t8({
|
|
46190
47079
|
id: "I6/uPI",
|
|
46191
47080
|
message: "Loading configuration..."
|
|
46192
47081
|
})
|
|
@@ -46195,7 +47084,7 @@ function LoadingScreen() {
|
|
|
46195
47084
|
});
|
|
46196
47085
|
}
|
|
46197
47086
|
function ErrorScreen({ error }) {
|
|
46198
|
-
const { _:
|
|
47087
|
+
const { _: _t9 } = useLingui();
|
|
46199
47088
|
return /* @__PURE__ */ jsx("div", {
|
|
46200
47089
|
className: "flex items-center justify-center min-h-screen",
|
|
46201
47090
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -46203,7 +47092,7 @@ function ErrorScreen({ error }) {
|
|
|
46203
47092
|
children: [
|
|
46204
47093
|
/* @__PURE__ */ jsx("h1", {
|
|
46205
47094
|
className: "text-2xl font-semibold leading-tight text-kumo-danger",
|
|
46206
|
-
children:
|
|
47095
|
+
children: _t9({
|
|
46207
47096
|
id: "SlfejT",
|
|
46208
47097
|
message: "Error"
|
|
46209
47098
|
})
|
|
@@ -46215,7 +47104,7 @@ function ErrorScreen({ error }) {
|
|
|
46215
47104
|
/* @__PURE__ */ jsx(Button, {
|
|
46216
47105
|
onClick: () => window.location.reload(),
|
|
46217
47106
|
className: "mt-4",
|
|
46218
|
-
children:
|
|
47107
|
+
children: _t9({
|
|
46219
47108
|
id: "6gRgw8",
|
|
46220
47109
|
message: "Retry"
|
|
46221
47110
|
})
|
|
@@ -46225,7 +47114,7 @@ function ErrorScreen({ error }) {
|
|
|
46225
47114
|
});
|
|
46226
47115
|
}
|
|
46227
47116
|
function NotFoundPage({ message }) {
|
|
46228
|
-
const { _:
|
|
47117
|
+
const { _: _t0 } = useLingui();
|
|
46229
47118
|
return /* @__PURE__ */ jsx("div", {
|
|
46230
47119
|
className: "flex items-center justify-center min-h-[50vh]",
|
|
46231
47120
|
children: /* @__PURE__ */ jsxs("div", {
|
|
@@ -46233,14 +47122,14 @@ function NotFoundPage({ message }) {
|
|
|
46233
47122
|
children: [
|
|
46234
47123
|
/* @__PURE__ */ jsx("h1", {
|
|
46235
47124
|
className: "text-2xl font-semibold leading-tight",
|
|
46236
|
-
children:
|
|
47125
|
+
children: _t0({
|
|
46237
47126
|
id: "boJlGf",
|
|
46238
47127
|
message: "Page Not Found"
|
|
46239
47128
|
})
|
|
46240
47129
|
}),
|
|
46241
47130
|
/* @__PURE__ */ jsx("p", {
|
|
46242
47131
|
className: "mt-2 text-sm text-kumo-subtle",
|
|
46243
|
-
children: message ??
|
|
47132
|
+
children: message ?? _t0({
|
|
46244
47133
|
id: "zEqK2w",
|
|
46245
47134
|
message: "The page you're looking for doesn't exist."
|
|
46246
47135
|
})
|
|
@@ -46248,7 +47137,7 @@ function NotFoundPage({ message }) {
|
|
|
46248
47137
|
/* @__PURE__ */ jsx(Link, {
|
|
46249
47138
|
to: "/",
|
|
46250
47139
|
className: "mt-4 inline-block text-kumo-link",
|
|
46251
|
-
children:
|
|
47140
|
+
children: _t0({
|
|
46252
47141
|
id: "cQPKZt",
|
|
46253
47142
|
message: "Go to Dashboard"
|
|
46254
47143
|
})
|
|
@@ -46353,5 +47242,5 @@ function AdminApp({ pluginAdmins = EMPTY_PLUGINS, authProviders = EMPTY_AUTH_PRO
|
|
|
46353
47242
|
}
|
|
46354
47243
|
|
|
46355
47244
|
//#endregion
|
|
46356
|
-
export { API_BASE, API_TOKEN_SCOPES, AdminApp, AdminApp as App, AuthProviderProvider, CAPABILITY_LABELS, ContentEditor, ContentList, DEFAULT_LOCALE, Dashboard, EditorHeader, Header, Link, LoginPage, MEDIA_SEARCH_MAX_LENGTH, 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, createBylineField, createBylineTranslation, createCollection, createContent, createField, createMenu, createMenuItem, createMenuTranslation, createRedirect, createSection, createTaxonomy, createTerm, createTermTranslation, createWidget, createWidgetArea, deleteAllowedDomain, deleteByline, deleteBylineField, 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, fetchBylineTranslations, fetchBylines, fetchCollection, fetchCollections, fetchComment, fetchCommentCounts, fetchComments, fetchContent, fetchContentAuthors, fetchContentList, fetchDashboardStats, fetchEmailSettings, fetchFields, fetchManifest, fetchMarketplacePlugin, fetchMediaItem, fetchMediaList, fetchMediaProviders, fetchMenu, fetchMenuTranslations, fetchMenus, fetchOrphanedTables, fetchPasskeys, fetchPlugin, fetchPluginSettings, fetchPlugins, fetchProviderMedia, fetchRedirects, fetchRevision, fetchRevisions, fetchSection, fetchSections, fetchSettings, fetchTaxonomyDef, fetchTaxonomyDefs, fetchTermTranslations, fetchTerms, fetchTheme, fetchTranslations, fetchTrashedContent, fetchUser, fetchUsers, fetchWidgetArea, fetchWidgetAreas, fetchWidgetComponents, generatePreviewUrl, getBylineFieldUsage, getDraftStatus, getPreviewUrl, hasAllowedDomains, importWxrMedia, importWxrMediaBatched, installMarketplacePlugin, inviteUser, listBylineFields, parseApiResponse, permanentDeleteContent, prepareWxrImport, probeImportUrl, publishContent, registerOrphanedTable, renamePasskey, reorderBylineFields, reorderFields, reorderMenuItems, reorderWidgets, requestSignup, resolveLocale, restoreContent, restoreRevision, revokeApiToken, rewriteContentUrls, scheduleContent, searchMarketplace, searchThemes, sendRecoveryLink, sendTestEmail, setPluginMcpEnabled, setSearchEnabled, throwResponseError, uninstallMarketplacePlugin, unpublishContent, unscheduleContent, updateAllowedDomain, updateByline, updateBylineField, updateCollection, updateCommentStatus, updateContent, updateField, updateMarketplacePlugin, updateMedia, updateMenu, updateMenuItem, updatePluginSettings, updateRedirect, updateSection, updateSettings, updateTerm, updateUser, updateWidget, uploadMedia, uploadToProvider, useAuthProviderList, useAuthProviders, useCurrentUser, useLocale, useNavigate, useParams, usePluginAdmins, usePluginField, usePluginHasPages, usePluginHasWidgets, usePluginPage, usePluginWidget, validateInviteToken, verifySignupToken };
|
|
47245
|
+
export { API_BASE, API_TOKEN_SCOPES, AdminApp, AdminApp as App, AuthProviderProvider, CAPABILITY_LABELS, ContentEditor, ContentList, DEFAULT_LOCALE, Dashboard, EditorHeader, Header, Link, LoginPage, MEDIA_SEARCH_MAX_LENGTH, 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, createBylineField, createBylineTranslation, createCollection, createContent, createField, createMenu, createMenuItem, createMenuTranslation, createRedirect, createSection, createTaxonomy, createTerm, createTermTranslation, createWidget, createWidgetArea, deleteAllowedDomain, deleteByline, deleteBylineField, 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, fetchBylineTranslations, fetchBylines, fetchCollection, fetchCollections, fetchComment, fetchCommentCounts, fetchComments, fetchContent, fetchContentAuthors, fetchContentList, fetchDashboardStats, fetchEmailSettings, fetchFields, fetchManifest, fetchMarketplacePlugin, fetchMediaItem, fetchMediaList, fetchMediaProviders, fetchMenu, fetchMenuTranslations, fetchMenus, fetchOrphanedTables, fetchPasskeys, fetchPlugin, fetchPluginSettings, fetchPlugins, fetchProviderMedia, fetchRedirects, fetchRevision, fetchRevisions, fetchSection, fetchSections, fetchSettings, fetchTaxonomyDef, fetchTaxonomyDefs, fetchTermTranslations, fetchTerms, fetchTheme, fetchTranslations, fetchTrashedContent, fetchUser, fetchUsers, fetchWidgetArea, fetchWidgetAreas, fetchWidgetComponents, generatePreviewUrl, getBylineFieldUsage, getDraftStatus, getPreviewUrl, hasAllowedDomains, importWxrMedia, importWxrMediaBatched, installMarketplacePlugin, inviteUser, listBylineFields, parseApiResponse, permanentDeleteContent, prepareWxrImport, probeImportUrl, publishContent, registerOrphanedTable, renamePasskey, reorderBylineFields, reorderCollections, reorderFields, reorderMenuItems, reorderWidgets, requestSignup, resolveLocale, restoreContent, restoreRevision, revokeApiToken, rewriteContentUrls, scheduleContent, searchMarketplace, searchThemes, sendRecoveryLink, sendTestEmail, setPluginMcpEnabled, setSearchEnabled, throwResponseError, uninstallMarketplacePlugin, unpublishContent, unscheduleContent, updateAllowedDomain, updateByline, updateBylineField, updateCollection, updateCommentStatus, updateContent, updateField, updateMarketplacePlugin, updateMedia, updateMenu, updateMenuItem, updatePluginSettings, updateRedirect, updateSection, updateSettings, updateTerm, updateUser, updateWidget, uploadMedia, uploadToProvider, useAuthProviderList, useAuthProviders, useCurrentUser, useLocale, useNavigate, useParams, usePluginAdmins, usePluginField, usePluginHasPages, usePluginHasWidgets, usePluginPage, usePluginWidget, validateInviteToken, verifySignupToken };
|
|
46357
47246
|
//# sourceMappingURL=index.js.map
|