@byline/admin 2.5.1 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (260) hide show
  1. package/dist/fields/array/array-field.d.ts +14 -0
  2. package/dist/fields/array/array-field.js +177 -0
  3. package/dist/fields/array/array-field.module.js +11 -0
  4. package/dist/fields/array/array-field_module.css +32 -0
  5. package/dist/fields/blocks/blocks-field.d.ts +13 -0
  6. package/dist/fields/blocks/blocks-field.js +245 -0
  7. package/dist/fields/blocks/blocks-field.module.js +26 -0
  8. package/dist/fields/blocks/blocks-field_module.css +107 -0
  9. package/dist/fields/checkbox/checkbox-field.d.ts +16 -0
  10. package/dist/fields/checkbox/checkbox-field.js +28 -0
  11. package/dist/fields/checkbox/checkbox-field.module.js +6 -0
  12. package/dist/fields/checkbox/checkbox-field_module.css +4 -0
  13. package/dist/fields/column-formatter.d.ts +20 -0
  14. package/dist/fields/column-formatter.js +15 -0
  15. package/dist/fields/date-time-formatter.d.ts +16 -0
  16. package/dist/fields/date-time-formatter.js +8 -0
  17. package/dist/fields/datetime/datetime-field.d.ts +16 -0
  18. package/dist/fields/datetime/datetime-field.js +37 -0
  19. package/dist/fields/datetime/datetime-field.module.js +5 -0
  20. package/dist/fields/datetime/datetime-field_module.css +4 -0
  21. package/dist/fields/draggable-context-menu.d.ts +6 -0
  22. package/dist/fields/draggable-context-menu.js +85 -0
  23. package/dist/fields/draggable-context-menu.module.js +15 -0
  24. package/dist/fields/draggable-context-menu_module.css +91 -0
  25. package/dist/fields/field-helpers.d.ts +26 -0
  26. package/dist/fields/field-helpers.js +50 -0
  27. package/dist/fields/field-renderer.d.ts +37 -0
  28. package/dist/fields/field-renderer.js +206 -0
  29. package/dist/fields/field-renderer.module.js +8 -0
  30. package/dist/fields/field-renderer_module.css +11 -0
  31. package/dist/fields/field-services-context.d.ts +16 -0
  32. package/dist/fields/field-services-context.js +13 -0
  33. package/dist/fields/field-services-types.d.ts +63 -0
  34. package/dist/fields/field-services-types.js +1 -0
  35. package/dist/fields/file/file-field.d.ts +19 -0
  36. package/dist/fields/file/file-field.js +225 -0
  37. package/dist/fields/file/file-field.module.js +18 -0
  38. package/dist/fields/file/file-field_module.css +131 -0
  39. package/dist/fields/file/file-upload-field.d.ts +21 -0
  40. package/dist/fields/file/file-upload-field.js +130 -0
  41. package/dist/fields/file/file-upload-field.module.js +15 -0
  42. package/dist/fields/file/file-upload-field_module.css +74 -0
  43. package/dist/fields/group/group-field.d.ts +15 -0
  44. package/dist/fields/group/group-field.js +59 -0
  45. package/dist/fields/group/group-field.module.js +9 -0
  46. package/dist/fields/group/group-field_module.css +27 -0
  47. package/dist/fields/image/image-field.d.ts +19 -0
  48. package/dist/fields/image/image-field.js +241 -0
  49. package/dist/fields/image/image-field.module.js +22 -0
  50. package/dist/fields/image/image-field_module.css +121 -0
  51. package/dist/fields/image/image-upload-field.d.ts +21 -0
  52. package/dist/fields/image/image-upload-field.js +190 -0
  53. package/dist/fields/image/image-upload-field.module.js +19 -0
  54. package/dist/fields/image/image-upload-field_module.css +92 -0
  55. package/dist/fields/local-date-time.d.ts +27 -0
  56. package/dist/fields/local-date-time.js +49 -0
  57. package/dist/fields/locale-badge.d.ts +18 -0
  58. package/dist/fields/locale-badge.js +10 -0
  59. package/dist/fields/locale-badge.module.js +5 -0
  60. package/dist/fields/locale-badge_module.css +27 -0
  61. package/dist/fields/numerical/numerical-field.d.ts +18 -0
  62. package/dist/fields/numerical/numerical-field.js +74 -0
  63. package/dist/fields/relation/relation-display.d.ts +40 -0
  64. package/dist/fields/relation/relation-display.js +58 -0
  65. package/dist/fields/relation/relation-display.module.js +9 -0
  66. package/dist/fields/relation/relation-display_module.css +21 -0
  67. package/dist/fields/relation/relation-field.d.ts +18 -0
  68. package/dist/fields/relation/relation-field.js +138 -0
  69. package/dist/fields/relation/relation-field.module.js +13 -0
  70. package/dist/fields/relation/relation-field_module.css +62 -0
  71. package/dist/fields/relation/relation-picker.d.ts +49 -0
  72. package/dist/fields/relation/relation-picker.js +236 -0
  73. package/dist/fields/relation/relation-picker.module.js +26 -0
  74. package/dist/fields/relation/relation-picker_module.css +124 -0
  75. package/dist/fields/relation/relation-summary.d.ts +31 -0
  76. package/dist/fields/relation/relation-summary.js +50 -0
  77. package/dist/fields/relation/relation-summary.module.js +11 -0
  78. package/dist/fields/relation/relation-summary_module.css +37 -0
  79. package/dist/fields/select/select-field.d.ts +16 -0
  80. package/dist/fields/select/select-field.js +50 -0
  81. package/dist/fields/select/select-field.module.js +5 -0
  82. package/dist/fields/select/select-field_module.css +4 -0
  83. package/dist/fields/sortable-item.d.ts +15 -0
  84. package/dist/fields/sortable-item.js +81 -0
  85. package/dist/fields/sortable-item.module.js +22 -0
  86. package/dist/fields/sortable-item_module.css +124 -0
  87. package/dist/fields/text/text-field.d.ts +20 -0
  88. package/dist/fields/text/text-field.js +104 -0
  89. package/dist/fields/text/text-field.module.js +6 -0
  90. package/dist/fields/text/text-field_module.css +5 -0
  91. package/dist/fields/text-area/text-area-field.d.ts +20 -0
  92. package/dist/fields/text-area/text-area-field.js +105 -0
  93. package/dist/fields/text-area/text-area-field.module.js +6 -0
  94. package/dist/fields/text-area/text-area-field_module.css +5 -0
  95. package/dist/fields/use-field-change-handler.d.ts +23 -0
  96. package/dist/fields/use-field-change-handler.js +52 -0
  97. package/dist/forms/document-actions.d.ts +48 -0
  98. package/dist/forms/document-actions.js +475 -0
  99. package/dist/forms/document-actions.module.js +34 -0
  100. package/dist/forms/document-actions_module.css +118 -0
  101. package/dist/forms/form-context.d.ts +89 -0
  102. package/dist/forms/form-context.js +466 -0
  103. package/dist/forms/form-renderer.d.ts +98 -0
  104. package/dist/forms/form-renderer.js +597 -0
  105. package/dist/forms/form-renderer.module.js +46 -0
  106. package/dist/forms/form-renderer_module.css +245 -0
  107. package/dist/forms/navigation-guard.d.ts +54 -0
  108. package/dist/forms/navigation-guard.js +22 -0
  109. package/dist/forms/path-widget.d.ts +36 -0
  110. package/dist/forms/path-widget.js +116 -0
  111. package/dist/forms/path-widget.module.js +8 -0
  112. package/dist/forms/path-widget_module.css +29 -0
  113. package/dist/forms/upload-executor.d.ts +57 -0
  114. package/dist/forms/upload-executor.js +94 -0
  115. package/dist/lib/translate-validation-error.d.ts +36 -0
  116. package/dist/lib/translate-validation-error.js +11 -0
  117. package/dist/modules/admin-account/commands.d.ts +2 -1
  118. package/dist/modules/admin-account/commands.js +13 -2
  119. package/dist/modules/admin-account/components/change-password.js +45 -36
  120. package/dist/modules/admin-account/components/container.js +185 -134
  121. package/dist/modules/admin-account/components/preferences.d.ts +8 -0
  122. package/dist/modules/admin-account/components/preferences.js +152 -0
  123. package/dist/modules/admin-account/components/preferences.module.js +11 -0
  124. package/dist/modules/admin-account/components/preferences_module.css +41 -0
  125. package/dist/modules/admin-account/components/update.js +50 -31
  126. package/dist/modules/admin-account/index.d.ts +3 -3
  127. package/dist/modules/admin-account/index.js +2 -2
  128. package/dist/modules/admin-account/schemas.d.ts +4 -0
  129. package/dist/modules/admin-account/schemas.js +4 -1
  130. package/dist/modules/admin-account/service.d.ts +1 -0
  131. package/dist/modules/admin-account/service.js +8 -0
  132. package/dist/modules/admin-permissions/components/inspector.js +31 -41
  133. package/dist/modules/admin-roles/components/create.js +43 -26
  134. package/dist/modules/admin-roles/components/permissions.js +26 -35
  135. package/dist/modules/admin-roles/components/update.js +26 -16
  136. package/dist/modules/admin-users/components/create.js +60 -40
  137. package/dist/modules/admin-users/components/roles.js +9 -15
  138. package/dist/modules/admin-users/components/set-password.js +30 -31
  139. package/dist/modules/admin-users/components/update.js +58 -39
  140. package/dist/modules/admin-users/dto.js +1 -0
  141. package/dist/modules/admin-users/repository.d.ts +17 -0
  142. package/dist/modules/admin-users/schemas.d.ts +4 -0
  143. package/dist/modules/admin-users/schemas.js +6 -2
  144. package/dist/modules/auth/components/sign-in-form.js +10 -8
  145. package/dist/presentation/group.d.ts +27 -0
  146. package/dist/presentation/group.js +14 -0
  147. package/dist/presentation/group.module.js +6 -0
  148. package/dist/presentation/group_module.css +19 -0
  149. package/dist/presentation/row.d.ts +25 -0
  150. package/dist/presentation/row.js +8 -0
  151. package/dist/presentation/row.module.js +5 -0
  152. package/dist/presentation/row_module.css +18 -0
  153. package/dist/presentation/tabs.d.ts +25 -0
  154. package/dist/presentation/tabs.js +39 -0
  155. package/dist/presentation/tabs.module.js +10 -0
  156. package/dist/presentation/tabs_module.css +68 -0
  157. package/dist/react.d.ts +66 -0
  158. package/dist/react.js +36 -0
  159. package/dist/services/admin-services-types.d.ts +16 -0
  160. package/dist/widgets/diff-viewer/diff-modal.d.ts +22 -0
  161. package/dist/widgets/diff-viewer/diff-modal.js +149 -0
  162. package/dist/widgets/diff-viewer/diff-modal.module.js +14 -0
  163. package/dist/widgets/diff-viewer/diff-modal_module.css +56 -0
  164. package/dist/widgets/status-badge/status-badge.d.ts +25 -0
  165. package/dist/widgets/status-badge/status-badge.js +37 -0
  166. package/dist/widgets/status-badge/status-badge.module.js +7 -0
  167. package/dist/widgets/status-badge/status-badge_module.css +20 -0
  168. package/package.json +14 -4
  169. package/src/fields/array/array-field.module.css +48 -0
  170. package/src/fields/array/array-field.tsx +267 -0
  171. package/src/fields/blocks/blocks-field.module.css +148 -0
  172. package/src/fields/blocks/blocks-field.tsx +323 -0
  173. package/src/fields/checkbox/checkbox-field.module.css +4 -0
  174. package/src/fields/checkbox/checkbox-field.tsx +54 -0
  175. package/src/fields/column-formatter.tsx +31 -0
  176. package/src/fields/date-time-formatter.tsx +22 -0
  177. package/src/fields/datetime/datetime-field.module.css +13 -0
  178. package/src/fields/datetime/datetime-field.tsx +54 -0
  179. package/src/fields/draggable-context-menu.module.css +127 -0
  180. package/src/fields/draggable-context-menu.tsx +87 -0
  181. package/src/fields/field-helpers.ts +69 -0
  182. package/src/fields/field-renderer.module.css +22 -0
  183. package/src/fields/field-renderer.tsx +288 -0
  184. package/src/fields/field-services-context.tsx +35 -0
  185. package/src/fields/field-services-types.ts +68 -0
  186. package/src/fields/file/file-field.module.css +153 -0
  187. package/src/fields/file/file-field.tsx +286 -0
  188. package/src/fields/file/file-upload-field.module.css +101 -0
  189. package/src/fields/file/file-upload-field.tsx +187 -0
  190. package/src/fields/group/group-field.module.css +43 -0
  191. package/src/fields/group/group-field.tsx +84 -0
  192. package/src/fields/image/image-field.module.css +155 -0
  193. package/src/fields/image/image-field.tsx +306 -0
  194. package/src/fields/image/image-upload-field.module.css +123 -0
  195. package/src/fields/image/image-upload-field.tsx +276 -0
  196. package/src/fields/local-date-time.tsx +88 -0
  197. package/src/fields/locale-badge.module.css +37 -0
  198. package/src/fields/locale-badge.tsx +32 -0
  199. package/src/fields/numerical/numerical-field.tsx +114 -0
  200. package/src/fields/relation/relation-display.module.css +36 -0
  201. package/src/fields/relation/relation-display.tsx +130 -0
  202. package/src/fields/relation/relation-field.module.css +83 -0
  203. package/src/fields/relation/relation-field.tsx +211 -0
  204. package/src/fields/relation/relation-picker.module.css +168 -0
  205. package/src/fields/relation/relation-picker.tsx +326 -0
  206. package/src/fields/relation/relation-summary.module.css +55 -0
  207. package/src/fields/relation/relation-summary.tsx +123 -0
  208. package/src/fields/select/select-field.module.css +13 -0
  209. package/src/fields/select/select-field.tsx +61 -0
  210. package/src/fields/sortable-item.module.css +167 -0
  211. package/src/fields/sortable-item.tsx +106 -0
  212. package/src/fields/text/text-field.module.css +13 -0
  213. package/src/fields/text/text-field.tsx +146 -0
  214. package/src/fields/text-area/text-area-field.module.css +13 -0
  215. package/src/fields/text-area/text-area-field.tsx +147 -0
  216. package/src/fields/use-field-change-handler.ts +112 -0
  217. package/src/forms/document-actions.module.css +160 -0
  218. package/src/forms/document-actions.tsx +482 -0
  219. package/src/forms/form-context.tsx +704 -0
  220. package/src/forms/form-renderer.module.css +321 -0
  221. package/src/forms/form-renderer.tsx +891 -0
  222. package/src/forms/navigation-guard.tsx +98 -0
  223. package/src/forms/path-widget.module.css +41 -0
  224. package/src/forms/path-widget.test.tsx +217 -0
  225. package/src/forms/path-widget.tsx +183 -0
  226. package/src/forms/upload-executor.ts +192 -0
  227. package/src/lib/translate-validation-error.ts +56 -0
  228. package/src/modules/admin-account/commands.ts +13 -0
  229. package/src/modules/admin-account/components/change-password.tsx +46 -31
  230. package/src/modules/admin-account/components/container.tsx +83 -38
  231. package/src/modules/admin-account/components/preferences.module.css +60 -0
  232. package/src/modules/admin-account/components/preferences.tsx +203 -0
  233. package/src/modules/admin-account/components/update.tsx +53 -27
  234. package/src/modules/admin-account/index.ts +3 -0
  235. package/src/modules/admin-account/schemas.ts +13 -0
  236. package/src/modules/admin-account/service.ts +12 -0
  237. package/src/modules/admin-permissions/components/inspector.tsx +22 -14
  238. package/src/modules/admin-roles/components/create.tsx +51 -23
  239. package/src/modules/admin-roles/components/permissions.tsx +25 -21
  240. package/src/modules/admin-roles/components/update.tsx +37 -19
  241. package/src/modules/admin-users/components/create.tsx +63 -34
  242. package/src/modules/admin-users/components/roles.tsx +9 -8
  243. package/src/modules/admin-users/components/set-password.tsx +34 -28
  244. package/src/modules/admin-users/components/update.tsx +58 -36
  245. package/src/modules/admin-users/dto.ts +1 -0
  246. package/src/modules/admin-users/repository.ts +17 -0
  247. package/src/modules/admin-users/schemas.ts +12 -0
  248. package/src/modules/auth/components/sign-in-form.tsx +14 -8
  249. package/src/presentation/group.module.css +41 -0
  250. package/src/presentation/group.tsx +40 -0
  251. package/src/presentation/row.module.css +32 -0
  252. package/src/presentation/row.tsx +33 -0
  253. package/src/presentation/tabs.module.css +107 -0
  254. package/src/presentation/tabs.tsx +84 -0
  255. package/src/react.ts +84 -0
  256. package/src/services/admin-services-types.ts +18 -0
  257. package/src/widgets/diff-viewer/diff-modal.module.css +79 -0
  258. package/src/widgets/diff-viewer/diff-modal.tsx +186 -0
  259. package/src/widgets/status-badge/status-badge.module.css +31 -0
  260. package/src/widgets/status-badge/status-badge.tsx +71 -0
@@ -0,0 +1,18 @@
1
+ :is(.row-WWZ32_, .byline-admin-row) {
2
+ align-items: flex-start;
3
+ gap: var(--spacing-16);
4
+ flex-direction: column;
5
+ display: flex;
6
+ }
7
+
8
+ :is(.row-WWZ32_ > *, .byline-admin-row > *) {
9
+ flex: 1;
10
+ min-width: 0;
11
+ }
12
+
13
+ @media (min-width: 40rem) {
14
+ :is(.row-WWZ32_, .byline-admin-row) {
15
+ flex-direction: row;
16
+ }
17
+ }
18
+
@@ -0,0 +1,25 @@
1
+ export interface AdminTabItem {
2
+ name: string;
3
+ label: string;
4
+ }
5
+ interface AdminTabsProps {
6
+ tabs: AdminTabItem[];
7
+ activeTab: string;
8
+ onChange: (name: string) => void;
9
+ /** Error counts keyed by tab name — shows a danger badge when > 0. */
10
+ errorCounts?: Record<string, number>;
11
+ className?: string;
12
+ }
13
+ /**
14
+ * Tabs navigation bar for admin form layouts.
15
+ *
16
+ * Used by FormRenderer when a CollectionAdminConfig declares a `tabs` array.
17
+ * Each tab is a simple button with a bottom-border active indicator.
18
+ * Inactive tabs show a subtle hover state. Fully dark-mode aware.
19
+ *
20
+ * Stable override handles: `.byline-admin-tabs`, `.byline-admin-tab`,
21
+ * `.byline-admin-tab-active`, `.byline-admin-tab-label`,
22
+ * `.byline-admin-tab-badge`.
23
+ */
24
+ export declare const AdminTabs: ({ tabs, activeTab, onChange, errorCounts, className, }: AdminTabsProps) => import("react").JSX.Element;
25
+ export {};
@@ -0,0 +1,39 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useTranslation } from "@byline/i18n/react";
4
+ import { Badge } from "@byline/ui/react";
5
+ import classnames from "classnames";
6
+ import tabs_module from "./tabs.module.js";
7
+ const AdminTabs = ({ tabs, activeTab, onChange, errorCounts, className })=>{
8
+ const { t } = useTranslation('byline-admin');
9
+ return /*#__PURE__*/ jsx("div", {
10
+ role: "tablist",
11
+ "aria-label": t('presentation.formTabsAriaLabel'),
12
+ className: classnames('byline-admin-tabs', tabs_module.tabs, className),
13
+ children: tabs.map((tab)=>{
14
+ const isActive = tab.name === activeTab;
15
+ return /*#__PURE__*/ jsx("button", {
16
+ type: "button",
17
+ role: "tab",
18
+ "aria-selected": isActive,
19
+ onClick: ()=>onChange(tab.name),
20
+ className: classnames('byline-admin-tab', tabs_module.tab, isActive && [
21
+ 'byline-admin-tab-active',
22
+ tabs_module["tab-active"]
23
+ ]),
24
+ children: /*#__PURE__*/ jsxs("span", {
25
+ className: classnames('byline-admin-tab-label', tabs_module.label),
26
+ children: [
27
+ tab.label,
28
+ (errorCounts?.[tab.name] ?? 0) > 0 && /*#__PURE__*/ jsx(Badge, {
29
+ intent: "danger",
30
+ className: classnames('byline-admin-tab-badge', tabs_module.badge),
31
+ children: errorCounts?.[tab.name]
32
+ })
33
+ ]
34
+ })
35
+ }, tab.name);
36
+ })
37
+ });
38
+ };
39
+ export { AdminTabs };
@@ -0,0 +1,10 @@
1
+ import "./tabs_module.css";
2
+ const tabs_module = {
3
+ tabs: "tabs-AUVgW2",
4
+ tab: "tab-Tn7xcQ",
5
+ "tab-active": "tab-active-cGf5N5",
6
+ tabActive: "tab-active-cGf5N5",
7
+ label: "label-PvJgbb",
8
+ badge: "badge-NJVOEv"
9
+ };
10
+ export default tabs_module;
@@ -0,0 +1,68 @@
1
+ :is(.tabs-AUVgW2, .byline-admin-tabs) {
2
+ gap: var(--spacing-16);
3
+ border-bottom: var(--border-width-thin) var(--border-style-solid) var(--gray-200);
4
+ display: flex;
5
+ }
6
+
7
+ :is(.tab-Tn7xcQ, .byline-admin-tab) {
8
+ color: var(--gray-500);
9
+ font-size: 1.1rem;
10
+ font-weight: var(--font-weight-medium);
11
+ cursor: pointer;
12
+ background: none;
13
+ border-bottom: 2px solid #0000;
14
+ outline: none;
15
+ margin-bottom: -1px;
16
+ padding: .625rem 0;
17
+ transition: color .15s, border-color .15s;
18
+ position: relative;
19
+ }
20
+
21
+ :is(.tab-Tn7xcQ:hover, .byline-admin-tab:hover) {
22
+ color: var(--gray-800);
23
+ border-bottom-color: var(--gray-300);
24
+ }
25
+
26
+ :is(.tab-Tn7xcQ:focus-visible, .byline-admin-tab:focus-visible) {
27
+ box-shadow: 0 0 0 2px var(--blue-500);
28
+ }
29
+
30
+ :is(.tab-active-cGf5N5, .byline-admin-tab-active), :is(.tab-active-cGf5N5:hover, .byline-admin-tab-active:hover) {
31
+ color: var(--primary-600);
32
+ border-bottom-color: var(--primary-400);
33
+ }
34
+
35
+ :is(.label-PvJgbb, .byline-admin-tab-label) {
36
+ align-items: center;
37
+ gap: .375rem;
38
+ display: flex;
39
+ }
40
+
41
+ :is(.badge-NJVOEv, .byline-admin-tab-badge) {
42
+ justify-content: center;
43
+ align-items: center;
44
+ min-width: 1.25rem;
45
+ height: 1.25rem;
46
+ padding: 0 .375rem;
47
+ font-size: .7rem;
48
+ display: flex;
49
+ }
50
+
51
+ :is(:is([data-theme="dark"], .dark) .tabs-AUVgW2, :is([data-theme="dark"], .dark) .byline-admin-tabs) {
52
+ border-bottom-color: var(--gray-700);
53
+ }
54
+
55
+ :is(:is([data-theme="dark"], .dark) .tab-Tn7xcQ, :is([data-theme="dark"], .dark) .byline-admin-tab) {
56
+ color: var(--gray-400);
57
+ }
58
+
59
+ :is(:is([data-theme="dark"], .dark) .tab-Tn7xcQ:hover, :is([data-theme="dark"], .dark) .byline-admin-tab:hover) {
60
+ color: var(--gray-200);
61
+ border-bottom-color: var(--gray-600);
62
+ }
63
+
64
+ :is(:is([data-theme="dark"], .dark) .tab-active-cGf5N5, :is([data-theme="dark"], .dark) .byline-admin-tab-active), :is(:is([data-theme="dark"], .dark) .tab-active-cGf5N5:hover, :is([data-theme="dark"], .dark) .byline-admin-tab-active:hover) {
65
+ color: var(--primary-200);
66
+ border-bottom-color: var(--primary-400);
67
+ }
68
+
@@ -0,0 +1,66 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ /**
9
+ * Single React barrel for `@byline/admin`. Hosts every client-side
10
+ * surface the admin shell needs to render the document editor —
11
+ * presentational layout primitives, field widgets, the form runtime,
12
+ * the editor-shared widgets (status badge, diff modal), and the
13
+ * field-side services Context. Generic drag-and-drop helpers
14
+ * (`DraggableSortable`, `useSortable`, `moveItem`) live in
15
+ * `@byline/ui/react` since they embed no CMS concepts.
16
+ *
17
+ * Why one barrel: per-area subpath exports break React Context
18
+ * identity under bundlers that pre-bundle subpaths individually
19
+ * (e.g. Vite's `optimizeDeps.include`) — a provider mounted on one
20
+ * Context identity and a hook reading another. A single specifier
21
+ * eliminates the trap structurally. Tree-shaking inside the ESM
22
+ * bundle still drops anything unused by the host.
23
+ *
24
+ * Sibling subpaths in this package — `@byline/admin/admin-users`,
25
+ * `@byline/admin/admin-roles/components/*`, `@byline/admin/auth`,
26
+ * etc. — host per-vertical components and server-side modules;
27
+ * those are intentionally separate so server-only imports don't pull
28
+ * React.
29
+ */
30
+ export * from './fields/array/array-field.js';
31
+ export * from './fields/blocks/blocks-field.js';
32
+ export * from './fields/checkbox/checkbox-field.js';
33
+ export * from './fields/column-formatter.js';
34
+ export * from './fields/date-time-formatter.js';
35
+ export * from './fields/datetime/datetime-field.js';
36
+ export * from './fields/draggable-context-menu.js';
37
+ export * from './fields/field-helpers.js';
38
+ export * from './fields/field-renderer.js';
39
+ export * from './fields/field-services-context.js';
40
+ export * from './fields/file/file-field.js';
41
+ export * from './fields/file/file-upload-field.js';
42
+ export * from './fields/group/group-field.js';
43
+ export * from './fields/image/image-field.js';
44
+ export * from './fields/image/image-upload-field.js';
45
+ export * from './fields/local-date-time.js';
46
+ export * from './fields/locale-badge.js';
47
+ export * from './fields/numerical/numerical-field.js';
48
+ export * from './fields/relation/relation-field.js';
49
+ export * from './fields/relation/relation-picker.js';
50
+ export * from './fields/select/select-field.js';
51
+ export * from './fields/sortable-item.js';
52
+ export * from './fields/text/text-field.js';
53
+ export * from './fields/text-area/text-area-field.js';
54
+ export * from './fields/use-field-change-handler.js';
55
+ export * from './forms/document-actions.js';
56
+ export * from './forms/form-context.js';
57
+ export * from './forms/form-renderer.js';
58
+ export * from './forms/navigation-guard.js';
59
+ export * from './forms/path-widget.js';
60
+ export * from './lib/translate-validation-error.js';
61
+ export * from './presentation/group.js';
62
+ export * from './presentation/row.js';
63
+ export * from './presentation/tabs.js';
64
+ export * from './widgets/diff-viewer/diff-modal.js';
65
+ export * from './widgets/status-badge/status-badge.js';
66
+ export type { BylineFieldServices, CollectionListDoc, CollectionListParams, CollectionListResponse, GetCollectionDocumentsFn, UploadedFileResult, UploadFieldFn, } from './fields/field-services-types.js';
package/dist/react.js ADDED
@@ -0,0 +1,36 @@
1
+ export * from "./fields/array/array-field.js";
2
+ export * from "./fields/blocks/blocks-field.js";
3
+ export * from "./fields/checkbox/checkbox-field.js";
4
+ export * from "./fields/column-formatter.js";
5
+ export * from "./fields/date-time-formatter.js";
6
+ export * from "./fields/datetime/datetime-field.js";
7
+ export * from "./fields/draggable-context-menu.js";
8
+ export * from "./fields/field-helpers.js";
9
+ export * from "./fields/field-renderer.js";
10
+ export * from "./fields/field-services-context.js";
11
+ export * from "./fields/file/file-field.js";
12
+ export * from "./fields/file/file-upload-field.js";
13
+ export * from "./fields/group/group-field.js";
14
+ export * from "./fields/image/image-field.js";
15
+ export * from "./fields/image/image-upload-field.js";
16
+ export * from "./fields/local-date-time.js";
17
+ export * from "./fields/locale-badge.js";
18
+ export * from "./fields/numerical/numerical-field.js";
19
+ export * from "./fields/relation/relation-field.js";
20
+ export * from "./fields/relation/relation-picker.js";
21
+ export * from "./fields/select/select-field.js";
22
+ export * from "./fields/sortable-item.js";
23
+ export * from "./fields/text/text-field.js";
24
+ export * from "./fields/text-area/text-area-field.js";
25
+ export * from "./fields/use-field-change-handler.js";
26
+ export * from "./forms/document-actions.js";
27
+ export * from "./forms/form-context.js";
28
+ export * from "./forms/form-renderer.js";
29
+ export * from "./forms/navigation-guard.js";
30
+ export * from "./forms/path-widget.js";
31
+ export * from "./lib/translate-validation-error.js";
32
+ export * from "./presentation/group.js";
33
+ export * from "./presentation/row.js";
34
+ export * from "./presentation/tabs.js";
35
+ export * from "./widgets/diff-viewer/diff-modal.js";
36
+ export * from "./widgets/status-badge/status-badge.js";
@@ -50,6 +50,21 @@ export type SignInResult = unknown;
50
50
  export type UpdateAccountInput = UpdateAccountRequest;
51
51
  /** Same shape as `ChangeAccountPasswordRequest` from `@byline/admin/admin-account`. */
52
52
  export type ChangeAccountPasswordInput = ChangeAccountPasswordRequest;
53
+ export interface SetInterfaceLocaleInput {
54
+ /** BCP 47 tag, or `null` to clear the preference and re-engage detection. */
55
+ locale: string | null;
56
+ }
57
+ /**
58
+ * Return shape for the locale-switcher service. `account` is populated
59
+ * when the request resolved an authenticated admin actor (the form on
60
+ * the account page); `null` on pre-auth surfaces (the sign-in page
61
+ * locale dropdown) where the cookie write is the only effect.
62
+ */
63
+ export interface SetInterfaceLocaleResult {
64
+ ok: true;
65
+ locale: string | null;
66
+ account: AccountResponse | null;
67
+ }
53
68
  export interface CreateAdminUserInput {
54
69
  email: string;
55
70
  password: string;
@@ -106,6 +121,7 @@ export interface BylineAdminServices {
106
121
  adminSignIn: AdminServiceCall<SignInInput, SignInResult>;
107
122
  updateAccount: AdminServiceCall<UpdateAccountInput, AccountResponse>;
108
123
  changeAccountPassword: AdminServiceCall<ChangeAccountPasswordInput, AccountResponse>;
124
+ setInterfaceLocale: AdminServiceCall<SetInterfaceLocaleInput, SetInterfaceLocaleResult>;
109
125
  createAdminUser: AdminServiceCall<CreateAdminUserInput, AdminUserResponse>;
110
126
  updateAdminUser: AdminServiceCall<UpdateAdminUserInput, AdminUserResponse>;
111
127
  setAdminUserPassword: AdminServiceCall<SetAdminUserPasswordInput, AdminUserResponse>;
@@ -0,0 +1,22 @@
1
+ export interface DiffModalProps {
2
+ isOpen: boolean;
3
+ onDismiss: () => void;
4
+ collection: string;
5
+ documentId: string;
6
+ /** The `versionId` of the historical version to compare. */
7
+ versionId: string;
8
+ /** A human-readable label for the historical version (e.g. a date string). */
9
+ versionLabel: string;
10
+ /** The already-loaded current (latest) version of the document. */
11
+ currentDocument: Record<string, unknown>;
12
+ /** Content locale to compare — undefined / 'all' shows all locales. */
13
+ locale?: string;
14
+ /**
15
+ * Host-provided loader for a historical document version. The diff
16
+ * modal is framework-neutral; callers wire this to whatever transport
17
+ * they use (e.g. `BylineAdminServices.getCollectionDocumentVersion` in
18
+ * the admin shell).
19
+ */
20
+ loadHistoricalVersion: (collection: string, documentId: string, versionId: string, locale: string | undefined) => Promise<Record<string, unknown>>;
21
+ }
22
+ export declare function DiffModal({ isOpen, onDismiss, collection, documentId, versionId, versionLabel, currentDocument, locale, loadHistoricalVersion, }: DiffModalProps): import("react").JSX.Element;
@@ -0,0 +1,149 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
4
+ import { useTranslation } from "@byline/i18n/react";
5
+ import { CloseIcon, IconButton, LoaderRing, Modal } from "@byline/ui/react";
6
+ import classnames from "classnames";
7
+ import react_diff_viewer_continued, { DiffMethod } from "react-diff-viewer-continued";
8
+ import diff_modal_module from "./diff-modal.module.js";
9
+ const STRIP_KEYS = new Set([
10
+ 'id',
11
+ 'versionId',
12
+ 'path',
13
+ 'status',
14
+ 'createdAt',
15
+ 'updatedAt',
16
+ 'hasPublishedVersion',
17
+ '_publishedVersion'
18
+ ]);
19
+ function stripMeta(doc) {
20
+ if (doc.fields && 'object' == typeof doc.fields) return doc.fields;
21
+ return Object.fromEntries(Object.entries(doc).filter(([k])=>!STRIP_KEYS.has(k)));
22
+ }
23
+ function DiffModal({ isOpen, onDismiss, collection, documentId, versionId, versionLabel, currentDocument, locale, loadHistoricalVersion }) {
24
+ const { t } = useTranslation('byline-admin');
25
+ const [historicalDoc, setHistoricalDoc] = useState(null);
26
+ const [loading, setLoading] = useState(false);
27
+ const [error, setError] = useState(null);
28
+ useEffect(()=>{
29
+ if (!isOpen || !versionId) return;
30
+ let cancelled = false;
31
+ setLoading(true);
32
+ setError(null);
33
+ setHistoricalDoc(null);
34
+ loadHistoricalVersion(collection, documentId, versionId, locale).then((doc)=>{
35
+ if (cancelled) return;
36
+ setHistoricalDoc(doc);
37
+ }).catch((err)=>{
38
+ if (cancelled) return;
39
+ setError(err instanceof Error ? err.message : t('diffModal.loadFailed'));
40
+ }).finally(()=>{
41
+ if (!cancelled) setLoading(false);
42
+ });
43
+ return ()=>{
44
+ cancelled = true;
45
+ };
46
+ }, [
47
+ isOpen,
48
+ collection,
49
+ documentId,
50
+ versionId,
51
+ locale,
52
+ loadHistoricalVersion,
53
+ t
54
+ ]);
55
+ const currentStr = currentDocument ? JSON.stringify(stripMeta(currentDocument), null, 2) : '';
56
+ const historicalStr = historicalDoc ? JSON.stringify(stripMeta(historicalDoc), null, 2) : '';
57
+ return /*#__PURE__*/ jsx(Modal, {
58
+ isOpen: isOpen,
59
+ closeOnOverlayClick: true,
60
+ onDismiss: onDismiss,
61
+ children: /*#__PURE__*/ jsxs(Modal.Container, {
62
+ style: {
63
+ width: '96vw',
64
+ maxWidth: '96vw',
65
+ height: '90vh',
66
+ maxHeight: '90vh',
67
+ display: 'flex',
68
+ flexDirection: 'column',
69
+ overflow: 'hidden'
70
+ },
71
+ children: [
72
+ /*#__PURE__*/ jsxs(Modal.Header, {
73
+ className: classnames('byline-diff-modal-header', diff_modal_module.header),
74
+ children: [
75
+ /*#__PURE__*/ jsxs("div", {
76
+ className: classnames('byline-diff-modal-title-stack', diff_modal_module["title-stack"]),
77
+ children: [
78
+ /*#__PURE__*/ jsx("h3", {
79
+ className: classnames('byline-diff-modal-title', diff_modal_module.title),
80
+ children: t('diffModal.title')
81
+ }),
82
+ /*#__PURE__*/ jsxs("p", {
83
+ className: classnames('byline-diff-modal-subtitle', diff_modal_module.subtitle),
84
+ children: [
85
+ t('diffModal.subtitleBefore'),
86
+ ' ',
87
+ /*#__PURE__*/ jsx("span", {
88
+ className: classnames('byline-diff-modal-version', diff_modal_module.version),
89
+ children: versionLabel
90
+ }),
91
+ ' ',
92
+ t('diffModal.subtitleAfter')
93
+ ]
94
+ })
95
+ ]
96
+ }),
97
+ /*#__PURE__*/ jsx(IconButton, {
98
+ onClick: onDismiss,
99
+ size: "xs",
100
+ "aria-label": t('diffModal.closeAriaLabel'),
101
+ children: /*#__PURE__*/ jsx(CloseIcon, {
102
+ width: "15px",
103
+ height: "15px"
104
+ })
105
+ })
106
+ ]
107
+ }),
108
+ /*#__PURE__*/ jsxs(Modal.Content, {
109
+ className: classnames('byline-diff-modal-content', diff_modal_module.content),
110
+ style: {
111
+ minHeight: 0
112
+ },
113
+ children: [
114
+ loading && /*#__PURE__*/ jsxs("div", {
115
+ className: classnames('byline-diff-modal-state', diff_modal_module.state),
116
+ children: [
117
+ /*#__PURE__*/ jsx(LoaderRing, {
118
+ size: 28,
119
+ color: "#666666"
120
+ }),
121
+ /*#__PURE__*/ jsx("span", {
122
+ children: t('diffModal.loading')
123
+ })
124
+ ]
125
+ }),
126
+ error && /*#__PURE__*/ jsx("div", {
127
+ className: classnames('byline-diff-modal-state', 'byline-diff-modal-error', diff_modal_module.state, diff_modal_module.error),
128
+ children: error
129
+ }),
130
+ !loading && !error && historicalDoc && /*#__PURE__*/ jsx("div", {
131
+ className: classnames('byline-diff-modal-viewer', diff_modal_module.viewer),
132
+ children: /*#__PURE__*/ jsx(react_diff_viewer_continued, {
133
+ oldValue: historicalStr,
134
+ newValue: currentStr,
135
+ splitView: true,
136
+ compareMethod: DiffMethod.LINES,
137
+ useDarkTheme: true,
138
+ leftTitle: versionLabel,
139
+ rightTitle: t('diffModal.currentVersion'),
140
+ hideLineNumbers: false
141
+ })
142
+ })
143
+ ]
144
+ })
145
+ ]
146
+ })
147
+ });
148
+ }
149
+ export { DiffModal };
@@ -0,0 +1,14 @@
1
+ import "./diff-modal_module.css";
2
+ const diff_modal_module = {
3
+ header: "header-da1tQG",
4
+ "title-stack": "title-stack-mSxmPG",
5
+ titleStack: "title-stack-mSxmPG",
6
+ title: "title-xO708s",
7
+ subtitle: "subtitle-VnkAjp",
8
+ version: "version-sRziHD",
9
+ content: "content-_KyVkg",
10
+ state: "state-Gg9w8j",
11
+ error: "error-BP4kEV",
12
+ viewer: "viewer-hxDZsJ"
13
+ };
14
+ export default diff_modal_module;
@@ -0,0 +1,56 @@
1
+ :is(.header-da1tQG, .byline-diff-modal-header) {
2
+ padding-top: var(--spacing-16);
3
+ margin-bottom: var(--spacing-8);
4
+ flex-shrink: 0;
5
+ }
6
+
7
+ :is(.title-stack-mSxmPG, .byline-diff-modal-title-stack) {
8
+ flex-direction: column;
9
+ display: flex;
10
+ }
11
+
12
+ :is(.title-xO708s, .byline-diff-modal-title) {
13
+ font-size: var(--font-size-xl);
14
+ margin: 0;
15
+ }
16
+
17
+ :is(.subtitle-VnkAjp, .byline-diff-modal-subtitle) {
18
+ font-size: var(--font-size-sm);
19
+ color: var(--gray-400);
20
+ margin: 0;
21
+ }
22
+
23
+ :is(.version-sRziHD, .byline-diff-modal-version) {
24
+ font-family: var(--font-family-mono);
25
+ font-size: var(--font-size-xs);
26
+ background-color: var(--canvas-700);
27
+ padding: 0 var(--spacing-4);
28
+ border-radius: var(--border-radius-sm);
29
+ }
30
+
31
+ :is(.content-_KyVkg, .byline-diff-modal-content) {
32
+ flex: 1 1 0;
33
+ min-height: 0;
34
+ padding: 0;
35
+ overflow: auto;
36
+ }
37
+
38
+ :is(.state-Gg9w8j, .byline-diff-modal-state) {
39
+ justify-content: center;
40
+ align-items: center;
41
+ gap: var(--spacing-12);
42
+ height: 100%;
43
+ color: var(--gray-400);
44
+ display: flex;
45
+ }
46
+
47
+ :is(.error-BP4kEV, .byline-diff-modal-error) {
48
+ color: var(--red-400);
49
+ gap: 0;
50
+ }
51
+
52
+ :is(.viewer-hxDZsJ, .byline-diff-modal-viewer) {
53
+ font-family: var(--font-family-mono);
54
+ font-size: var(--font-size-sm);
55
+ }
56
+
@@ -0,0 +1,25 @@
1
+ /**
2
+ * This Source Code is subject to the terms of the Mozilla Public
3
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
4
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
+ *
6
+ * Copyright (c) Infonomic Company Limited
7
+ */
8
+ import type { WorkflowStatus } from '@byline/core';
9
+ /**
10
+ * Compact badge for workflow status values. Maps the three built-in
11
+ * statuses (draft, published, archived) to semantic intents and falls
12
+ * back to `noeffect` for any custom workflow statuses.
13
+ *
14
+ * When `hasPublishedVersion` is true and the current status is not
15
+ * `published`, a small green dot is rendered before the badge to
16
+ * indicate that a published version is live.
17
+ *
18
+ * Stable override handles: `.byline-status-badge-wrap`,
19
+ * `.byline-status-badge-dot`, `.byline-status-badge`.
20
+ */
21
+ export declare const StatusBadge: ({ status, workflowStatuses, hasPublishedVersion, }: {
22
+ status: string;
23
+ workflowStatuses: WorkflowStatus[];
24
+ hasPublishedVersion?: boolean;
25
+ }) => import("react").JSX.Element;
@@ -0,0 +1,37 @@
1
+ import { jsx, jsxs } from "react/jsx-runtime";
2
+ import { WORKFLOW_STATUS_ARCHIVED, WORKFLOW_STATUS_DRAFT, WORKFLOW_STATUS_PUBLISHED } from "@byline/core";
3
+ import { useTranslation } from "@byline/i18n/react";
4
+ import { Badge } from "@byline/ui/react";
5
+ import classnames from "classnames";
6
+ import status_badge_module from "./status-badge.module.js";
7
+ function statusIntent(status) {
8
+ switch(status){
9
+ case WORKFLOW_STATUS_PUBLISHED:
10
+ return 'success';
11
+ case WORKFLOW_STATUS_DRAFT:
12
+ return 'warning';
13
+ case WORKFLOW_STATUS_ARCHIVED:
14
+ return 'info';
15
+ default:
16
+ return 'noeffect';
17
+ }
18
+ }
19
+ const StatusBadge = ({ status, workflowStatuses, hasPublishedVersion })=>{
20
+ const { t } = useTranslation('byline-admin');
21
+ const label = workflowStatuses.find((s)=>s.name === status)?.label ?? String(status ?? '');
22
+ return /*#__PURE__*/ jsxs("span", {
23
+ className: classnames('byline-status-badge-wrap', status_badge_module.wrap),
24
+ children: [
25
+ true === hasPublishedVersion && 'published' !== status && /*#__PURE__*/ jsx("span", {
26
+ title: t('statusBadge.publishedVersionLive'),
27
+ className: classnames('byline-status-badge-dot', status_badge_module.dot)
28
+ }),
29
+ /*#__PURE__*/ jsx(Badge, {
30
+ intent: statusIntent(status),
31
+ className: classnames('byline-status-badge', status_badge_module.badge),
32
+ children: label
33
+ })
34
+ ]
35
+ });
36
+ };
37
+ export { StatusBadge };
@@ -0,0 +1,7 @@
1
+ import "./status-badge_module.css";
2
+ const status_badge_module = {
3
+ wrap: "wrap-ZbeRnh",
4
+ dot: "dot-VmpmJH",
5
+ badge: "badge-zXEFyw"
6
+ };
7
+ export default status_badge_module;
@@ -0,0 +1,20 @@
1
+ :is(.wrap-ZbeRnh, .byline-status-badge-wrap) {
2
+ align-items: center;
3
+ gap: var(--spacing-4);
4
+ display: inline-flex;
5
+ }
6
+
7
+ :is(.dot-VmpmJH, .byline-status-badge-dot) {
8
+ border-radius: var(--border-radius-full);
9
+ background-color: var(--green-500);
10
+ width: .5rem;
11
+ height: .5rem;
12
+ display: inline-block;
13
+ }
14
+
15
+ :is(.badge-zXEFyw, .byline-status-badge) {
16
+ padding: 0 .375rem;
17
+ font-size: .65rem;
18
+ line-height: 1.5;
19
+ }
20
+