@openrails/contentkit-ui 0.104.0-rc.1 → 0.104.0-rc.2

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 (210) hide show
  1. package/README.md +6 -6
  2. package/dist/client/beacons.js +4 -1
  3. package/dist/client/beacons.js.map +1 -1
  4. package/dist/client/contents.d.ts +7 -1
  5. package/dist/client/contents.js +8 -0
  6. package/dist/client/contents.js.map +1 -1
  7. package/dist/client/discovery.d.ts +6 -2
  8. package/dist/client/discovery.js +1 -1
  9. package/dist/client/discovery.js.map +1 -1
  10. package/dist/client/generated/routes.d.ts +41 -28
  11. package/dist/client/generated/routes.js +63 -61
  12. package/dist/client/generated/routes.js.map +1 -1
  13. package/dist/client/generated/wire.d.ts +36 -74
  14. package/dist/client/generated/wire.js.map +1 -1
  15. package/dist/client/index.d.ts +1 -1
  16. package/dist/client/media/windows.d.ts +2 -0
  17. package/dist/client/media/windows.js +4 -1
  18. package/dist/client/media/windows.js.map +1 -1
  19. package/dist/client/stats.d.ts +4 -20
  20. package/dist/client/stats.js +0 -11
  21. package/dist/client/stats.js.map +1 -1
  22. package/dist/client/versions.d.ts +8 -6
  23. package/dist/client/versions.js +15 -10
  24. package/dist/client/versions.js.map +1 -1
  25. package/dist/components/admin/bulk-drafts.d.ts +17 -0
  26. package/dist/components/admin/bulk-drafts.js +41 -0
  27. package/dist/components/admin/bulk-drafts.js.map +1 -0
  28. package/dist/components/admin/content-admin.d.ts +1 -1
  29. package/dist/components/admin/content-admin.js.map +1 -1
  30. package/dist/components/admin/content-manager.d.ts +11 -3
  31. package/dist/components/admin/content-manager.js +739 -380
  32. package/dist/components/admin/content-manager.js.map +1 -1
  33. package/dist/components/admin/group-manager.d.ts +8 -3
  34. package/dist/components/admin/group-manager.js +218 -146
  35. package/dist/components/admin/group-manager.js.map +1 -1
  36. package/dist/components/admin/page-notices.d.ts +16 -0
  37. package/dist/components/admin/page-notices.js +113 -0
  38. package/dist/components/admin/page-notices.js.map +1 -0
  39. package/dist/components/admin/page-picker.d.ts +38 -0
  40. package/dist/components/admin/page-picker.js +159 -0
  41. package/dist/components/admin/page-picker.js.map +1 -0
  42. package/dist/components/admin/reader-content-editor.js +537 -500
  43. package/dist/components/admin/reader-content-editor.js.map +1 -1
  44. package/dist/components/admin/reader-manifest.js +181 -179
  45. package/dist/components/admin/reader-manifest.js.map +1 -1
  46. package/dist/components/admin/shell.d.ts +10 -2
  47. package/dist/components/admin/shell.js +114 -42
  48. package/dist/components/admin/shell.js.map +1 -1
  49. package/dist/components/admin/stats-dashboard.d.ts +4 -9
  50. package/dist/components/admin/stats-dashboard.js +300 -202
  51. package/dist/components/admin/stats-dashboard.js.map +1 -1
  52. package/dist/components/admin/upload-queue.d.ts +14 -0
  53. package/dist/components/admin/upload-queue.js +115 -98
  54. package/dist/components/admin/upload-queue.js.map +1 -1
  55. package/dist/components/content/card.d.ts +31 -3
  56. package/dist/components/content/card.js +324 -158
  57. package/dist/components/content/card.js.map +1 -1
  58. package/dist/components/content/daily-releases.js +14 -12
  59. package/dist/components/content/daily-releases.js.map +1 -1
  60. package/dist/components/content/editor-save.js +27 -25
  61. package/dist/components/content/editor-save.js.map +1 -1
  62. package/dist/components/content/editors.js +274 -253
  63. package/dist/components/content/editors.js.map +1 -1
  64. package/dist/components/content/favorites.d.ts +1 -1
  65. package/dist/components/content/favorites.js +36 -22
  66. package/dist/components/content/favorites.js.map +1 -1
  67. package/dist/components/content/grid.d.ts +11 -4
  68. package/dist/components/content/grid.js +52 -43
  69. package/dist/components/content/grid.js.map +1 -1
  70. package/dist/components/content/history.js +83 -63
  71. package/dist/components/content/history.js.map +1 -1
  72. package/dist/components/content/index.d.ts +5 -3
  73. package/dist/components/content/listing.d.ts +14 -3
  74. package/dist/components/content/listing.js +65 -56
  75. package/dist/components/content/listing.js.map +1 -1
  76. package/dist/components/content/offer-fields.js +6 -6
  77. package/dist/components/content/paged-grid.d.ts +10 -0
  78. package/dist/components/content/paged-grid.js +116 -0
  79. package/dist/components/content/paged-grid.js.map +1 -0
  80. package/dist/components/content/pagination.d.ts +19 -0
  81. package/dist/components/content/pagination.js +97 -0
  82. package/dist/components/content/pagination.js.map +1 -0
  83. package/dist/components/content/paywall.d.ts +9 -0
  84. package/dist/components/content/paywall.js +27 -3
  85. package/dist/components/content/paywall.js.map +1 -1
  86. package/dist/components/content/post-list.d.ts +37 -0
  87. package/dist/components/content/post-list.js +203 -0
  88. package/dist/components/content/post-list.js.map +1 -0
  89. package/dist/components/content/reader-settings.d.ts +2 -0
  90. package/dist/components/content/reader-settings.js +1 -1
  91. package/dist/components/content/reader-settings.js.map +1 -1
  92. package/dist/components/groups/banner.d.ts +6 -2
  93. package/dist/components/groups/banner.js +79 -61
  94. package/dist/components/groups/banner.js.map +1 -1
  95. package/dist/components/groups/directory.d.ts +12 -2
  96. package/dist/components/groups/directory.js +168 -105
  97. package/dist/components/groups/directory.js.map +1 -1
  98. package/dist/components/groups/editor.js +10 -10
  99. package/dist/components/groups/editor.js.map +1 -1
  100. package/dist/components/groups/entity-chips.d.ts +61 -0
  101. package/dist/components/groups/entity-chips.js +382 -0
  102. package/dist/components/groups/entity-chips.js.map +1 -0
  103. package/dist/components/groups/group-members.d.ts +29 -0
  104. package/dist/components/groups/group-members.js +474 -0
  105. package/dist/components/groups/group-members.js.map +1 -0
  106. package/dist/components/groups/header.js +53 -45
  107. package/dist/components/groups/header.js.map +1 -1
  108. package/dist/components/groups/index.d.ts +3 -1
  109. package/dist/components/groups/memberships.d.ts +3 -36
  110. package/dist/components/groups/memberships.js +105 -480
  111. package/dist/components/groups/memberships.js.map +1 -1
  112. package/dist/components/groups/scoped.d.ts +23 -0
  113. package/dist/components/groups/scoped.js +92 -0
  114. package/dist/components/groups/scoped.js.map +1 -0
  115. package/dist/components/media-folder-editor.d.ts +5 -0
  116. package/dist/components/media-folder-editor.js +418 -230
  117. package/dist/components/media-folder-editor.js.map +1 -1
  118. package/dist/components/sortable-list.d.ts +5 -1
  119. package/dist/components/sortable-list.js +97 -81
  120. package/dist/components/sortable-list.js.map +1 -1
  121. package/dist/index.d.ts +1 -1
  122. package/dist/index.js +41 -37
  123. package/dist/locales/admin/de.js +78 -45
  124. package/dist/locales/admin/de.js.map +1 -1
  125. package/dist/locales/admin/en.d.ts +74 -41
  126. package/dist/locales/admin/en.js +78 -45
  127. package/dist/locales/admin/en.js.map +1 -1
  128. package/dist/locales/admin/es.js +78 -45
  129. package/dist/locales/admin/es.js.map +1 -1
  130. package/dist/locales/admin/ja.js +78 -45
  131. package/dist/locales/admin/ja.js.map +1 -1
  132. package/dist/locales/admin/ko.js +78 -45
  133. package/dist/locales/admin/ko.js.map +1 -1
  134. package/dist/locales/admin/zh.js +78 -45
  135. package/dist/locales/admin/zh.js.map +1 -1
  136. package/dist/locales/de.js +1 -0
  137. package/dist/locales/de.js.map +1 -1
  138. package/dist/locales/discovery/de.js +25 -1
  139. package/dist/locales/discovery/de.js.map +1 -1
  140. package/dist/locales/discovery/en.d.ts +24 -0
  141. package/dist/locales/discovery/en.js +25 -1
  142. package/dist/locales/discovery/en.js.map +1 -1
  143. package/dist/locales/discovery/es.js +25 -1
  144. package/dist/locales/discovery/es.js.map +1 -1
  145. package/dist/locales/discovery/ja.js +25 -1
  146. package/dist/locales/discovery/ja.js.map +1 -1
  147. package/dist/locales/discovery/ko.js +25 -1
  148. package/dist/locales/discovery/ko.js.map +1 -1
  149. package/dist/locales/discovery/zh.js +25 -1
  150. package/dist/locales/discovery/zh.js.map +1 -1
  151. package/dist/locales/en.d.ts +119 -43
  152. package/dist/locales/en.js +1 -0
  153. package/dist/locales/en.js.map +1 -1
  154. package/dist/locales/es.js +1 -0
  155. package/dist/locales/es.js.map +1 -1
  156. package/dist/locales/groups/de.js +22 -4
  157. package/dist/locales/groups/de.js.map +1 -1
  158. package/dist/locales/groups/en.d.ts +20 -2
  159. package/dist/locales/groups/en.js +22 -4
  160. package/dist/locales/groups/en.js.map +1 -1
  161. package/dist/locales/groups/es.js +22 -4
  162. package/dist/locales/groups/es.js.map +1 -1
  163. package/dist/locales/groups/ja.js +22 -4
  164. package/dist/locales/groups/ja.js.map +1 -1
  165. package/dist/locales/groups/ko.js +22 -4
  166. package/dist/locales/groups/ko.js.map +1 -1
  167. package/dist/locales/groups/zh.js +22 -4
  168. package/dist/locales/groups/zh.js.map +1 -1
  169. package/dist/locales/ja.js +1 -0
  170. package/dist/locales/ja.js.map +1 -1
  171. package/dist/locales/ko.js +1 -0
  172. package/dist/locales/ko.js.map +1 -1
  173. package/dist/locales/zh.js +1 -0
  174. package/dist/locales/zh.js.map +1 -1
  175. package/dist/react/discovery.d.ts +16 -0
  176. package/dist/react/discovery.js +69 -37
  177. package/dist/react/discovery.js.map +1 -1
  178. package/dist/react/groups.d.ts +19 -3
  179. package/dist/react/groups.js +49 -22
  180. package/dist/react/groups.js.map +1 -1
  181. package/dist/react/index.d.ts +6 -4
  182. package/dist/react/page-notices.d.ts +13 -0
  183. package/dist/react/page-notices.js +38 -0
  184. package/dist/react/page-notices.js.map +1 -0
  185. package/dist/react/post-reads.d.ts +23 -0
  186. package/dist/react/post-reads.js +90 -0
  187. package/dist/react/post-reads.js.map +1 -0
  188. package/dist/react/remembered-sort.d.ts +5 -0
  189. package/dist/react/remembered-sort.js +29 -0
  190. package/dist/react/remembered-sort.js.map +1 -0
  191. package/dist/react/resources.js +2 -2
  192. package/dist/react/resources.js.map +1 -1
  193. package/dist/react/stats.d.ts +3 -7
  194. package/dist/react/stats.js +2 -6
  195. package/dist/react/stats.js.map +1 -1
  196. package/dist/react/use-engagement.d.ts +2 -0
  197. package/dist/react/use-engagement.js +8 -3
  198. package/dist/react/use-engagement.js.map +1 -1
  199. package/dist/react.js +29 -27
  200. package/dist/styles.css +1 -1
  201. package/dist/urls/index.d.ts +1 -1
  202. package/dist/urls.js +2 -2
  203. package/dist/urls.js.map +1 -1
  204. package/package.json +1 -1
  205. package/dist/components/admin/page-review.d.ts +0 -13
  206. package/dist/components/admin/page-review.js +0 -225
  207. package/dist/components/admin/page-review.js.map +0 -1
  208. package/dist/react/page-review.d.ts +0 -14
  209. package/dist/react/page-review.js +0 -37
  210. package/dist/react/page-review.js.map +0 -1
@@ -2,83 +2,86 @@ import { useLanguageName as e, useMessages as t } from "../../i18n/context.js";
2
2
  import { useGroups as n, useKinds as r } from "../../react/groups.js";
3
3
  import { Button as i } from "../../ui/button.js";
4
4
  import { Badge as a } from "../../ui/badge.js";
5
- import { Select as o, SelectContent as s, SelectItem as c, SelectTrigger as l, SelectValue as u } from "../../ui/select.js";
6
- import { contentError as d } from "../social/parts.js";
7
- import { AdminRoot as f, LoadFailed as p, NoAccess as m, Rows as h } from "./shell.js";
8
- import { useAdminLocation as g, useFlowClient as _, useStaffAccess as v } from "../../react/admin.js";
9
- import { Tabs as y, TabsList as b, TabsTrigger as x } from "../../ui/tabs.js";
10
- import { LETTERS as S } from "../../client/group-fields.js";
11
- import { labelOf as C } from "../groups/parts.js";
12
- import { GroupEditor as w } from "../groups/editor.js";
13
- import { GroupMembers as T } from "../groups/memberships.js";
14
- import { useMemo as E } from "react";
15
- import { Fragment as D, jsx as O, jsxs as k } from "react/jsx-runtime";
5
+ import { Input as o } from "../../ui/input.js";
6
+ import { Select as s, SelectContent as c, SelectItem as l, SelectTrigger as u, SelectValue as d } from "../../ui/select.js";
7
+ import { contentError as f, useAction as p } from "../social/parts.js";
8
+ import { AdminRoot as m, LoadFailed as h, NoAccess as g, Rows as _ } from "./shell.js";
9
+ import { useAdminLocation as v, useFlowClient as y, useStaffAccess as b } from "../../react/admin.js";
10
+ import { Tabs as x, TabsList as S, TabsTrigger as C } from "../../ui/tabs.js";
11
+ import { LETTERS as w } from "../../client/group-fields.js";
12
+ import { labelOf as T } from "../groups/parts.js";
13
+ import { ScopedGroups as E } from "../groups/scoped.js";
14
+ import { GroupEditor as D } from "../groups/editor.js";
15
+ import { GroupMembers as O } from "../groups/group-members.js";
16
+ import { useEffect as k, useMemo as A, useState as j } from "react";
17
+ import { Fragment as M, jsx as N, jsxs as P } from "react/jsx-runtime";
18
+ import { cn as F } from "cn";
16
19
  //#region src/components/admin/group-manager.tsx
17
- function A(e = {}) {
18
- return v(["groups"], e);
20
+ function I(e = {}) {
21
+ return b(["groups"], e);
19
22
  }
20
- var j = [
23
+ var L = [
21
24
  "name",
22
25
  "count",
23
26
  "newest"
24
27
  ];
25
- function M({ client: e, baseUrl: t, auth: n, guard: r, appearance: i, className: a, language: o, messages: s, ...c }) {
26
- let l = _({
28
+ function R({ client: e, baseUrl: t, auth: n, guard: r, appearance: i, className: a, language: o, messages: s, ...c }) {
29
+ let l = y({
27
30
  client: e,
28
31
  baseUrl: t,
29
32
  auth: n
30
33
  });
31
- return /* @__PURE__ */ O(f, {
34
+ return /* @__PURE__ */ N(m, {
32
35
  flow: "group-manager",
33
36
  appearance: i,
34
37
  className: a,
35
38
  language: o,
36
39
  messages: s,
37
40
  guard: r,
38
- children: /* @__PURE__ */ O(N, {
41
+ children: /* @__PURE__ */ N(z, {
39
42
  ...c,
40
43
  client: l
41
44
  })
42
45
  });
43
46
  }
44
- function N({ basePath: e, navigation: n, ...i }) {
45
- let { t: a } = t(), o = g(e, n), s = A({ client: i.client }), c = r({ client: i.client }), l = c.kinds, u = E(() => i.groupKinds ?? Object.entries(l?.entity_kinds ?? {}).filter(([, e]) => e.owner !== "user").map(([e]) => e).sort(), [i.groupKinds, l]);
46
- if (s.loading || c.loading) return /* @__PURE__ */ O(h, {});
47
- if (!s.allowed.groups) return /* @__PURE__ */ O(m, { children: a("groupManager.noAccess") });
48
- if (!l) return /* @__PURE__ */ O(p, {
47
+ function z({ basePath: e, navigation: n, ...i }) {
48
+ let { t: a } = t(), o = v(e, n), s = I({ client: i.client }), c = r({ client: i.client }), l = c.kinds, u = A(() => i.groupKinds ?? Object.entries(l?.entity_kinds ?? {}).filter(([, e]) => e.owner !== "user").map(([e]) => e).sort(), [i.groupKinds, l]);
49
+ if (s.loading || c.loading) return /* @__PURE__ */ N(_, {});
50
+ if (!s.allowed.groups) return /* @__PURE__ */ N(g, { children: a("groupManager.noAccess") });
51
+ if (!l) return /* @__PURE__ */ N(h, {
49
52
  error: c.error,
50
53
  message: a("groupManager.kindsFailed"),
51
54
  retry: c.reload
52
55
  });
53
- if (!u.length) return /* @__PURE__ */ O("p", {
56
+ if (!u.length) return /* @__PURE__ */ N("p", {
54
57
  className: "text-muted-foreground",
55
58
  children: a("groupManager.noKinds")
56
59
  });
57
- let [d, f] = o.view.split("/"), _ = u.includes(d ?? "") ? d : u[0], v = {
60
+ let [d, f] = o.view.split("/"), p = u.includes(d ?? "") ? d : u[0], m = {
58
61
  ...i,
59
62
  loc: o,
60
- kind: _,
63
+ kind: p,
61
64
  kinds: l
62
65
  };
63
- return /* @__PURE__ */ k(D, { children: [u.length > 1 && /* @__PURE__ */ O(y, {
64
- value: _,
66
+ return /* @__PURE__ */ P(M, { children: [u.length > 1 && /* @__PURE__ */ N(x, {
67
+ value: p,
65
68
  onValueChange: (e) => o.go(String(e)),
66
- children: /* @__PURE__ */ O(b, {
69
+ children: /* @__PURE__ */ N(S, {
67
70
  className: "flex-wrap group-data-horizontal/tabs:h-auto",
68
- children: u.map((e) => /* @__PURE__ */ O(x, {
71
+ children: u.map((e) => /* @__PURE__ */ N(C, {
69
72
  value: e,
70
73
  className: "h-7.5",
71
- children: C(i.labels, e)
74
+ children: T(i.labels, e)
72
75
  }, e))
73
76
  })
74
- }), f ? f === "new" ? /* @__PURE__ */ O(I, { ...v }, _) : /* @__PURE__ */ O(L, {
75
- ...v,
77
+ }), f ? f === "new" ? /* @__PURE__ */ N(H, { ...m }, p) : /* @__PURE__ */ N(U, {
78
+ ...m,
76
79
  id: f
77
- }, f) : /* @__PURE__ */ O(F, { ...v }, _)] });
80
+ }, f) : /* @__PURE__ */ N(V, { ...m }, p)] });
78
81
  }
79
- function P({ loc: e, kind: n }) {
82
+ function B({ loc: e, kind: n }) {
80
83
  let { t: r } = t();
81
- return /* @__PURE__ */ O(i, {
84
+ return /* @__PURE__ */ N(i, {
82
85
  variant: "ghost",
83
86
  size: "sm",
84
87
  className: "justify-self-start",
@@ -86,145 +89,206 @@ function P({ loc: e, kind: n }) {
86
89
  children: r("groupManager.back")
87
90
  });
88
91
  }
89
- function F({ loc: r, kind: f, kinds: m, client: g, contentKind: _, labels: v, pageSize: y = 50 }) {
90
- let b = t(), { t: x } = b, w = e(), T = m.languages, E = r.query.get("letter") ?? "", D = S.includes(E) ? E : void 0, A = r.query.get("sort") ?? "", M = j.includes(A) ? A : "name", N = r.query.get("language") ?? "", P = T.includes(N) ? N : T[0], F = {
91
- letter: D,
92
- sort: M === "name" ? void 0 : M,
93
- language: P === T[0] ? void 0 : P
94
- }, I = (e) => r.go(f, {
95
- ...F,
92
+ function V({ loc: r, kind: m, kinds: g, client: v, contentKind: y, labels: b, onError: x, pageSize: S = 50 }) {
93
+ let C = t(), { t: E } = C, D = e(), O = g.languages, A = r.query.get("deleted") === "1", M = r.query.get("q") ?? "", [I, R] = j(M);
94
+ k(() => R(M), [M]);
95
+ let z = r.query.get("letter") ?? "", B = w.includes(z) ? z : void 0, V = r.query.get("sort") ?? "", H = L.includes(V) ? V : "name", U = r.query.get("language") ?? "", W = O.includes(U) ? U : O[0], G = {
96
+ letter: B,
97
+ sort: H === "name" ? void 0 : H,
98
+ language: W === O[0] ? void 0 : W,
99
+ q: M || void 0,
100
+ deleted: A ? "1" : void 0
101
+ }, K = (e) => r.go(m, {
102
+ ...G,
96
103
  ...e
97
- }), L = n({
98
- kind: f,
99
- letter: D,
100
- sort: M,
101
- language: P,
102
- contentKind: _,
103
- pageSize: y
104
+ });
105
+ k(() => {
106
+ if (I.trim() === M) return;
107
+ let e = setTimeout(() => r.go(m, {
108
+ ...G,
109
+ q: I.trim() || void 0
110
+ }, { replace: !0 }), 250);
111
+ return () => clearTimeout(e);
112
+ }, [I]);
113
+ let q = n({
114
+ kind: m,
115
+ letter: B,
116
+ sort: H,
117
+ language: W,
118
+ contentKind: y,
119
+ pageSize: S,
120
+ query: M || void 0,
121
+ deleted: A
104
122
  }, {
105
- client: g,
123
+ client: v,
106
124
  management: !0
107
- }), R = C(v, f);
108
- return /* @__PURE__ */ k("div", {
125
+ }), J = p("group.save", x), Y = T(b, m);
126
+ return /* @__PURE__ */ P("div", {
109
127
  className: "grid gap-4",
110
128
  "data-ckui": "group-list",
111
- "data-kind": f,
129
+ "data-kind": m,
112
130
  children: [
113
- /* @__PURE__ */ k("div", {
131
+ /* @__PURE__ */ P("div", {
114
132
  className: "flex flex-wrap items-center justify-between gap-2",
115
- children: [/* @__PURE__ */ O("h2", {
133
+ children: [/* @__PURE__ */ N("h2", {
116
134
  className: "text-base font-semibold",
117
- children: R
118
- }), /* @__PURE__ */ O(i, {
135
+ children: Y
136
+ }), /* @__PURE__ */ N(i, {
119
137
  size: "sm",
120
- onClick: () => r.go(`${f}/new`),
121
- children: x("groupManager.new", { kind: R })
138
+ onClick: () => r.go(`${m}/new`),
139
+ children: E("groupManager.new", { kind: Y })
122
140
  })]
123
141
  }),
124
- /* @__PURE__ */ k("div", {
125
- className: "flex flex-wrap items-center gap-2",
126
- children: [/* @__PURE__ */ k(o, {
127
- value: M,
128
- onValueChange: (e) => I({ sort: e === "name" ? void 0 : String(e) }),
129
- children: [/* @__PURE__ */ O(l, {
130
- size: "sm",
131
- "aria-label": x("groupManager.sort"),
132
- children: /* @__PURE__ */ O(u, { children: (e) => x(`groupManager.sort_${e}`) })
133
- }), /* @__PURE__ */ O(s, { children: j.map((e) => /* @__PURE__ */ O(c, {
134
- value: e,
135
- children: x(`groupManager.sort_${e}`)
136
- }, e)) })]
137
- }), T.length > 1 && /* @__PURE__ */ k(o, {
138
- value: P,
139
- onValueChange: (e) => I({ language: e === T[0] ? void 0 : String(e) }),
140
- children: [/* @__PURE__ */ O(l, {
141
- size: "sm",
142
- "aria-label": x("groupManager.language"),
143
- children: /* @__PURE__ */ O(u, { children: (e) => w(e) })
144
- }), /* @__PURE__ */ O(s, { children: T.map((e) => /* @__PURE__ */ O(c, {
145
- value: e,
146
- children: w(e)
147
- }, e)) })]
142
+ /* @__PURE__ */ P("div", {
143
+ className: "flex gap-2",
144
+ role: "group",
145
+ "aria-label": Y,
146
+ children: [/* @__PURE__ */ N(i, {
147
+ size: "sm",
148
+ variant: A ? "outline" : "default",
149
+ "aria-pressed": !A,
150
+ onClick: () => K({ deleted: void 0 }),
151
+ children: E("groupManager.active")
152
+ }), /* @__PURE__ */ N(i, {
153
+ size: "sm",
154
+ variant: A ? "default" : "outline",
155
+ "aria-pressed": A,
156
+ onClick: () => K({ deleted: "1" }),
157
+ children: E("groupManager.deleted")
148
158
  })]
149
159
  }),
150
- /* @__PURE__ */ O("nav", {
151
- "aria-label": x("groups.byLetter"),
160
+ /* @__PURE__ */ P("div", {
161
+ className: "flex flex-wrap items-center gap-2",
162
+ children: [
163
+ /* @__PURE__ */ N(o, {
164
+ type: "search",
165
+ className: "h-8 min-w-48 flex-1",
166
+ "aria-label": E("groupManager.search"),
167
+ placeholder: E("groupManager.search"),
168
+ value: I,
169
+ onChange: (e) => R(e.target.value)
170
+ }),
171
+ /* @__PURE__ */ P(s, {
172
+ value: H,
173
+ onValueChange: (e) => K({ sort: e === "name" ? void 0 : String(e) }),
174
+ children: [/* @__PURE__ */ N(u, {
175
+ size: "sm",
176
+ "aria-label": E("groupManager.sort"),
177
+ children: /* @__PURE__ */ N(d, { children: (e) => E(`groupManager.sort_${e}`) })
178
+ }), /* @__PURE__ */ N(c, { children: L.map((e) => /* @__PURE__ */ N(l, {
179
+ value: e,
180
+ children: E(`groupManager.sort_${e}`)
181
+ }, e)) })]
182
+ }),
183
+ O.length > 1 && /* @__PURE__ */ P(s, {
184
+ value: W,
185
+ onValueChange: (e) => K({ language: e === O[0] ? void 0 : String(e) }),
186
+ children: [/* @__PURE__ */ N(u, {
187
+ size: "sm",
188
+ "aria-label": E("groupManager.language"),
189
+ children: /* @__PURE__ */ N(d, { children: (e) => D(e) })
190
+ }), /* @__PURE__ */ N(c, { children: O.map((e) => /* @__PURE__ */ N(l, {
191
+ value: e,
192
+ children: D(e)
193
+ }, e)) })]
194
+ })
195
+ ]
196
+ }),
197
+ /* @__PURE__ */ N("nav", {
198
+ "aria-label": E("groups.byLetter"),
152
199
  className: "flex flex-wrap gap-1",
153
200
  "data-ckui": "letters",
154
- children: [void 0, ...S].map((e) => /* @__PURE__ */ O(i, {
201
+ children: [void 0, ...w].map((e) => /* @__PURE__ */ N(i, {
155
202
  size: "xs",
156
- variant: D === e ? "default" : "ghost",
157
- "aria-pressed": D === e,
158
- "aria-label": e === void 0 ? void 0 : e === "#" ? x("groups.otherLetters") : e.toUpperCase(),
203
+ variant: B === e ? "default" : "ghost",
204
+ "aria-pressed": B === e,
205
+ "aria-label": e === void 0 ? void 0 : e === "#" ? E("groups.otherLetters") : e.toUpperCase(),
159
206
  className: "min-w-7",
160
- onClick: () => I({ letter: e }),
161
- children: e === void 0 ? x("groups.all") : e.toUpperCase()
207
+ onClick: () => K({ letter: e }),
208
+ children: e === void 0 ? E("groups.all") : e.toUpperCase()
162
209
  }, e ?? "all"))
163
210
  }),
164
- L.loading && !L.items.length ? /* @__PURE__ */ O(h, {}) : L.error && !L.items.length ? /* @__PURE__ */ O(p, {
165
- error: L.error,
166
- message: x("groupManager.loadFailed"),
167
- retry: L.reload
168
- }) : L.items.length ? /* @__PURE__ */ O("ul", {
211
+ q.loading && !q.items.length ? /* @__PURE__ */ N(_, {}) : q.error && !q.items.length ? /* @__PURE__ */ N(h, {
212
+ error: q.error,
213
+ message: E("groupManager.loadFailed"),
214
+ retry: q.reload
215
+ }) : q.items.length ? /* @__PURE__ */ N("ul", {
169
216
  className: "grid divide-y divide-border rounded-lg border border-border",
170
- "aria-busy": L.loading,
171
- children: L.items.map((e) => /* @__PURE__ */ k("li", {
217
+ "aria-busy": q.loading,
218
+ children: q.items.map((e) => /* @__PURE__ */ P("li", {
172
219
  className: "flex flex-wrap items-center gap-3 p-3",
173
220
  "data-ckui": "group-row",
174
221
  "data-slug": e.slug,
175
- children: [/* @__PURE__ */ k("div", {
176
- className: "grid min-w-0 flex-1 gap-0.5",
177
- children: [
178
- /* @__PURE__ */ O("button", {
179
- type: "button",
180
- className: "text-left font-medium break-words hover:underline",
181
- onClick: () => r.go(`${f}/${e.id}`),
182
- children: e.name || e.slug
183
- }),
184
- /* @__PURE__ */ O("span", {
185
- className: "text-xs text-muted-foreground",
186
- children: e.slug
187
- }),
188
- e.internal && /* @__PURE__ */ O(a, {
189
- variant: "secondary",
190
- className: "justify-self-start",
191
- children: x("groupEditor.internal")
192
- })
193
- ]
194
- }), /* @__PURE__ */ O("span", {
195
- className: "text-sm text-muted-foreground tabular-nums",
196
- title: x("groupManager.count"),
197
- children: new Intl.NumberFormat(b.language).format(e.count)
198
- })]
222
+ "data-state": A ? "deleted" : "active",
223
+ children: [
224
+ (e.avatar?.renditions?.[0] ?? e.cover?.renditions?.[0]) && /* @__PURE__ */ N("img", {
225
+ src: (e.avatar?.renditions?.[0] ?? e.cover?.renditions?.[0]).url,
226
+ alt: "",
227
+ loading: "lazy",
228
+ className: F("size-9 shrink-0 object-cover", e.avatar?.renditions?.[0] ? "rounded-full" : "rounded-sm")
229
+ }),
230
+ /* @__PURE__ */ P("div", {
231
+ className: "grid min-w-0 flex-1 gap-0.5",
232
+ children: [
233
+ /* @__PURE__ */ N("button", {
234
+ type: "button",
235
+ className: "text-left font-medium break-words hover:underline",
236
+ onClick: () => r.go(`${m}/${e.id}`),
237
+ children: e.name || e.slug
238
+ }),
239
+ /* @__PURE__ */ N("span", {
240
+ className: "text-xs text-muted-foreground",
241
+ children: e.slug
242
+ }),
243
+ e.internal && /* @__PURE__ */ N(a, {
244
+ variant: "secondary",
245
+ className: "justify-self-start",
246
+ children: E("groupEditor.internal")
247
+ })
248
+ ]
249
+ }),
250
+ /* @__PURE__ */ N("span", {
251
+ className: "text-sm text-muted-foreground tabular-nums",
252
+ title: E("groupManager.count"),
253
+ children: new Intl.NumberFormat(C.language).format(e.count)
254
+ }),
255
+ A && /* @__PURE__ */ N(i, {
256
+ size: "sm",
257
+ variant: "outline",
258
+ disabled: J.pending,
259
+ onClick: () => void J.run(() => v.entities.update(e.id, { state: "active" })).then((e) => e !== void 0 && q.reload()),
260
+ children: E("groupEditor.restore")
261
+ })
262
+ ]
199
263
  }, e.id))
200
- }) : /* @__PURE__ */ O("p", {
264
+ }) : /* @__PURE__ */ N("p", {
201
265
  className: "text-muted-foreground",
202
- children: x("groups.empty")
266
+ children: E(A ? "groupManager.noDeleted" : M ? "groupManager.noMatches" : "groups.empty")
203
267
  }),
204
- L.hasMore && /* @__PURE__ */ k("div", {
268
+ q.hasMore && /* @__PURE__ */ P("div", {
205
269
  className: "grid justify-items-center gap-2",
206
- children: [L.error && /* @__PURE__ */ O("p", {
270
+ children: [q.error && /* @__PURE__ */ N("p", {
207
271
  role: "alert",
208
272
  className: "text-destructive",
209
- children: d(b, L.error)
210
- }), /* @__PURE__ */ O(i, {
273
+ children: f(C, q.error)
274
+ }), /* @__PURE__ */ N(i, {
211
275
  variant: "outline",
212
276
  size: "sm",
213
- disabled: L.loadingMore,
214
- onClick: () => void L.loadMore(),
215
- children: L.loadingMore ? x("groups.loading") : L.error ? x("common.retry") : x("groups.loadMore")
277
+ disabled: q.loadingMore,
278
+ onClick: () => void q.loadMore(),
279
+ children: q.loadingMore ? E("groups.loading") : q.error ? E("common.retry") : E("groups.loadMore")
216
280
  })]
217
281
  })
218
282
  ]
219
283
  });
220
284
  }
221
- function I({ loc: e, kind: t, client: n, labels: r, onError: i }) {
222
- return /* @__PURE__ */ k("div", {
285
+ function H({ loc: e, kind: t, client: n, labels: r, onError: i }) {
286
+ return /* @__PURE__ */ P("div", {
223
287
  className: "grid gap-4",
224
- children: [/* @__PURE__ */ O(P, {
288
+ children: [/* @__PURE__ */ N(B, {
225
289
  loc: e,
226
290
  kind: t
227
- }), /* @__PURE__ */ O(w, {
291
+ }), /* @__PURE__ */ N(D, {
228
292
  management: !0,
229
293
  id: null,
230
294
  kind: t,
@@ -235,32 +299,40 @@ function I({ loc: e, kind: t, client: n, labels: r, onError: i }) {
235
299
  })]
236
300
  });
237
301
  }
238
- function L({ loc: e, kind: t, client: n, labels: r, onError: i, renderContent: a, id: o }) {
239
- return /* @__PURE__ */ k("div", {
302
+ function U({ loc: e, kind: t, client: n, labels: r, onError: i, renderContent: a, contentHref: o, newContentHref: s, id: c }) {
303
+ return /* @__PURE__ */ P("div", {
240
304
  className: "grid gap-4",
241
- children: [/* @__PURE__ */ O(P, {
305
+ children: [/* @__PURE__ */ N(B, {
242
306
  loc: e,
243
307
  kind: t
244
- }), /* @__PURE__ */ O(w, {
308
+ }), /* @__PURE__ */ N(D, {
245
309
  management: !0,
246
- id: o,
310
+ id: c,
247
311
  kind: t,
248
312
  labels: r,
249
313
  client: n,
250
314
  onError: i,
251
315
  onMerged: (n) => e.go(`${t}/${n.into}`, void 0, { replace: !0 }),
252
- children: (e) => /* @__PURE__ */ O(T, {
253
- group: e,
316
+ children: (t) => /* @__PURE__ */ P(M, { children: [/* @__PURE__ */ N(E, {
317
+ group: t,
318
+ management: !0,
319
+ labels: r,
320
+ client: n,
321
+ onSelect: (t) => e.go(`${t.kind}/${t.id}`)
322
+ }), /* @__PURE__ */ N(O, {
323
+ group: t,
254
324
  labels: r,
255
325
  client: n,
256
326
  onError: i,
257
327
  renderContent: a,
258
- onUseCover: (t) => n.entities.update(e.id, { cover: { content_id: t } })
259
- })
328
+ contentHref: o,
329
+ newContentHref: s,
330
+ onUseCover: (e) => n.entities.update(t.id, { cover: { content_id: e } })
331
+ })] })
260
332
  })]
261
333
  });
262
334
  }
263
335
  //#endregion
264
- export { M as GroupManager, A as useGroupManagerAccess };
336
+ export { R as GroupManager, I as useGroupManagerAccess };
265
337
 
266
338
  //# sourceMappingURL=group-manager.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"group-manager.js","names":[],"sources":["../../../src/components/admin/group-manager.tsx"],"sourcesContent":["import { useMemo, type ReactNode } from \"react\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport { LETTERS } from \"../../client/group-fields.js\";\nimport type { ContentModel, Membership } from \"../../client/generated/wire.js\";\nimport { useLanguageName, useMessages } from \"../../i18n/context.js\";\nimport { useAdminLocation, useFlowClient, useStaffAccess, type AdminLocation, type FlowClientOptions, type StaffAccess } from \"../../react/admin.js\";\nimport { useGroups, useKinds, type GroupSort } from \"../../react/groups.js\";\nimport { Badge } from \"#ckui/ui/badge\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"#ckui/ui/select\";\nimport { Tabs, TabsList, TabsTrigger } from \"#ckui/ui/tabs\";\nimport { GroupEditor } from \"../groups/editor.js\";\nimport { GroupMembers } from \"../groups/memberships.js\";\nimport { labelOf, type Labels } from \"../groups/parts.js\";\nimport { contentError } from \"../social/parts.js\";\nimport { AdminRoot, LoadFailed, NoAccess, Rows, type AdminFlowProps, type AdminRouteProps } from \"./shell.js\";\n\nexport interface GroupManagerProps extends AdminFlowProps, AdminRouteProps {\n /** The group kinds managed, in tab order; default the content model's site-owned kinds. */\n groupKinds?: readonly string[];\n /** Display names of kinds, attributes, roles and values by identifier. */\n labels?: Labels;\n /** Counts of this content kind; default every kind. */\n contentKind?: string;\n /** One member, e.g. a link with its title; default its content id. */\n renderContent?: (member: Membership) => ReactNode;\n pageSize?: number;\n}\n\n/** Whether the caller may manage groups (root:groups:write). */\nexport function useGroupManagerAccess(o: FlowClientOptions = {}): StaffAccess<\"groups\"> {\n return useStaffAccess([\"groups\"] as const, o);\n}\n\nconst SORTS: readonly GroupSort[] = [\"name\", \"count\", \"newest\"];\n\n/**\n * Staff: groups per kind. A kind's groups by letter, order and language; a\n * new group; a group's editor (GroupEditor) and its members (GroupMembers).\n * Kinds are at basePath/{kind}, a group at basePath/{kind}/{id}, filters in the query.\n */\nexport function GroupManager({ client: own, baseUrl, auth, guard, appearance, className, language, messages, ...p }: GroupManagerProps) {\n const client = useFlowClient({ client: own, baseUrl, auth });\n return (\n <AdminRoot flow=\"group-manager\" appearance={appearance} className={className} language={language} messages={messages} guard={guard}>\n <Manager {...p} client={client} />\n </AdminRoot>\n );\n}\n\ntype Inner = Omit<GroupManagerProps, \"client\" | \"baseUrl\" | \"auth\" | \"guard\" | \"appearance\" | \"className\" | \"language\" | \"messages\"> & { client: ContentKitClient };\ntype Ctx = Inner & { loc: AdminLocation; kind: string; kinds: ContentModel };\n\nfunction Manager({ basePath, navigation, ...p }: Inner) {\n const { t } = useMessages();\n const loc = useAdminLocation(basePath, navigation);\n const access = useGroupManagerAccess({ client: p.client });\n const model = useKinds({ client: p.client });\n const kinds = model.kinds;\n const list = useMemo(\n () =>\n p.groupKinds ??\n Object.entries(kinds?.entity_kinds ?? {})\n .filter(([, k]) => k.owner !== \"user\")\n .map(([name]) => name)\n .sort(),\n [p.groupKinds, kinds],\n );\n if (access.loading || model.loading) return <Rows />;\n if (!access.allowed.groups) return <NoAccess>{t(\"groupManager.noAccess\")}</NoAccess>;\n if (!kinds) return <LoadFailed error={model.error} message={t(\"groupManager.kindsFailed\")} retry={model.reload} />;\n if (!list.length) return <p className=\"text-muted-foreground\">{t(\"groupManager.noKinds\")}</p>;\n const [k, sub] = loc.view.split(\"/\");\n const kind = list.includes(k ?? \"\") ? k! : list[0]!;\n const ctx: Ctx = { ...p, loc, kind, kinds };\n return (\n <>\n {list.length > 1 && (\n <Tabs value={kind} onValueChange={(v) => loc.go(String(v))}>\n <TabsList className=\"flex-wrap group-data-horizontal/tabs:h-auto\">\n {list.map((x) => (\n <TabsTrigger key={x} value={x} className=\"h-7.5\">\n {labelOf(p.labels, x)}\n </TabsTrigger>\n ))}\n </TabsList>\n </Tabs>\n )}\n {!sub ? <List key={kind} {...ctx} /> : sub === \"new\" ? <Create key={kind} {...ctx} /> : <Edit key={sub} {...ctx} id={sub} />}\n </>\n );\n}\n\nfunction Back({ loc, kind }: { loc: AdminLocation; kind: string }) {\n const { t } = useMessages();\n return (\n <Button variant=\"ghost\" size=\"sm\" className=\"justify-self-start\" onClick={() => loc.go(kind)}>\n {t(\"groupManager.back\")}\n </Button>\n );\n}\n\nfunction List({ loc, kind, kinds, client, contentKind, labels, pageSize = 50 }: Ctx) {\n const m = useMessages();\n const { t } = m;\n const languageName = useLanguageName();\n const languages = kinds.languages;\n const letterParam = loc.query.get(\"letter\") ?? \"\";\n const letter = LETTERS.includes(letterParam) ? letterParam : undefined;\n const sortParam = loc.query.get(\"sort\") ?? \"\";\n const sort = (SORTS as readonly string[]).includes(sortParam) ? (sortParam as GroupSort) : \"name\";\n const languageParam = loc.query.get(\"language\") ?? \"\";\n const language = languages.includes(languageParam) ? languageParam : languages[0];\n const filters: { letter?: string; sort?: GroupSort; language?: string } = { letter, sort: sort === \"name\" ? undefined : sort, language: language === languages[0] ? undefined : language };\n const filter = (next: Partial<typeof filters>) => loc.go(kind, { ...filters, ...next });\n const groups = useGroups({ kind, letter, sort, language, contentKind, pageSize }, { client, management: true });\n const label = labelOf(labels, kind);\n return (\n <div className=\"grid gap-4\" data-ckui=\"group-list\" data-kind={kind}>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h2 className=\"text-base font-semibold\">{label}</h2>\n <Button size=\"sm\" onClick={() => loc.go(`${kind}/new`)}>\n {t(\"groupManager.new\", { kind: label })}\n </Button>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Select value={sort} onValueChange={(v) => filter({ sort: v === \"name\" ? undefined : (String(v) as GroupSort) })}>\n <SelectTrigger size=\"sm\" aria-label={t(\"groupManager.sort\")}>\n <SelectValue>{(v: string) => t(`groupManager.sort_${v as GroupSort}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {SORTS.map((s) => (\n <SelectItem key={s} value={s}>\n {t(`groupManager.sort_${s}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {languages.length > 1 && (\n <Select value={language} onValueChange={(v) => filter({ language: v === languages[0] ? undefined : String(v) })}>\n <SelectTrigger size=\"sm\" aria-label={t(\"groupManager.language\")}>\n <SelectValue>{(v: string) => languageName(v)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {languages.map((l) => (\n <SelectItem key={l} value={l}>\n {languageName(l)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </div>\n <nav aria-label={t(\"groups.byLetter\")} className=\"flex flex-wrap gap-1\" data-ckui=\"letters\">\n {[undefined, ...LETTERS].map((l) => (\n <Button\n key={l ?? \"all\"}\n size=\"xs\"\n variant={letter === l ? \"default\" : \"ghost\"}\n aria-pressed={letter === l}\n aria-label={l === undefined ? undefined : l === \"#\" ? t(\"groups.otherLetters\") : l.toUpperCase()}\n className=\"min-w-7\"\n onClick={() => filter({ letter: l })}\n >\n {l === undefined ? t(\"groups.all\") : l.toUpperCase()}\n </Button>\n ))}\n </nav>\n {groups.loading && !groups.items.length ? (\n <Rows />\n ) : groups.error && !groups.items.length ? (\n <LoadFailed error={groups.error} message={t(\"groupManager.loadFailed\")} retry={groups.reload} />\n ) : !groups.items.length ? (\n <p className=\"text-muted-foreground\">{t(\"groups.empty\")}</p>\n ) : (\n <ul className=\"grid divide-y divide-border rounded-lg border border-border\" aria-busy={groups.loading}>\n {groups.items.map((g) => (\n <li key={g.id} className=\"flex flex-wrap items-center gap-3 p-3\" data-ckui=\"group-row\" data-slug={g.slug}>\n <div className=\"grid min-w-0 flex-1 gap-0.5\">\n <button type=\"button\" className=\"text-left font-medium break-words hover:underline\" onClick={() => loc.go(`${kind}/${g.id}`)}>\n {g.name || g.slug}\n </button>\n <span className=\"text-xs text-muted-foreground\">{g.slug}</span>\n {g.internal && <Badge variant=\"secondary\" className=\"justify-self-start\">{t(\"groupEditor.internal\")}</Badge>}\n </div>\n <span className=\"text-sm text-muted-foreground tabular-nums\" title={t(\"groupManager.count\")}>\n {new Intl.NumberFormat(m.language).format(g.count)}\n </span>\n </li>\n ))}\n </ul>\n )}\n {groups.hasMore && (\n <div className=\"grid justify-items-center gap-2\">\n {groups.error && <p role=\"alert\" className=\"text-destructive\">{contentError(m, groups.error)}</p>}\n <Button variant=\"outline\" size=\"sm\" disabled={groups.loadingMore} onClick={() => void groups.loadMore()}>\n {groups.loadingMore ? t(\"groups.loading\") : groups.error ? t(\"common.retry\") : t(\"groups.loadMore\")}\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nfunction Create({ loc, kind, client, labels, onError }: Ctx) {\n return (\n <div className=\"grid gap-4\">\n <Back loc={loc} kind={kind} />\n <GroupEditor\n management\n id={null}\n kind={kind}\n labels={labels}\n client={client}\n onError={onError}\n onCreated={(g) => loc.go(`${kind}/${g.id}`, undefined, { replace: true })}\n />\n </div>\n );\n}\n\nfunction Edit({ loc, kind, client, labels, onError, renderContent, id }: Ctx & { id: string }) {\n return (\n <div className=\"grid gap-4\">\n <Back loc={loc} kind={kind} />\n <GroupEditor\n management\n id={id}\n kind={kind}\n labels={labels}\n client={client}\n onError={onError}\n onMerged={(r) => loc.go(`${kind}/${r.into}`, undefined, { replace: true })}\n >\n {(group) => (\n <GroupMembers\n group={group}\n labels={labels}\n client={client}\n onError={onError}\n renderContent={renderContent}\n onUseCover={(content) => client.entities.update(group.id, { cover: { content_id: content } })}\n />\n )}\n </GroupEditor>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"group-manager.js","names":[],"sources":["../../../src/components/admin/group-manager.tsx"],"sourcesContent":["import { cn } from \"cn\";\nimport { useEffect, useMemo, useState, type ReactNode } from \"react\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport { LETTERS } from \"../../client/group-fields.js\";\nimport type { Content, ContentModel, Membership } from \"../../client/generated/wire.js\";\nimport { useLanguageName, useMessages } from \"../../i18n/context.js\";\nimport { useAdminLocation, useFlowClient, useStaffAccess, type AdminLocation, type FlowClientOptions, type StaffAccess } from \"../../react/admin.js\";\nimport { useGroups, useKinds, type GroupSort } from \"../../react/groups.js\";\nimport { Badge } from \"#ckui/ui/badge\";\nimport { Button } from \"#ckui/ui/button\";\nimport { Input } from \"#ckui/ui/input\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"#ckui/ui/select\";\nimport { Tabs, TabsList, TabsTrigger } from \"#ckui/ui/tabs\";\nimport { GroupEditor } from \"../groups/editor.js\";\nimport { GroupMembers, type GroupMembersProps } from \"../groups/group-members.js\";\nimport { labelOf, type Labels } from \"../groups/parts.js\";\nimport { ScopedGroups } from \"../groups/scoped.js\";\nimport { contentError, useAction } from \"../social/parts.js\";\nimport { AdminRoot, LoadFailed, NoAccess, Rows, type AdminFlowProps, type AdminRouteProps } from \"./shell.js\";\n\nexport interface GroupManagerProps extends AdminFlowProps, AdminRouteProps {\n /** The group kinds managed, in tab order; default the content model's site-owned kinds. */\n groupKinds?: readonly string[];\n /** Display names of kinds, attributes, roles and values by identifier. */\n labels?: Labels;\n /** Counts of this content kind; default every kind. */\n contentKind?: string;\n /** Where a member's card links, e.g. the host's editor; none: not a link. */\n contentHref?: (content: Content) => string | undefined;\n /** Where a new item of a content kind starts already in the group being edited; none: no action. */\n newContentHref?: GroupMembersProps[\"newContentHref\"];\n /** Replaces a member's card body; default its cover and title. */\n renderContent?: (member: Membership, content?: Content) => ReactNode;\n pageSize?: number;\n}\n\n/** Whether the caller may manage groups (root:groups:write). */\nexport function useGroupManagerAccess(o: FlowClientOptions = {}): StaffAccess<\"groups\"> {\n return useStaffAccess([\"groups\"] as const, o);\n}\n\nconst SORTS: readonly GroupSort[] = [\"name\", \"count\", \"newest\"];\n\n/**\n * Staff: groups per kind. A kind's groups by letter, order and language; a\n * new group; a group's editor (GroupEditor) and its members (GroupMembers).\n * Kinds are at basePath/{kind}, a group at basePath/{kind}/{id}, filters in the query.\n */\nexport function GroupManager({ client: own, baseUrl, auth, guard, appearance, className, language, messages, ...p }: GroupManagerProps) {\n const client = useFlowClient({ client: own, baseUrl, auth });\n return (\n <AdminRoot flow=\"group-manager\" appearance={appearance} className={className} language={language} messages={messages} guard={guard}>\n <Manager {...p} client={client} />\n </AdminRoot>\n );\n}\n\ntype Inner = Omit<GroupManagerProps, \"client\" | \"baseUrl\" | \"auth\" | \"guard\" | \"appearance\" | \"className\" | \"language\" | \"messages\"> & { client: ContentKitClient };\ntype Ctx = Inner & { loc: AdminLocation; kind: string; kinds: ContentModel };\n\nfunction Manager({ basePath, navigation, ...p }: Inner) {\n const { t } = useMessages();\n const loc = useAdminLocation(basePath, navigation);\n const access = useGroupManagerAccess({ client: p.client });\n const model = useKinds({ client: p.client });\n const kinds = model.kinds;\n const list = useMemo(\n () =>\n p.groupKinds ??\n Object.entries(kinds?.entity_kinds ?? {})\n .filter(([, k]) => k.owner !== \"user\")\n .map(([name]) => name)\n .sort(),\n [p.groupKinds, kinds],\n );\n if (access.loading || model.loading) return <Rows />;\n if (!access.allowed.groups) return <NoAccess>{t(\"groupManager.noAccess\")}</NoAccess>;\n if (!kinds) return <LoadFailed error={model.error} message={t(\"groupManager.kindsFailed\")} retry={model.reload} />;\n if (!list.length) return <p className=\"text-muted-foreground\">{t(\"groupManager.noKinds\")}</p>;\n const [k, sub] = loc.view.split(\"/\");\n const kind = list.includes(k ?? \"\") ? k! : list[0]!;\n const ctx: Ctx = { ...p, loc, kind, kinds };\n return (\n <>\n {list.length > 1 && (\n <Tabs value={kind} onValueChange={(v) => loc.go(String(v))}>\n <TabsList className=\"flex-wrap group-data-horizontal/tabs:h-auto\">\n {list.map((x) => (\n <TabsTrigger key={x} value={x} className=\"h-7.5\">\n {labelOf(p.labels, x)}\n </TabsTrigger>\n ))}\n </TabsList>\n </Tabs>\n )}\n {!sub ? <List key={kind} {...ctx} /> : sub === \"new\" ? <Create key={kind} {...ctx} /> : <Edit key={sub} {...ctx} id={sub} />}\n </>\n );\n}\n\nfunction Back({ loc, kind }: { loc: AdminLocation; kind: string }) {\n const { t } = useMessages();\n return (\n <Button variant=\"ghost\" size=\"sm\" className=\"justify-self-start\" onClick={() => loc.go(kind)}>\n {t(\"groupManager.back\")}\n </Button>\n );\n}\n\nfunction List({ loc, kind, kinds, client, contentKind, labels, onError, pageSize = 50 }: Ctx) {\n const m = useMessages();\n const { t } = m;\n const languageName = useLanguageName();\n const languages = kinds.languages;\n const deleted = loc.query.get(\"deleted\") === \"1\";\n const query = loc.query.get(\"q\") ?? \"\";\n // Typing narrows the list as it goes; the URL keeps the search.\n const [text, setText] = useState(query);\n useEffect(() => setText(query), [query]);\n const letterParam = loc.query.get(\"letter\") ?? \"\";\n const letter = LETTERS.includes(letterParam) ? letterParam : undefined;\n const sortParam = loc.query.get(\"sort\") ?? \"\";\n const sort = (SORTS as readonly string[]).includes(sortParam) ? (sortParam as GroupSort) : \"name\";\n const languageParam = loc.query.get(\"language\") ?? \"\";\n const language = languages.includes(languageParam) ? languageParam : languages[0];\n const filters: { letter?: string; sort?: GroupSort; language?: string; q?: string; deleted?: string } = {\n letter,\n sort: sort === \"name\" ? undefined : sort,\n language: language === languages[0] ? undefined : language,\n q: query || undefined,\n deleted: deleted ? \"1\" : undefined,\n };\n const filter = (next: Partial<typeof filters>) => loc.go(kind, { ...filters, ...next });\n useEffect(() => {\n if (text.trim() === query) return;\n const timer = setTimeout(() => loc.go(kind, { ...filters, q: text.trim() || undefined }, { replace: true }), 250);\n return () => clearTimeout(timer);\n }, [text]); // eslint-disable-line react-hooks/exhaustive-deps\n const groups = useGroups({ kind, letter, sort, language, contentKind, pageSize, query: query || undefined, deleted }, { client, management: true });\n const restore = useAction(\"group.save\", onError);\n const label = labelOf(labels, kind);\n return (\n <div className=\"grid gap-4\" data-ckui=\"group-list\" data-kind={kind}>\n <div className=\"flex flex-wrap items-center justify-between gap-2\">\n <h2 className=\"text-base font-semibold\">{label}</h2>\n <Button size=\"sm\" onClick={() => loc.go(`${kind}/new`)}>\n {t(\"groupManager.new\", { kind: label })}\n </Button>\n </div>\n <div className=\"flex gap-2\" role=\"group\" aria-label={label}>\n <Button size=\"sm\" variant={deleted ? \"outline\" : \"default\"} aria-pressed={!deleted} onClick={() => filter({ deleted: undefined })}>\n {t(\"groupManager.active\")}\n </Button>\n <Button size=\"sm\" variant={deleted ? \"default\" : \"outline\"} aria-pressed={deleted} onClick={() => filter({ deleted: \"1\" })}>\n {t(\"groupManager.deleted\")}\n </Button>\n </div>\n <div className=\"flex flex-wrap items-center gap-2\">\n <Input\n type=\"search\"\n className=\"h-8 min-w-48 flex-1\"\n aria-label={t(\"groupManager.search\")}\n placeholder={t(\"groupManager.search\")}\n value={text}\n onChange={(e) => setText(e.target.value)}\n />\n <Select value={sort} onValueChange={(v) => filter({ sort: v === \"name\" ? undefined : (String(v) as GroupSort) })}>\n <SelectTrigger size=\"sm\" aria-label={t(\"groupManager.sort\")}>\n <SelectValue>{(v: string) => t(`groupManager.sort_${v as GroupSort}`)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {SORTS.map((s) => (\n <SelectItem key={s} value={s}>\n {t(`groupManager.sort_${s}`)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n {languages.length > 1 && (\n <Select value={language} onValueChange={(v) => filter({ language: v === languages[0] ? undefined : String(v) })}>\n <SelectTrigger size=\"sm\" aria-label={t(\"groupManager.language\")}>\n <SelectValue>{(v: string) => languageName(v)}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n {languages.map((l) => (\n <SelectItem key={l} value={l}>\n {languageName(l)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n </div>\n <nav aria-label={t(\"groups.byLetter\")} className=\"flex flex-wrap gap-1\" data-ckui=\"letters\">\n {[undefined, ...LETTERS].map((l) => (\n <Button\n key={l ?? \"all\"}\n size=\"xs\"\n variant={letter === l ? \"default\" : \"ghost\"}\n aria-pressed={letter === l}\n aria-label={l === undefined ? undefined : l === \"#\" ? t(\"groups.otherLetters\") : l.toUpperCase()}\n className=\"min-w-7\"\n onClick={() => filter({ letter: l })}\n >\n {l === undefined ? t(\"groups.all\") : l.toUpperCase()}\n </Button>\n ))}\n </nav>\n {groups.loading && !groups.items.length ? (\n <Rows />\n ) : groups.error && !groups.items.length ? (\n <LoadFailed error={groups.error} message={t(\"groupManager.loadFailed\")} retry={groups.reload} />\n ) : !groups.items.length ? (\n <p className=\"text-muted-foreground\">{t(deleted ? \"groupManager.noDeleted\" : query ? \"groupManager.noMatches\" : \"groups.empty\")}</p>\n ) : (\n <ul className=\"grid divide-y divide-border rounded-lg border border-border\" aria-busy={groups.loading}>\n {groups.items.map((g) => (\n <li key={g.id} className=\"flex flex-wrap items-center gap-3 p-3\" data-ckui=\"group-row\" data-slug={g.slug} data-state={deleted ? \"deleted\" : \"active\"}>\n {(g.avatar?.renditions?.[0] ?? g.cover?.renditions?.[0]) && (\n <img src={(g.avatar?.renditions?.[0] ?? g.cover?.renditions?.[0])!.url} alt=\"\" loading=\"lazy\" className={cn(\"size-9 shrink-0 object-cover\", g.avatar?.renditions?.[0] ? \"rounded-full\" : \"rounded-sm\")} />\n )}\n <div className=\"grid min-w-0 flex-1 gap-0.5\">\n <button type=\"button\" className=\"text-left font-medium break-words hover:underline\" onClick={() => loc.go(`${kind}/${g.id}`)}>\n {g.name || g.slug}\n </button>\n <span className=\"text-xs text-muted-foreground\">{g.slug}</span>\n {g.internal && <Badge variant=\"secondary\" className=\"justify-self-start\">{t(\"groupEditor.internal\")}</Badge>}\n </div>\n <span className=\"text-sm text-muted-foreground tabular-nums\" title={t(\"groupManager.count\")}>\n {new Intl.NumberFormat(m.language).format(g.count)}\n </span>\n {deleted && (\n <Button size=\"sm\" variant=\"outline\" disabled={restore.pending}\n onClick={() => void restore.run(() => client.entities.update(g.id, { state: \"active\" })).then((d) => d !== undefined && groups.reload())}>\n {t(\"groupEditor.restore\")}\n </Button>\n )}\n </li>\n ))}\n </ul>\n )}\n {groups.hasMore && (\n <div className=\"grid justify-items-center gap-2\">\n {groups.error && <p role=\"alert\" className=\"text-destructive\">{contentError(m, groups.error)}</p>}\n <Button variant=\"outline\" size=\"sm\" disabled={groups.loadingMore} onClick={() => void groups.loadMore()}>\n {groups.loadingMore ? t(\"groups.loading\") : groups.error ? t(\"common.retry\") : t(\"groups.loadMore\")}\n </Button>\n </div>\n )}\n </div>\n );\n}\n\nfunction Create({ loc, kind, client, labels, onError }: Ctx) {\n return (\n <div className=\"grid gap-4\">\n <Back loc={loc} kind={kind} />\n <GroupEditor\n management\n id={null}\n kind={kind}\n labels={labels}\n client={client}\n onError={onError}\n onCreated={(g) => loc.go(`${kind}/${g.id}`, undefined, { replace: true })}\n />\n </div>\n );\n}\n\nfunction Edit({ loc, kind, client, labels, onError, renderContent, contentHref, newContentHref, id }: Ctx & { id: string }) {\n return (\n <div className=\"grid gap-4\">\n <Back loc={loc} kind={kind} />\n <GroupEditor\n management\n id={id}\n kind={kind}\n labels={labels}\n client={client}\n onError={onError}\n onMerged={(r) => loc.go(`${kind}/${r.into}`, undefined, { replace: true })}\n >\n {(group) => (\n <>\n <ScopedGroups group={group} management labels={labels} client={client} onSelect={(c) => loc.go(`${c.kind}/${c.id}`)} />\n <GroupMembers\n group={group}\n labels={labels}\n client={client}\n onError={onError}\n renderContent={renderContent}\n contentHref={contentHref}\n newContentHref={newContentHref}\n onUseCover={(content) => client.entities.update(group.id, { cover: { content_id: content } })}\n />\n </>\n )}\n </GroupEditor>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { ContentKitClient } from '../../client/client.js';
2
+ import { ContentKitErrorHandler } from '../../react/context.js';
3
+ export interface PageNoticesProps {
4
+ content: string;
5
+ version: string;
6
+ client?: ContentKitClient;
7
+ onError?: ContentKitErrorHandler;
8
+ className?: string;
9
+ }
10
+ /**
11
+ * Low-key notes about what automatic page processing did: pages removed as
12
+ * blank, duplicate or covered by a two-page spread (restorable), and an
13
+ * archive put into name order. Collapsed by default; nothing here blocks
14
+ * saving or publishing. Renders nothing without notices.
15
+ */
16
+ export declare function PageNotices({ content, version, client, onError, className }: PageNoticesProps): import('react').JSX.Element | null;