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

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 (217) 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 +9 -1
  5. package/dist/client/contents.js +73 -55
  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/error-codes.d.ts +1 -1
  11. package/dist/client/generated/error-codes.js +4 -0
  12. package/dist/client/generated/error-codes.js.map +1 -1
  13. package/dist/client/generated/routes.d.ts +43 -30
  14. package/dist/client/generated/routes.js +70 -63
  15. package/dist/client/generated/routes.js.map +1 -1
  16. package/dist/client/generated/wire.d.ts +36 -74
  17. package/dist/client/generated/wire.js.map +1 -1
  18. package/dist/client/index.d.ts +1 -1
  19. package/dist/client/media/windows.d.ts +2 -0
  20. package/dist/client/media/windows.js +4 -1
  21. package/dist/client/media/windows.js.map +1 -1
  22. package/dist/client/stats.d.ts +4 -20
  23. package/dist/client/stats.js +0 -11
  24. package/dist/client/stats.js.map +1 -1
  25. package/dist/client/versions.d.ts +8 -6
  26. package/dist/client/versions.js +15 -10
  27. package/dist/client/versions.js.map +1 -1
  28. package/dist/components/admin/bulk-drafts.d.ts +17 -0
  29. package/dist/components/admin/bulk-drafts.js +41 -0
  30. package/dist/components/admin/bulk-drafts.js.map +1 -0
  31. package/dist/components/admin/content-admin.d.ts +1 -1
  32. package/dist/components/admin/content-admin.js.map +1 -1
  33. package/dist/components/admin/content-manager.d.ts +11 -3
  34. package/dist/components/admin/content-manager.js +739 -380
  35. package/dist/components/admin/content-manager.js.map +1 -1
  36. package/dist/components/admin/group-manager.d.ts +8 -3
  37. package/dist/components/admin/group-manager.js +218 -146
  38. package/dist/components/admin/group-manager.js.map +1 -1
  39. package/dist/components/admin/page-notices.d.ts +16 -0
  40. package/dist/components/admin/page-notices.js +113 -0
  41. package/dist/components/admin/page-notices.js.map +1 -0
  42. package/dist/components/admin/page-picker.d.ts +38 -0
  43. package/dist/components/admin/page-picker.js +159 -0
  44. package/dist/components/admin/page-picker.js.map +1 -0
  45. package/dist/components/admin/reader-content-editor.js +537 -500
  46. package/dist/components/admin/reader-content-editor.js.map +1 -1
  47. package/dist/components/admin/reader-manifest.js +181 -179
  48. package/dist/components/admin/reader-manifest.js.map +1 -1
  49. package/dist/components/admin/shell.d.ts +10 -2
  50. package/dist/components/admin/shell.js +114 -42
  51. package/dist/components/admin/shell.js.map +1 -1
  52. package/dist/components/admin/stats-dashboard.d.ts +4 -9
  53. package/dist/components/admin/stats-dashboard.js +300 -202
  54. package/dist/components/admin/stats-dashboard.js.map +1 -1
  55. package/dist/components/admin/upload-queue.d.ts +14 -0
  56. package/dist/components/admin/upload-queue.js +115 -98
  57. package/dist/components/admin/upload-queue.js.map +1 -1
  58. package/dist/components/content/card.d.ts +31 -3
  59. package/dist/components/content/card.js +324 -158
  60. package/dist/components/content/card.js.map +1 -1
  61. package/dist/components/content/daily-releases.js +14 -12
  62. package/dist/components/content/daily-releases.js.map +1 -1
  63. package/dist/components/content/editor-save.js +27 -25
  64. package/dist/components/content/editor-save.js.map +1 -1
  65. package/dist/components/content/editors.js +274 -253
  66. package/dist/components/content/editors.js.map +1 -1
  67. package/dist/components/content/favorites.d.ts +1 -1
  68. package/dist/components/content/favorites.js +36 -22
  69. package/dist/components/content/favorites.js.map +1 -1
  70. package/dist/components/content/grid.d.ts +11 -4
  71. package/dist/components/content/grid.js +52 -43
  72. package/dist/components/content/grid.js.map +1 -1
  73. package/dist/components/content/history.js +83 -63
  74. package/dist/components/content/history.js.map +1 -1
  75. package/dist/components/content/index.d.ts +5 -3
  76. package/dist/components/content/listing.d.ts +14 -3
  77. package/dist/components/content/listing.js +65 -56
  78. package/dist/components/content/listing.js.map +1 -1
  79. package/dist/components/content/offer-fields.js +6 -6
  80. package/dist/components/content/paged-grid.d.ts +10 -0
  81. package/dist/components/content/paged-grid.js +116 -0
  82. package/dist/components/content/paged-grid.js.map +1 -0
  83. package/dist/components/content/pagination.d.ts +19 -0
  84. package/dist/components/content/pagination.js +97 -0
  85. package/dist/components/content/pagination.js.map +1 -0
  86. package/dist/components/content/paywall.d.ts +9 -0
  87. package/dist/components/content/paywall.js +27 -3
  88. package/dist/components/content/paywall.js.map +1 -1
  89. package/dist/components/content/post-list.d.ts +37 -0
  90. package/dist/components/content/post-list.js +203 -0
  91. package/dist/components/content/post-list.js.map +1 -0
  92. package/dist/components/content/reader-settings.d.ts +2 -0
  93. package/dist/components/content/reader-settings.js +1 -1
  94. package/dist/components/content/reader-settings.js.map +1 -1
  95. package/dist/components/groups/banner.d.ts +6 -2
  96. package/dist/components/groups/banner.js +79 -61
  97. package/dist/components/groups/banner.js.map +1 -1
  98. package/dist/components/groups/directory.d.ts +12 -2
  99. package/dist/components/groups/directory.js +168 -105
  100. package/dist/components/groups/directory.js.map +1 -1
  101. package/dist/components/groups/editor.js +10 -10
  102. package/dist/components/groups/editor.js.map +1 -1
  103. package/dist/components/groups/entity-chips.d.ts +61 -0
  104. package/dist/components/groups/entity-chips.js +382 -0
  105. package/dist/components/groups/entity-chips.js.map +1 -0
  106. package/dist/components/groups/group-members.d.ts +29 -0
  107. package/dist/components/groups/group-members.js +474 -0
  108. package/dist/components/groups/group-members.js.map +1 -0
  109. package/dist/components/groups/header.js +53 -45
  110. package/dist/components/groups/header.js.map +1 -1
  111. package/dist/components/groups/index.d.ts +3 -1
  112. package/dist/components/groups/memberships.d.ts +3 -36
  113. package/dist/components/groups/memberships.js +105 -480
  114. package/dist/components/groups/memberships.js.map +1 -1
  115. package/dist/components/groups/scoped.d.ts +23 -0
  116. package/dist/components/groups/scoped.js +92 -0
  117. package/dist/components/groups/scoped.js.map +1 -0
  118. package/dist/components/media-folder-editor.d.ts +5 -0
  119. package/dist/components/media-folder-editor.js +418 -230
  120. package/dist/components/media-folder-editor.js.map +1 -1
  121. package/dist/components/social/poll.js +57 -48
  122. package/dist/components/social/poll.js.map +1 -1
  123. package/dist/components/sortable-list.d.ts +5 -1
  124. package/dist/components/sortable-list.js +97 -81
  125. package/dist/components/sortable-list.js.map +1 -1
  126. package/dist/index.d.ts +1 -1
  127. package/dist/index.js +41 -37
  128. package/dist/locales/admin/de.js +78 -45
  129. package/dist/locales/admin/de.js.map +1 -1
  130. package/dist/locales/admin/en.d.ts +74 -41
  131. package/dist/locales/admin/en.js +78 -45
  132. package/dist/locales/admin/en.js.map +1 -1
  133. package/dist/locales/admin/es.js +78 -45
  134. package/dist/locales/admin/es.js.map +1 -1
  135. package/dist/locales/admin/ja.js +78 -45
  136. package/dist/locales/admin/ja.js.map +1 -1
  137. package/dist/locales/admin/ko.js +78 -45
  138. package/dist/locales/admin/ko.js.map +1 -1
  139. package/dist/locales/admin/zh.js +78 -45
  140. package/dist/locales/admin/zh.js.map +1 -1
  141. package/dist/locales/de.js +2 -0
  142. package/dist/locales/de.js.map +1 -1
  143. package/dist/locales/discovery/de.js +25 -1
  144. package/dist/locales/discovery/de.js.map +1 -1
  145. package/dist/locales/discovery/en.d.ts +24 -0
  146. package/dist/locales/discovery/en.js +25 -1
  147. package/dist/locales/discovery/en.js.map +1 -1
  148. package/dist/locales/discovery/es.js +25 -1
  149. package/dist/locales/discovery/es.js.map +1 -1
  150. package/dist/locales/discovery/ja.js +25 -1
  151. package/dist/locales/discovery/ja.js.map +1 -1
  152. package/dist/locales/discovery/ko.js +25 -1
  153. package/dist/locales/discovery/ko.js.map +1 -1
  154. package/dist/locales/discovery/zh.js +25 -1
  155. package/dist/locales/discovery/zh.js.map +1 -1
  156. package/dist/locales/en.d.ts +120 -43
  157. package/dist/locales/en.js +2 -0
  158. package/dist/locales/en.js.map +1 -1
  159. package/dist/locales/es.js +2 -0
  160. package/dist/locales/es.js.map +1 -1
  161. package/dist/locales/groups/de.js +22 -4
  162. package/dist/locales/groups/de.js.map +1 -1
  163. package/dist/locales/groups/en.d.ts +20 -2
  164. package/dist/locales/groups/en.js +22 -4
  165. package/dist/locales/groups/en.js.map +1 -1
  166. package/dist/locales/groups/es.js +22 -4
  167. package/dist/locales/groups/es.js.map +1 -1
  168. package/dist/locales/groups/ja.js +22 -4
  169. package/dist/locales/groups/ja.js.map +1 -1
  170. package/dist/locales/groups/ko.js +22 -4
  171. package/dist/locales/groups/ko.js.map +1 -1
  172. package/dist/locales/groups/zh.js +22 -4
  173. package/dist/locales/groups/zh.js.map +1 -1
  174. package/dist/locales/ja.js +2 -0
  175. package/dist/locales/ja.js.map +1 -1
  176. package/dist/locales/ko.js +2 -0
  177. package/dist/locales/ko.js.map +1 -1
  178. package/dist/locales/zh.js +2 -0
  179. package/dist/locales/zh.js.map +1 -1
  180. package/dist/react/contents.js +1 -1
  181. package/dist/react/contents.js.map +1 -1
  182. package/dist/react/discovery.d.ts +16 -0
  183. package/dist/react/discovery.js +69 -37
  184. package/dist/react/discovery.js.map +1 -1
  185. package/dist/react/groups.d.ts +19 -3
  186. package/dist/react/groups.js +49 -22
  187. package/dist/react/groups.js.map +1 -1
  188. package/dist/react/index.d.ts +6 -4
  189. package/dist/react/page-notices.d.ts +13 -0
  190. package/dist/react/page-notices.js +38 -0
  191. package/dist/react/page-notices.js.map +1 -0
  192. package/dist/react/post-reads.d.ts +23 -0
  193. package/dist/react/post-reads.js +90 -0
  194. package/dist/react/post-reads.js.map +1 -0
  195. package/dist/react/remembered-sort.d.ts +5 -0
  196. package/dist/react/remembered-sort.js +29 -0
  197. package/dist/react/remembered-sort.js.map +1 -0
  198. package/dist/react/resources.js +2 -2
  199. package/dist/react/resources.js.map +1 -1
  200. package/dist/react/stats.d.ts +3 -7
  201. package/dist/react/stats.js +2 -6
  202. package/dist/react/stats.js.map +1 -1
  203. package/dist/react/use-engagement.d.ts +2 -0
  204. package/dist/react/use-engagement.js +40 -34
  205. package/dist/react/use-engagement.js.map +1 -1
  206. package/dist/react.js +29 -27
  207. package/dist/styles.css +1 -1
  208. package/dist/urls/index.d.ts +1 -1
  209. package/dist/urls.js +2 -2
  210. package/dist/urls.js.map +1 -1
  211. package/package.json +1 -1
  212. package/dist/components/admin/page-review.d.ts +0 -13
  213. package/dist/components/admin/page-review.js +0 -225
  214. package/dist/components/admin/page-review.js.map +0 -1
  215. package/dist/react/page-review.d.ts +0 -14
  216. package/dist/react/page-review.js +0 -37
  217. package/dist/react/page-review.js.map +0 -1
@@ -0,0 +1,474 @@
1
+ import { useMessages as e } from "../../i18n/context.js";
2
+ import { ContentKitUiRoot as t } from "../../scope.js";
3
+ import { useContentKitClient as n } from "../../react/context.js";
4
+ import { useGroupMembers as r, useKinds as i } from "../../react/groups.js";
5
+ import { Button as a, buttonVariants as o } from "../../ui/button.js";
6
+ import { SortableList as s } from "../sortable-list.js";
7
+ import { Badge as c } from "../../ui/badge.js";
8
+ import { Select as l, SelectContent as u, SelectItem as d, SelectTrigger as f, SelectValue as p } from "../../ui/select.js";
9
+ import { Skeleton as m } from "../../ui/skeleton.js";
10
+ import { ErrorLine as h, contentError as g, formatDate as _, useAction as v } from "../social/parts.js";
11
+ import { useTypeahead as y } from "../../react/discovery.js";
12
+ import { labelOf as b } from "./parts.js";
13
+ import { WindowFields as x } from "./entity-chips.js";
14
+ import { accessLabel as S, contentStatus as C } from "../admin/content-manager.js";
15
+ import { useCallback as w, useEffect as T, useId as E, useMemo as D, useState as O } from "react";
16
+ import { Fragment as k, jsx as A, jsxs as j } from "react/jsx-runtime";
17
+ import { cn as M } from "cn";
18
+ import { Cancel01Icon as N, Image01Icon as P, Tick02Icon as F } from "@hugeicons/core-free-icons";
19
+ import { HugeiconsIcon as I } from "@hugeicons/react";
20
+ //#region src/components/groups/group-members.tsx
21
+ var L = "__none__", R = 100, z = (e) => `${e.content_id}|${e.version_id ?? ""}`;
22
+ function B(e, t) {
23
+ let [n, r] = O(/* @__PURE__ */ new Map()), i = D(() => [...new Set(e)].sort(), [e]);
24
+ return T(() => {
25
+ let e = i.filter((e) => !n.has(e));
26
+ if (!e.length) return;
27
+ let a = new AbortController(), o = [];
28
+ for (let t = 0; t < e.length; t += R) o.push(e.slice(t, t + R));
29
+ return Promise.all(o.map((e) => t.contents.manage({
30
+ ids: e,
31
+ limit: e.length
32
+ }, a.signal).catch(() => []))).then((e) => {
33
+ a.signal.aborted || r((t) => {
34
+ let n = new Map(t);
35
+ for (let t of e.flat()) n.set(t.id, t);
36
+ return n;
37
+ });
38
+ }), () => a.abort();
39
+ }, [i, t]), n;
40
+ }
41
+ var V = (e) => e?.cover?.url ?? e?.versions.find((e) => e.cover?.url)?.cover?.url;
42
+ function H(l) {
43
+ let u = e(), { t: d } = u, f = n(l.client), { kinds: p } = i({ client: l.client }), y = p?.entity_kinds?.[l.group.kind] ?? {}, w = r(l.group.id, {
44
+ pageSize: l.pageSize,
45
+ client: l.client
46
+ }), T = B(D(() => w.items.map((e) => e.content_id).filter(Boolean), [w.items]), f), E = v("membership.save", l.onError), [L, R] = O(null), [H, W] = O({}), G = (e) => T.get(e.content_id ?? "")?.title || e.content_id || "", K = (e) => `${G(e)}${e.version_id ? ` (${d("memberships.version")})` : ""}`, ee = (e) => [...new Map(e.map((e) => [z(e), {
47
+ content_id: e.content_id,
48
+ version_id: e.version_id
49
+ }])).values()], q = ({ id: e, ...t }) => t, J = (e, t) => /* @__PURE__ */ j(k, { children: [
50
+ t && t.access.level !== "public" && /* @__PURE__ */ A(c, {
51
+ variant: "secondary",
52
+ children: S(d, t.access, l.labels)
53
+ }),
54
+ t && (t.state === "deleted" || C(t) !== "published") && /* @__PURE__ */ A(c, {
55
+ variant: t.state === "deleted" ? "destructive" : "outline",
56
+ children: d(t.state === "deleted" ? "contentManager.deleted" : `contentManager.${C(t)}`)
57
+ }),
58
+ e.version_id && /* @__PURE__ */ A(c, {
59
+ variant: "outline",
60
+ children: d("memberships.version")
61
+ }),
62
+ e.role && /* @__PURE__ */ A(c, {
63
+ variant: "secondary",
64
+ children: b(l.labels, e.role)
65
+ }),
66
+ e.state === "proposed" && /* @__PURE__ */ A(c, {
67
+ variant: "secondary",
68
+ children: d("memberships.proposed")
69
+ })
70
+ ] }), Y = (e) => /* @__PURE__ */ j(k, { children: [
71
+ e.state === "proposed" && /* @__PURE__ */ A(a, {
72
+ size: "icon-xs",
73
+ variant: "secondary",
74
+ disabled: E.pending,
75
+ "aria-label": `${d("memberships.accept")}: ${K(e)}`,
76
+ title: d("memberships.accept"),
77
+ onClick: () => void E.run(() => w.add([{
78
+ ...q(e),
79
+ state: "active"
80
+ }])),
81
+ children: /* @__PURE__ */ A(I, {
82
+ icon: F,
83
+ strokeWidth: 2.5
84
+ })
85
+ }),
86
+ l.onUseCover && !e.version_id && /* @__PURE__ */ A(a, {
87
+ size: "icon-xs",
88
+ variant: "secondary",
89
+ "aria-label": `${d("memberships.useCover")}: ${K(e)}`,
90
+ title: d("memberships.useCover"),
91
+ disabled: E.pending || l.group.cover?.content_id === e.content_id && !l.group.cover?.auto,
92
+ onClick: () => void E.run(() => l.onUseCover(e.content_id)),
93
+ children: /* @__PURE__ */ A(I, {
94
+ icon: P,
95
+ strokeWidth: 2
96
+ })
97
+ }),
98
+ /* @__PURE__ */ A(a, {
99
+ size: "icon-xs",
100
+ variant: "secondary",
101
+ disabled: E.pending,
102
+ "aria-label": d("memberships.remove", { name: K(e) }),
103
+ title: d("common.remove"),
104
+ onClick: () => void E.run(() => w.remove([q(e)])),
105
+ children: /* @__PURE__ */ A(I, {
106
+ icon: N,
107
+ strokeWidth: 2.5
108
+ })
109
+ })
110
+ ] }), X = (e) => y.windows && (L === e.id ? /* @__PURE__ */ j("span", {
111
+ className: "flex flex-wrap items-center gap-1",
112
+ children: [
113
+ /* @__PURE__ */ A(x, {
114
+ from: H.from,
115
+ until: H.until,
116
+ name: K(e),
117
+ onChange: (e) => W((t) => ({
118
+ from: "active_from" in e ? e.active_from : t.from,
119
+ until: "active_until" in e ? e.active_until : t.until
120
+ }))
121
+ }),
122
+ /* @__PURE__ */ A(a, {
123
+ size: "xs",
124
+ disabled: E.pending,
125
+ onClick: () => void E.run(() => w.add([{
126
+ ...q(e),
127
+ active_from: H.from,
128
+ active_until: H.until
129
+ }])).then((e) => e !== void 0 && R(null)),
130
+ children: d("common.save")
131
+ }),
132
+ /* @__PURE__ */ A(a, {
133
+ size: "xs",
134
+ variant: "ghost",
135
+ onClick: () => R(null),
136
+ children: d("common.cancel")
137
+ })
138
+ ]
139
+ }) : /* @__PURE__ */ A("button", {
140
+ type: "button",
141
+ className: "text-start text-xs text-muted-foreground hover:underline",
142
+ "data-ckui": "member-window",
143
+ onClick: () => {
144
+ W({
145
+ from: e.active_from,
146
+ until: e.active_until
147
+ }), R(e.id);
148
+ },
149
+ children: e.active_from || e.active_until ? d("memberships.window", {
150
+ from: e.active_from ? _(u, e.active_from) : "…",
151
+ until: e.active_until ? _(u, e.active_until) : "…"
152
+ }) : d("memberships.always")
153
+ })), Z = (e, t) => {
154
+ let n = V(e);
155
+ return n ? /* @__PURE__ */ A("img", {
156
+ src: n,
157
+ alt: "",
158
+ loading: "lazy",
159
+ className: M("object-cover", t)
160
+ }) : /* @__PURE__ */ A("span", {
161
+ "aria-hidden": !0,
162
+ className: M("bg-muted", t)
163
+ });
164
+ }, Q = (e, t, n) => {
165
+ let r = T.get(e.content_id ?? ""), i = r && l.contentHref?.(r);
166
+ return i ? /* @__PURE__ */ A("a", {
167
+ href: i,
168
+ className: M("hover:underline", n),
169
+ children: t
170
+ }) : /* @__PURE__ */ A("span", {
171
+ className: n,
172
+ children: t
173
+ });
174
+ }, te = (e) => {
175
+ let t = T.get(e.content_id ?? "");
176
+ return /* @__PURE__ */ j("li", {
177
+ className: "group/member relative grid content-start gap-1.5",
178
+ "data-ckui": "group-member",
179
+ "data-content": e.content_id,
180
+ "data-state": e.state ?? "active",
181
+ children: [
182
+ l.renderContent ? l.renderContent(e, t) : /* @__PURE__ */ j(k, { children: [Q(e, Z(t, "aspect-[7/10] w-full rounded-md"), "block"), Q(e, G(e), M("line-clamp-2 text-sm font-medium break-words", !t && "font-mono text-xs"))] }),
183
+ /* @__PURE__ */ A("span", {
184
+ className: "flex flex-wrap gap-1",
185
+ children: J(e, t)
186
+ }),
187
+ X(e),
188
+ /* @__PURE__ */ A("span", {
189
+ className: "absolute end-1 top-1 flex gap-1 opacity-0 transition-opacity group-hover/member:opacity-100 focus-within:opacity-100",
190
+ children: Y(e)
191
+ })
192
+ ]
193
+ }, e.id);
194
+ }, ne = (e, t) => {
195
+ let n = T.get(e.content_id ?? "");
196
+ return /* @__PURE__ */ j("div", {
197
+ className: "group/member flex flex-wrap items-center gap-2",
198
+ "data-ckui": "group-member",
199
+ "data-content": e.content_id,
200
+ "data-state": e.state ?? "active",
201
+ children: [
202
+ t,
203
+ e.position !== void 0 && /* @__PURE__ */ A("span", {
204
+ className: "w-8 text-xs text-muted-foreground tabular-nums",
205
+ children: e.position
206
+ }),
207
+ l.renderContent ? /* @__PURE__ */ A("span", {
208
+ className: "min-w-0 flex-1",
209
+ children: l.renderContent(e, n)
210
+ }) : /* @__PURE__ */ j(k, { children: [Q(e, Z(n, "h-12 w-9 rounded-sm"), "shrink-0"), Q(e, G(e), M("min-w-0 flex-1 break-words", !n && "font-mono text-xs"))] }),
211
+ J(e, n),
212
+ X(e),
213
+ /* @__PURE__ */ A("span", {
214
+ className: "flex gap-1 opacity-60 transition-opacity group-hover/member:opacity-100 focus-within:opacity-100",
215
+ children: Y(e)
216
+ })
217
+ ]
218
+ });
219
+ }, $ = D(() => {
220
+ let e = /* @__PURE__ */ new Map();
221
+ for (let t of w.items) {
222
+ let n = T.get(t.content_id ?? "")?.kind ?? "";
223
+ e.set(n, [...e.get(n) ?? [], t]);
224
+ }
225
+ return [...e].sort(([e], [t]) => e === "" ? 1 : t === "" ? -1 : e.localeCompare(t));
226
+ }, [w.items, T]), re = y.version_level ? [] : Object.entries(p?.kinds ?? {}).flatMap(([e, t]) => {
227
+ let n = t.entities?.includes(l.group.kind) ? l.newContentHref?.(e, l.group) : void 0;
228
+ return n ? [{
229
+ kind: e,
230
+ href: n
231
+ }] : [];
232
+ });
233
+ return /* @__PURE__ */ j(t, {
234
+ appearance: l.appearance,
235
+ className: M("grid gap-3 text-sm", l.className),
236
+ "data-ckui": "group-members",
237
+ children: [
238
+ /* @__PURE__ */ A("h3", {
239
+ className: "font-medium",
240
+ children: d("memberships.members")
241
+ }),
242
+ re.length > 0 && /* @__PURE__ */ A("div", {
243
+ className: "flex flex-wrap gap-2",
244
+ children: re.map((e) => /* @__PURE__ */ A("a", {
245
+ href: e.href,
246
+ className: o({
247
+ variant: "outline",
248
+ size: "sm"
249
+ }),
250
+ "data-ckui": "group-member-new",
251
+ children: d("memberships.newContent", {
252
+ kind: b(l.labels, e.kind),
253
+ name: l.group.name
254
+ })
255
+ }, e.kind))
256
+ }),
257
+ /* @__PURE__ */ A(U, {
258
+ spec: y,
259
+ labels: l.labels,
260
+ client: f,
261
+ onAdd: (e) => E.run(() => w.add([e]))
262
+ }),
263
+ w.loading && !w.items.length ? /* @__PURE__ */ A(m, { className: "h-40 w-full" }) : w.error && !w.items.length ? /* @__PURE__ */ j("div", {
264
+ role: "alert",
265
+ className: "grid justify-items-start gap-2",
266
+ children: [/* @__PURE__ */ A("p", {
267
+ className: "text-destructive",
268
+ children: g(u, w.error)
269
+ }), /* @__PURE__ */ A(a, {
270
+ size: "sm",
271
+ variant: "outline",
272
+ onClick: w.reload,
273
+ children: d("common.retry")
274
+ })]
275
+ }) : w.items.length ? y.ordered ? /* @__PURE__ */ A(s, {
276
+ items: w.items,
277
+ id: (e) => e.id,
278
+ name: K,
279
+ label: d("memberships.members"),
280
+ disabled: E.pending,
281
+ onMove: (e, t) => {
282
+ let n = [...w.items], [r] = n.splice(e, 1);
283
+ n.splice(t, 0, r), E.run(() => w.reorder(ee(n)));
284
+ },
285
+ children: (e, t) => ne(e, t)
286
+ }) : $.map(([e, t]) => /* @__PURE__ */ j("section", {
287
+ className: "grid gap-2",
288
+ "data-ckui": "group-members-kind",
289
+ "data-kind": e,
290
+ children: [$.length > 1 && e && /* @__PURE__ */ A("h4", {
291
+ className: "text-xs font-medium text-muted-foreground uppercase",
292
+ children: b(l.labels, e)
293
+ }), /* @__PURE__ */ A("ul", {
294
+ className: "grid grid-cols-[repeat(auto-fill,minmax(7.5rem,1fr))] gap-3",
295
+ children: t.map(te)
296
+ })]
297
+ }, e || "other")) : /* @__PURE__ */ A("p", {
298
+ className: "text-muted-foreground",
299
+ children: d("memberships.noMembers")
300
+ }),
301
+ w.hasMore && /* @__PURE__ */ j("div", {
302
+ className: "grid justify-items-center gap-2",
303
+ children: [w.error && /* @__PURE__ */ A("p", {
304
+ role: "alert",
305
+ className: "text-destructive",
306
+ children: g(u, w.error)
307
+ }), /* @__PURE__ */ A(a, {
308
+ variant: "outline",
309
+ size: "sm",
310
+ disabled: w.loadingMore,
311
+ onClick: () => void w.loadMore(),
312
+ children: w.loadingMore ? d("groups.loading") : w.error ? d("common.retry") : d("groups.loadMore")
313
+ })]
314
+ }),
315
+ /* @__PURE__ */ A(h, { error: E.error })
316
+ ]
317
+ });
318
+ }
319
+ function U({ spec: t, labels: n, client: r, onAdd: i }) {
320
+ let { t: o } = e(), s = E(), [c, m] = O(""), [h, g] = O(0), [_, v] = O(null), [S, C] = O(""), [D, k] = O(""), [N, P] = O(), [F, I] = O(), R = w((e, t) => r.discovery.adminSuggestions({
321
+ q: e.q,
322
+ display_language: e.display_language,
323
+ include_contents: !0,
324
+ include_entities: !1,
325
+ limit: 8
326
+ }, t), [r]), z = y(c, {
327
+ request: R,
328
+ client: r,
329
+ limit: 8
330
+ }), B = z.contents, V = c.trim() !== "" && !_ && B.length > 0;
331
+ T(() => g(0), [c]);
332
+ let H = !!t.version_level || !!t.roles?.length || !!t.windows, U = () => {
333
+ m(""), v(null), C("");
334
+ }, W = (e, t) => void i({
335
+ content_id: e.id,
336
+ version_id: t || void 0,
337
+ role: D || void 0,
338
+ active_from: N,
339
+ active_until: F
340
+ }).then((e) => e !== void 0 && U()), G = (e) => {
341
+ if (!H) return W(e);
342
+ v({ card: e }), m(e.title), t.version_level && r.contents.manage({
343
+ ids: [e.id],
344
+ limit: 1
345
+ }).then((t) => v((n) => n?.card.id === e.id ? {
346
+ card: e,
347
+ versions: t[0]?.versions
348
+ } : n), () => void 0);
349
+ };
350
+ return /* @__PURE__ */ j("div", {
351
+ className: "grid gap-2",
352
+ "data-ckui": "add-member",
353
+ children: [/* @__PURE__ */ j("div", {
354
+ className: "relative",
355
+ children: [
356
+ /* @__PURE__ */ A("input", {
357
+ id: `${s}-q`,
358
+ role: "combobox",
359
+ "aria-label": o("memberships.searchContent"),
360
+ "aria-expanded": V,
361
+ "aria-controls": `${s}-list`,
362
+ "aria-activedescendant": V ? `${s}-${h}` : void 0,
363
+ "aria-autocomplete": "list",
364
+ autoComplete: "off",
365
+ className: "h-8 w-full rounded-md border border-input bg-transparent px-2.5 text-sm outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40",
366
+ placeholder: o("memberships.searchContent"),
367
+ value: c,
368
+ onChange: (e) => {
369
+ m(e.target.value), v(null);
370
+ },
371
+ onKeyDown: (e) => {
372
+ e.key === "ArrowDown" && V ? (e.preventDefault(), g((e) => Math.min(B.length - 1, e + 1))) : e.key === "ArrowUp" && V ? (e.preventDefault(), g((e) => Math.max(0, e - 1))) : e.key === "Enter" && V ? (e.preventDefault(), G(B[h])) : e.key === "Escape" && U();
373
+ }
374
+ }),
375
+ V && /* @__PURE__ */ A("ul", {
376
+ id: `${s}-list`,
377
+ role: "listbox",
378
+ "aria-label": o("memberships.searchContent"),
379
+ className: "absolute start-0 top-full z-10 mt-1 grid w-full overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md",
380
+ children: B.map((e, t) => /* @__PURE__ */ j("li", {
381
+ id: `${s}-${t}`,
382
+ role: "option",
383
+ "aria-selected": t === h,
384
+ className: M("flex cursor-pointer items-center gap-2 px-2 py-1.5 text-sm", t === h && "bg-accent text-accent-foreground"),
385
+ onMouseEnter: () => g(t),
386
+ onMouseDown: (t) => {
387
+ t.preventDefault(), G(e);
388
+ },
389
+ children: [
390
+ e.cover[0]?.url ? /* @__PURE__ */ A("img", {
391
+ src: e.cover[0].url,
392
+ alt: "",
393
+ className: "h-9 w-6 shrink-0 rounded-sm object-cover"
394
+ }) : /* @__PURE__ */ A("span", {
395
+ "aria-hidden": !0,
396
+ className: "h-9 w-6 shrink-0 rounded-sm bg-muted"
397
+ }),
398
+ /* @__PURE__ */ A("span", {
399
+ className: "min-w-0 flex-1 truncate",
400
+ children: e.title
401
+ }),
402
+ /* @__PURE__ */ A("span", {
403
+ className: "text-xs text-muted-foreground",
404
+ children: b(n, e.kind)
405
+ })
406
+ ]
407
+ }, e.id))
408
+ }),
409
+ c.trim() !== "" && !_ && !z.loading && z.query === c.trim() && !B.length && /* @__PURE__ */ A("p", {
410
+ className: "mt-1 text-xs text-muted-foreground",
411
+ children: o("memberships.noMatches")
412
+ })
413
+ ]
414
+ }), _ && /* @__PURE__ */ j("div", {
415
+ className: "flex flex-wrap items-end gap-2",
416
+ "data-ckui": "add-member-details",
417
+ children: [
418
+ t.version_level && /* @__PURE__ */ j(l, {
419
+ value: S || L,
420
+ onValueChange: (e) => C(e === L ? "" : String(e)),
421
+ children: [/* @__PURE__ */ A(f, {
422
+ size: "sm",
423
+ "aria-label": o("memberships.version"),
424
+ children: /* @__PURE__ */ A(p, { children: (e) => e === L ? o("memberships.wholeContent") : _.versions?.find((t) => t.id === e)?.title ?? e })
425
+ }), /* @__PURE__ */ j(u, { children: [/* @__PURE__ */ A(d, {
426
+ value: L,
427
+ children: o("memberships.wholeContent")
428
+ }), (_.versions ?? []).map((e, t) => /* @__PURE__ */ A(d, {
429
+ value: e.id,
430
+ children: e.title || `#${t + 1}`
431
+ }, e.id))] })]
432
+ }),
433
+ !!t.roles?.length && /* @__PURE__ */ j(l, {
434
+ value: D || L,
435
+ onValueChange: (e) => k(e === L ? "" : String(e)),
436
+ children: [/* @__PURE__ */ A(f, {
437
+ size: "sm",
438
+ "aria-label": o("memberships.role"),
439
+ children: /* @__PURE__ */ A(p, { children: (e) => e === L ? o("memberships.noRole") : b(n, e) })
440
+ }), /* @__PURE__ */ j(u, { children: [/* @__PURE__ */ A(d, {
441
+ value: L,
442
+ children: o("memberships.noRole")
443
+ }), t.roles.map((e) => /* @__PURE__ */ A(d, {
444
+ value: e,
445
+ children: b(n, e)
446
+ }, e))] })]
447
+ }),
448
+ t.windows && /* @__PURE__ */ A(x, {
449
+ from: N,
450
+ until: F,
451
+ name: o("memberships.newMember"),
452
+ onChange: (e) => {
453
+ "active_from" in e && P(e.active_from), "active_until" in e && I(e.active_until);
454
+ }
455
+ }),
456
+ /* @__PURE__ */ A(a, {
457
+ size: "sm",
458
+ onClick: () => W(_.card, S),
459
+ children: o("memberships.addMember")
460
+ }),
461
+ /* @__PURE__ */ A(a, {
462
+ size: "sm",
463
+ variant: "ghost",
464
+ onClick: U,
465
+ children: o("common.cancel")
466
+ })
467
+ ]
468
+ })]
469
+ });
470
+ }
471
+ //#endregion
472
+ export { H as GroupMembers };
473
+
474
+ //# sourceMappingURL=group-members.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"group-members.js","names":[],"sources":["../../../src/components/groups/group-members.tsx"],"sourcesContent":["import { Cancel01Icon, Image01Icon, Tick02Icon } from \"@hugeicons/core-free-icons\";\nimport { HugeiconsIcon } from \"@hugeicons/react\";\nimport { cn } from \"cn\";\nimport { useCallback, useEffect, useId, useMemo, useState, type ReactNode } from \"react\";\nimport type { ContentKitUiAppearance } from \"../../appearance.js\";\nimport type { ContentKitClient } from \"../../client/client.js\";\nimport type { TypeaheadQuery } from \"../../client/discovery.js\";\nimport type { Card, Content, GroupDetail, GroupKind, Membership } from \"../../client/generated/wire.js\";\nimport { useMessages } from \"../../i18n/context.js\";\nimport { useContentKitClient, type ContentKitErrorHandler } from \"../../react/context.js\";\nimport { useTypeahead } from \"../../react/discovery.js\";\nimport { useGroupMembers, useKinds, type Member } from \"../../react/groups.js\";\nimport { ContentKitUiRoot } from \"../../scope.js\";\nimport { Badge } from \"#ckui/ui/badge\";\nimport { Button, buttonVariants } from \"#ckui/ui/button\";\nimport { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from \"#ckui/ui/select\";\nimport { Skeleton } from \"#ckui/ui/skeleton\";\nimport { accessLabel, contentStatus } from \"../admin/content-manager.js\";\nimport { SortableList } from \"../sortable-list.js\";\nimport { contentError, ErrorLine, formatDate, useAction } from \"../social/parts.js\";\nimport { WindowFields } from \"./entity-chips.js\";\nimport { labelOf, type Labels } from \"./parts.js\";\n\nconst NONE = \"__none__\";\n// The managed listing hydrates at most this many ids per request.\nconst BATCH = 100;\n\nexport interface GroupMembersProps {\n group: Pick<GroupDetail, \"id\" | \"kind\" | \"name\" | \"slug\" | \"cover\" | \"code\">;\n labels?: Labels;\n /** Where a member's card links, e.g. its admin editor; none: not a link. */\n contentHref?: (content: Content) => string | undefined;\n /** Where a new item of a content kind starts already in this group, e.g. the host's editor with `?with=<code>`; none: no action. */\n newContentHref?: (contentKind: string, group: GroupMembersProps[\"group\"]) => string | undefined;\n /** Replaces a member's card body; default its cover and title. */\n renderContent?: (member: Membership, content?: Content) => ReactNode;\n /** Select a member's cover as the group's. */\n onUseCover?: (contentId: string) => Promise<unknown>;\n pageSize?: number;\n client?: ContentKitClient;\n onError?: ContentKitErrorHandler;\n className?: string;\n appearance?: ContentKitUiAppearance;\n}\n\nconst refKey = (x: Membership) => `${x.content_id}|${x.version_id ?? \"\"}`;\n\n/** Members' contents by id through the managed listing: drafts and deleted ones too. */\nfunction useMemberContents(ids: readonly string[], client: ContentKitClient) {\n const [byId, setById] = useState<ReadonlyMap<string, Content>>(new Map());\n const wanted = useMemo(() => [...new Set(ids)].sort(), [ids]);\n useEffect(() => {\n const missing = wanted.filter((id) => !byId.has(id));\n if (!missing.length) return;\n const ctl = new AbortController();\n const batches: string[][] = [];\n for (let i = 0; i < missing.length; i += BATCH) batches.push(missing.slice(i, i + BATCH));\n // A failed lookup leaves the member's id as its label; the list stays usable.\n void Promise.all(batches.map((b) => client.contents.manage({ ids: b, limit: b.length }, ctl.signal).catch(() => [] as Content[]))).then((pages) => {\n if (ctl.signal.aborted) return;\n setById((cur) => {\n const next = new Map(cur);\n for (const c of pages.flat()) next.set(c.id, c);\n return next;\n });\n });\n return () => ctl.abort();\n // byId is read, not a trigger: only new ids fetch.\n }, [wanted, client]); // eslint-disable-line react-hooks/exhaustive-deps\n return byId;\n}\n\nconst coverOf = (c?: Content) => c?.cover?.url ?? c?.versions.find((v) => v.cover?.url)?.cover?.url;\n\n/**\n * Staff: an entity's contents as cover cards grouped by content kind (an\n * ordered kind as a reorderable list), each with its access, state, role and\n * version; add one by searching titles, remove or use its cover on hover.\n */\nexport function GroupMembers(p: GroupMembersProps) {\n const m = useMessages();\n const { t } = m;\n const client = useContentKitClient(p.client);\n const { kinds } = useKinds({ client: p.client });\n const spec: GroupKind = kinds?.entity_kinds?.[p.group.kind] ?? {};\n const members = useGroupMembers(p.group.id, { pageSize: p.pageSize, client: p.client });\n const contents = useMemberContents(\n useMemo(() => members.items.map((x) => x.content_id!).filter(Boolean), [members.items]),\n client,\n );\n const save = useAction(\"membership.save\", p.onError);\n const [editing, setEditing] = useState<string | null>(null);\n const [win, setWin] = useState<{ from?: string; until?: string }>({});\n const title = (x: Membership) => contents.get(x.content_id ?? \"\")?.title || x.content_id || \"\";\n const spoken = (x: Member) => `${title(x)}${x.version_id ? ` (${t(\"memberships.version\")})` : \"\"}`;\n // Every role of one member shares its place: order unique content and version pairs.\n const order = (items: Member[]) => [...new Map(items.map((x) => [refKey(x), { content_id: x.content_id!, version_id: x.version_id }])).values()];\n const strip = ({ id: _id, ...x }: Member): Membership => x;\n const badges = (x: Member, c?: Content) => (\n <>\n {c && c.access.level !== \"public\" && <Badge variant=\"secondary\">{accessLabel(t, c.access, p.labels)}</Badge>}\n {c && (c.state === \"deleted\" || contentStatus(c) !== \"published\") && (\n <Badge variant={c.state === \"deleted\" ? \"destructive\" : \"outline\"}>{t(c.state === \"deleted\" ? \"contentManager.deleted\" : `contentManager.${contentStatus(c)}`)}</Badge>\n )}\n {x.version_id && <Badge variant=\"outline\">{t(\"memberships.version\")}</Badge>}\n {x.role && <Badge variant=\"secondary\">{labelOf(p.labels, x.role)}</Badge>}\n {x.state === \"proposed\" && <Badge variant=\"secondary\">{t(\"memberships.proposed\")}</Badge>}\n </>\n );\n const actions = (x: Member) => (\n <>\n {x.state === \"proposed\" && (\n <Button size=\"icon-xs\" variant=\"secondary\" disabled={save.pending} aria-label={`${t(\"memberships.accept\")}: ${spoken(x)}`} title={t(\"memberships.accept\")}\n onClick={() => void save.run(() => members.add([{ ...strip(x), state: \"active\" }]))}>\n <HugeiconsIcon icon={Tick02Icon} strokeWidth={2.5} />\n </Button>\n )}\n {p.onUseCover && !x.version_id && (\n <Button size=\"icon-xs\" variant=\"secondary\" aria-label={`${t(\"memberships.useCover\")}: ${spoken(x)}`} title={t(\"memberships.useCover\")}\n disabled={save.pending || (p.group.cover?.content_id === x.content_id && !p.group.cover?.auto)}\n onClick={() => void save.run(() => p.onUseCover!(x.content_id!))}>\n <HugeiconsIcon icon={Image01Icon} strokeWidth={2} />\n </Button>\n )}\n <Button size=\"icon-xs\" variant=\"secondary\" disabled={save.pending} aria-label={t(\"memberships.remove\", { name: spoken(x) })} title={t(\"common.remove\")}\n onClick={() => void save.run(() => members.remove([strip(x)]))}>\n <HugeiconsIcon icon={Cancel01Icon} strokeWidth={2.5} />\n </Button>\n </>\n );\n const dates = (x: Member) =>\n spec.windows &&\n (editing === x.id ? (\n <span className=\"flex flex-wrap items-center gap-1\">\n <WindowFields from={win.from} until={win.until} name={spoken(x)} onChange={(w) => setWin((cur) => ({ from: \"active_from\" in w ? w.active_from : cur.from, until: \"active_until\" in w ? w.active_until : cur.until }))} />\n <Button size=\"xs\" disabled={save.pending} onClick={() => void save.run(() => members.add([{ ...strip(x), active_from: win.from, active_until: win.until }])).then((d) => d !== undefined && setEditing(null))}>\n {t(\"common.save\")}\n </Button>\n <Button size=\"xs\" variant=\"ghost\" onClick={() => setEditing(null)}>\n {t(\"common.cancel\")}\n </Button>\n </span>\n ) : (\n <button type=\"button\" className=\"text-start text-xs text-muted-foreground hover:underline\" data-ckui=\"member-window\"\n onClick={() => {\n setWin({ from: x.active_from, until: x.active_until });\n setEditing(x.id);\n }}>\n {x.active_from || x.active_until\n ? t(\"memberships.window\", { from: x.active_from ? formatDate(m, x.active_from) : \"…\", until: x.active_until ? formatDate(m, x.active_until) : \"…\" })\n : t(\"memberships.always\")}\n </button>\n ));\n const thumb = (c: Content | undefined, className: string) => {\n const url = coverOf(c);\n return url ? <img src={url} alt=\"\" loading=\"lazy\" className={cn(\"object-cover\", className)} /> : <span aria-hidden className={cn(\"bg-muted\", className)} />;\n };\n const linked = (x: Member, body: ReactNode, className?: string) => {\n const c = contents.get(x.content_id ?? \"\");\n const href = c && p.contentHref?.(c);\n return href ? <a href={href} className={cn(\"hover:underline\", className)}>{body}</a> : <span className={className}>{body}</span>;\n };\n const card = (x: Member) => {\n const c = contents.get(x.content_id ?? \"\");\n return (\n <li key={x.id} className=\"group/member relative grid content-start gap-1.5\" data-ckui=\"group-member\" data-content={x.content_id} data-state={x.state ?? \"active\"}>\n {p.renderContent ? (\n p.renderContent(x, c)\n ) : (\n <>\n {linked(x, thumb(c, \"aspect-[7/10] w-full rounded-md\"), \"block\")}\n {linked(x, title(x), cn(\"line-clamp-2 text-sm font-medium break-words\", !c && \"font-mono text-xs\"))}\n </>\n )}\n <span className=\"flex flex-wrap gap-1\">{badges(x, c)}</span>\n {dates(x)}\n <span className=\"absolute end-1 top-1 flex gap-1 opacity-0 transition-opacity group-hover/member:opacity-100 focus-within:opacity-100\">{actions(x)}</span>\n </li>\n );\n };\n const row = (x: Member, handle?: ReactNode) => {\n const c = contents.get(x.content_id ?? \"\");\n return (\n <div className=\"group/member flex flex-wrap items-center gap-2\" data-ckui=\"group-member\" data-content={x.content_id} data-state={x.state ?? \"active\"}>\n {handle}\n {x.position !== undefined && <span className=\"w-8 text-xs text-muted-foreground tabular-nums\">{x.position}</span>}\n {p.renderContent ? (\n <span className=\"min-w-0 flex-1\">{p.renderContent(x, c)}</span>\n ) : (\n <>\n {linked(x, thumb(c, \"h-12 w-9 rounded-sm\"), \"shrink-0\")}\n {linked(x, title(x), cn(\"min-w-0 flex-1 break-words\", !c && \"font-mono text-xs\"))}\n </>\n )}\n {badges(x, c)}\n {dates(x)}\n <span className=\"flex gap-1 opacity-60 transition-opacity group-hover/member:opacity-100 focus-within:opacity-100\">{actions(x)}</span>\n </div>\n );\n };\n // Unordered kinds read best as covers per content kind; unknown kinds last.\n const byKind = useMemo(() => {\n const out = new Map<string, Member[]>();\n for (const x of members.items) {\n const kind = contents.get(x.content_id ?? \"\")?.kind ?? \"\";\n out.set(kind, [...(out.get(kind) ?? []), x]);\n }\n return [...out].sort(([a], [b]) => (a === \"\" ? 1 : b === \"\" ? -1 : a.localeCompare(b)));\n }, [members.items, contents]);\n // Version-level kinds link a version, which a new item does not have yet.\n const starts = spec.version_level\n ? []\n : Object.entries(kinds?.kinds ?? {}).flatMap(([kind, k]) => {\n const href = k.entities?.includes(p.group.kind) ? p.newContentHref?.(kind, p.group) : undefined;\n return href ? [{ kind, href }] : [];\n });\n return (\n <ContentKitUiRoot appearance={p.appearance} className={cn(\"grid gap-3 text-sm\", p.className)} data-ckui=\"group-members\">\n <h3 className=\"font-medium\">{t(\"memberships.members\")}</h3>\n {starts.length > 0 && (\n <div className=\"flex flex-wrap gap-2\">\n {starts.map((x) => (\n <a key={x.kind} href={x.href} className={buttonVariants({ variant: \"outline\", size: \"sm\" })} data-ckui=\"group-member-new\">\n {t(\"memberships.newContent\", { kind: labelOf(p.labels, x.kind), name: p.group.name })}\n </a>\n ))}\n </div>\n )}\n <AddContent spec={spec} labels={p.labels} client={client} onAdd={(x) => save.run(() => members.add([x]))} />\n {members.loading && !members.items.length ? (\n <Skeleton className=\"h-40 w-full\" />\n ) : members.error && !members.items.length ? (\n <div role=\"alert\" className=\"grid justify-items-start gap-2\">\n <p className=\"text-destructive\">{contentError(m, members.error)}</p>\n <Button size=\"sm\" variant=\"outline\" onClick={members.reload}>\n {t(\"common.retry\")}\n </Button>\n </div>\n ) : !members.items.length ? (\n <p className=\"text-muted-foreground\">{t(\"memberships.noMembers\")}</p>\n ) : spec.ordered ? (\n <SortableList\n items={members.items}\n id={(x) => x.id}\n name={spoken}\n label={t(\"memberships.members\")}\n disabled={save.pending}\n onMove={(from, to) => {\n const items = [...members.items];\n const [moved] = items.splice(from, 1);\n items.splice(to, 0, moved!);\n void save.run(() => members.reorder(order(items)));\n }}\n >\n {(x, handle) => row(x, handle)}\n </SortableList>\n ) : (\n byKind.map(([kind, items]) => (\n <section key={kind || \"other\"} className=\"grid gap-2\" data-ckui=\"group-members-kind\" data-kind={kind}>\n {byKind.length > 1 && kind && <h4 className=\"text-xs font-medium text-muted-foreground uppercase\">{labelOf(p.labels, kind)}</h4>}\n <ul className=\"grid grid-cols-[repeat(auto-fill,minmax(7.5rem,1fr))] gap-3\">{items.map(card)}</ul>\n </section>\n ))\n )}\n {members.hasMore && (\n <div className=\"grid justify-items-center gap-2\">\n {members.error && <p role=\"alert\" className=\"text-destructive\">{contentError(m, members.error)}</p>}\n <Button variant=\"outline\" size=\"sm\" disabled={members.loadingMore} onClick={() => void members.loadMore()}>\n {members.loadingMore ? t(\"groups.loading\") : members.error ? t(\"common.retry\") : t(\"groups.loadMore\")}\n </Button>\n </div>\n )}\n <ErrorLine error={save.error} />\n </ContentKitUiRoot>\n );\n}\n\n/** A title search over contents the caller manages; picking one adds it, after its role, version or dates when the kind has them. */\nfunction AddContent({ spec, labels, client, onAdd }: { spec: GroupKind; labels?: Labels; client: ContentKitClient; onAdd: (m: Membership) => Promise<unknown> }) {\n const { t } = useMessages();\n const id = useId();\n const [text, setText] = useState(\"\");\n const [active, setActive] = useState(0);\n const [picked, setPicked] = useState<{ card: Card; versions?: Content[\"versions\"] } | null>(null);\n const [version, setVersion] = useState(\"\");\n const [role, setRole] = useState(\"\");\n const [from, setFrom] = useState<string>();\n const [until, setUntil] = useState<string>();\n const request = useCallback(\n (q: TypeaheadQuery, signal: AbortSignal) =>\n client.discovery.adminSuggestions({ q: q.q, display_language: q.display_language, include_contents: true, include_entities: false, limit: 8 }, signal),\n [client],\n );\n const found = useTypeahead(text, { request, client, limit: 8 });\n const results = found.contents;\n const listOpen = text.trim() !== \"\" && !picked && results.length > 0;\n useEffect(() => setActive(0), [text]);\n const detailed = !!spec.version_level || !!spec.roles?.length || !!spec.windows;\n const reset = () => {\n setText(\"\");\n setPicked(null);\n setVersion(\"\");\n };\n const add = (card: Card, v?: string) =>\n void onAdd({ content_id: card.id, version_id: v || undefined, role: role || undefined, active_from: from, active_until: until }).then((d) => d !== undefined && reset());\n const pick = (card: Card) => {\n if (!detailed) return add(card);\n setPicked({ card });\n setText(card.title);\n // A version-level kind links one version: list the picked content's.\n if (spec.version_level)\n void client.contents.manage({ ids: [card.id], limit: 1 }).then(\n (r) => setPicked((cur) => (cur?.card.id === card.id ? { card, versions: r[0]?.versions } : cur)),\n () => undefined,\n );\n };\n return (\n <div className=\"grid gap-2\" data-ckui=\"add-member\">\n <div className=\"relative\">\n <input\n id={`${id}-q`}\n role=\"combobox\"\n aria-label={t(\"memberships.searchContent\")}\n aria-expanded={listOpen}\n aria-controls={`${id}-list`}\n aria-activedescendant={listOpen ? `${id}-${active}` : undefined}\n aria-autocomplete=\"list\"\n autoComplete=\"off\"\n className=\"h-8 w-full rounded-md border border-input bg-transparent px-2.5 text-sm outline-none placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-2 focus-visible:ring-ring/40\"\n placeholder={t(\"memberships.searchContent\")}\n value={text}\n onChange={(e) => {\n setText(e.target.value);\n setPicked(null);\n }}\n onKeyDown={(e) => {\n if (e.key === \"ArrowDown\" && listOpen) {\n e.preventDefault();\n setActive((a) => Math.min(results.length - 1, a + 1));\n } else if (e.key === \"ArrowUp\" && listOpen) {\n e.preventDefault();\n setActive((a) => Math.max(0, a - 1));\n } else if (e.key === \"Enter\" && listOpen) {\n e.preventDefault();\n pick(results[active]!);\n } else if (e.key === \"Escape\") reset();\n }}\n />\n {listOpen && (\n <ul id={`${id}-list`} role=\"listbox\" aria-label={t(\"memberships.searchContent\")} className=\"absolute start-0 top-full z-10 mt-1 grid w-full overflow-hidden rounded-md border border-border bg-popover text-popover-foreground shadow-md\">\n {results.map((c, i) => (\n <li\n key={c.id}\n id={`${id}-${i}`}\n role=\"option\"\n aria-selected={i === active}\n className={cn(\"flex cursor-pointer items-center gap-2 px-2 py-1.5 text-sm\", i === active && \"bg-accent text-accent-foreground\")}\n onMouseEnter={() => setActive(i)}\n onMouseDown={(e) => {\n e.preventDefault();\n pick(c);\n }}\n >\n {c.cover[0]?.url ? <img src={c.cover[0].url} alt=\"\" className=\"h-9 w-6 shrink-0 rounded-sm object-cover\" /> : <span aria-hidden className=\"h-9 w-6 shrink-0 rounded-sm bg-muted\" />}\n <span className=\"min-w-0 flex-1 truncate\">{c.title}</span>\n <span className=\"text-xs text-muted-foreground\">{labelOf(labels, c.kind)}</span>\n </li>\n ))}\n </ul>\n )}\n {text.trim() !== \"\" && !picked && !found.loading && found.query === text.trim() && !results.length && (\n <p className=\"mt-1 text-xs text-muted-foreground\">{t(\"memberships.noMatches\")}</p>\n )}\n </div>\n {picked && (\n <div className=\"flex flex-wrap items-end gap-2\" data-ckui=\"add-member-details\">\n {spec.version_level && (\n <Select value={version || NONE} onValueChange={(v) => setVersion(v === NONE ? \"\" : String(v))}>\n <SelectTrigger size=\"sm\" aria-label={t(\"memberships.version\")}>\n <SelectValue>{(v: string) => (v === NONE ? t(\"memberships.wholeContent\") : (picked.versions?.find((x) => x.id === v)?.title ?? v))}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>{t(\"memberships.wholeContent\")}</SelectItem>\n {(picked.versions ?? []).map((v, i) => (\n <SelectItem key={v.id} value={v.id}>\n {v.title || `#${i + 1}`}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n {!!spec.roles?.length && (\n <Select value={role || NONE} onValueChange={(v) => setRole(v === NONE ? \"\" : String(v))}>\n <SelectTrigger size=\"sm\" aria-label={t(\"memberships.role\")}>\n <SelectValue>{(v: string) => (v === NONE ? t(\"memberships.noRole\") : labelOf(labels, v))}</SelectValue>\n </SelectTrigger>\n <SelectContent>\n <SelectItem value={NONE}>{t(\"memberships.noRole\")}</SelectItem>\n {spec.roles.map((r) => (\n <SelectItem key={r} value={r}>\n {labelOf(labels, r)}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n )}\n {spec.windows && (\n <WindowFields\n from={from}\n until={until}\n name={t(\"memberships.newMember\")}\n onChange={(w) => {\n if (\"active_from\" in w) setFrom(w.active_from);\n if (\"active_until\" in w) setUntil(w.active_until);\n }}\n />\n )}\n <Button size=\"sm\" onClick={() => add(picked.card, version)}>\n {t(\"memberships.addMember\")}\n </Button>\n <Button size=\"sm\" variant=\"ghost\" onClick={reset}>\n {t(\"common.cancel\")}\n </Button>\n </div>\n )}\n </div>\n );\n}\n"],"mappings":"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"}