@byline/host-tanstack-start 4.16.0 → 4.17.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 (146) hide show
  1. package/dist/admin-shell/chrome/admin-menu-drawer.js +14 -14
  2. package/dist/admin-shell/chrome/dashboard.js +41 -5
  3. package/dist/admin-shell/chrome/dashboard.test.d.ts +8 -0
  4. package/dist/admin-shell/collections/api.d.ts +2 -2
  5. package/dist/admin-shell/collections/create.d.ts +2 -2
  6. package/dist/admin-shell/collections/create.js +1 -0
  7. package/dist/admin-shell/collections/edit.d.ts +2 -2
  8. package/dist/admin-shell/collections/edit.js +1 -0
  9. package/dist/admin-shell/collections/history.d.ts +4 -12
  10. package/dist/admin-shell/collections/history.js +112 -303
  11. package/dist/admin-shell/collections/reindex-button.d.ts +1 -1
  12. package/dist/admin-shell/collections/reindex-button.js +5 -1
  13. package/dist/admin-shell/collections/restore-version-modal.d.ts +4 -4
  14. package/dist/admin-shell/collections/restore-version-modal.js +8 -24
  15. package/dist/admin-shell/collections/version-history.d.ts +72 -0
  16. package/dist/admin-shell/collections/version-history.js +259 -0
  17. package/dist/admin-shell/singletons/history.d.ts +19 -0
  18. package/dist/admin-shell/singletons/history.js +170 -0
  19. package/dist/admin-shell/singletons/history.test.d.ts +8 -0
  20. package/dist/admin-shell/singletons/preview-link.d.ts +12 -0
  21. package/dist/admin-shell/singletons/preview-link.js +54 -0
  22. package/dist/admin-shell/singletons/view-menu.d.ts +13 -0
  23. package/dist/admin-shell/singletons/view-menu.js +116 -0
  24. package/dist/admin-shell/singletons/view.d.ts +18 -0
  25. package/dist/admin-shell/singletons/view.js +259 -0
  26. package/dist/admin-shell/singletons/view.test.d.ts +8 -0
  27. package/dist/integrations/api-utils.d.ts +18 -4
  28. package/dist/integrations/api-utils.js +10 -3
  29. package/dist/routes/create-admin-dashboard-route.js +2 -2
  30. package/dist/routes/create-collection-api-route.js +3 -3
  31. package/dist/routes/create-collection-create-route.js +4 -3
  32. package/dist/routes/create-collection-edit-route.js +4 -3
  33. package/dist/routes/create-collection-history-route.js +4 -3
  34. package/dist/routes/create-collection-list-route.js +4 -3
  35. package/dist/routes/create-singleton-history-route.d.ts +8 -0
  36. package/dist/routes/create-singleton-history-route.js +99 -0
  37. package/dist/routes/create-singleton-route.d.ts +35 -0
  38. package/dist/routes/create-singleton-route.js +130 -0
  39. package/dist/routes/get-multi-collection-definition.d.ts +10 -0
  40. package/dist/routes/get-multi-collection-definition.js +6 -0
  41. package/dist/routes/get-singleton-definition.d.ts +10 -0
  42. package/dist/routes/get-singleton-definition.js +6 -0
  43. package/dist/routes/index.d.ts +2 -0
  44. package/dist/routes/index.js +2 -0
  45. package/dist/server-fns/actors.d.ts +16 -0
  46. package/dist/server-fns/actors.js +25 -0
  47. package/dist/server-fns/admin-document-presentation.d.ts +30 -0
  48. package/dist/server-fns/admin-document-presentation.js +32 -0
  49. package/dist/server-fns/collections/actors.d.ts +1 -10
  50. package/dist/server-fns/collections/actors.js +1 -25
  51. package/dist/server-fns/collections/get.js +9 -26
  52. package/dist/server-fns/collections/reorder.js +1 -1
  53. package/dist/server-fns/collections/scheduled-publication.js +2 -2
  54. package/dist/server-fns/collections/upload.js +3 -3
  55. package/dist/server-fns/collections/utils.d.ts +1 -7
  56. package/dist/server-fns/collections/utils.js +1 -4
  57. package/dist/server-fns/serialise.d.ts +14 -0
  58. package/dist/server-fns/serialise.js +4 -0
  59. package/dist/server-fns/singleton-document-read.d.ts +20 -0
  60. package/dist/server-fns/singleton-document-read.js +10 -0
  61. package/dist/server-fns/singletons/cancel-scheduled-publish.d.ts +12 -0
  62. package/dist/server-fns/singletons/cancel-scheduled-publish.js +7 -0
  63. package/dist/server-fns/singletons/change-status.d.ts +14 -0
  64. package/dist/server-fns/singletons/change-status.js +7 -0
  65. package/dist/server-fns/singletons/confirm-scheduled-publish.d.ts +14 -0
  66. package/dist/server-fns/singletons/confirm-scheduled-publish.js +9 -0
  67. package/dist/server-fns/singletons/copy-to-locale.d.ts +18 -0
  68. package/dist/server-fns/singletons/copy-to-locale.js +11 -0
  69. package/dist/server-fns/singletons/find-by-version.d.ts +16 -0
  70. package/dist/server-fns/singletons/find-by-version.js +9 -0
  71. package/dist/server-fns/singletons/get-scheduled-publish.d.ts +12 -0
  72. package/dist/server-fns/singletons/get-scheduled-publish.js +7 -0
  73. package/dist/server-fns/singletons/get.d.ts +24 -0
  74. package/dist/server-fns/singletons/get.js +6 -0
  75. package/dist/server-fns/singletons/history.d.ts +31 -0
  76. package/dist/server-fns/singletons/history.js +22 -0
  77. package/dist/server-fns/singletons/index.d.ts +19 -0
  78. package/dist/server-fns/singletons/index.js +12 -0
  79. package/dist/server-fns/singletons/restore-version.d.ts +14 -0
  80. package/dist/server-fns/singletons/restore-version.js +7 -0
  81. package/dist/server-fns/singletons/schedule-publish.d.ts +16 -0
  82. package/dist/server-fns/singletons/schedule-publish.js +10 -0
  83. package/dist/server-fns/singletons/unpublish.d.ts +12 -0
  84. package/dist/server-fns/singletons/unpublish.js +7 -0
  85. package/dist/server-fns/singletons/update.d.ts +14 -0
  86. package/dist/server-fns/singletons/update.js +14 -0
  87. package/dist/vitest-jsdom.test.d.ts +8 -0
  88. package/package.json +24 -18
  89. package/src/admin-shell/chrome/admin-menu-drawer.tsx +13 -13
  90. package/src/admin-shell/chrome/dashboard.test.tsx +199 -0
  91. package/src/admin-shell/chrome/dashboard.tsx +43 -9
  92. package/src/admin-shell/collections/api.tsx +2 -2
  93. package/src/admin-shell/collections/create.tsx +6 -2
  94. package/src/admin-shell/collections/edit.tsx +6 -2
  95. package/src/admin-shell/collections/history.module.css +1 -1
  96. package/src/admin-shell/collections/history.tsx +162 -442
  97. package/src/admin-shell/collections/reindex-button.tsx +4 -2
  98. package/src/admin-shell/collections/restore-version-modal.tsx +19 -25
  99. package/src/admin-shell/collections/version-history.tsx +349 -0
  100. package/src/admin-shell/singletons/history.test.tsx +407 -0
  101. package/src/admin-shell/singletons/history.tsx +185 -0
  102. package/src/admin-shell/singletons/preview-link.tsx +75 -0
  103. package/src/admin-shell/singletons/view-menu.tsx +136 -0
  104. package/src/admin-shell/singletons/view.test.tsx +400 -0
  105. package/src/admin-shell/singletons/view.tsx +351 -0
  106. package/src/integrations/api-utils.ts +34 -9
  107. package/src/routes/create-admin-dashboard-route.test.node.ts +70 -0
  108. package/src/routes/create-admin-dashboard-route.tsx +10 -2
  109. package/src/routes/create-collection-api-route.tsx +4 -4
  110. package/src/routes/create-collection-create-route.tsx +5 -8
  111. package/src/routes/create-collection-edit-route.tsx +5 -4
  112. package/src/routes/create-collection-history-route.tsx +5 -8
  113. package/src/routes/create-collection-list-route.tsx +5 -8
  114. package/src/routes/create-singleton-history-route.test.node.ts +148 -0
  115. package/src/routes/create-singleton-history-route.tsx +116 -0
  116. package/src/routes/create-singleton-route.test.node.ts +172 -0
  117. package/src/routes/create-singleton-route.tsx +176 -0
  118. package/src/routes/get-multi-collection-definition.ts +16 -0
  119. package/src/routes/get-singleton-definition.ts +16 -0
  120. package/src/routes/index.ts +2 -0
  121. package/src/server-fns/actors.ts +43 -0
  122. package/src/server-fns/admin-document-presentation.ts +78 -0
  123. package/src/server-fns/collections/actors.ts +1 -52
  124. package/src/server-fns/collections/get.ts +10 -49
  125. package/src/server-fns/collections/reorder.ts +1 -1
  126. package/src/server-fns/collections/scheduled-publication.ts +7 -1
  127. package/src/server-fns/collections/upload-singleton.test.node.ts +164 -0
  128. package/src/server-fns/collections/upload.ts +7 -3
  129. package/src/server-fns/collections/utils.ts +1 -9
  130. package/src/server-fns/serialise.ts +17 -0
  131. package/src/server-fns/singleton-document-read.ts +32 -0
  132. package/src/server-fns/singletons/cancel-scheduled-publish.ts +19 -0
  133. package/src/server-fns/singletons/change-status.ts +19 -0
  134. package/src/server-fns/singletons/confirm-scheduled-publish.ts +23 -0
  135. package/src/server-fns/singletons/copy-to-locale.ts +32 -0
  136. package/src/server-fns/singletons/find-by-version.ts +23 -0
  137. package/src/server-fns/singletons/get-scheduled-publish.ts +19 -0
  138. package/src/server-fns/singletons/get.ts +32 -0
  139. package/src/server-fns/singletons/history.ts +41 -0
  140. package/src/server-fns/singletons/index.ts +20 -0
  141. package/src/server-fns/singletons/restore-version.ts +19 -0
  142. package/src/server-fns/singletons/schedule-publish.ts +24 -0
  143. package/src/server-fns/singletons/singletons.test.node.ts +298 -0
  144. package/src/server-fns/singletons/unpublish.ts +19 -0
  145. package/src/server-fns/singletons/update.ts +31 -0
  146. package/src/vitest-jsdom.test.tsx +27 -0
@@ -0,0 +1,72 @@
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 ReactNode } from 'react';
9
+ import { type CollectionDefinition } from '@byline/core';
10
+ interface VersionHistoryDocument extends Record<string, unknown> {
11
+ id: string;
12
+ versionId?: string;
13
+ status: string;
14
+ createdAt: string;
15
+ createdBy?: string;
16
+ eventType?: string;
17
+ fields?: Record<string, unknown>;
18
+ }
19
+ export interface VersionHistoryData {
20
+ docs: VersionHistoryDocument[];
21
+ meta: {
22
+ total: number;
23
+ page: number;
24
+ pageSize: number;
25
+ totalPages: number;
26
+ order?: string;
27
+ desc?: boolean;
28
+ };
29
+ /** Admin-resolved acting-user labels keyed by the raw version actor id. */
30
+ actors?: Record<string, {
31
+ label: string;
32
+ }>;
33
+ }
34
+ interface VersionHistoryRowContext {
35
+ document: VersionHistoryDocument;
36
+ versionId: string | undefined;
37
+ versionNumber: number;
38
+ currentVersionId: string | null;
39
+ actorLabel: string;
40
+ actionLabel: string;
41
+ restoreStatusLabel: string;
42
+ openCompare: () => void;
43
+ openRestore: () => void;
44
+ }
45
+ /**
46
+ * Resource-specific table columns. Collection history projects configured
47
+ * columns; singleton history supplies its fixed status/time/actor/restore
48
+ * presentation so restore never depends on a `useAsTitle` field.
49
+ */
50
+ export interface VersionHistoryRowPresentation {
51
+ headers: ReactNode;
52
+ auditColSpan: number;
53
+ renderCells: (context: VersionHistoryRowContext) => ReactNode;
54
+ }
55
+ export type HistoricalVersionLoader = (resourcePath: string, documentId: string, versionId: string, locale: string | undefined) => Promise<Record<string, unknown>>;
56
+ export declare function HistoryStats({ total }: {
57
+ total: number;
58
+ }): import("react").JSX.Element;
59
+ export declare function VersionHistoryCore({ data, resourceDefinition, resourcePath, documentId, currentDocument, locale, rowPresentation, loadHistoricalVersion, onPageSizeChange, restoreVersion, onRestoreComplete, }: {
60
+ data: VersionHistoryData;
61
+ resourceDefinition: CollectionDefinition;
62
+ resourcePath: string;
63
+ documentId: string;
64
+ currentDocument?: Record<string, unknown> | null;
65
+ locale?: string;
66
+ rowPresentation: VersionHistoryRowPresentation;
67
+ loadHistoricalVersion: HistoricalVersionLoader;
68
+ onPageSizeChange: (pageSize: number) => void;
69
+ restoreVersion: (versionId: string) => Promise<unknown>;
70
+ onRestoreComplete: () => void | Promise<void>;
71
+ }): import("react").JSX.Element;
72
+ export {};
@@ -0,0 +1,259 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { Fragment as external_react_Fragment, Suspense, lazy, useState } from "react";
3
+ import { getDefaultStatus, getWorkflowStatuses } from "@byline/core";
4
+ import { useTranslation } from "@byline/i18n/react";
5
+ import { CloseIcon, IconButton, Modal, Select, Table } from "@byline/ui/react";
6
+ import clsx from "clsx";
7
+ import { RouterPager } from "../chrome/router-pager.js";
8
+ import { formatNumber } from "../chrome/utils.js";
9
+ import history_module from "./history.module.js";
10
+ import { RestoreVersionModal } from "./restore-version-modal.js";
11
+ const DiffModal = /*#__PURE__*/ lazy(()=>import("@byline/admin/react").then((m)=>({
12
+ default: m.DiffModal
13
+ })));
14
+ const AUDIT_ACTION_KEYS = {
15
+ create: 'collections.history.audit.actionCreate',
16
+ update: 'collections.history.audit.actionUpdate',
17
+ restore: 'collections.history.audit.actionRestore',
18
+ copy_to_locale: 'collections.history.audit.actionCopyToLocale',
19
+ delete_locale: 'collections.history.audit.actionDeleteLocale'
20
+ };
21
+ function HistoryStats({ total }) {
22
+ return /*#__PURE__*/ jsx("span", {
23
+ className: clsx('byline-coll-history-stats', history_module.stats),
24
+ children: formatNumber(total, 0)
25
+ });
26
+ }
27
+ function padRows(value) {
28
+ return Array.from({
29
+ length: Math.max(0, value)
30
+ }).map((_, index)=>/*#__PURE__*/ jsx("div", {
31
+ className: clsx('byline-coll-history-pad-row', history_module.padRow),
32
+ children: "\xa0"
33
+ }, `empty-row-${index}`));
34
+ }
35
+ function VersionHistoryCore({ data, resourceDefinition, resourcePath, documentId, currentDocument, locale, rowPresentation, loadHistoricalVersion, onPageSizeChange, restoreVersion, onRestoreComplete }) {
36
+ const { t } = useTranslation('byline-admin');
37
+ const [selectedVersion, setSelectedVersion] = useState(null);
38
+ const [restoreTarget, setRestoreTarget] = useState(null);
39
+ const currentVersionId = currentDocument && 'string' == typeof currentDocument.versionId ? currentDocument.versionId : null;
40
+ const restoreStatus = getDefaultStatus(resourceDefinition);
41
+ const restoreStatusLabel = getWorkflowStatuses(resourceDefinition).find((status)=>status.name === restoreStatus)?.label ?? restoreStatus;
42
+ return /*#__PURE__*/ jsxs(Fragment, {
43
+ children: [
44
+ /*#__PURE__*/ jsx("div", {
45
+ className: clsx('byline-coll-history-options', history_module.options),
46
+ children: /*#__PURE__*/ jsx(RouterPager, {
47
+ page: data.meta.page,
48
+ count: data.meta.totalPages,
49
+ showFirstButton: true,
50
+ showLastButton: true,
51
+ componentName: "pagerTop",
52
+ "aria-label": t('collections.list.pagerTopAriaLabel')
53
+ })
54
+ }),
55
+ /*#__PURE__*/ jsxs(Table.Container, {
56
+ className: clsx('byline-coll-history-table-wrap', history_module.tableWrap),
57
+ children: [
58
+ /*#__PURE__*/ jsxs(Table, {
59
+ children: [
60
+ /*#__PURE__*/ jsx(Table.Header, {
61
+ children: /*#__PURE__*/ jsxs(Table.Row, {
62
+ children: [
63
+ /*#__PURE__*/ jsx("th", {
64
+ scope: "col",
65
+ className: clsx('byline-coll-history-col-version', history_module.colVersion)
66
+ }),
67
+ rowPresentation.headers
68
+ ]
69
+ })
70
+ }),
71
+ /*#__PURE__*/ jsx(Table.Body, {
72
+ children: data.docs.map((document, rowIndex)=>{
73
+ const versionId = document.versionId;
74
+ const { total, page, pageSize, desc } = data.meta;
75
+ const versionNumber = desc ? total - (page - 1) * pageSize - rowIndex : (page - 1) * pageSize + rowIndex + 1;
76
+ const actorLabel = document.createdBy ? data.actors?.[document.createdBy]?.label ?? t('collections.history.audit.formerUser') : t('collections.history.audit.unknown');
77
+ const actionKey = document.eventType ? AUDIT_ACTION_KEYS[document.eventType] : void 0;
78
+ const actionLabel = actionKey ? t(actionKey) : document.eventType ?? '';
79
+ const versionLabel = new Date(document.createdAt).toLocaleString();
80
+ const openCompare = ()=>{
81
+ if (null == versionId) return;
82
+ setSelectedVersion({
83
+ versionId,
84
+ label: versionLabel
85
+ });
86
+ };
87
+ const openRestore = ()=>{
88
+ if (null == versionId || versionId === currentVersionId) return;
89
+ setRestoreTarget({
90
+ versionId,
91
+ label: versionLabel,
92
+ versionNumber
93
+ });
94
+ };
95
+ return /*#__PURE__*/ jsxs(external_react_Fragment, {
96
+ children: [
97
+ /*#__PURE__*/ jsxs(Table.Row, {
98
+ className: clsx('byline-coll-history-row', history_module.historyRow),
99
+ children: [
100
+ /*#__PURE__*/ jsx(Table.Cell, {
101
+ className: clsx('byline-coll-history-version-cell', history_module.versionCell),
102
+ children: versionId && currentDocument ? /*#__PURE__*/ jsx(IconButton, {
103
+ size: "xs",
104
+ variant: "outlined",
105
+ intent: "noeffect",
106
+ "aria-label": t('collections.history.compareAriaLabel'),
107
+ title: t('collections.history.compareTitle'),
108
+ className: clsx('byline-coll-history-version-button', history_module.versionButton),
109
+ onClick: openCompare,
110
+ children: versionNumber
111
+ }) : null
112
+ }),
113
+ rowPresentation.renderCells({
114
+ document,
115
+ versionId,
116
+ versionNumber,
117
+ currentVersionId,
118
+ actorLabel,
119
+ actionLabel,
120
+ restoreStatusLabel,
121
+ openCompare,
122
+ openRestore
123
+ })
124
+ ]
125
+ }),
126
+ /*#__PURE__*/ jsxs(Table.Row, {
127
+ className: clsx('byline-coll-history-audit-row', history_module.auditRow),
128
+ "aria-label": t('collections.history.audit.createdBy', {
129
+ label: actorLabel
130
+ }),
131
+ children: [
132
+ /*#__PURE__*/ jsx(Table.Cell, {
133
+ className: clsx('byline-coll-history-audit-spacer-cell', history_module.auditSpacerCell)
134
+ }),
135
+ /*#__PURE__*/ jsx(Table.Cell, {
136
+ colSpan: rowPresentation.auditColSpan,
137
+ className: clsx('byline-coll-history-audit-cell', history_module.auditCell),
138
+ children: /*#__PURE__*/ jsxs("span", {
139
+ className: clsx('byline-coll-history-audit', history_module.audit),
140
+ children: [
141
+ actionLabel,
142
+ ' · ',
143
+ t('collections.history.audit.createdBy', {
144
+ label: actorLabel
145
+ }),
146
+ ' · ',
147
+ versionLabel
148
+ ]
149
+ })
150
+ })
151
+ ]
152
+ })
153
+ ]
154
+ }, versionId ?? document.id);
155
+ })
156
+ })
157
+ ]
158
+ }),
159
+ padRows(6 - data.docs.length)
160
+ ]
161
+ }),
162
+ /*#__PURE__*/ jsxs("div", {
163
+ className: clsx('byline-coll-history-options byline-coll-history-options-bottom', history_module.options, history_module.optionsBottom),
164
+ children: [
165
+ /*#__PURE__*/ jsx(Select, {
166
+ containerClassName: clsx('byline-coll-history-page-size', history_module.pageSize),
167
+ id: "page_size",
168
+ name: "page_size",
169
+ size: "sm",
170
+ defaultValue: "15",
171
+ items: [
172
+ {
173
+ value: '15',
174
+ label: '15'
175
+ },
176
+ {
177
+ value: '30',
178
+ label: '30'
179
+ },
180
+ {
181
+ value: '50',
182
+ label: '50'
183
+ },
184
+ {
185
+ value: '100',
186
+ label: '100'
187
+ }
188
+ ],
189
+ onValueChange: (value)=>{
190
+ if ('string' != typeof value || 0 === value.length) return;
191
+ onPageSizeChange(Number.parseInt(value, 10));
192
+ }
193
+ }),
194
+ /*#__PURE__*/ jsx(RouterPager, {
195
+ smoothScrollToTop: true,
196
+ page: data.meta.page,
197
+ count: data.meta.totalPages,
198
+ showFirstButton: true,
199
+ showLastButton: true,
200
+ componentName: "pagerBottom",
201
+ "aria-label": t('collections.list.pagerBottomAriaLabel')
202
+ })
203
+ ]
204
+ }),
205
+ selectedVersion && currentDocument && /*#__PURE__*/ jsx(Suspense, {
206
+ fallback: null,
207
+ children: /*#__PURE__*/ jsx(DiffModal, {
208
+ isOpen: true,
209
+ onDismiss: ()=>setSelectedVersion(null),
210
+ collection: resourcePath,
211
+ documentId: documentId,
212
+ versionId: selectedVersion.versionId,
213
+ versionLabel: selectedVersion.label,
214
+ currentDocument: currentDocument,
215
+ locale: locale,
216
+ loadHistoricalVersion: loadHistoricalVersion
217
+ })
218
+ }),
219
+ /*#__PURE__*/ jsx(Modal, {
220
+ isOpen: null != restoreTarget,
221
+ onDismiss: ()=>setRestoreTarget(null),
222
+ closeOnOverlayClick: false,
223
+ children: /*#__PURE__*/ jsxs(Modal.Container, {
224
+ className: clsx('byline-coll-history-restore-modal', history_module.restoreModal),
225
+ children: [
226
+ /*#__PURE__*/ jsxs(Modal.Header, {
227
+ className: clsx('byline-coll-history-restore-modal-head', history_module.restoreModalHead),
228
+ children: [
229
+ /*#__PURE__*/ jsx("h3", {
230
+ className: "m-0",
231
+ children: t('collections.history.restoreModalTitle')
232
+ }),
233
+ /*#__PURE__*/ jsx(IconButton, {
234
+ "aria-label": t('common.actions.close'),
235
+ size: "xs",
236
+ onClick: ()=>setRestoreTarget(null),
237
+ children: /*#__PURE__*/ jsx(CloseIcon, {
238
+ width: "14px",
239
+ height: "14px",
240
+ svgClassName: "white-icon"
241
+ })
242
+ })
243
+ ]
244
+ }),
245
+ restoreTarget ? /*#__PURE__*/ jsx(RestoreVersionModal, {
246
+ versionLabel: restoreTarget.label,
247
+ versionNumber: restoreTarget.versionNumber,
248
+ restoreStatusLabel: restoreStatusLabel,
249
+ onClose: ()=>setRestoreTarget(null),
250
+ restoreVersion: ()=>restoreVersion(restoreTarget.versionId),
251
+ onRestoreComplete: onRestoreComplete
252
+ }) : null
253
+ ]
254
+ })
255
+ })
256
+ ]
257
+ });
258
+ }
259
+ export { HistoryStats, VersionHistoryCore };
@@ -0,0 +1,19 @@
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 { SingletonAdminConfig, SingletonDefinition, WorkflowStatus } from '@byline/core';
9
+ import { type VersionHistoryData } from '../collections/version-history.js';
10
+ import type { ContentLocaleOption } from '../collections/view-menu.js';
11
+ export declare function SingletonHistoryView({ singletonDefinition, adminConfig, data, currentDocument, contentLocales, defaultContentLocale, workflowStatuses, }: {
12
+ singletonDefinition: SingletonDefinition;
13
+ adminConfig?: SingletonAdminConfig;
14
+ data: VersionHistoryData;
15
+ currentDocument?: Record<string, unknown> | null;
16
+ contentLocales: ReadonlyArray<ContentLocaleOption>;
17
+ defaultContentLocale: string;
18
+ workflowStatuses: WorkflowStatus[];
19
+ }): import("react").JSX.Element;
@@ -0,0 +1,170 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { useRouter, useRouterState } from "@tanstack/react-router";
3
+ import { StatusBadge } from "@byline/admin/react";
4
+ import { useTranslation } from "@byline/i18n/react";
5
+ import { Button, Container, Section, Table } from "@byline/ui/react";
6
+ import clsx from "clsx";
7
+ import { getAdminRoutePath } from "../../routes/admin-path.js";
8
+ import { findSingletonByVersion, restoreSingletonVersion } from "../../server-fns/singletons/index.js";
9
+ import { useNavigate } from "../chrome/loose-router.js";
10
+ import history_module from "../collections/history.module.js";
11
+ import { HistoryStats, VersionHistoryCore } from "../collections/version-history.js";
12
+ import { SingletonViewMenu } from "./view-menu.js";
13
+ function SingletonHistoryView({ singletonDefinition, adminConfig, data, currentDocument, contentLocales, defaultContentLocale, workflowStatuses }) {
14
+ const singleton = singletonDefinition.path;
15
+ const navigate = useNavigate();
16
+ const router = useRouter();
17
+ const location = useRouterState({
18
+ select: (state)=>state.location
19
+ });
20
+ const locale = location.search.locale;
21
+ const { t } = useTranslation('byline-admin');
22
+ function handlePageSizeChange(pageSize) {
23
+ const params = structuredClone(location.search);
24
+ delete params.page;
25
+ params.page_size = pageSize;
26
+ navigate({
27
+ to: getAdminRoutePath('singletons', '$singleton', 'history'),
28
+ params: {
29
+ singleton
30
+ },
31
+ search: params
32
+ });
33
+ }
34
+ const rowPresentation = {
35
+ headers: /*#__PURE__*/ jsxs(Fragment, {
36
+ children: [
37
+ /*#__PURE__*/ jsx("th", {
38
+ scope: "col",
39
+ children: t('collections.history.statusColumn')
40
+ }),
41
+ /*#__PURE__*/ jsx("th", {
42
+ scope: "col",
43
+ children: t('collections.documentHistory.colWhen')
44
+ }),
45
+ /*#__PURE__*/ jsx("th", {
46
+ scope: "col",
47
+ children: t('collections.documentHistory.colActor')
48
+ }),
49
+ /*#__PURE__*/ jsx("th", {
50
+ scope: "col",
51
+ className: clsx('byline-coll-history-col-restore', history_module.colRestore)
52
+ })
53
+ ]
54
+ }),
55
+ auditColSpan: 4,
56
+ renderCells: ({ document, versionId, currentVersionId, actorLabel, restoreStatusLabel, openRestore })=>/*#__PURE__*/ jsxs(Fragment, {
57
+ children: [
58
+ /*#__PURE__*/ jsx(Table.Cell, {
59
+ className: "byline-singleton-history-status-cell",
60
+ children: /*#__PURE__*/ jsx(StatusBadge, {
61
+ status: document.status,
62
+ workflowStatuses: workflowStatuses
63
+ })
64
+ }),
65
+ /*#__PURE__*/ jsx(Table.Cell, {
66
+ className: "byline-singleton-history-created-cell",
67
+ children: new Date(document.createdAt).toLocaleString()
68
+ }),
69
+ /*#__PURE__*/ jsx(Table.Cell, {
70
+ className: "byline-singleton-history-actor-cell",
71
+ children: actorLabel
72
+ }),
73
+ /*#__PURE__*/ jsx(Table.Cell, {
74
+ className: clsx('byline-coll-history-restore-cell', history_module.restoreCell),
75
+ children: versionId && versionId !== currentVersionId ? /*#__PURE__*/ jsx(Button, {
76
+ type: "button",
77
+ variant: "outlined",
78
+ size: "xs",
79
+ intent: "noeffect",
80
+ onClick: openRestore,
81
+ className: clsx('byline-coll-history-restore-button', history_module.restoreButton),
82
+ title: t('collections.history.restoreButtonTitle', {
83
+ status: restoreStatusLabel
84
+ }),
85
+ children: t('collections.history.restoreButton')
86
+ }) : null
87
+ })
88
+ ]
89
+ })
90
+ };
91
+ const documentId = currentDocument && 'string' == typeof currentDocument.id ? currentDocument.id : '';
92
+ return /*#__PURE__*/ jsxs(Fragment, {
93
+ children: [
94
+ /*#__PURE__*/ jsx(Section, {
95
+ children: /*#__PURE__*/ jsx(Container, {
96
+ children: /*#__PURE__*/ jsxs("div", {
97
+ className: clsx('byline-coll-history-head', history_module.head),
98
+ children: [
99
+ /*#__PURE__*/ jsxs("h2", {
100
+ className: clsx('byline-coll-history-title', history_module.title),
101
+ children: [
102
+ t('collections.history.title', {
103
+ label: singletonDefinition.label
104
+ }),
105
+ ' ',
106
+ /*#__PURE__*/ jsx(HistoryStats, {
107
+ total: data.meta.total
108
+ })
109
+ ]
110
+ }),
111
+ /*#__PURE__*/ jsx(SingletonViewMenu, {
112
+ singleton: singleton,
113
+ activeView: "history",
114
+ locale: locale,
115
+ contentLocales: contentLocales,
116
+ defaultContentLocale: defaultContentLocale,
117
+ adminConfig: adminConfig,
118
+ doc: null == currentDocument ? void 0 : currentDocument
119
+ })
120
+ ]
121
+ })
122
+ })
123
+ }),
124
+ /*#__PURE__*/ jsx(Section, {
125
+ children: /*#__PURE__*/ jsx(Container, {
126
+ children: /*#__PURE__*/ jsx(VersionHistoryCore, {
127
+ data: data,
128
+ resourceDefinition: singletonDefinition,
129
+ resourcePath: singleton,
130
+ documentId: documentId,
131
+ currentDocument: currentDocument,
132
+ locale: locale,
133
+ rowPresentation: rowPresentation,
134
+ loadHistoricalVersion: async (_path, _documentId, versionId, versionLocale)=>{
135
+ const historical = await findSingletonByVersion({
136
+ data: {
137
+ singleton,
138
+ versionId,
139
+ locale: versionLocale
140
+ }
141
+ });
142
+ if (null == historical) throw new Error('Singleton version not found');
143
+ return historical;
144
+ },
145
+ onPageSizeChange: handlePageSizeChange,
146
+ restoreVersion: (versionId)=>restoreSingletonVersion({
147
+ data: {
148
+ singleton,
149
+ versionId
150
+ }
151
+ }),
152
+ onRestoreComplete: async ()=>{
153
+ await router.invalidate();
154
+ navigate({
155
+ to: getAdminRoutePath('singletons', '$singleton'),
156
+ params: {
157
+ singleton
158
+ },
159
+ search: locale ? {
160
+ locale
161
+ } : {}
162
+ });
163
+ }
164
+ })
165
+ })
166
+ })
167
+ ]
168
+ });
169
+ }
170
+ export { SingletonHistoryView };
@@ -0,0 +1,8 @@
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
+ export {};
@@ -0,0 +1,12 @@
1
+ import type { SingletonAdminConfig, SingletonPreviewDocument } from '@byline/core';
2
+ /**
3
+ * Explicit-preview-only singleton affordance. A singleton's stored path is
4
+ * internal identity metadata, so unlike collection previews there is no
5
+ * schema or conventional path fallback.
6
+ */
7
+ export declare function SingletonPreviewLink({ doc, adminConfig, locale, className, }: {
8
+ doc: SingletonPreviewDocument;
9
+ adminConfig: SingletonAdminConfig;
10
+ locale?: string;
11
+ className?: string;
12
+ }): import("react").JSX.Element | null;
@@ -0,0 +1,54 @@
1
+ "use client";
2
+ import { jsx } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { useTranslation } from "@byline/i18n/react";
5
+ import { ExternalLinkIcon, IconButton, useToastManager } from "@byline/ui/react";
6
+ import clsx from "clsx";
7
+ import { enablePreviewModeFn } from "../../server-fns/preview/index.js";
8
+ function SingletonPreviewLink({ doc, adminConfig, locale, className }) {
9
+ const toastManager = useToastManager();
10
+ const { t } = useTranslation('byline-admin');
11
+ const [busy, setBusy] = useState(false);
12
+ const url = adminConfig.preview?.url(doc, {
13
+ locale
14
+ }) ?? null;
15
+ if (null == url) return null;
16
+ const handleClick = async ()=>{
17
+ if (busy) return;
18
+ setBusy(true);
19
+ try {
20
+ await enablePreviewModeFn();
21
+ window.location.assign(url);
22
+ } catch (err) {
23
+ toastManager.add({
24
+ title: t('collections.preview.toastTitle'),
25
+ description: t("collections.preview.failedDescription", {
26
+ message: err.message
27
+ }),
28
+ data: {
29
+ intent: 'danger',
30
+ iconType: 'danger',
31
+ icon: true,
32
+ close: true
33
+ }
34
+ });
35
+ } finally{
36
+ setBusy(false);
37
+ }
38
+ };
39
+ return /*#__PURE__*/ jsx(IconButton, {
40
+ className: clsx('byline-preview-link', className),
41
+ size: "xs",
42
+ variant: "text",
43
+ disabled: busy,
44
+ onClick: handleClick,
45
+ "aria-label": t('collections.preview.openAriaLabel'),
46
+ title: t('collections.preview.title'),
47
+ children: /*#__PURE__*/ jsx(ExternalLinkIcon, {
48
+ width: "20px",
49
+ height: "20px",
50
+ className: "byline-preview-link-icon"
51
+ })
52
+ });
53
+ }
54
+ export { SingletonPreviewLink };
@@ -0,0 +1,13 @@
1
+ import type { SingletonAdminConfig, SingletonPreviewDocument } from '@byline/core';
2
+ import type { ContentLocaleOption } from '../collections/view-menu.js';
3
+ export type SingletonViewMenuPath = 'edit' | 'history';
4
+ /** Id-less edit/history navigation; preview appears only for a mapped document. */
5
+ export declare function SingletonViewMenu({ singleton, activeView, locale, contentLocales, defaultContentLocale, adminConfig, doc, }: {
6
+ singleton: string;
7
+ activeView: SingletonViewMenuPath;
8
+ locale?: string;
9
+ contentLocales: ReadonlyArray<ContentLocaleOption>;
10
+ defaultContentLocale: string;
11
+ adminConfig?: SingletonAdminConfig;
12
+ doc?: SingletonPreviewDocument;
13
+ }): import("react").JSX.Element;