@openrails/contentkit-ui 0.71.0 → 0.73.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.
Files changed (134) hide show
  1. package/README.md +122 -10
  2. package/dist/client/content/bans.d.ts +2 -0
  3. package/dist/client/content/bans.js +24 -12
  4. package/dist/client/content/bans.js.map +1 -1
  5. package/dist/client/content/comments.d.ts +2 -0
  6. package/dist/client/content/comments.js.map +1 -1
  7. package/dist/client/content/polls.d.ts +9 -2
  8. package/dist/client/content/polls.js.map +1 -1
  9. package/dist/client/generated/routes.d.ts +28 -2
  10. package/dist/client/generated/routes.js +40 -0
  11. package/dist/client/generated/routes.js.map +1 -1
  12. package/dist/client/generated/wire.d.ts +4 -0
  13. package/dist/client/generated/wire.js.map +1 -1
  14. package/dist/client/index.d.ts +3 -3
  15. package/dist/client/media/queue.d.ts +1 -1
  16. package/dist/client/media/queue.js +1 -1
  17. package/dist/client/media/queue.js.map +1 -1
  18. package/dist/client/taxonomy.d.ts +5 -1
  19. package/dist/client/taxonomy.js +7 -0
  20. package/dist/client/taxonomy.js.map +1 -1
  21. package/dist/client.js +2 -2
  22. package/dist/components/admin/media-item-panel.d.ts +27 -0
  23. package/dist/components/admin/media-item-panel.js +397 -0
  24. package/dist/components/admin/media-item-panel.js.map +1 -0
  25. package/dist/components/admin/poll-manager.d.ts +28 -0
  26. package/dist/components/admin/poll-manager.js +297 -0
  27. package/dist/components/admin/poll-manager.js.map +1 -0
  28. package/dist/components/admin/post-manager.d.ts +45 -0
  29. package/dist/components/admin/post-manager.js +602 -0
  30. package/dist/components/admin/post-manager.js.map +1 -0
  31. package/dist/components/admin/shell.d.ts +73 -0
  32. package/dist/components/admin/shell.js +148 -0
  33. package/dist/components/admin/shell.js.map +1 -0
  34. package/dist/components/admin/taxonomy-manager.d.ts +54 -0
  35. package/dist/components/admin/taxonomy-manager.js +976 -0
  36. package/dist/components/admin/taxonomy-manager.js.map +1 -0
  37. package/dist/components/admin/upload-queue.d.ts +23 -0
  38. package/dist/components/admin/upload-queue.js +365 -0
  39. package/dist/components/admin/upload-queue.js.map +1 -0
  40. package/dist/components/admin/user-comment-standing.d.ts +25 -0
  41. package/dist/components/admin/user-comment-standing.js +229 -0
  42. package/dist/components/admin/user-comment-standing.js.map +1 -0
  43. package/dist/components/social/bans.d.ts +5 -2
  44. package/dist/components/social/bans.js +132 -134
  45. package/dist/components/social/bans.js.map +1 -1
  46. package/dist/components/social/index.d.ts +1 -1
  47. package/dist/components/social/moderation.d.ts +11 -13
  48. package/dist/components/social/moderation.js +299 -218
  49. package/dist/components/social/moderation.js.map +1 -1
  50. package/dist/components/social/parts.d.ts +3 -2
  51. package/dist/components/social/parts.js +74 -48
  52. package/dist/components/social/parts.js.map +1 -1
  53. package/dist/components/social/poll-editor.js +1 -0
  54. package/dist/components/social/poll-editor.js.map +1 -1
  55. package/dist/editor/index.d.ts +1 -0
  56. package/dist/editor/rich-text-editor.d.ts +13 -0
  57. package/dist/editor/rich-text-editor.js +228 -0
  58. package/dist/editor/rich-text-editor.js.map +1 -0
  59. package/dist/editor.js +2 -0
  60. package/dist/index.d.ts +8 -0
  61. package/dist/index.js +15 -8
  62. package/dist/locales/admin/de.d.ts +2 -0
  63. package/dist/locales/admin/de.js +227 -0
  64. package/dist/locales/admin/de.js.map +1 -0
  65. package/dist/locales/admin/en.d.ts +222 -0
  66. package/dist/locales/admin/en.js +227 -0
  67. package/dist/locales/admin/en.js.map +1 -0
  68. package/dist/locales/admin/es.d.ts +2 -0
  69. package/dist/locales/admin/es.js +227 -0
  70. package/dist/locales/admin/es.js.map +1 -0
  71. package/dist/locales/admin/ja.d.ts +2 -0
  72. package/dist/locales/admin/ja.js +227 -0
  73. package/dist/locales/admin/ja.js.map +1 -0
  74. package/dist/locales/admin/ko.d.ts +2 -0
  75. package/dist/locales/admin/ko.js +227 -0
  76. package/dist/locales/admin/ko.js.map +1 -0
  77. package/dist/locales/admin/zh.d.ts +2 -0
  78. package/dist/locales/admin/zh.js +227 -0
  79. package/dist/locales/admin/zh.js.map +1 -0
  80. package/dist/locales/de.js +5 -3
  81. package/dist/locales/de.js.map +1 -1
  82. package/dist/locales/en.d.ts +227 -0
  83. package/dist/locales/en.js +5 -3
  84. package/dist/locales/en.js.map +1 -1
  85. package/dist/locales/es.js +5 -3
  86. package/dist/locales/es.js.map +1 -1
  87. package/dist/locales/ja.js +5 -3
  88. package/dist/locales/ja.js.map +1 -1
  89. package/dist/locales/ko.js +5 -3
  90. package/dist/locales/ko.js.map +1 -1
  91. package/dist/locales/social/de.js +8 -1
  92. package/dist/locales/social/de.js.map +1 -1
  93. package/dist/locales/social/en.d.ts +7 -0
  94. package/dist/locales/social/en.js +8 -1
  95. package/dist/locales/social/en.js.map +1 -1
  96. package/dist/locales/social/es.js +8 -1
  97. package/dist/locales/social/es.js.map +1 -1
  98. package/dist/locales/social/ja.js +8 -1
  99. package/dist/locales/social/ja.js.map +1 -1
  100. package/dist/locales/social/ko.js +8 -1
  101. package/dist/locales/social/ko.js.map +1 -1
  102. package/dist/locales/social/zh.js +8 -1
  103. package/dist/locales/social/zh.js.map +1 -1
  104. package/dist/locales/zh.js +5 -3
  105. package/dist/locales/zh.js.map +1 -1
  106. package/dist/provider.d.ts +2 -0
  107. package/dist/provider.js +23 -19
  108. package/dist/provider.js.map +1 -1
  109. package/dist/react/admin.d.ts +55 -0
  110. package/dist/react/admin.js +97 -0
  111. package/dist/react/admin.js.map +1 -0
  112. package/dist/react/comments.d.ts +18 -2
  113. package/dist/react/comments.js +24 -8
  114. package/dist/react/comments.js.map +1 -1
  115. package/dist/react/context.d.ts +7 -1
  116. package/dist/react/context.js +6 -1
  117. package/dist/react/context.js.map +1 -1
  118. package/dist/react/folder.js.map +1 -1
  119. package/dist/react/index.d.ts +4 -3
  120. package/dist/react/polls.js +88 -87
  121. package/dist/react/polls.js.map +1 -1
  122. package/dist/react/posts.js +123 -122
  123. package/dist/react/posts.js.map +1 -1
  124. package/dist/react/resources.js +3 -0
  125. package/dist/react/resources.js.map +1 -1
  126. package/dist/react/upload.d.ts +10 -10
  127. package/dist/react/upload.js +1 -1
  128. package/dist/react/upload.js.map +1 -1
  129. package/dist/react/use-resource.d.ts +16 -0
  130. package/dist/react/use-resource.js +20 -1
  131. package/dist/react/use-resource.js.map +1 -1
  132. package/dist/react.js +21 -20
  133. package/dist/styles.css +1 -1
  134. package/package.json +37 -2
@@ -0,0 +1,976 @@
1
+ import { toContentKitError as e } from "../../client/errors.js";
2
+ import { useMessages as t } from "../../i18n/context.js";
3
+ import { useErrorReporter as n } from "../../react/context.js";
4
+ import { usePublicImage as r } from "../../react/public.js";
5
+ import { Button as i } from "../../ui/button.js";
6
+ import { CoverUpload as a } from "../slot-upload.js";
7
+ import { keyOf as o, useContentScope as s, useResource as c } from "../../react/use-resource.js";
8
+ import { Badge as l } from "../../ui/badge.js";
9
+ import { Input as u } from "../../ui/input.js";
10
+ import { Label as d } from "../../ui/label.js";
11
+ import { Select as f, SelectContent as p, SelectItem as m, SelectTrigger as h, SelectValue as g } from "../../ui/select.js";
12
+ import { Skeleton as _ } from "../../ui/skeleton.js";
13
+ import { ErrorLine as v, RelativeTime as y, contentError as b, useAction as x } from "../social/parts.js";
14
+ import { AdminRoot as S, LoadFailed as C, NoAccess as w, Pager as T, Rows as E, pageOf as D, useConfirm as O } from "./shell.js";
15
+ import { useAdminLocation as k, useFlowClient as A, useStaffAccess as j } from "../../react/admin.js";
16
+ import { Tabs as M, TabsList as N, TabsTrigger as P } from "../../ui/tabs.js";
17
+ import { useEffect as F, useId as I, useMemo as L, useRef as R, useState as z } from "react";
18
+ import { Fragment as B, jsx as V, jsxs as H } from "react/jsx-runtime";
19
+ //#region src/components/admin/taxonomy-manager.tsx
20
+ function U(e = {}) {
21
+ return j(["taxonomy"], e);
22
+ }
23
+ var W = (e) => (e ?? []).map((e) => typeof e == "string" ? {
24
+ value: e,
25
+ label: e
26
+ } : e), G = [
27
+ "name",
28
+ "count",
29
+ "created",
30
+ "updated",
31
+ "oldest"
32
+ ], K = [
33
+ "active",
34
+ "deleted",
35
+ "merged"
36
+ ];
37
+ function q(e) {
38
+ return e.normalize("NFKD").replace(/[̀-ͯ]/g, "").toLowerCase().trim().replace(/[\s/]+/g, "-").replace(/[^\p{L}\p{N}-]+/gu, "").replace(/-+/g, "-").replace(/^-|-$/g, "").slice(0, 200);
39
+ }
40
+ function J({ client: e, baseUrl: t, auth: n, guard: r, appearance: i, className: a, language: o, messages: s, ...c }) {
41
+ let l = A({
42
+ client: e,
43
+ baseUrl: t,
44
+ auth: n
45
+ });
46
+ return /* @__PURE__ */ V(S, {
47
+ flow: "taxonomy-manager",
48
+ appearance: i,
49
+ className: a,
50
+ language: o,
51
+ messages: s,
52
+ guard: r,
53
+ children: /* @__PURE__ */ V(ee, {
54
+ ...c,
55
+ client: l
56
+ })
57
+ });
58
+ }
59
+ function ee({ basePath: e, navigation: n, ...r }) {
60
+ let { t: i } = t(), a = k(e, n), o = U({ client: r.client });
61
+ if (o.loading) return /* @__PURE__ */ V(E, {});
62
+ if (!o.allowed.taxonomy) return /* @__PURE__ */ V(w, { children: i("taxonomyManager.noAccess") });
63
+ if (!r.kinds.length) return null;
64
+ let [s, c] = a.view.split("/"), l = r.kinds.find((e) => e.kind === s) ?? r.kinds[0], u = {
65
+ ...r,
66
+ loc: a,
67
+ kind: l,
68
+ lang: W(r.languages)[0]?.value ?? "en"
69
+ };
70
+ return /* @__PURE__ */ H(B, { children: [r.kinds.length > 1 && /* @__PURE__ */ V(M, {
71
+ value: l.kind,
72
+ onValueChange: (e) => a.go(String(e)),
73
+ children: /* @__PURE__ */ V(N, { children: r.kinds.map((e) => /* @__PURE__ */ V(P, {
74
+ value: e.kind,
75
+ children: e.label
76
+ }, e.kind)) })
77
+ }), c ? c === "new" ? /* @__PURE__ */ V(Y, { ...u }, l.kind) : /* @__PURE__ */ V(X, {
78
+ ...u,
79
+ id: c
80
+ }, c) : /* @__PURE__ */ V(te, { ...u }, l.kind)] });
81
+ }
82
+ function te({ loc: e, kind: n, client: r, languages: a, contentKind: _, pageSize: v = 25, lang: b }) {
83
+ let x = t(), { t: S } = x, w = I(), O = W(a), k = e.query.get("q") ?? "", A = e.query.get("state") ?? "", j = K.includes(A) ? A : "active", M = e.query.get("language") || b, N = Math.max(0, Number(e.query.get("min_count")) || 0), P = e.query.get("sort") ?? "", L = G.includes(P) ? P : "name", R = D(e.query), B = {
84
+ q: k,
85
+ state: j === "active" ? void 0 : j,
86
+ language: M === b ? void 0 : M,
87
+ min_count: N || void 0,
88
+ sort: L === "name" ? void 0 : L
89
+ }, U = (t) => e.go(n.kind, {
90
+ ...B,
91
+ ...t
92
+ }), [q, J] = z(k);
93
+ F(() => J(k), [k]);
94
+ let { store: ee, scope: te } = s(r), Y = (R - 1) * v, X = c(ee, o("taxonomy-nodes", te, n.kind, k, j, M, N, L, _, Y, v), { type: "taxonomy-nodes" }, (e) => r.taxonomy.nodes({
95
+ kind: n.kind,
96
+ q: k || void 0,
97
+ state: [j],
98
+ language: M,
99
+ min_count: N || void 0,
100
+ sort: L,
101
+ content_kind: _,
102
+ offset: Y,
103
+ limit: v
104
+ }, e)), Z = X.data?.nodes ?? [], Q = X.data?.total ?? 0, $ = X.loading || !X.loaded;
105
+ return /* @__PURE__ */ H("div", {
106
+ className: "grid gap-4",
107
+ children: [
108
+ /* @__PURE__ */ H("div", {
109
+ className: "flex flex-wrap items-center justify-between gap-2",
110
+ children: [/* @__PURE__ */ V("h2", {
111
+ className: "text-base font-semibold",
112
+ children: n.label
113
+ }), /* @__PURE__ */ V(i, {
114
+ size: "sm",
115
+ onClick: () => e.go(`${n.kind}/new`),
116
+ children: S("taxonomyManager.new")
117
+ })]
118
+ }),
119
+ /* @__PURE__ */ H("div", {
120
+ className: "grid gap-2 sm:grid-cols-[minmax(0,1fr)_auto]",
121
+ children: [/* @__PURE__ */ H("form", {
122
+ className: "flex gap-2",
123
+ role: "search",
124
+ onSubmit: (e) => {
125
+ e.preventDefault(), U({ q: q.trim() });
126
+ },
127
+ children: [
128
+ /* @__PURE__ */ V(d, {
129
+ htmlFor: `${w}-q`,
130
+ className: "sr-only",
131
+ children: S("taxonomyManager.search")
132
+ }),
133
+ /* @__PURE__ */ V(u, {
134
+ id: `${w}-q`,
135
+ className: "h-8",
136
+ type: "search",
137
+ value: q,
138
+ placeholder: S("taxonomyManager.search"),
139
+ onChange: (e) => J(e.target.value)
140
+ }),
141
+ /* @__PURE__ */ V(i, {
142
+ type: "submit",
143
+ size: "sm",
144
+ variant: "outline",
145
+ children: S("moderation.filter")
146
+ })
147
+ ]
148
+ }), /* @__PURE__ */ H("div", {
149
+ className: "flex flex-wrap gap-2",
150
+ children: [
151
+ /* @__PURE__ */ H(f, {
152
+ value: j,
153
+ onValueChange: (e) => U({ state: e === "active" ? void 0 : String(e) }),
154
+ children: [/* @__PURE__ */ V(h, {
155
+ size: "sm",
156
+ "aria-label": S("taxonomyManager.state"),
157
+ children: /* @__PURE__ */ V(g, { children: (e) => S(`taxonomyManager.${e}`) })
158
+ }), /* @__PURE__ */ V(p, { children: K.map((e) => /* @__PURE__ */ V(m, {
159
+ value: e,
160
+ children: S(`taxonomyManager.${e}`)
161
+ }, e)) })]
162
+ }),
163
+ O.length > 1 && /* @__PURE__ */ H(f, {
164
+ value: M,
165
+ onValueChange: (e) => U({ language: e === b ? void 0 : String(e) }),
166
+ children: [/* @__PURE__ */ V(h, {
167
+ size: "sm",
168
+ "aria-label": S("taxonomyManager.language"),
169
+ children: /* @__PURE__ */ V(g, { children: (e) => O.find((t) => t.value === e)?.label ?? e })
170
+ }), /* @__PURE__ */ V(p, { children: O.map((e) => /* @__PURE__ */ V(m, {
171
+ value: e.value,
172
+ children: e.label
173
+ }, e.value)) })]
174
+ }),
175
+ /* @__PURE__ */ H(f, {
176
+ value: L,
177
+ onValueChange: (e) => U({ sort: e === "name" ? void 0 : String(e) }),
178
+ children: [/* @__PURE__ */ V(h, {
179
+ size: "sm",
180
+ "aria-label": S("taxonomyManager.sort"),
181
+ children: /* @__PURE__ */ V(g, { children: (e) => S(`taxonomyManager.sort_${e}`) })
182
+ }), /* @__PURE__ */ V(p, { children: G.map((e) => /* @__PURE__ */ V(m, {
183
+ value: e,
184
+ children: S(`taxonomyManager.sort_${e}`)
185
+ }, e)) })]
186
+ }),
187
+ /* @__PURE__ */ H("div", {
188
+ className: "flex items-center gap-1.5",
189
+ children: [/* @__PURE__ */ V(d, {
190
+ htmlFor: `${w}-min`,
191
+ className: "text-xs text-muted-foreground",
192
+ children: S("taxonomyManager.minCount")
193
+ }), /* @__PURE__ */ V(u, {
194
+ id: `${w}-min`,
195
+ className: "h-8 w-20",
196
+ type: "number",
197
+ min: 0,
198
+ value: N || "",
199
+ onChange: (e) => U({ min_count: Number(e.target.value) || void 0 })
200
+ })]
201
+ })
202
+ ]
203
+ })]
204
+ }),
205
+ $ && !Z.length ? /* @__PURE__ */ V(E, {}) : X.error && !Z.length ? /* @__PURE__ */ V(C, {
206
+ error: X.error,
207
+ message: S("taxonomyManager.loadFailed"),
208
+ retry: X.reload
209
+ }) : Z.length ? /* @__PURE__ */ V("ul", {
210
+ className: "grid divide-y divide-border rounded-lg border border-border",
211
+ "aria-busy": $,
212
+ children: Z.map((t) => /* @__PURE__ */ H("li", {
213
+ className: "flex flex-wrap items-center gap-3 p-3",
214
+ "data-ckui": "node-row",
215
+ "data-state": t.state,
216
+ children: [/* @__PURE__ */ H("div", {
217
+ className: "grid min-w-0 flex-1 gap-0.5",
218
+ children: [/* @__PURE__ */ V("button", {
219
+ type: "button",
220
+ className: "text-left font-medium break-words hover:underline",
221
+ onClick: () => e.go(`${n.kind}/${t.taxonomy_id}`),
222
+ children: t.name || t.slug
223
+ }), /* @__PURE__ */ H("div", {
224
+ className: "flex flex-wrap items-center gap-x-2 gap-y-1 text-xs text-muted-foreground",
225
+ children: [
226
+ /* @__PURE__ */ V("span", { children: t.slug }),
227
+ t.state !== "active" && /* @__PURE__ */ V(l, {
228
+ variant: "outline",
229
+ children: S(`taxonomyManager.${t.state}`)
230
+ }),
231
+ /* @__PURE__ */ V(y, { at: t.updated_at })
232
+ ]
233
+ })]
234
+ }), /* @__PURE__ */ V("span", {
235
+ className: "text-sm tabular-nums text-muted-foreground",
236
+ title: S("taxonomyManager.count"),
237
+ children: t.count
238
+ })]
239
+ }, t.taxonomy_id))
240
+ }) : /* @__PURE__ */ V("p", {
241
+ className: "text-muted-foreground",
242
+ children: S("taxonomyManager.empty")
243
+ }),
244
+ Q > 0 && /* @__PURE__ */ V("p", {
245
+ className: "text-center text-xs text-muted-foreground",
246
+ children: x.plural("taxonomyManager.total", Q)
247
+ }),
248
+ /* @__PURE__ */ V(T, {
249
+ page: R,
250
+ hasNext: Y + Z.length < Q,
251
+ disabled: $,
252
+ onPage: (t) => e.go(n.kind, {
253
+ ...B,
254
+ page: t > 1 ? t : void 0
255
+ })
256
+ })
257
+ ]
258
+ });
259
+ }
260
+ function Y({ loc: e, kind: n, client: r, languages: a, lang: o, onError: s }) {
261
+ let c = t(), { t: l } = c, f = I(), p = W(a), [m, h] = z({}), [g, _] = z(""), [y, S] = z(!1), C = x("taxonomy.save", s), w = m[o] ?? "";
262
+ F(() => {
263
+ y || _(q(w));
264
+ }, [w, y]);
265
+ let T = p.length ? p : [{
266
+ value: o,
267
+ label: o
268
+ }], E = async () => {
269
+ let t = T.filter((e) => m[e.value]?.trim()).map((e) => ({
270
+ language: e.value,
271
+ kind: "name",
272
+ name: m[e.value].trim(),
273
+ source_revision: 0
274
+ })), i = await C.run(() => r.taxonomy.createNodes([{
275
+ kind: n.kind,
276
+ slug: g.trim(),
277
+ names: t,
278
+ source_revision: 0
279
+ }]));
280
+ i?.[0] && e.go(`${n.kind}/${i[0].taxonomy_id}`, void 0, { replace: !0 });
281
+ };
282
+ return /* @__PURE__ */ H("form", {
283
+ className: "grid gap-4",
284
+ "data-ckui": "node-create",
285
+ onSubmit: (e) => {
286
+ e.preventDefault(), E();
287
+ },
288
+ children: [
289
+ /* @__PURE__ */ V(i, {
290
+ type: "button",
291
+ variant: "ghost",
292
+ size: "sm",
293
+ className: "justify-self-start",
294
+ onClick: () => e.go(n.kind),
295
+ children: l("taxonomyManager.back", { kind: n.label })
296
+ }),
297
+ /* @__PURE__ */ V("h2", {
298
+ className: "text-base font-semibold",
299
+ children: l("taxonomyManager.newTitle", { kind: n.label })
300
+ }),
301
+ T.map((e, t) => /* @__PURE__ */ H("div", {
302
+ className: "grid gap-1.5",
303
+ children: [/* @__PURE__ */ V(d, {
304
+ htmlFor: `${f}-${e.value}`,
305
+ children: l("taxonomyManager.nameIn", { language: e.label })
306
+ }), /* @__PURE__ */ V(u, {
307
+ id: `${f}-${e.value}`,
308
+ required: t === 0,
309
+ value: m[e.value] ?? "",
310
+ onChange: (t) => h((n) => ({
311
+ ...n,
312
+ [e.value]: t.target.value
313
+ }))
314
+ })]
315
+ }, e.value)),
316
+ /* @__PURE__ */ H("div", {
317
+ className: "grid gap-1.5",
318
+ children: [/* @__PURE__ */ V(d, {
319
+ htmlFor: `${f}-slug`,
320
+ children: l("taxonomyManager.slug")
321
+ }), /* @__PURE__ */ V(u, {
322
+ id: `${f}-slug`,
323
+ required: !0,
324
+ value: g,
325
+ onChange: (e) => {
326
+ S(!0), _(e.target.value);
327
+ }
328
+ })]
329
+ }),
330
+ C.error && /* @__PURE__ */ V(v, { children: b(c, C.error) }),
331
+ /* @__PURE__ */ V(i, {
332
+ type: "submit",
333
+ className: "justify-self-start",
334
+ disabled: C.pending || !w.trim() || !g.trim(),
335
+ children: C.pending ? l("common.saving") : l("taxonomyManager.create")
336
+ })
337
+ ]
338
+ });
339
+ }
340
+ function X({ id: e, loc: n, kind: r, client: a, lang: u, ...d }) {
341
+ let { t: f } = t(), { store: p, scope: m } = s(a), h = c(p, o("taxonomy-node", m, e), {
342
+ type: "taxonomy-node",
343
+ id: e
344
+ }, (t) => a.taxonomy.node(e, t)), g = h.data, y = L(() => [...new Set((g?.edges ?? []).flatMap((e) => [e.from_taxonomy_id, e.to_taxonomy_id]).filter((t) => t !== e))].sort(), [g?.edges, e]), b = c(p, y.length ? o("taxonomy-partners", m, u, ...y) : null, { type: "taxonomy-partners" }, (e) => a.taxonomy.nodes({
345
+ id: y,
346
+ state: [
347
+ "active",
348
+ "merged",
349
+ "deleted"
350
+ ],
351
+ language: u,
352
+ limit: Math.min(500, y.length)
353
+ }, e)), S = L(() => new Map((b.data?.nodes ?? []).map((e) => [e.taxonomy_id, e])), [b.data]), w = x("taxonomy.save", d.onError), { confirm: T, dialog: E } = O(), D = /* @__PURE__ */ V(i, {
354
+ variant: "ghost",
355
+ size: "sm",
356
+ className: "justify-self-start",
357
+ onClick: () => n.go(r.kind),
358
+ children: f("taxonomyManager.back", { kind: r.label })
359
+ });
360
+ if (!g) return /* @__PURE__ */ H(B, { children: [D, h.error ? /* @__PURE__ */ V(C, {
361
+ error: h.error,
362
+ message: f("taxonomyManager.nodeLoadFailed"),
363
+ retry: h.reload
364
+ }) : /* @__PURE__ */ V(_, { className: "h-40 w-full" })] });
365
+ let k = (g.names.find((e) => e.kind === "name" && e.language === u) ?? g.names.find((e) => e.kind === "name"))?.name ?? g.slug, A = async (t) => {
366
+ (t !== "deleted" || await T({
367
+ title: f("taxonomyManager.deleteTitle", { name: k }),
368
+ description: f("taxonomyManager.deleteBody"),
369
+ confirm: f("taxonomyManager.delete")
370
+ })) && await w.run(() => a.taxonomy.updateNode(e, { state: t }));
371
+ };
372
+ return /* @__PURE__ */ H("div", {
373
+ className: "grid gap-5",
374
+ "data-ckui": "node-view",
375
+ "data-state": g.state,
376
+ children: [
377
+ D,
378
+ /* @__PURE__ */ H("div", {
379
+ className: "flex flex-wrap items-center gap-2",
380
+ children: [
381
+ /* @__PURE__ */ V("h2", {
382
+ className: "text-base font-semibold break-words",
383
+ children: k
384
+ }),
385
+ /* @__PURE__ */ V(l, {
386
+ variant: g.state === "active" ? "outline" : "secondary",
387
+ children: f(`taxonomyManager.${g.state}`)
388
+ }),
389
+ /* @__PURE__ */ H("div", {
390
+ className: "ms-auto flex flex-wrap gap-2",
391
+ children: [g.state === "active" && /* @__PURE__ */ V(ie, {
392
+ node: g,
393
+ title: k,
394
+ kind: r,
395
+ client: a,
396
+ loc: n,
397
+ lang: u,
398
+ onError: d.onError
399
+ }), g.state === "active" ? /* @__PURE__ */ V(i, {
400
+ size: "sm",
401
+ variant: "destructive",
402
+ disabled: w.pending,
403
+ onClick: () => void A("deleted"),
404
+ children: f("taxonomyManager.delete")
405
+ }) : g.state === "deleted" ? /* @__PURE__ */ V(i, {
406
+ size: "sm",
407
+ variant: "outline",
408
+ disabled: w.pending,
409
+ onClick: () => void A("active"),
410
+ children: f("taxonomyManager.restore")
411
+ }) : null]
412
+ })
413
+ ]
414
+ }),
415
+ g.state === "merged" && /* @__PURE__ */ V(re, {
416
+ node: g,
417
+ byId: S,
418
+ kind: r,
419
+ loc: n
420
+ }),
421
+ /* @__PURE__ */ V(v, { error: w.error }),
422
+ /* @__PURE__ */ V(Q, {
423
+ node: g,
424
+ client: a,
425
+ onError: d.onError
426
+ }),
427
+ /* @__PURE__ */ V($, {
428
+ node: g,
429
+ client: a,
430
+ languages: d.languages,
431
+ lang: u,
432
+ onError: d.onError
433
+ }),
434
+ d.renderFields && /* @__PURE__ */ V("section", {
435
+ "data-ckui": "node-fields",
436
+ children: d.renderFields(g)
437
+ }),
438
+ r.cover && /* @__PURE__ */ V(ne, {
439
+ node: g,
440
+ cover: r.cover,
441
+ client: a
442
+ }),
443
+ /* @__PURE__ */ V(oe, {
444
+ node: g,
445
+ kind: r,
446
+ kinds: d.kinds,
447
+ byId: S,
448
+ client: a,
449
+ loc: n,
450
+ lang: u,
451
+ onError: d.onError
452
+ }),
453
+ /* @__PURE__ */ V(se, { node: g }),
454
+ /* @__PURE__ */ V(ce, {
455
+ id: e,
456
+ client: a,
457
+ renderContent: d.renderContent
458
+ }),
459
+ E
460
+ ]
461
+ });
462
+ }
463
+ function Z({ title: e, children: t, ckui: n }) {
464
+ return /* @__PURE__ */ H("section", {
465
+ className: "grid gap-2",
466
+ "data-ckui": n,
467
+ children: [/* @__PURE__ */ V("h3", {
468
+ className: "font-medium",
469
+ children: e
470
+ }), t]
471
+ });
472
+ }
473
+ function Q({ node: e, client: n, onError: r }) {
474
+ let { t: a } = t(), o = I(), [s, c] = z(e.slug);
475
+ F(() => c(e.slug), [e.slug]);
476
+ let l = x("taxonomy.save", r);
477
+ return /* @__PURE__ */ H("form", {
478
+ className: "flex flex-wrap items-end gap-2",
479
+ onSubmit: (t) => {
480
+ t.preventDefault(), l.run(() => n.taxonomy.updateNode(e.taxonomy_id, { slug: s.trim() }));
481
+ },
482
+ children: [
483
+ /* @__PURE__ */ H("div", {
484
+ className: "grid min-w-48 flex-1 gap-1.5",
485
+ children: [/* @__PURE__ */ V(d, {
486
+ htmlFor: `${o}-slug`,
487
+ children: a("taxonomyManager.slug")
488
+ }), /* @__PURE__ */ V(u, {
489
+ id: `${o}-slug`,
490
+ className: "h-8",
491
+ value: s,
492
+ onChange: (e) => c(e.target.value)
493
+ })]
494
+ }),
495
+ /* @__PURE__ */ V(i, {
496
+ type: "submit",
497
+ size: "sm",
498
+ variant: "outline",
499
+ disabled: l.pending || !s.trim() || s.trim() === e.slug,
500
+ children: a("common.save")
501
+ }),
502
+ /* @__PURE__ */ V(v, {
503
+ error: l.error,
504
+ className: "basis-full"
505
+ })
506
+ ]
507
+ });
508
+ }
509
+ function $({ node: e, client: n, languages: r, lang: a, onError: o }) {
510
+ let { t: s } = t(), c = I(), _ = W(r), y = _.length ? _ : [{
511
+ value: a,
512
+ label: a
513
+ }], [b, S] = z(y[0].value), [C, w] = z("alias"), [T, E] = z(""), D = x("taxonomy.save", o), O = e.taxonomy_id, k = (e) => y.find((t) => t.value === e)?.label ?? e, A = [...e.names].sort((e, t) => e.language.localeCompare(t.language) || (e.kind === t.kind ? e.name.localeCompare(t.name) : e.kind === "name" ? -1 : 1));
514
+ return /* @__PURE__ */ H(Z, {
515
+ title: s("taxonomyManager.names"),
516
+ ckui: "node-names",
517
+ children: [
518
+ A.length ? /* @__PURE__ */ V("ul", {
519
+ className: "grid divide-y divide-border rounded-lg border border-border",
520
+ children: A.map((e) => /* @__PURE__ */ H("li", {
521
+ className: "flex flex-wrap items-center gap-2 p-2.5",
522
+ "data-ckui": "node-name",
523
+ "data-kind": e.kind,
524
+ children: [
525
+ /* @__PURE__ */ V(l, {
526
+ variant: "outline",
527
+ children: k(e.language)
528
+ }),
529
+ /* @__PURE__ */ V("span", {
530
+ className: "min-w-0 flex-1 break-words",
531
+ children: e.name
532
+ }),
533
+ /* @__PURE__ */ V("span", {
534
+ className: "text-xs text-muted-foreground",
535
+ children: s(e.kind === "name" ? "taxonomyManager.canonical" : "taxonomyManager.alias")
536
+ }),
537
+ e.kind === "alias" && /* @__PURE__ */ V(i, {
538
+ size: "xs",
539
+ variant: "ghost",
540
+ disabled: D.pending,
541
+ onClick: () => void D.run(() => n.taxonomy.names(O, "add", [{
542
+ ...e,
543
+ kind: "name"
544
+ }])),
545
+ children: s("taxonomyManager.makeCanonical")
546
+ }),
547
+ /* @__PURE__ */ V(i, {
548
+ size: "xs",
549
+ variant: "ghost",
550
+ disabled: D.pending,
551
+ "aria-label": s("taxonomyManager.removeName", { name: e.name }),
552
+ onClick: () => void D.run(() => n.taxonomy.names(O, "remove", [e])),
553
+ children: s("common.remove")
554
+ })
555
+ ]
556
+ }, `${e.language}:${e.name}`))
557
+ }) : /* @__PURE__ */ V("p", {
558
+ className: "text-muted-foreground",
559
+ children: s("taxonomyManager.noNames")
560
+ }),
561
+ /* @__PURE__ */ H("form", {
562
+ className: "flex flex-wrap items-end gap-2",
563
+ onSubmit: (e) => {
564
+ e.preventDefault();
565
+ let t = T.trim();
566
+ t && D.run(() => n.taxonomy.names(O, "add", [{
567
+ language: b,
568
+ kind: C,
569
+ name: t,
570
+ source_revision: 0
571
+ }])).then((e) => e && E(""));
572
+ },
573
+ children: [
574
+ y.length > 1 && /* @__PURE__ */ H(f, {
575
+ value: b,
576
+ onValueChange: (e) => S(String(e)),
577
+ children: [/* @__PURE__ */ V(h, {
578
+ size: "sm",
579
+ "aria-label": s("taxonomyManager.language"),
580
+ children: /* @__PURE__ */ V(g, { children: (e) => k(e) })
581
+ }), /* @__PURE__ */ V(p, { children: y.map((e) => /* @__PURE__ */ V(m, {
582
+ value: e.value,
583
+ children: e.label
584
+ }, e.value)) })]
585
+ }),
586
+ /* @__PURE__ */ H(f, {
587
+ value: C,
588
+ onValueChange: (e) => w(e),
589
+ children: [/* @__PURE__ */ V(h, {
590
+ size: "sm",
591
+ "aria-label": s("taxonomyManager.nameKind"),
592
+ children: /* @__PURE__ */ V(g, { children: (e) => s(e === "name" ? "taxonomyManager.canonical" : "taxonomyManager.alias") })
593
+ }), /* @__PURE__ */ H(p, { children: [/* @__PURE__ */ V(m, {
594
+ value: "alias",
595
+ children: s("taxonomyManager.alias")
596
+ }), /* @__PURE__ */ V(m, {
597
+ value: "name",
598
+ children: s("taxonomyManager.canonical")
599
+ })] })]
600
+ }),
601
+ /* @__PURE__ */ V(d, {
602
+ htmlFor: `${c}-name`,
603
+ className: "sr-only",
604
+ children: s("taxonomyManager.newName")
605
+ }),
606
+ /* @__PURE__ */ V(u, {
607
+ id: `${c}-name`,
608
+ className: "h-8 min-w-40 flex-1",
609
+ value: T,
610
+ placeholder: s("taxonomyManager.newName"),
611
+ onChange: (e) => E(e.target.value)
612
+ }),
613
+ /* @__PURE__ */ V(i, {
614
+ type: "submit",
615
+ size: "sm",
616
+ variant: "outline",
617
+ disabled: D.pending || !T.trim(),
618
+ children: s("taxonomyManager.addName")
619
+ })
620
+ ]
621
+ }),
622
+ /* @__PURE__ */ V(v, { error: D.error })
623
+ ]
624
+ });
625
+ }
626
+ function ne({ node: e, cover: n, client: i }) {
627
+ let { t: o } = t(), s = {
628
+ kind: n.kind,
629
+ id: e.taxonomy_id
630
+ }, { image: c } = r(n.kind, e.taxonomy_id, n.preset ?? "cover", { client: i });
631
+ return /* @__PURE__ */ V("section", {
632
+ className: "grid max-w-xl gap-2",
633
+ "data-ckui": "node-cover",
634
+ children: /* @__PURE__ */ V(a, {
635
+ item: s,
636
+ path: n.path ?? "cover",
637
+ image: c,
638
+ client: i,
639
+ removable: !0,
640
+ label: o("taxonomyManager.cover")
641
+ })
642
+ });
643
+ }
644
+ function re({ node: e, byId: n, kind: r, loc: i }) {
645
+ let { t: a } = t(), o = e.edges.find((t) => t.relation === "alias_of" && t.from_taxonomy_id === e.taxonomy_id)?.to_taxonomy_id;
646
+ if (!o) return null;
647
+ let s = n.get(o);
648
+ return /* @__PURE__ */ H("p", {
649
+ className: "text-muted-foreground",
650
+ "data-ckui": "merged-into",
651
+ children: [
652
+ a("taxonomyManager.mergedInto"),
653
+ " ",
654
+ /* @__PURE__ */ V("button", {
655
+ type: "button",
656
+ className: "font-medium text-foreground hover:underline",
657
+ onClick: () => i.go(`${s?.kind ?? r.kind}/${o}`),
658
+ children: s?.name || s?.slug || o
659
+ })
660
+ ]
661
+ });
662
+ }
663
+ function ie({ node: e, title: n, kind: r, client: a, loc: o, lang: s, onError: c }) {
664
+ let { t: l } = t(), [u, d] = z(!1), f = x("taxonomy.save", c), { confirm: p, dialog: m } = O(), [h, g] = z(null), _ = async (t) => {
665
+ if (d(!1), !await p({
666
+ title: l("taxonomyManager.mergeTitle", {
667
+ from: n,
668
+ into: t.name || t.slug
669
+ }),
670
+ description: l("taxonomyManager.mergeBody"),
671
+ confirm: l("taxonomyManager.merge"),
672
+ typed: l("taxonomyManager.mergeWord")
673
+ })) return;
674
+ let i = await f.run(() => a.taxonomy.merge(e.taxonomy_id, t.taxonomy_id));
675
+ i && (g(i), o.go(`${r.kind}/${t.taxonomy_id}`));
676
+ };
677
+ return /* @__PURE__ */ H(B, { children: [
678
+ u ? /* @__PURE__ */ H("div", {
679
+ className: "flex flex-wrap items-center gap-2",
680
+ "data-ckui": "merge-picker",
681
+ children: [/* @__PURE__ */ V(ae, {
682
+ kind: r.kind,
683
+ exclude: e.taxonomy_id,
684
+ client: a,
685
+ lang: s,
686
+ label: l("taxonomyManager.mergeInto"),
687
+ onPick: (e) => void _(e)
688
+ }), /* @__PURE__ */ V(i, {
689
+ size: "sm",
690
+ variant: "ghost",
691
+ onClick: () => d(!1),
692
+ children: l("common.cancel")
693
+ })]
694
+ }) : /* @__PURE__ */ V(i, {
695
+ size: "sm",
696
+ variant: "outline",
697
+ disabled: f.pending,
698
+ onClick: () => d(!0),
699
+ children: l("taxonomyManager.merge")
700
+ }),
701
+ f.error && /* @__PURE__ */ V(v, {
702
+ error: f.error,
703
+ className: "basis-full"
704
+ }),
705
+ h && /* @__PURE__ */ V("p", {
706
+ role: "status",
707
+ className: "sr-only",
708
+ children: l("taxonomyManager.mergeDone", { count: h.assignments_moved })
709
+ }),
710
+ m
711
+ ] });
712
+ }
713
+ function ae({ kind: n, exclude: r, client: i, lang: a, label: o, onPick: s }) {
714
+ let { t: c } = t(), l = I(), [d, f] = z(""), [p, m] = z([]), [h, g] = z(0), [_, y] = z(null), b = R(0);
715
+ F(() => {
716
+ let t = d.trim(), o = ++b.current;
717
+ if (!t) {
718
+ m([]);
719
+ return;
720
+ }
721
+ let s = new AbortController(), c = setTimeout(() => {
722
+ i.taxonomy.nodes({
723
+ kind: n,
724
+ q: t,
725
+ language: a,
726
+ limit: 8,
727
+ sort: "name"
728
+ }, s.signal).then((e) => {
729
+ o === b.current && (y(null), m(e.nodes.filter((e) => e.taxonomy_id !== r)), g(0));
730
+ }, (t) => {
731
+ let n = e(t);
732
+ n.code !== "aborted" && o === b.current && y(n);
733
+ });
734
+ }, 200);
735
+ return () => {
736
+ clearTimeout(c), s.abort();
737
+ };
738
+ }, [
739
+ d,
740
+ n,
741
+ a,
742
+ r,
743
+ i
744
+ ]);
745
+ let x = p.length > 0;
746
+ return /* @__PURE__ */ H("div", {
747
+ className: "relative grid min-w-56 flex-1 gap-1",
748
+ "data-ckui": "node-picker",
749
+ children: [
750
+ /* @__PURE__ */ V(u, {
751
+ role: "combobox",
752
+ "aria-label": o,
753
+ "aria-expanded": x,
754
+ "aria-controls": `${l}-list`,
755
+ "aria-activedescendant": x ? `${l}-${h}` : void 0,
756
+ autoComplete: "off",
757
+ className: "h-8",
758
+ value: d,
759
+ placeholder: c("taxonomyManager.searchNodes"),
760
+ autoFocus: !0,
761
+ onChange: (e) => f(e.target.value),
762
+ onKeyDown: (e) => {
763
+ x && (e.key === "ArrowDown" ? (e.preventDefault(), g((e) => Math.min(p.length - 1, e + 1))) : e.key === "ArrowUp" ? (e.preventDefault(), g((e) => Math.max(0, e - 1))) : e.key === "Enter" ? (e.preventDefault(), s(p[h])) : e.key === "Escape" && m([]));
764
+ }
765
+ }),
766
+ x && /* @__PURE__ */ V("ul", {
767
+ id: `${l}-list`,
768
+ role: "listbox",
769
+ "aria-label": o,
770
+ className: "absolute top-full z-10 mt-1 grid w-full overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md",
771
+ children: p.map((e, t) => /* @__PURE__ */ H("li", {
772
+ id: `${l}-${t}`,
773
+ role: "option",
774
+ "aria-selected": t === h,
775
+ className: `cursor-pointer px-3 py-1.5 ${t === h ? "bg-accent text-accent-foreground" : ""}`,
776
+ onMouseEnter: () => g(t),
777
+ onMouseDown: (t) => {
778
+ t.preventDefault(), s(e);
779
+ },
780
+ children: [
781
+ e.name || e.slug,
782
+ " ",
783
+ /* @__PURE__ */ V("span", {
784
+ className: "text-xs text-muted-foreground",
785
+ children: e.slug
786
+ })
787
+ ]
788
+ }, e.taxonomy_id))
789
+ }),
790
+ _ && /* @__PURE__ */ V(v, { error: _ })
791
+ ]
792
+ });
793
+ }
794
+ function oe({ node: e, kind: n, kinds: r, byId: a, client: o, loc: s, lang: c, onError: l }) {
795
+ let { t: u } = t(), d = x("taxonomy.save", l), [f, p] = z(null), m = e.taxonomy_id, h = e.edges.filter((e) => e.from_taxonomy_id === m && e.relation !== "alias_of"), g = e.edges.filter((e) => e.to_taxonomy_id === m && e.relation !== "alias_of"), _ = n.relations ?? [], y = r.flatMap((e) => (e.relations ?? []).filter((e) => e.to === n.kind).map((t) => ({
796
+ ...t,
797
+ from: e
798
+ }))), b = (e, t) => {
799
+ let n = a.get(e);
800
+ return /* @__PURE__ */ V("button", {
801
+ type: "button",
802
+ className: "font-medium hover:underline",
803
+ onClick: () => s.go(`${n?.kind ?? t}/${e}`),
804
+ children: n?.name || n?.slug || e
805
+ });
806
+ };
807
+ return !_.length && !y.length && !h.length && !g.length ? null : /* @__PURE__ */ H(Z, {
808
+ title: u("taxonomyManager.relations"),
809
+ ckui: "node-relations",
810
+ children: [
811
+ _.map((e, t) => {
812
+ let n = h.filter((t) => t.relation === e.relation && (a.get(t.to_taxonomy_id)?.kind ?? e.to) === e.to);
813
+ return /* @__PURE__ */ H("div", {
814
+ className: "grid gap-1.5",
815
+ "data-ckui": "relation",
816
+ "data-relation": e.relation,
817
+ children: [/* @__PURE__ */ H("div", {
818
+ className: "flex flex-wrap items-center gap-2",
819
+ children: [
820
+ /* @__PURE__ */ V("span", {
821
+ className: "text-sm text-muted-foreground",
822
+ children: e.label
823
+ }),
824
+ n.map((t) => /* @__PURE__ */ H("span", {
825
+ className: "inline-flex items-center gap-1 rounded-md border border-border px-2 py-0.5",
826
+ "data-ckui": "edge",
827
+ children: [b(t.to_taxonomy_id, e.to), /* @__PURE__ */ V("button", {
828
+ type: "button",
829
+ className: "text-muted-foreground hover:text-destructive",
830
+ "aria-label": u("taxonomyManager.removeRelation", { name: a.get(t.to_taxonomy_id)?.name ?? t.to_taxonomy_id }),
831
+ disabled: d.pending,
832
+ onClick: () => void d.run(() => o.taxonomy.edges("remove", [t])),
833
+ children: "×"
834
+ })]
835
+ }, t.to_taxonomy_id)),
836
+ f !== t && /* @__PURE__ */ V(i, {
837
+ size: "xs",
838
+ variant: "ghost",
839
+ onClick: () => p(t),
840
+ children: u("taxonomyManager.addRelation", { relation: e.label })
841
+ })
842
+ ]
843
+ }), f === t && /* @__PURE__ */ H("div", {
844
+ className: "flex flex-wrap items-center gap-2",
845
+ children: [/* @__PURE__ */ V(ae, {
846
+ kind: e.to,
847
+ exclude: m,
848
+ client: o,
849
+ lang: c,
850
+ label: e.label,
851
+ onPick: (t) => {
852
+ p(null), d.run(() => o.taxonomy.edges("add", [{
853
+ from_taxonomy_id: m,
854
+ relation: e.relation,
855
+ to_taxonomy_id: t.taxonomy_id,
856
+ source_revision: 0
857
+ }]));
858
+ }
859
+ }), /* @__PURE__ */ V(i, {
860
+ size: "sm",
861
+ variant: "ghost",
862
+ onClick: () => p(null),
863
+ children: u("common.cancel")
864
+ })]
865
+ })]
866
+ }, `${e.relation}:${e.to}`);
867
+ }),
868
+ y.map((e) => {
869
+ let t = g.filter((t) => t.relation === e.relation && (a.get(t.from_taxonomy_id)?.kind ?? e.from.kind) === e.from.kind);
870
+ return t.length ? /* @__PURE__ */ H("div", {
871
+ className: "flex flex-wrap items-center gap-2",
872
+ "data-ckui": "relation",
873
+ "data-relation": `inverse:${e.relation}`,
874
+ children: [/* @__PURE__ */ V("span", {
875
+ className: "text-sm text-muted-foreground",
876
+ children: e.inverseLabel ?? e.from.label
877
+ }), t.map((t) => /* @__PURE__ */ V("span", {
878
+ className: "rounded-md border border-border px-2 py-0.5",
879
+ "data-ckui": "edge",
880
+ children: b(t.from_taxonomy_id, e.from.kind)
881
+ }, t.from_taxonomy_id))]
882
+ }, `in:${e.relation}:${e.from.kind}`) : null;
883
+ }),
884
+ /* @__PURE__ */ V(v, { error: d.error })
885
+ ]
886
+ });
887
+ }
888
+ function se({ node: e }) {
889
+ let { t: n } = t();
890
+ return /* @__PURE__ */ V(Z, {
891
+ title: n("taxonomyManager.counts"),
892
+ ckui: "node-counts",
893
+ children: e.counts.length ? /* @__PURE__ */ V("ul", {
894
+ className: "flex flex-wrap gap-2",
895
+ children: e.counts.map((e) => /* @__PURE__ */ H("li", {
896
+ className: "rounded-md border border-border px-2 py-1 text-xs",
897
+ children: [
898
+ e.content_kind,
899
+ " · ",
900
+ e.language,
901
+ ": ",
902
+ /* @__PURE__ */ V("span", {
903
+ className: "tabular-nums font-medium",
904
+ children: e.count
905
+ })
906
+ ]
907
+ }, `${e.content_kind}:${e.language}`))
908
+ }) : /* @__PURE__ */ V("p", {
909
+ className: "text-muted-foreground",
910
+ children: n("taxonomyManager.noCounts")
911
+ })
912
+ });
913
+ }
914
+ function ce({ id: r, client: a, renderContent: o }) {
915
+ let { t: s } = t(), c = n(), [u, d] = z([]), [f, p] = z(!0), [m, h] = z(null), g = async (t) => {
916
+ p(!0), h(null);
917
+ try {
918
+ let e = await a.taxonomy.nodeAssignments(r, {
919
+ cursor: t,
920
+ limit: 25
921
+ });
922
+ d((n) => t ? [...n, e] : [e]);
923
+ } catch (t) {
924
+ let n = e(t);
925
+ h(n), c(n, "taxonomy.load");
926
+ } finally {
927
+ p(!1);
928
+ }
929
+ };
930
+ F(() => void g(), [r, a]);
931
+ let _ = u.flatMap((e) => e.assignments), v = u.at(-1)?.next_cursor;
932
+ return /* @__PURE__ */ H(Z, {
933
+ title: s("taxonomyManager.contents"),
934
+ ckui: "node-contents",
935
+ children: [f && !_.length ? /* @__PURE__ */ V(E, { count: 2 }) : m && !_.length ? /* @__PURE__ */ V(C, {
936
+ error: m,
937
+ message: s("taxonomyManager.contentsLoadFailed"),
938
+ retry: () => void g()
939
+ }) : _.length ? /* @__PURE__ */ V("ul", {
940
+ className: "grid divide-y divide-border rounded-lg border border-border",
941
+ children: _.map((e) => /* @__PURE__ */ H("li", {
942
+ className: "flex flex-wrap items-center gap-2 p-2.5",
943
+ "data-ckui": "node-content",
944
+ "data-state": e.state,
945
+ children: [
946
+ /* @__PURE__ */ V("span", {
947
+ className: "min-w-0 flex-1 break-words",
948
+ children: o ? o(e, e) : `${e.content_kind}/${e.content_id}${e.content_version_id ? ` (${e.content_version_id})` : ""}`
949
+ }),
950
+ /* @__PURE__ */ V("span", {
951
+ className: "text-xs text-muted-foreground",
952
+ children: e.relation
953
+ }),
954
+ e.state === "proposed" && /* @__PURE__ */ V(l, {
955
+ variant: "secondary",
956
+ children: s("taxonomyManager.proposed")
957
+ })
958
+ ]
959
+ }, `${e.content_kind}/${e.content_id}/${e.content_version_id ?? ""}/${e.relation}`))
960
+ }) : /* @__PURE__ */ V("p", {
961
+ className: "text-muted-foreground",
962
+ children: s("taxonomyManager.noContents")
963
+ }), v && /* @__PURE__ */ V(i, {
964
+ variant: "outline",
965
+ size: "sm",
966
+ className: "justify-self-center",
967
+ disabled: f,
968
+ onClick: () => void g(v),
969
+ children: s("moderation.loadMore")
970
+ })]
971
+ });
972
+ }
973
+ //#endregion
974
+ export { J as TaxonomyManager, q as slugify, U as useTaxonomyManagerAccess };
975
+
976
+ //# sourceMappingURL=taxonomy-manager.js.map