@openrails/contentkit-ui 0.103.2 → 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 (253) hide show
  1. package/README.md +111 -49
  2. package/dist/client/beacons.d.ts +3 -13
  3. package/dist/client/beacons.js +8 -46
  4. package/dist/client/beacons.js.map +1 -1
  5. package/dist/client/client.d.ts +3 -0
  6. package/dist/client/client.js +45 -43
  7. package/dist/client/client.js.map +1 -1
  8. package/dist/client/content/favorites.d.ts +2 -0
  9. package/dist/client/content/favorites.js.map +1 -1
  10. package/dist/client/content/types.d.ts +3 -0
  11. package/dist/client/content/types.js.map +1 -1
  12. package/dist/client/contents.d.ts +7 -1
  13. package/dist/client/contents.js +8 -0
  14. package/dist/client/contents.js.map +1 -1
  15. package/dist/client/discovery.d.ts +34 -5
  16. package/dist/client/discovery.js +23 -2
  17. package/dist/client/discovery.js.map +1 -1
  18. package/dist/client/engagement.d.ts +70 -0
  19. package/dist/client/engagement.js +191 -0
  20. package/dist/client/engagement.js.map +1 -0
  21. package/dist/client/generated/routes.d.ts +74 -35
  22. package/dist/client/generated/routes.js +119 -60
  23. package/dist/client/generated/routes.js.map +1 -1
  24. package/dist/client/generated/wire.d.ts +88 -85
  25. package/dist/client/generated/wire.js.map +1 -1
  26. package/dist/client/guest-reading-history.d.ts +40 -0
  27. package/dist/client/guest-reading-history.js +144 -0
  28. package/dist/client/guest-reading-history.js.map +1 -0
  29. package/dist/client/index.d.ts +5 -3
  30. package/dist/client/media/windows.d.ts +2 -0
  31. package/dist/client/media/windows.js +4 -1
  32. package/dist/client/media/windows.js.map +1 -1
  33. package/dist/client/stats.d.ts +4 -20
  34. package/dist/client/stats.js +0 -11
  35. package/dist/client/stats.js.map +1 -1
  36. package/dist/client/versions.d.ts +8 -6
  37. package/dist/client/versions.js +15 -10
  38. package/dist/client/versions.js.map +1 -1
  39. package/dist/client.js +24 -22
  40. package/dist/components/admin/bulk-drafts.d.ts +17 -0
  41. package/dist/components/admin/bulk-drafts.js +41 -0
  42. package/dist/components/admin/bulk-drafts.js.map +1 -0
  43. package/dist/components/admin/content-admin.d.ts +1 -1
  44. package/dist/components/admin/content-admin.js.map +1 -1
  45. package/dist/components/admin/content-manager.d.ts +11 -3
  46. package/dist/components/admin/content-manager.js +751 -394
  47. package/dist/components/admin/content-manager.js.map +1 -1
  48. package/dist/components/admin/group-manager.d.ts +8 -3
  49. package/dist/components/admin/group-manager.js +218 -146
  50. package/dist/components/admin/group-manager.js.map +1 -1
  51. package/dist/components/admin/page-notices.d.ts +16 -0
  52. package/dist/components/admin/page-notices.js +113 -0
  53. package/dist/components/admin/page-notices.js.map +1 -0
  54. package/dist/components/admin/page-picker.d.ts +38 -0
  55. package/dist/components/admin/page-picker.js +159 -0
  56. package/dist/components/admin/page-picker.js.map +1 -0
  57. package/dist/components/admin/quick-search.d.ts +14 -0
  58. package/dist/components/admin/quick-search.js +60 -0
  59. package/dist/components/admin/quick-search.js.map +1 -0
  60. package/dist/components/admin/reader-content-editor.js +382 -321
  61. package/dist/components/admin/reader-content-editor.js.map +1 -1
  62. package/dist/components/admin/reader-manifest.js +181 -179
  63. package/dist/components/admin/reader-manifest.js.map +1 -1
  64. package/dist/components/admin/shell.d.ts +10 -2
  65. package/dist/components/admin/shell.js +114 -42
  66. package/dist/components/admin/shell.js.map +1 -1
  67. package/dist/components/admin/stats-dashboard.d.ts +4 -9
  68. package/dist/components/admin/stats-dashboard.js +303 -207
  69. package/dist/components/admin/stats-dashboard.js.map +1 -1
  70. package/dist/components/admin/upload-queue.d.ts +14 -0
  71. package/dist/components/admin/upload-queue.js +115 -98
  72. package/dist/components/admin/upload-queue.js.map +1 -1
  73. package/dist/components/content/card.d.ts +31 -3
  74. package/dist/components/content/card.js +324 -158
  75. package/dist/components/content/card.js.map +1 -1
  76. package/dist/components/content/daily-releases.js +144 -190
  77. package/dist/components/content/daily-releases.js.map +1 -1
  78. package/dist/components/content/editor-save.js +27 -25
  79. package/dist/components/content/editor-save.js.map +1 -1
  80. package/dist/components/content/editors.js +274 -253
  81. package/dist/components/content/editors.js.map +1 -1
  82. package/dist/components/content/favorites.d.ts +6 -0
  83. package/dist/components/content/favorites.js +47 -0
  84. package/dist/components/content/favorites.js.map +1 -0
  85. package/dist/components/content/filter-dialog.js +19 -15
  86. package/dist/components/content/filter-dialog.js.map +1 -1
  87. package/dist/components/content/filters.d.ts +2 -0
  88. package/dist/components/content/filters.js +5 -1
  89. package/dist/components/content/filters.js.map +1 -1
  90. package/dist/components/content/grid.d.ts +44 -16
  91. package/dist/components/content/grid.js +308 -270
  92. package/dist/components/content/grid.js.map +1 -1
  93. package/dist/components/content/history.d.ts +6 -0
  94. package/dist/components/content/history.js +111 -0
  95. package/dist/components/content/history.js.map +1 -0
  96. package/dist/components/content/index.d.ts +6 -3
  97. package/dist/components/content/listing.d.ts +14 -3
  98. package/dist/components/content/listing.js +65 -56
  99. package/dist/components/content/listing.js.map +1 -1
  100. package/dist/components/content/offer-fields.js +6 -6
  101. package/dist/components/content/paged-grid.d.ts +10 -0
  102. package/dist/components/content/paged-grid.js +116 -0
  103. package/dist/components/content/paged-grid.js.map +1 -0
  104. package/dist/components/content/pagination.d.ts +19 -0
  105. package/dist/components/content/pagination.js +97 -0
  106. package/dist/components/content/pagination.js.map +1 -0
  107. package/dist/components/content/paywall.d.ts +9 -0
  108. package/dist/components/content/paywall.js +27 -3
  109. package/dist/components/content/paywall.js.map +1 -1
  110. package/dist/components/content/post-list.d.ts +37 -0
  111. package/dist/components/content/post-list.js +203 -0
  112. package/dist/components/content/post-list.js.map +1 -0
  113. package/dist/components/content/reader-settings.d.ts +2 -0
  114. package/dist/components/content/reader-settings.js +1 -1
  115. package/dist/components/content/reader-settings.js.map +1 -1
  116. package/dist/components/content/search.d.ts +11 -4
  117. package/dist/components/content/search.js +22 -11
  118. package/dist/components/content/search.js.map +1 -1
  119. package/dist/components/content/summary-tile.d.ts +14 -0
  120. package/dist/components/content/summary-tile.js +63 -0
  121. package/dist/components/content/summary-tile.js.map +1 -0
  122. package/dist/components/groups/banner.d.ts +6 -2
  123. package/dist/components/groups/banner.js +79 -61
  124. package/dist/components/groups/banner.js.map +1 -1
  125. package/dist/components/groups/directory.d.ts +12 -2
  126. package/dist/components/groups/directory.js +168 -105
  127. package/dist/components/groups/directory.js.map +1 -1
  128. package/dist/components/groups/editor.js +10 -10
  129. package/dist/components/groups/editor.js.map +1 -1
  130. package/dist/components/groups/entity-chips.d.ts +61 -0
  131. package/dist/components/groups/entity-chips.js +382 -0
  132. package/dist/components/groups/entity-chips.js.map +1 -0
  133. package/dist/components/groups/group-members.d.ts +29 -0
  134. package/dist/components/groups/group-members.js +474 -0
  135. package/dist/components/groups/group-members.js.map +1 -0
  136. package/dist/components/groups/header.js +53 -45
  137. package/dist/components/groups/header.js.map +1 -1
  138. package/dist/components/groups/index.d.ts +3 -1
  139. package/dist/components/groups/memberships.d.ts +3 -36
  140. package/dist/components/groups/memberships.js +105 -480
  141. package/dist/components/groups/memberships.js.map +1 -1
  142. package/dist/components/groups/scoped.d.ts +23 -0
  143. package/dist/components/groups/scoped.js +92 -0
  144. package/dist/components/groups/scoped.js.map +1 -0
  145. package/dist/components/media-folder-editor.d.ts +5 -0
  146. package/dist/components/media-folder-editor.js +419 -231
  147. package/dist/components/media-folder-editor.js.map +1 -1
  148. package/dist/components/sortable-list.d.ts +5 -1
  149. package/dist/components/sortable-list.js +97 -81
  150. package/dist/components/sortable-list.js.map +1 -1
  151. package/dist/components/video-mini-player.d.ts +4 -1
  152. package/dist/components/video-mini-player.js +77 -71
  153. package/dist/components/video-mini-player.js.map +1 -1
  154. package/dist/components/video-player.d.ts +4 -1
  155. package/dist/components/video-player.js +280 -276
  156. package/dist/components/video-player.js.map +1 -1
  157. package/dist/index.d.ts +2 -1
  158. package/dist/index.js +41 -34
  159. package/dist/locales/admin/de.js +80 -47
  160. package/dist/locales/admin/de.js.map +1 -1
  161. package/dist/locales/admin/en.d.ts +74 -41
  162. package/dist/locales/admin/en.js +80 -47
  163. package/dist/locales/admin/en.js.map +1 -1
  164. package/dist/locales/admin/es.js +80 -47
  165. package/dist/locales/admin/es.js.map +1 -1
  166. package/dist/locales/admin/ja.js +80 -47
  167. package/dist/locales/admin/ja.js.map +1 -1
  168. package/dist/locales/admin/ko.js +80 -47
  169. package/dist/locales/admin/ko.js.map +1 -1
  170. package/dist/locales/admin/zh.js +80 -47
  171. package/dist/locales/admin/zh.js.map +1 -1
  172. package/dist/locales/de.js +1 -0
  173. package/dist/locales/de.js.map +1 -1
  174. package/dist/locales/discovery/de.js +25 -2
  175. package/dist/locales/discovery/de.js.map +1 -1
  176. package/dist/locales/discovery/en.d.ts +24 -1
  177. package/dist/locales/discovery/en.js +25 -2
  178. package/dist/locales/discovery/en.js.map +1 -1
  179. package/dist/locales/discovery/es.js +25 -2
  180. package/dist/locales/discovery/es.js.map +1 -1
  181. package/dist/locales/discovery/ja.js +25 -2
  182. package/dist/locales/discovery/ja.js.map +1 -1
  183. package/dist/locales/discovery/ko.js +25 -2
  184. package/dist/locales/discovery/ko.js.map +1 -1
  185. package/dist/locales/discovery/zh.js +25 -2
  186. package/dist/locales/discovery/zh.js.map +1 -1
  187. package/dist/locales/en.d.ts +119 -44
  188. package/dist/locales/en.js +1 -0
  189. package/dist/locales/en.js.map +1 -1
  190. package/dist/locales/es.js +1 -0
  191. package/dist/locales/es.js.map +1 -1
  192. package/dist/locales/groups/de.js +22 -4
  193. package/dist/locales/groups/de.js.map +1 -1
  194. package/dist/locales/groups/en.d.ts +20 -2
  195. package/dist/locales/groups/en.js +22 -4
  196. package/dist/locales/groups/en.js.map +1 -1
  197. package/dist/locales/groups/es.js +22 -4
  198. package/dist/locales/groups/es.js.map +1 -1
  199. package/dist/locales/groups/ja.js +22 -4
  200. package/dist/locales/groups/ja.js.map +1 -1
  201. package/dist/locales/groups/ko.js +22 -4
  202. package/dist/locales/groups/ko.js.map +1 -1
  203. package/dist/locales/groups/zh.js +22 -4
  204. package/dist/locales/groups/zh.js.map +1 -1
  205. package/dist/locales/ja.js +1 -0
  206. package/dist/locales/ja.js.map +1 -1
  207. package/dist/locales/ko.js +1 -0
  208. package/dist/locales/ko.js.map +1 -1
  209. package/dist/locales/zh.js +1 -0
  210. package/dist/locales/zh.js.map +1 -1
  211. package/dist/react/discovery.d.ts +36 -17
  212. package/dist/react/discovery.js +305 -221
  213. package/dist/react/discovery.js.map +1 -1
  214. package/dist/react/groups.d.ts +19 -3
  215. package/dist/react/groups.js +49 -22
  216. package/dist/react/groups.js.map +1 -1
  217. package/dist/react/index.d.ts +7 -4
  218. package/dist/react/page-notices.d.ts +13 -0
  219. package/dist/react/page-notices.js +38 -0
  220. package/dist/react/page-notices.js.map +1 -0
  221. package/dist/react/post-reads.d.ts +23 -0
  222. package/dist/react/post-reads.js +90 -0
  223. package/dist/react/post-reads.js.map +1 -0
  224. package/dist/react/remembered-sort.d.ts +5 -0
  225. package/dist/react/remembered-sort.js +29 -0
  226. package/dist/react/remembered-sort.js.map +1 -0
  227. package/dist/react/resources.d.ts +3 -1
  228. package/dist/react/resources.js +6 -2
  229. package/dist/react/resources.js.map +1 -1
  230. package/dist/react/stats.d.ts +3 -7
  231. package/dist/react/stats.js +2 -6
  232. package/dist/react/stats.js.map +1 -1
  233. package/dist/react/use-engagement.d.ts +28 -0
  234. package/dist/react/use-engagement.js +226 -0
  235. package/dist/react/use-engagement.js.map +1 -0
  236. package/dist/react/use-resource.d.ts +4 -3
  237. package/dist/react/use-resource.js +2 -1
  238. package/dist/react/use-resource.js.map +1 -1
  239. package/dist/react.js +29 -26
  240. package/dist/styles.css +1 -1
  241. package/dist/ui/dialog.d.ts +2 -1
  242. package/dist/ui/dialog.js +23 -20
  243. package/dist/ui/dialog.js.map +1 -1
  244. package/dist/urls/index.d.ts +1 -1
  245. package/dist/urls.js +2 -2
  246. package/dist/urls.js.map +1 -1
  247. package/package.json +1 -1
  248. package/dist/components/admin/page-review.d.ts +0 -13
  249. package/dist/components/admin/page-review.js +0 -225
  250. package/dist/components/admin/page-review.js.map +0 -1
  251. package/dist/react/page-review.d.ts +0 -14
  252. package/dist/react/page-review.js +0 -37
  253. package/dist/react/page-review.js.map +0 -1
@@ -1,97 +1,101 @@
1
1
  import { toContentKitError as e } from "../../client/errors.js";
2
2
  import { stem as t } from "../../client/media/client.js";
3
- import { useMessages as n } from "../../i18n/context.js";
4
- import { useErrorReporter as r, useGuarded as i } from "../../react/context.js";
5
- import { useContentScope as ee } from "../../react/use-resource.js";
6
- import { useContentGroups as te } from "../../react/groups.js";
7
- import { isProcessing as ne } from "../../client/media/windows.js";
8
- import { Button as a } from "../../ui/button.js";
9
- import { useMediaFolder as re } from "../../react/folder.js";
10
- import { MediaFolderEditor as ie } from "../media-folder-editor.js";
11
- import { Badge as ae } from "../../ui/badge.js";
12
- import { Input as o } from "../../ui/input.js";
13
- import { Label as s } from "../../ui/label.js";
14
- import { Select as c, SelectContent as l, SelectItem as oe, SelectTrigger as u, SelectValue as d } from "../../ui/select.js";
15
- import { Textarea as se } from "../../ui/textarea.js";
16
- import { ErrorLine as f, contentError as ce, useAction as le } from "../social/parts.js";
17
- import { LoadFailed as ue, Rows as de, useConfirm as fe } from "./shell.js";
18
- import { localInput as pe } from "../social/bans.js";
19
- import { imageRefs as me } from "../../client/contents.js";
20
- import { parseAttributes as he } from "../../client/group-fields.js";
21
- import { GroupPicker as ge, labelOf as _e } from "../groups/parts.js";
22
- import { useDraft as p } from "../../react/use-draft.js";
23
- import { EditorSaveContext as ve, readerMediaReady as ye, useEditorSaveCoordinator as be } from "../content/editor-save.js";
24
- import { OfferFields as xe } from "../content/offer-fields.js";
25
- import { AttributeFields as Se, formOf as Ce } from "../groups/fields.js";
26
- import { MembershipRow as we } from "../groups/memberships.js";
27
- import { ReaderManifestEditor as Te } from "./reader-manifest.js";
28
- import { usePageReview as Ee } from "../../react/page-review.js";
29
- import { PageReview as De } from "./page-review.js";
30
- import { RuleFields as Oe, VersionsEditor as ke, cleanRule as Ae, complete as je, versionLabel as Me } from "../content/editors.js";
31
- import { useContent as Ne } from "../../react/contents.js";
32
- import { contentStatus as Pe } from "./content-manager.js";
33
- import { useEffect as Fe, useId as Ie, useMemo as m, useRef as Le, useState as h } from "react";
3
+ import { ruleFor as n } from "../../client/media/rules.js";
4
+ import { useMessages as r } from "../../i18n/context.js";
5
+ import { useErrorReporter as i, useGuarded as ee } from "../../react/context.js";
6
+ import { useContentScope as te } from "../../react/use-resource.js";
7
+ import { useContentGroups as ne } from "../../react/groups.js";
8
+ import { isProcessing as re, pageRemoved as a } from "../../client/media/windows.js";
9
+ import { Button as o } from "../../ui/button.js";
10
+ import { ImageCropDialog as s } from "../image-crop-dialog.js";
11
+ import { useEditorCrop as ie } from "../../react/crop.js";
12
+ import { useMediaFolder as ae } from "../../react/folder.js";
13
+ import { MediaFolderEditor as c, positionalName as oe } from "../media-folder-editor.js";
14
+ import { Badge as se } from "../../ui/badge.js";
15
+ import { Input as ce } from "../../ui/input.js";
16
+ import { Label as l } from "../../ui/label.js";
17
+ import { Select as u, SelectContent as le, SelectItem as ue, SelectTrigger as de, SelectValue as fe } from "../../ui/select.js";
18
+ import { Textarea as pe } from "../../ui/textarea.js";
19
+ import { ErrorLine as d, contentError as me, useAction as he } from "../social/parts.js";
20
+ import { LoadFailed as ge, Rows as _e, useConfirm as ve } from "./shell.js";
21
+ import { localInput as ye } from "../social/bans.js";
22
+ import { parseAttributes as be } from "../../client/group-fields.js";
23
+ import { labelOf as xe } from "../groups/parts.js";
24
+ import { useDraft as Se } from "../../react/use-draft.js";
25
+ import { EditorSaveContext as Ce, readerMediaReady as we, useEditorSaveCoordinator as Te } from "../content/editor-save.js";
26
+ import { OfferFields as Ee } from "../content/offer-fields.js";
27
+ import { AttributeFields as De, formOf as Oe } from "../groups/fields.js";
28
+ import { useContent as ke } from "../../react/contents.js";
29
+ import { usePageNotices as Ae } from "../../react/page-notices.js";
30
+ import { EntityChips as je } from "../groups/entity-chips.js";
31
+ import { ReaderManifestEditor as Me } from "./reader-manifest.js";
32
+ import { PageNotices as Ne } from "./page-notices.js";
33
+ import { RuleFields as Pe, VersionsEditor as Fe, cleanRule as Ie, complete as Le, versionLabel as Re } from "../content/editors.js";
34
+ import { fileTitle as ze } from "./bulk-drafts.js";
35
+ import { contentStatus as Be } from "./content-manager.js";
36
+ import { useEffect as f, useId as Ve, useMemo as p, useRef as m, useState as h } from "react";
34
37
  import { jsx as g, jsxs as _ } from "react/jsx-runtime";
35
- import { StarIcon as Re } from "@hugeicons/core-free-icons";
36
- import { HugeiconsIcon as ze } from "@hugeicons/react";
37
38
  //#region src/components/admin/reader-content-editor.tsx
38
- var v = () => ({
39
+ var He = {
40
+ kind: "",
41
+ id: ""
42
+ }, v = () => ({
39
43
  title: "",
40
44
  slug: "",
41
45
  description: "",
42
46
  body: ""
43
- }), Be = (e, t) => e?.text?.[t] ?? (e?.language === t ? {
47
+ }), Ue = (e, t) => e?.text?.[t] ?? (e?.language === t ? {
44
48
  title: e.title,
45
49
  slug: e.slug,
46
50
  description: e.description,
47
51
  body: e.body
48
- } : v()), Ve = (e) => e.replace(/\.[^.]+$/, "").replace(/[_-]+/g, " ").trim().slice(0, 300), He = (e) => ({
52
+ } : v()), We = (e) => ({
49
53
  ...e,
50
54
  title: e.title.trim(),
51
- slug: e.slug?.trim() || void 0,
52
55
  description: e.description?.trim()
53
56
  }), y = class extends Error {};
54
- function b({ title: e, children: t, className: n = "" }) {
57
+ function b({ title: e, label: t, children: n, className: r = "" }) {
55
58
  return /* @__PURE__ */ _("section", {
56
- className: `grid min-w-0 content-start gap-4 rounded-xl border border-border bg-card p-4 ${n}`,
57
- children: [/* @__PURE__ */ g("h2", {
59
+ "aria-label": e ? void 0 : t,
60
+ className: `grid min-w-0 content-start gap-4 rounded-xl border border-border bg-card p-4 ${r}`,
61
+ children: [e && /* @__PURE__ */ g("h2", {
58
62
  className: "text-base font-semibold",
59
63
  children: e
60
- }), t]
64
+ }), n]
61
65
  });
62
66
  }
63
67
  function x(x) {
64
- let { client: S, scope: Ue } = ee(x.client), We = n(), { t: C } = We, w = Ie(), Ge = i(), Ke = r(x.onError), T = x.model, E = T.kinds[x.kind], qe = x.languages?.map((e) => typeof e == "string" ? {
68
+ let { client: S, scope: Ge } = te(x.client), Ke = r(), { t: C } = Ke, w = Ve(), qe = ee(), Je = i(x.onError), T = x.model, E = T.kinds[x.kind], Ye = x.languages?.map((e) => typeof e == "string" ? {
65
69
  value: e,
66
70
  label: e
67
- } : e), D = qe?.length ? qe : T.languages.map((e) => ({
71
+ } : e), D = Ye?.length ? Ye : T.languages.map((e) => ({
68
72
  value: e,
69
73
  label: e
70
- })), Je = D.map((e) => e.value).join("|"), [O, Ye] = h(D[0]?.value ?? "en"), [Xe, Ze] = h(""), k = Ne(x.id, x.kind, O, {
74
+ })), Xe = D.map((e) => e.value).join("|"), [O, Ze] = h(D[0]?.value ?? "en"), [Qe, $e] = h(""), k = ke(x.id, x.kind, O, {
71
75
  client: S,
72
- version: Xe || void 0
73
- }), [Qe, $e] = h(null), A = k.content ?? Qe, j = Le({
76
+ version: Qe || void 0
77
+ }), [et, tt] = h(null), A = k.content ?? et, j = m({
74
78
  item: A,
75
- scope: Ue,
79
+ scope: Ge,
76
80
  alive: !0
77
81
  });
78
- j.current.item = A, Fe(() => {
82
+ j.current.item = A, f(() => {
79
83
  let e = j.current;
80
84
  return e.alive = !0, () => {
81
85
  e.alive = !1;
82
86
  };
83
87
  }, []);
84
- let M = () => j.current.alive && j.current.scope === Ue, N = Le(null), [et, tt] = h(!1), [P, nt] = h(!1), [rt, F] = h(), [it, at] = h(""), I = p(m(() => ({ at: A?.publish_at ? pe(new Date(A.publish_at)) : "" }), [A?.publish_at])), L = I.value.at, ot = (e) => I.edit({ at: e }), [st, ct] = h(!1), [lt, ut] = h([]), [dt, ft] = h(!1), [pt, mt] = h(!1), R = m(() => [...A?.versions ?? []].sort((e, t) => e.position - t.position), [A?.versions]), z = R.find((e) => e.id === Xe) ?? R[0];
85
- Fe(() => {
86
- dt && z && ut((e) => e.includes(z.id) ? e : [...e, z.id]);
87
- }, [dt, z]);
88
- let B = te(A?.id, {
88
+ let M = () => j.current.alive && j.current.scope === Ge, N = m(null), [nt, rt] = h(!1), [P, it] = h(!1), [F, I] = h(), [at, ot] = h(""), st = Se(p(() => ({ at: A?.publish_at ? ye(new Date(A.publish_at)) : "" }), [A?.publish_at])), ct = st.value.at, lt = (e) => st.edit({ at: e }), [ut, dt] = h(!1), [ft, pt] = h([]), [mt, ht] = h(!1), [L, gt] = h(null), [_t, vt] = h(null), R = p(() => [...A?.versions ?? []].sort((e, t) => e.position - t.position), [A?.versions]), z = R.find((e) => e.id === Qe) ?? R[0];
89
+ f(() => {
90
+ mt && z && pt((e) => e.includes(z.id) ? e : [...e, z.id]);
91
+ }, [mt, z]);
92
+ let B = ne(A?.id, {
89
93
  language: O,
90
94
  client: S
91
- }), ht = m(() => new Map(B.entities), [B.entities]), [gt, _t] = h(/* @__PURE__ */ new Map()), vt = m(() => new Map([...gt, ...ht]), [ht, gt]), V = m(() => E.entities ?? [], [E.entities]), H = p(m(() => Object.fromEntries(Je.split("|").map((e) => [e, Be(A, e)])), [A, Je])), U = p(m(() => ({
95
+ }), yt = p(() => new Map(B.entities), [B.entities]), [bt, xt] = h(/* @__PURE__ */ new Map()), St = p(() => new Map([...bt, ...yt]), [yt, bt]), V = p(() => E.entities ?? [], [E.entities]), H = Se(p(() => Object.fromEntries(Xe.split("|").map((e) => [e, Ue(A, e)])), [A, Xe])), U = Se(p(() => ({
92
96
  listing: A?.listing ?? "listed",
93
97
  comments: A?.comments ?? "open",
94
- attributes: Ce(E.attributes ?? {}, A?.attributes ?? {}),
98
+ attributes: Oe(E.attributes ?? {}, A?.attributes ?? {}),
95
99
  access: A?.access ?? { level: "public" }
96
100
  }), [
97
101
  A?.listing,
@@ -99,11 +103,17 @@ function x(x) {
99
103
  A?.attributes,
100
104
  A?.access,
101
105
  E.attributes
102
- ])), W = p(m(() => ({ memberships: B.memberships.filter((e) => V.includes(B.entities.get(e.group_id ?? "")?.kind ?? "")) }), [
106
+ ])), W = Se(p(() => ({
107
+ memberships: B.memberships.filter((e) => V.includes(B.entities.get(e.group_id ?? "")?.kind ?? "")),
108
+ create: []
109
+ }), [
103
110
  B.memberships,
104
111
  B.entities,
105
112
  V
106
- ])), G = be(), K = Le({
113
+ ])), Ct = (e, t, n) => {
114
+ let r = T.entity_kinds[e]?.scoped_by;
115
+ if (r) return new Set(t.filter((e) => St.get(e.group_id ?? "")?.kind === r).map((e) => e.group_id)).size + n.filter((e) => e.kind === r).length === 1 ? void 0 : xe(x.labels, r);
116
+ }, G = Te(), K = m({
107
117
  texts: H,
108
118
  details: U,
109
119
  associations: W,
@@ -115,19 +125,33 @@ function x(x) {
115
125
  associations: W,
116
126
  language: O
117
127
  };
118
- let q = H.value[O] ?? v(), yt = (q.body ?? "").replace(me(), (e, t) => k.imageSrc(t) ?? e), J = (e) => H.edit((t) => ({
128
+ let wt = m(!1);
129
+ f(() => {
130
+ if (wt.current || x.id || !x.entities?.length) return;
131
+ wt.current = !0;
132
+ let e = x.entities.filter((e) => V.includes(e.kind));
133
+ e.length && (xt((t) => new Map([...t, ...e.map((e) => [e.id, e])])), K.current.associations.edit((t) => ({
134
+ ...t,
135
+ memberships: [...t.memberships, ...e.filter((e) => !t.memberships.some((t) => t.group_id === e.id)).map((e) => ({ group_id: e.id }))]
136
+ })));
137
+ }, [
138
+ x.id,
139
+ x.entities,
140
+ V
141
+ ]);
142
+ let Tt = H.value[O] ?? v(), Et = (e) => H.edit((t) => ({
119
143
  ...t,
120
144
  [O]: {
121
145
  ...t[O] ?? v(),
122
146
  ...e
123
147
  }
124
- })), bt = (t) => {
125
- M() && (F(t instanceof y ? t.message : t), t instanceof y || Ke(e(t), "content.save"));
126
- }, xt = async (e) => {
148
+ })), Dt = (t) => {
149
+ M() && (I(t instanceof y ? t.message : t), t instanceof y || Je(e(t), "content.save"));
150
+ }, Ot = async (e) => {
127
151
  if (j.current.item) return j.current.item;
128
152
  if (N.current) return N.current;
129
- tt(!0);
130
- let t = K.current.language, n = K.current.texts.get()[t] ?? v(), r = n.title.trim() || Ve(e ?? "") || C("readerEditor.untitled");
153
+ rt(!0);
154
+ let t = K.current.language, n = K.current.texts.get()[t] ?? v(), r = n.title.trim() || ze(e ?? "") || C("readerEditor.untitled");
131
155
  n.title.trim() || K.current.texts.edit((e) => ({
132
156
  ...e,
133
157
  [t]: {
@@ -143,10 +167,10 @@ function x(x) {
143
167
  } },
144
168
  owner_group_id: x.ownerGroup
145
169
  };
146
- return N.current = k.create(i).then((e) => (j.current.item = e, M() && ($e(e), x.onCreated?.(e)), e)).finally(() => {
147
- N.current = null, M() && tt(!1);
170
+ return N.current = k.create(i).then((e) => (j.current.item = e, M() && (tt(e), x.onCreated?.(e)), e)).finally(() => {
171
+ N.current = null, M() && rt(!1);
148
172
  }), N.current;
149
- }, Y = m(() => A && z ? {
173
+ }, q = p(() => A && z ? {
150
174
  kind: x.kind,
151
175
  id: A.id,
152
176
  version: z.id
@@ -154,97 +178,126 @@ function x(x) {
154
178
  x.kind,
155
179
  A,
156
180
  z
157
- ]), X = le("content.save", x.onError), Z = le("offer.save", x.onError), Q = le("content.save", x.onError), $ = re(Y, {
181
+ ]), J = he("content.save", x.onError), Y = he("offer.save", x.onError), X = he("content.save", x.onError), Z = ae(q, {
158
182
  commit: z?.live ? "manual" : "auto",
159
183
  client: S,
160
184
  onError: x.onError
161
- }), St = Le($);
162
- St.current = $;
163
- let Ct = $.read.read?.files ?? [], wt = Ee(A?.id, z?.id, { client: S }), Tt = !!$.error || $.queue.items.some((e) => e.status === "failed") || Ct.some((e) => e.failed), Et = Ct.some(ne), Dt = wt.review?.selected ?? 0, Ot = $.busy || et || Et || Tt || wt.loading || !!wt.error || Dt === 0 || G.pending || X.pending || Z.pending, kt = (e) => {
185
+ }), kt = m(Z);
186
+ kt.current = Z;
187
+ let At = Z.read.read?.files ?? [], jt = Ae(A?.id, z?.id, { client: S }).reload, Mt = q && Z.read.read ? JSON.stringify([
188
+ q.id,
189
+ q.version,
190
+ At.filter((e) => e.upload).map((e) => [
191
+ e.path,
192
+ e.size,
193
+ e.staged,
194
+ e.pending,
195
+ e.failed
196
+ ])
197
+ ]) : null;
198
+ f(() => {
199
+ Mt && jt();
200
+ }, [Mt, jt]);
201
+ let Q = Z.groups.filter((e) => e.rule?.page).flatMap((e) => e.files.filter((e) => !a(e)));
202
+ f(() => {
203
+ L && !Q.some((e) => e.path === L.path) && gt(null);
204
+ }, [L, Q]);
205
+ let Nt = Z.groups.flatMap((e) => e.rule ? [e.rule] : []), Pt = z?.cover?.image ? At.find((e) => e.upload && !n(Nt, e.path)?.page && t(e.path).split("/").at(-1) === z.cover?.image) : void 0, $ = ie(q ?? He, _t?.path, {
206
+ client: S,
207
+ onError: x.onError,
208
+ onSaved: () => vt(null)
209
+ }), Ft = (e) => vt({
210
+ path: e,
211
+ aspect: n(Nt, e)?.aspect ?? ""
212
+ }), It = !!Z.error || Z.queue.items.some((e) => e.status === "failed") || At.some((e) => e.failed), Lt = At.some(re), Rt = Q.length, zt = Z.busy || nt || Lt || Z.read.loading || J.pending, Bt = zt || It || !!Z.read.error || Rt === 0 || G.pending || Y.pending, Vt = (e) => {
164
213
  let t = [...e];
165
- t.length && ($.add(t), xt(t.find((e) => /\.zip$/i.test(e.name))?.name ?? t[0]?.name).catch(bt));
166
- }, At = I.dirty.length > 0 || H.dirty.length > 0 || U.dirty.length > 0 || W.dirty.length > 0 || G.dirty;
167
- Fe(() => {
168
- if (!At && !$.busy) return;
214
+ t.length && (Z.add(t), Ot(t.find((e) => /\.zip$/i.test(e.name))?.name ?? t[0]?.name).catch(Dt));
215
+ }, Ht = st.dirty.length > 0 || H.dirty.length > 0 || U.dirty.length > 0 || W.dirty.length > 0 || G.dirty, Ut = Ht || Z.pending.length > 0 || Z.queue.items.some((e) => e.status === "uploaded");
216
+ f(() => {
217
+ if (!Ht && !Z.busy) return;
169
218
  let e = (e) => {
170
219
  e.preventDefault(), e.returnValue = "";
171
220
  };
172
221
  return addEventListener("beforeunload", e), () => removeEventListener("beforeunload", e);
173
- }, [At, $.busy]);
174
- let jt = async (e) => {
222
+ }, [Ht, Z.busy]);
223
+ let Wt = async (e) => {
175
224
  if (P) return;
176
- F(void 0), at("");
225
+ I(void 0), ot("");
177
226
  let t = K.current;
178
- if (!t.texts.get()[t.language]?.title.trim()) return F(C("contentManager.titleRequired"));
227
+ if (!t.texts.get()[t.language]?.title.trim()) return I(C("contentManager.titleRequired"));
179
228
  let n = G.problem();
180
- if (n) return F(C("readerEditor.fixSection", { section: n }));
181
- if (!je(t.details.get().access) || t.details.get().access.level === "tier" && !t.details.get().access.tiers?.length) return F(C("readerEditor.accessRequired"));
229
+ if (n) return I(C("readerEditor.fixSection", { section: n }));
230
+ if (!Le(t.details.get().access) || t.details.get().access.level === "tier" && !t.details.get().access.tiers?.length) return I(C("readerEditor.accessRequired"));
182
231
  let r;
183
232
  try {
184
- r = he(E.attributes ?? {}, t.details.get().attributes);
233
+ r = be(E.attributes ?? {}, t.details.get().attributes);
185
234
  } catch (e) {
186
- return bt(e);
235
+ return Dt(e);
187
236
  }
188
- if (e && Ot) return F(C("readerEditor.filesNotReady"));
189
- nt(!0);
190
- let i = t.texts.checkpoint(), ee = t.details.checkpoint(), te = t.associations.checkpoint(), ne = t.texts.dirty.slice(), a = { ...t.texts.get() }, re = t.details.get(), ie = t.associations.get().memberships.slice(), ae = !0;
237
+ if (e && Bt) return I(C("readerEditor.filesNotReady"));
238
+ it(!0);
239
+ let i = t.texts.checkpoint(), ee = t.details.checkpoint(), te = t.associations.checkpoint(), ne = t.texts.dirty.slice(), re = { ...t.texts.get() }, a = t.details.get(), o = t.associations.get().memberships.slice(), s = t.associations.get().create.slice(), ie = (e) => !!Ct(e.kind, o, s), ae = !0;
191
240
  try {
192
- let n = await xt();
241
+ let n = await Ot();
193
242
  if (!M()) return;
194
243
  if (B.error) throw B.error;
195
- if (await Ge(async () => {
244
+ if (await qe(async () => {
196
245
  for (let e of ne) {
197
- let t = String(e), r = a[t];
246
+ let t = String(e), r = re[t];
198
247
  if (!r?.title.trim()) throw new y(C("contentManager.titleRequired"));
199
- if (n = await S.contents.putText(n.id, t, He(r)), !M()) return;
248
+ if (n = await S.contents.putText(n.id, t, We(r)), !M()) return;
200
249
  }
201
250
  if (n = await S.contents.get(n.id, O), M() && (n = await S.contents.update(n.id, {
202
- listing: re.listing,
203
- comments: re.comments,
251
+ listing: a.listing,
252
+ comments: a.comments,
204
253
  attributes: r,
205
- access: Ae(re.access),
254
+ access: Ie(a.access),
206
255
  revision: n.revision
207
256
  }), M() && t.associations.dirty.length)) {
208
- let e = n.versions.find((e) => e.id === z?.id) ?? n.versions[0], t = ie.map((t) => {
209
- let n = vt.get(t.group_id ?? "")?.kind;
257
+ let e = n.versions.find((e) => e.id === z?.id) ?? n.versions[0], t = o.map((t) => {
258
+ let n = St.get(t.group_id ?? "")?.kind;
210
259
  return n && T.entity_kinds[n]?.version_level && !t.version_id ? {
211
260
  ...t,
212
261
  version_id: e?.id
213
262
  } : t;
214
263
  }), r = await S.entities.setOfContent(n.id, {
215
264
  kinds: [...V],
216
- memberships: t
265
+ memberships: t,
266
+ create: s.filter((e) => !ie(e))
217
267
  }, O);
218
- ae = te({ memberships: r.memberships.filter((e) => V.includes(r.entities.find((t) => t.id === e.group_id)?.kind ?? "")) });
268
+ xt((e) => new Map([...e, ...r.entities.map((e) => [e.id, e])])), ae = te({
269
+ memberships: r.memberships.filter((e) => V.includes(r.entities.find((t) => t.id === e.group_id)?.kind ?? "")),
270
+ create: s.filter(ie)
271
+ });
219
272
  }
220
273
  }), !M()) return;
221
- let o = St.current;
222
- !o.busy && (o.pending.length || o.queue.items.some((e) => e.status === "uploaded")) && await o.commit();
223
- let s = await G.save(M);
224
- if (s) throw new y(C("readerEditor.fixSection", { section: s }));
274
+ let c = kt.current;
275
+ !c.busy && (c.pending.length || c.queue.items.some((e) => e.status === "uploaded")) && await c.commit();
276
+ let oe = await G.save(M);
277
+ if (oe) throw new y(C("readerEditor.fixSection", { section: oe }));
225
278
  if (!M()) return;
226
- let c = i(Object.fromEntries(D.map((e) => [e.value, n.text?.[e.value] ?? a[e.value] ?? v()]))), l = ee({
279
+ let se = i(Object.fromEntries(D.map((e) => [e.value, n.text?.[e.value] ?? re[e.value] ?? v()]))), ce = ee({
227
280
  listing: n.listing,
228
281
  comments: n.comments,
229
- attributes: Ce(E.attributes ?? {}, n.attributes),
282
+ attributes: Oe(E.attributes ?? {}, n.attributes),
230
283
  access: n.access
231
284
  });
232
285
  if (e) {
233
- if (!c || !l || !ae) throw new y(C("readerEditor.changedDuringSave"));
234
- let e = St.current;
235
- if (!Y || e.busy || e.error || e.queue.items.some((e) => e.status === "failed") || !await ye(S, Y)) throw new y(C("readerEditor.filesNotReady"));
286
+ if (!se || !ce || !ae) throw new y(C("readerEditor.changedDuringSave"));
287
+ let e = kt.current;
288
+ if (!q || e.busy || e.error || e.queue.items.some((e) => e.status === "failed") || !await we(S, q)) throw new y(C("readerEditor.filesNotReady"));
236
289
  if ((z ? await S.contents.version(n.id, z.id, O) : null)?.state !== "published") throw new y(C("readerEditor.versionDraft"));
237
290
  if (!M()) return;
238
- let t = I.checkpoint(), r = await Ge(() => S.contents.publish(n.id, L ? new Date(L).toISOString() : void 0));
239
- t({ at: r.publish_at ? pe(new Date(r.publish_at)) : "" }), at(C("contentManager.publishedNotice"));
240
- } else at(C("pollEditor.saved"));
291
+ let t = st.checkpoint(), r = await qe(() => S.contents.publish(n.id, ct ? new Date(ct).toISOString() : void 0));
292
+ t({ at: r.publish_at ? ye(new Date(r.publish_at)) : "" }), ot(C("contentManager.publishedNotice"));
293
+ } else ot(C("pollEditor.saved"));
241
294
  } catch (e) {
242
- bt(e);
295
+ Dt(e);
243
296
  } finally {
244
- M() && nt(!1);
297
+ M() && it(!1);
245
298
  }
246
- }, Mt = async (e) => {
247
- let t = await xt(e.name), n = t.versions.find((e) => e.id === z?.id) ?? t.versions[0];
299
+ }, Gt = async (e) => {
300
+ let t = await Ot(e.name), n = t.versions.find((e) => e.id === z?.id) ?? t.versions[0];
248
301
  if (!n || !M()) return;
249
302
  let r = {
250
303
  kind: x.kind,
@@ -252,40 +305,40 @@ function x(x) {
252
305
  version: n.id
253
306
  }, i = await S.media.uploadNamed(r, e, { path: await S.media.presetPath(x.kind, "cover", e) });
254
307
  M() && await S.contents.setCover(t.id, n.id, i.name);
255
- }, Nt = async (e) => {
256
- if (!Y || !A || !z) return;
257
- let n = await S.media.presetPath(x.kind, "cover", new File([], e.path.split("/").at(-1) ?? "cover", { type: e.type }));
258
- await S.media.commit(Y, [{
308
+ }, Kt = async (e) => {
309
+ if (!q || !A || !z) return;
310
+ let n = /\.[^./]+$/.exec(e.path)?.[0] ?? "", r = await S.media.presetPath(x.kind, "cover", new File([], `i-${crypto.randomUUID()}${n}`, { type: e.type }));
311
+ await S.media.commit(q, [{
259
312
  op: "copy",
260
313
  from: {
261
314
  id: A.id,
262
315
  version: z.id,
263
316
  path: e.path
264
317
  },
265
- to: n
266
- }]), M() && await S.contents.setCover(A.id, z.id, t(n).split("/").at(-1));
267
- }, { confirm: Pt, dialog: Ft } = fe(), It = async () => {
268
- A && await Pt({
318
+ to: r
319
+ }]), M() && (await S.contents.setCover(A.id, z.id, t(r).split("/").at(-1)), M() && Ft(r));
320
+ }, { confirm: qt, dialog: Jt } = ve(), Yt = async () => {
321
+ A && await qt({
269
322
  title: C("contentManager.deleteTitle", { title: A.title }),
270
323
  description: C("contentManager.deleteBody"),
271
324
  confirm: C("contentManager.delete")
272
- }) && await Q.run(async () => {
273
- $.discard(), await S.contents.remove(A.id), M() && x.onDeleted?.(A);
325
+ }) && await X.run(async () => {
326
+ Z.discard(), await S.contents.remove(A.id), M() && x.onDeleted?.(A);
274
327
  });
275
328
  };
276
- if (x.id && !A) return k.error ? /* @__PURE__ */ g(ue, {
329
+ if (x.id && !A) return k.error ? /* @__PURE__ */ g(ge, {
277
330
  error: k.error,
278
331
  message: C("contentManager.loadFailed"),
279
332
  retry: k.reload
280
- }) : /* @__PURE__ */ g(de, {});
281
- let Lt = A ? Pe(A) : "draft", Rt = z?.id, zt = (e) => U.edit((t) => ({
333
+ }) : /* @__PURE__ */ g(_e, {});
334
+ let Xt = A ? Be(A) : "draft", Zt = z?.id, Qt = (e) => U.edit((t) => ({
282
335
  ...t,
283
336
  ...e
284
- })), Bt = R.map((e) => ({
337
+ })), $t = R.map((e) => ({
285
338
  id: e.id,
286
- label: Me(e, (e) => D.find((t) => t.value === e)?.label ?? e, x.labels)
339
+ label: Re(e, (e) => D.find((t) => t.value === e)?.label ?? e, x.labels)
287
340
  }));
288
- return /* @__PURE__ */ g(ve.Provider, {
341
+ return /* @__PURE__ */ g(Ce.Provider, {
289
342
  value: G.context,
290
343
  children: /* @__PURE__ */ _("div", {
291
344
  className: "grid gap-5 text-base",
@@ -294,49 +347,73 @@ function x(x) {
294
347
  /* @__PURE__ */ _("div", {
295
348
  className: "sticky top-0 z-10 flex flex-wrap items-center gap-3 rounded-xl border border-border bg-background/95 p-4 shadow-sm",
296
349
  children: [
350
+ /* @__PURE__ */ g("button", {
351
+ type: "button",
352
+ className: "h-20 shrink-0 overflow-hidden rounded-md border border-border bg-muted disabled:cursor-default",
353
+ style: { aspectRatio: .7071 },
354
+ disabled: !Pt || P,
355
+ title: C("readerEditor.thumbnail"),
356
+ "aria-label": C("readerEditor.editThumbnail"),
357
+ onClick: () => Pt && Ft(Pt.path),
358
+ "data-ckui": "editor-thumbnail",
359
+ children: z?.cover?.url && /* @__PURE__ */ g("img", {
360
+ src: z.cover.url,
361
+ alt: "",
362
+ className: "size-full object-cover"
363
+ })
364
+ }),
297
365
  /* @__PURE__ */ _("div", {
298
366
  className: "min-w-0 flex-1",
299
367
  children: [/* @__PURE__ */ g("h1", {
300
- className: "truncate text-xl font-semibold",
301
- children: q.title || C("readerEditor.new")
368
+ className: "sr-only",
369
+ children: Tt.title || C("readerEditor.new")
302
370
  }), /* @__PURE__ */ _("div", {
303
- className: "mt-1 flex items-center gap-2 text-sm text-muted-foreground",
371
+ className: "flex items-center gap-2 text-sm text-muted-foreground",
304
372
  children: [
305
- /* @__PURE__ */ g(ae, {
373
+ /* @__PURE__ */ g(se, {
306
374
  variant: A?.live ? "default" : "outline",
307
- children: C(`contentManager.${Lt}`)
375
+ children: C(`contentManager.${Xt}`)
308
376
  }),
309
- z && /* @__PURE__ */ g("span", { children: C("contentEditor.pageCount", { count: z.pages ?? Dt }) }),
310
- et && /* @__PURE__ */ g("span", {
377
+ z && /* @__PURE__ */ g("span", { children: C("contentEditor.pageCount", { count: Z.read.read ? Rt : z.pages ?? 0 }) }),
378
+ nt && /* @__PURE__ */ g("span", {
311
379
  role: "status",
312
380
  children: C("common.saving")
313
381
  })
314
382
  ]
315
383
  })]
316
384
  }),
317
- A?.live && x.contentHref?.(A) && /* @__PURE__ */ g("a", {
385
+ A && x.contentHref?.(A) && /* @__PURE__ */ g("a", {
318
386
  href: x.contentHref(A),
319
387
  className: "text-sm underline",
320
- children: C("contentManager.view")
388
+ ...A.live ? {} : {
389
+ target: "_blank",
390
+ rel: "noopener"
391
+ },
392
+ children: C(A.live ? "contentManager.view" : "readerEditor.preview")
321
393
  }),
322
- /* @__PURE__ */ g(a, {
323
- disabled: P || et,
324
- onClick: () => void jt(!1),
325
- children: C(P ? "common.saving" : A?.live ? "common.save" : "readerEditor.saveDraft")
394
+ A && !Ut && !P ? /* @__PURE__ */ g("span", {
395
+ role: "status",
396
+ className: "text-sm text-muted-foreground",
397
+ "data-ckui": "editor-saved",
398
+ children: C("readerEditor.allSaved")
399
+ }) : /* @__PURE__ */ g(o, {
400
+ disabled: P || nt || !Ut,
401
+ onClick: () => void Wt(!1),
402
+ children: C(P ? "common.saving" : A?.live ? "readerEditor.saveChanges" : "readerEditor.saveDraft")
326
403
  }),
327
- !A?.live && /* @__PURE__ */ g(a, {
404
+ !A?.live && /* @__PURE__ */ g(o, {
328
405
  variant: "outline",
329
- disabled: P || Ot,
330
- onClick: () => void jt(!0),
331
- children: C(L ? "readerEditor.schedule" : "contentManager.publish")
406
+ disabled: P || Bt,
407
+ onClick: () => void Wt(!0),
408
+ children: C(ct ? "readerEditor.schedule" : "contentManager.publish")
332
409
  })
333
410
  ]
334
411
  }),
335
- rt != null && /* @__PURE__ */ g(f, { children: typeof rt == "string" ? rt : ce(We, e(rt)) }),
336
- it && /* @__PURE__ */ g("p", {
412
+ F != null && /* @__PURE__ */ g(d, { children: typeof F == "string" ? F : me(Ke, e(F)) }),
413
+ at && /* @__PURE__ */ g("p", {
337
414
  role: "status",
338
415
  className: "text-sm text-muted-foreground",
339
- children: it
416
+ children: at
340
417
  }),
341
418
  /* @__PURE__ */ _("fieldset", {
342
419
  disabled: P,
@@ -345,34 +422,34 @@ function x(x) {
345
422
  className: "grid min-w-0 gap-5",
346
423
  children: [
347
424
  /* @__PURE__ */ _(b, {
348
- title: C("readerEditor.details"),
425
+ label: C("readerEditor.details"),
349
426
  children: [
350
427
  /* @__PURE__ */ _("div", {
351
428
  className: "grid gap-4 sm:grid-cols-[minmax(0,1fr)_10rem]",
352
429
  children: [/* @__PURE__ */ _("div", {
353
430
  className: "grid gap-1.5",
354
- children: [/* @__PURE__ */ g(s, {
431
+ children: [/* @__PURE__ */ g(l, {
355
432
  htmlFor: `${w}-title`,
356
433
  children: C("contentManager.itemTitle")
357
- }), /* @__PURE__ */ g(o, {
434
+ }), /* @__PURE__ */ g(ce, {
358
435
  id: `${w}-title`,
359
436
  required: !0,
360
437
  maxLength: 300,
361
- value: q.title,
362
- onChange: (e) => J({ title: e.target.value })
438
+ value: Tt.title,
439
+ onChange: (e) => Et({ title: e.target.value })
363
440
  })]
364
441
  }), /* @__PURE__ */ _("div", {
365
442
  className: "grid gap-1.5",
366
- children: [/* @__PURE__ */ g(s, {
443
+ children: [/* @__PURE__ */ g(l, {
367
444
  htmlFor: `${w}-language`,
368
445
  children: C("contentManager.language")
369
- }), /* @__PURE__ */ _(c, {
446
+ }), /* @__PURE__ */ _(u, {
370
447
  value: O,
371
- onValueChange: (e) => e && Ye(e),
372
- children: [/* @__PURE__ */ g(u, {
448
+ onValueChange: (e) => e && Ze(e),
449
+ children: [/* @__PURE__ */ g(de, {
373
450
  id: `${w}-language`,
374
- children: /* @__PURE__ */ g(d, { children: D.find((e) => e.value === O)?.label ?? O })
375
- }), /* @__PURE__ */ g(l, { children: D.map((e) => /* @__PURE__ */ g(oe, {
451
+ children: /* @__PURE__ */ g(fe, { children: D.find((e) => e.value === O)?.label ?? O })
452
+ }), /* @__PURE__ */ g(le, { children: D.map((e) => /* @__PURE__ */ g(ue, {
376
453
  value: e.value,
377
454
  children: e.label
378
455
  }, e.value)) })]
@@ -381,76 +458,38 @@ function x(x) {
381
458
  }),
382
459
  /* @__PURE__ */ _("div", {
383
460
  className: "grid gap-1.5",
384
- children: [/* @__PURE__ */ g(s, {
461
+ children: [/* @__PURE__ */ g(l, {
385
462
  htmlFor: `${w}-description`,
386
- children: C("contentManager.description")
387
- }), /* @__PURE__ */ g(se, {
463
+ children: C("readerEditor.headerText")
464
+ }), /* @__PURE__ */ g(pe, {
388
465
  id: `${w}-description`,
389
466
  rows: 3,
390
- value: q.description ?? "",
391
- onChange: (e) => J({ description: e.target.value })
467
+ value: Tt.description ?? "",
468
+ onChange: (e) => Et({ description: e.target.value })
392
469
  })]
393
470
  }),
394
- /* @__PURE__ */ g(Se, {
471
+ /* @__PURE__ */ g(De, {
395
472
  declared: E.attributes ?? {},
396
473
  form: U.value.attributes,
397
- onChange: (e, t) => zt({ attributes: {
474
+ onChange: (e, t) => Qt({ attributes: {
398
475
  ...U.value.attributes,
399
476
  [e]: t
400
477
  } }),
401
478
  labels: x.labels
402
- }),
403
- /* @__PURE__ */ _("details", {
404
- className: "grid gap-3",
405
- children: [/* @__PURE__ */ g("summary", {
406
- className: "cursor-pointer text-sm text-muted-foreground",
407
- children: C("readerEditor.additionalText")
408
- }), /* @__PURE__ */ _("div", {
409
- className: "mt-3 grid gap-3",
410
- children: [
411
- /* @__PURE__ */ _("div", {
412
- className: "grid gap-1.5",
413
- children: [/* @__PURE__ */ g(s, {
414
- htmlFor: `${w}-slug`,
415
- children: C("contentManager.slug")
416
- }), /* @__PURE__ */ g(o, {
417
- id: `${w}-slug`,
418
- value: q.slug ?? "",
419
- placeholder: C("contentManager.slugAuto"),
420
- onChange: (e) => J({ slug: e.target.value })
421
- })]
422
- }),
423
- /* @__PURE__ */ g(s, {
424
- htmlFor: `${w}-body`,
425
- children: C("contentManager.body")
426
- }),
427
- x.renderEditor ? x.renderEditor({
428
- value: yt,
429
- onChange: (e) => J({ body: k.storedBody(e) }),
430
- uploadImage: A ? (e) => k.uploadImage(e) : void 0,
431
- disabled: P,
432
- "aria-label": C("contentManager.body")
433
- }) : /* @__PURE__ */ g(se, {
434
- id: `${w}-body`,
435
- value: q.body ?? "",
436
- onChange: (e) => J({ body: e.target.value })
437
- })
438
- ]
439
- })]
440
479
  })
441
480
  ]
442
481
  }),
443
482
  /* @__PURE__ */ _(b, {
444
483
  title: C("readerEditor.files"),
445
484
  children: [
446
- R.length > 1 && /* @__PURE__ */ _(c, {
447
- value: Rt ?? "",
448
- onValueChange: (e) => e && Ze(e),
449
- disabled: $.busy || $.pending.length > 0,
450
- children: [/* @__PURE__ */ g(u, {
485
+ R.length > 1 && /* @__PURE__ */ _(u, {
486
+ value: Zt ?? "",
487
+ onValueChange: (e) => e && $e(e),
488
+ disabled: Z.busy || Z.pending.length > 0,
489
+ children: [/* @__PURE__ */ g(de, {
451
490
  "aria-label": C("contentEditor.versions"),
452
- children: /* @__PURE__ */ g(d, { children: Bt.find((e) => e.id === Rt)?.label })
453
- }), /* @__PURE__ */ g(l, { children: Bt.map((e) => /* @__PURE__ */ g(oe, {
491
+ children: /* @__PURE__ */ g(fe, { children: $t.find((e) => e.id === Zt)?.label })
492
+ }), /* @__PURE__ */ g(le, { children: $t.map((e) => /* @__PURE__ */ g(ue, {
454
493
  value: e.id,
455
494
  children: e.label
456
495
  }, e.id)) })]
@@ -459,54 +498,60 @@ function x(x) {
459
498
  className: "text-sm text-muted-foreground",
460
499
  children: C("readerEditor.fileHelp")
461
500
  }),
462
- /* @__PURE__ */ g(ie, {
501
+ L && /* @__PURE__ */ _("div", {
502
+ className: "flex flex-wrap items-center gap-2 text-sm",
503
+ "data-ckui": "selected-page",
504
+ children: [/* @__PURE__ */ g("span", {
505
+ className: "text-muted-foreground",
506
+ children: C("readerEditor.pageSelected", { name: oe(Q.findIndex((e) => e.path === L.path) + 1, Q.length, L.path) })
507
+ }), /* @__PURE__ */ g(o, {
508
+ size: "sm",
509
+ variant: "secondary",
510
+ disabled: J.pending || P,
511
+ onClick: () => void J.run(() => Kt(L)),
512
+ children: C("readerEditor.setThumbnail")
513
+ })]
514
+ }),
515
+ /* @__PURE__ */ g(c, {
463
516
  folder: {
464
- ...$,
465
- add: kt
517
+ ...Z,
518
+ add: Vt
466
519
  },
467
- label: C("readerEditor.files"),
520
+ label: !1,
468
521
  layout: "grid",
469
522
  disabled: P,
470
523
  inputLabel: C("readerEditor.files"),
471
- rowActions: (e) => e.type.startsWith("image/") && $.groups.some((t) => t.rule?.page && t.files.some((t) => t.path === e.path)) ? /* @__PURE__ */ g(a, {
472
- size: "icon-sm",
473
- variant: "ghost",
474
- title: C("readerEditor.useCover"),
475
- "aria-label": C("readerEditor.useCoverFor", { name: e.path.split("/").at(-1) ?? e.path }),
476
- disabled: X.pending || P,
477
- onClick: () => void X.run(() => Nt(e)),
478
- children: /* @__PURE__ */ g(ze, { icon: Re })
479
- }) : null
524
+ selectedPage: L?.path ?? null,
525
+ onSelectPage: gt
526
+ }),
527
+ Z.read.error && /* @__PURE__ */ g(ge, {
528
+ error: Z.read.error,
529
+ message: C("contentManager.loadFailed"),
530
+ retry: Z.read.reload
480
531
  }),
481
- Ot && /* @__PURE__ */ g("p", {
532
+ (It || zt || !Z.read.error && Rt === 0) && /* @__PURE__ */ g("p", {
482
533
  role: "status",
483
534
  className: "text-sm text-muted-foreground",
484
- children: Tt ? C("readerEditor.filesFailed") : Et || $.busy ? C("readerEditor.processing") : C("readerEditor.addPages")
535
+ children: C(It ? "readerEditor.filesFailed" : zt ? "readerEditor.processing" : "readerEditor.addPages")
485
536
  }),
486
- A && z && /* @__PURE__ */ _("details", {
487
- onToggle: (e) => e.currentTarget.open && mt(!0),
488
- children: [/* @__PURE__ */ g("summary", {
489
- className: "cursor-pointer font-medium",
490
- children: C("pageReview.title")
491
- }), pt && /* @__PURE__ */ g(De, {
492
- content: A.id,
493
- version: z.id,
494
- client: S,
495
- onError: x.onError
496
- }, z.id)]
537
+ A && z && /* @__PURE__ */ g(Ne, {
538
+ content: A.id,
539
+ version: z.id,
540
+ client: S,
541
+ onError: x.onError
497
542
  })
498
543
  ]
499
544
  }),
500
545
  A && /* @__PURE__ */ _("details", {
501
546
  className: "rounded-xl border border-border bg-card p-4",
502
- onToggle: (e) => e.currentTarget.open && ct(!0),
547
+ onToggle: (e) => e.currentTarget.open && dt(!0),
503
548
  children: [/* @__PURE__ */ g("summary", {
504
549
  className: "cursor-pointer font-medium",
505
550
  children: C("readerEditor.versions")
506
- }), st && /* @__PURE__ */ g(ke, {
551
+ }), ut && /* @__PURE__ */ g(Fe, {
507
552
  content: A,
508
553
  media: !1,
509
- activeVersion: Rt,
554
+ activeVersion: Zt,
510
555
  client: S,
511
556
  labels: x.labels,
512
557
  onError: x.onError
@@ -514,13 +559,13 @@ function x(x) {
514
559
  }),
515
560
  A && z && /* @__PURE__ */ _("details", {
516
561
  className: "rounded-xl border border-border bg-card p-4",
517
- onToggle: (e) => ft(e.currentTarget.open),
562
+ onToggle: (e) => ht(e.currentTarget.open),
518
563
  children: [/* @__PURE__ */ g("summary", {
519
564
  className: "cursor-pointer font-medium",
520
565
  children: C("readerEditor.readerTools")
521
- }), lt.filter((e) => R.some((t) => t.id === e)).map((e) => /* @__PURE__ */ g("div", {
566
+ }), ft.filter((e) => R.some((t) => t.id === e)).map((e) => /* @__PURE__ */ g("div", {
522
567
  hidden: e !== z.id,
523
- children: /* @__PURE__ */ g(Te, {
568
+ children: /* @__PURE__ */ g(Me, {
524
569
  content: A.id,
525
570
  version: e,
526
571
  client: S,
@@ -534,60 +579,63 @@ function x(x) {
534
579
  children: [
535
580
  /* @__PURE__ */ _(b, {
536
581
  title: C("readerEditor.entities"),
537
- children: [B.error && /* @__PURE__ */ g(f, { error: B.error }), V.map((e) => {
582
+ children: [B.error && /* @__PURE__ */ g(d, { error: B.error }), V.map((e) => {
538
583
  let t = W.value.memberships.map((e, t) => ({
539
584
  a: e,
540
585
  index: t
541
- })).filter(({ a: t }) => vt.get(t.group_id ?? "")?.kind === e);
542
- return /* @__PURE__ */ _("fieldset", {
586
+ })).filter(({ a: t }) => St.get(t.group_id ?? "")?.kind === e);
587
+ return /* @__PURE__ */ g(je, {
588
+ kind: e,
589
+ label: xe(x.labels, e),
590
+ memberships: t.map(({ a: e }) => e),
591
+ cards: St,
592
+ spec: T.entity_kinds[e] ?? {},
593
+ labels: x.labels,
594
+ versions: $t,
595
+ versionLabel: (e) => $t.find((t) => t.id === e)?.label ?? e,
596
+ language: O,
597
+ management: x.management,
598
+ client: S,
543
599
  disabled: !!A && B.loading,
544
- className: "grid min-w-0 gap-2",
545
- children: [
546
- /* @__PURE__ */ g("legend", {
547
- className: "mb-2 font-semibold",
548
- children: _e(x.labels, e)
549
- }),
550
- t.map(({ a: t, index: n }) => /* @__PURE__ */ g(we, {
551
- m: t,
552
- card: vt.get(t.group_id ?? ""),
553
- spec: T.entity_kinds[e] ?? {},
554
- labels: x.labels,
555
- versions: Bt,
556
- versionLabel: (e) => Bt.find((t) => t.id === e)?.label ?? e,
557
- onChange: (e) => W.edit((t) => ({ memberships: t.memberships.map((t, r) => r === n ? {
558
- ...t,
559
- ...e
560
- } : t) })),
561
- onRemove: () => W.edit((e) => ({ memberships: e.memberships.filter((e, t) => t !== n) }))
562
- }, `${t.group_id}:${n}`)),
563
- /* @__PURE__ */ g(ge, {
600
+ created: W.value.create.filter((t) => t.kind === e).map((e) => e.name),
601
+ needsScope: Ct(e, W.value.memberships, W.value.create),
602
+ onCreatedChange: (t) => W.edit((n) => ({
603
+ ...n,
604
+ create: [...n.create.filter((t) => t.kind !== e), ...t.map((t) => ({
564
605
  kind: e,
565
- management: x.management,
566
- language: O,
567
- exclude: t.filter(({ a: e }) => !e.version_id && !e.role).map(({ a: e }) => e.group_id),
568
- label: C("memberships.add", { kind: _e(x.labels, e) }),
569
- client: S,
570
- onPick: (t) => {
571
- _t((e) => new Map(e).set(t.id, t)), W.edit((n) => ({ memberships: [...n.memberships, {
572
- group_id: t.id,
573
- ...T.entity_kinds[e]?.version_level && z ? { version_id: z.id } : {}
574
- }] }));
575
- }
576
- })
577
- ]
606
+ name: t,
607
+ language: O
608
+ }))]
609
+ })),
610
+ onChange: (e, n) => W.edit((r) => ({
611
+ ...r,
612
+ memberships: r.memberships.map((r, i) => i === t[e].index ? {
613
+ ...r,
614
+ ...n
615
+ } : r)
616
+ })),
617
+ onRemove: (e) => W.edit((n) => ({
618
+ ...n,
619
+ memberships: n.memberships.filter((n, r) => r !== t[e].index)
620
+ })),
621
+ onAdd: (t) => {
622
+ xt((e) => new Map(e).set(t.id, t)), W.edit((n) => ({
623
+ ...n,
624
+ memberships: [...n.memberships, {
625
+ group_id: t.id,
626
+ ...T.entity_kinds[e]?.version_level && z ? { version_id: z.id } : {}
627
+ }]
628
+ }));
629
+ }
578
630
  }, e);
579
631
  })]
580
632
  }),
581
633
  /* @__PURE__ */ _(b, {
582
634
  title: C("contentManager.cover"),
583
635
  children: [
584
- z?.cover?.url ? /* @__PURE__ */ g("img", {
585
- src: z.cover.url,
586
- alt: "",
587
- className: "mx-auto max-h-64 rounded-lg object-contain"
588
- }) : /* @__PURE__ */ g("p", {
636
+ /* @__PURE__ */ g("p", {
589
637
  className: "text-sm text-muted-foreground",
590
- children: C("readerEditor.firstPageCover")
638
+ children: C("readerEditor.thumbnailHelp")
591
639
  }),
592
640
  /* @__PURE__ */ _("label", {
593
641
  className: "inline-flex cursor-pointer justify-center rounded-md border border-border px-3 py-2 text-sm font-medium hover:bg-muted",
@@ -596,35 +644,35 @@ function x(x) {
596
644
  accept: "image/*",
597
645
  className: "sr-only",
598
646
  "aria-label": C("contentManager.cover"),
599
- disabled: X.pending || P,
647
+ disabled: J.pending || P,
600
648
  onChange: (e) => {
601
649
  let t = e.target.files?.[0];
602
- e.target.value = "", t && X.run(() => Mt(t));
650
+ e.target.value = "", t && J.run(() => Gt(t));
603
651
  }
604
652
  })]
605
653
  }),
606
- /* @__PURE__ */ g(f, { error: X.error })
654
+ /* @__PURE__ */ g(d, { error: J.error })
607
655
  ]
608
656
  }),
609
657
  /* @__PURE__ */ _(b, {
610
658
  title: C("contentEditor.accessTitle"),
611
659
  children: [
612
- /* @__PURE__ */ g(Oe, {
660
+ /* @__PURE__ */ g(Pe, {
613
661
  value: U.value.access,
614
- onChange: (e) => zt({ access: e }),
662
+ onChange: (e) => Qt({ access: e }),
615
663
  model: T,
616
664
  kind: x.kind,
617
665
  owner: A?.owner_group_id ?? x.ownerGroup,
618
666
  labels: x.labels,
619
667
  client: S
620
668
  }),
621
- A && (U.value.access.level === "ppv" || U.value.access.level === "group_ppv" || A.offer) && /* @__PURE__ */ g(xe, {
669
+ A && (U.value.access.level === "ppv" || U.value.access.level === "group_ppv" || A.offer) && /* @__PURE__ */ g(Ee, {
622
670
  offer: A.offer,
623
- pending: Z.pending,
624
- onSell: (e) => Z.run(() => S.offers.sell({ content: A.id }, e)),
625
- onWithdraw: () => void Z.run(() => S.offers.withdraw({ content: A.id }))
671
+ pending: Y.pending,
672
+ onSell: (e) => Y.run(() => S.offers.sell({ content: A.id }, e)),
673
+ onWithdraw: () => void Y.run(() => S.offers.withdraw({ content: A.id }))
626
674
  }),
627
- /* @__PURE__ */ g(f, { error: Z.error })
675
+ /* @__PURE__ */ g(d, { error: Y.error })
628
676
  ]
629
677
  }),
630
678
  /* @__PURE__ */ _(b, {
@@ -632,73 +680,86 @@ function x(x) {
632
680
  children: [
633
681
  !A?.live && /* @__PURE__ */ _("div", {
634
682
  className: "grid gap-1.5",
635
- children: [/* @__PURE__ */ g(s, {
683
+ children: [/* @__PURE__ */ g(l, {
636
684
  htmlFor: `${w}-publish`,
637
685
  children: C("contentManager.publishAt")
638
- }), /* @__PURE__ */ g(o, {
686
+ }), /* @__PURE__ */ g(ce, {
639
687
  id: `${w}-publish`,
640
688
  type: "datetime-local",
641
- value: L,
642
- onChange: (e) => ot(e.target.value)
689
+ value: ct,
690
+ onChange: (e) => lt(e.target.value)
643
691
  })]
644
692
  }),
645
- /* @__PURE__ */ g(s, {
693
+ /* @__PURE__ */ g(l, {
646
694
  htmlFor: `${w}-listing`,
647
695
  children: C("contentEditor.listing")
648
696
  }),
649
- /* @__PURE__ */ _(c, {
697
+ /* @__PURE__ */ _(u, {
650
698
  value: U.value.listing,
651
- onValueChange: (e) => e && zt({ listing: e }),
652
- children: [/* @__PURE__ */ g(u, {
699
+ onValueChange: (e) => e && Qt({ listing: e }),
700
+ children: [/* @__PURE__ */ g(de, {
653
701
  id: `${w}-listing`,
654
- children: /* @__PURE__ */ g(d, { children: C(`contentEditor.listing_${U.value.listing}`) })
655
- }), /* @__PURE__ */ g(l, { children: [
702
+ children: /* @__PURE__ */ g(fe, { children: C(`contentEditor.listing_${U.value.listing}`) })
703
+ }), /* @__PURE__ */ g(le, { children: [
656
704
  "listed",
657
705
  "members",
658
706
  "unlisted"
659
- ].map((e) => /* @__PURE__ */ g(oe, {
707
+ ].map((e) => /* @__PURE__ */ g(ue, {
660
708
  value: e,
661
709
  children: C(`contentEditor.listing_${e}`)
662
710
  }, e)) })]
663
711
  }),
664
- /* @__PURE__ */ g(s, {
712
+ /* @__PURE__ */ g(l, {
665
713
  htmlFor: `${w}-comments`,
666
714
  children: C("contentEditor.comments")
667
715
  }),
668
- /* @__PURE__ */ _(c, {
716
+ /* @__PURE__ */ _(u, {
669
717
  value: U.value.comments,
670
- onValueChange: (e) => e && zt({ comments: e }),
671
- children: [/* @__PURE__ */ g(u, {
718
+ onValueChange: (e) => e && Qt({ comments: e }),
719
+ children: [/* @__PURE__ */ g(de, {
672
720
  id: `${w}-comments`,
673
- children: /* @__PURE__ */ g(d, { children: C(`contentEditor.comments_${U.value.comments}`) })
674
- }), /* @__PURE__ */ g(l, { children: [
721
+ children: /* @__PURE__ */ g(fe, { children: C(`contentEditor.comments_${U.value.comments}`) })
722
+ }), /* @__PURE__ */ g(le, { children: [
675
723
  "open",
676
724
  "closed",
677
725
  "hidden"
678
- ].map((e) => /* @__PURE__ */ g(oe, {
726
+ ].map((e) => /* @__PURE__ */ g(ue, {
679
727
  value: e,
680
728
  children: C(`contentEditor.comments_${e}`)
681
729
  }, e)) })]
682
730
  }),
683
- A?.state === "published" && /* @__PURE__ */ g(a, {
731
+ A?.state === "published" && /* @__PURE__ */ g(o, {
684
732
  variant: "outline",
685
- disabled: Q.pending,
686
- onClick: () => void Q.run(() => S.contents.unpublish(A.id)),
733
+ disabled: X.pending,
734
+ onClick: () => void X.run(() => S.contents.unpublish(A.id)),
687
735
  children: C("contentManager.unpublish")
688
736
  }),
689
- A && /* @__PURE__ */ g(a, {
737
+ A && /* @__PURE__ */ g(o, {
690
738
  variant: "destructive",
691
- disabled: Q.pending,
692
- onClick: () => void It(),
739
+ disabled: X.pending,
740
+ onClick: () => void Yt(),
693
741
  children: C("contentManager.delete")
694
742
  }),
695
- /* @__PURE__ */ g(f, { error: Q.error })
743
+ /* @__PURE__ */ g(d, { error: X.error })
696
744
  ]
697
745
  })
698
746
  ]
699
747
  })]
700
748
  }),
701
- Ft
749
+ Jt,
750
+ /* @__PURE__ */ g(s, {
751
+ open: !!_t,
752
+ onOpenChange: (e) => !e && $.status !== "saving" && vt(null),
753
+ source: "source" in $ ? $.source ?? null : null,
754
+ aspect: _t?.aspect ?? "",
755
+ rotatable: !1,
756
+ initialEdit: "edit" in $ ? $.edit : null,
757
+ title: C("readerEditor.thumbnail"),
758
+ confirmLabel: C("readerEditor.setThumbnail"),
759
+ busy: $.status === "saving",
760
+ error: $.status === "error" ? me(Ke, $.error) : void 0,
761
+ onConfirm: (e) => void $.save(e)
762
+ })
702
763
  ]
703
764
  })
704
765
  });