@byline/host-tanstack-start 3.9.0 → 3.10.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.
- package/dist/admin-shell/collections/document-history.d.ts +53 -0
- package/dist/admin-shell/collections/document-history.js +103 -0
- package/dist/admin-shell/collections/document-history.module.js +9 -0
- package/dist/admin-shell/collections/document-history_module.css +28 -0
- package/dist/admin-shell/collections/history.d.ts +8 -1
- package/dist/admin-shell/collections/history.js +73 -29
- package/dist/admin-shell/collections/history.module.js +1 -0
- package/dist/admin-shell/collections/history_module.css +4 -0
- package/dist/routes/create-collection-history-route.js +23 -6
- package/dist/server-fns/collections/audit.d.ts +50 -0
- package/dist/server-fns/collections/audit.js +40 -0
- package/dist/server-fns/collections/index.d.ts +1 -0
- package/dist/server-fns/collections/index.js +1 -0
- package/package.json +8 -8
- package/src/admin-shell/collections/document-history.module.css +46 -0
- package/src/admin-shell/collections/document-history.tsx +156 -0
- package/src/admin-shell/collections/history.module.css +6 -0
- package/src/admin-shell/collections/history.tsx +331 -281
- package/src/routes/create-collection-history-route.tsx +25 -3
- package/src/server-fns/collections/audit.ts +97 -0
- package/src/server-fns/collections/index.ts +1 -0
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
import { Fragment, lazy, Suspense, useState } from 'react'
|
|
10
10
|
import { useParams, useRouterState } from '@tanstack/react-router'
|
|
11
11
|
|
|
12
|
-
import { renderFormatted, StatusBadge } from '@byline/admin/react'
|
|
12
|
+
import { AdminTabs, renderFormatted, StatusBadge } from '@byline/admin/react'
|
|
13
13
|
import { useBylineAdminServices } from '@byline/admin/services'
|
|
14
14
|
import type { CollectionAdminConfig, CollectionDefinition, WorkflowStatus } from '@byline/core'
|
|
15
15
|
import type { AnyCollectionSchemaTypes } from '@byline/core/zod-schemas'
|
|
@@ -30,6 +30,7 @@ import { Link, useNavigate } from '../chrome/loose-router.js'
|
|
|
30
30
|
import { RouterPager } from '../chrome/router-pager.js'
|
|
31
31
|
import { TableHeadingCellSortable } from '../chrome/th-sortable.js'
|
|
32
32
|
import { formatNumber } from '../chrome/utils.js'
|
|
33
|
+
import { type DocumentHistoryData, DocumentHistoryView } from './document-history.js'
|
|
33
34
|
import styles from './history.module.css'
|
|
34
35
|
import { RestoreVersionModal } from './restore-version-modal.js'
|
|
35
36
|
import { ViewMenu } from './view-menu.js'
|
|
@@ -110,6 +111,7 @@ export const HistoryView = ({
|
|
|
110
111
|
collectionDefinition,
|
|
111
112
|
adminConfig,
|
|
112
113
|
data,
|
|
114
|
+
auditLog,
|
|
113
115
|
workflowStatuses,
|
|
114
116
|
currentDocument,
|
|
115
117
|
contentLocales,
|
|
@@ -125,6 +127,12 @@ export const HistoryView = ({
|
|
|
125
127
|
*/
|
|
126
128
|
actors?: Record<string, { label: string }>
|
|
127
129
|
}
|
|
130
|
+
/**
|
|
131
|
+
* Document-grain audit log for the "Document history" tab (docs/AUDIT.md —
|
|
132
|
+
* Workstream 3): the non-versioned path / available-locales / status
|
|
133
|
+
* changes and the deletion event, with admin-resolved actor labels.
|
|
134
|
+
*/
|
|
135
|
+
auditLog?: DocumentHistoryData
|
|
128
136
|
workflowStatuses?: WorkflowStatus[]
|
|
129
137
|
currentDocument?: Record<string, unknown> | null
|
|
130
138
|
contentLocales: ReadonlyArray<ContentLocaleOption>
|
|
@@ -144,6 +152,10 @@ export const HistoryView = ({
|
|
|
144
152
|
const titleFieldName = collectionDefinition.useAsTitle
|
|
145
153
|
const location = useRouterState({ select: (s) => s.location })
|
|
146
154
|
const locale = (location.search as { locale?: string }).locale
|
|
155
|
+
// Which sub-view is active (docs/AUDIT.md — W3). Absent / anything but
|
|
156
|
+
// 'document' → the content version stream.
|
|
157
|
+
const activeTab =
|
|
158
|
+
(location.search as { tab?: string }).tab === 'document' ? 'document' : 'versions'
|
|
147
159
|
const [selectedVersion, setSelectedVersion] = useState<{
|
|
148
160
|
versionId: string
|
|
149
161
|
label: string
|
|
@@ -158,6 +170,23 @@ export const HistoryView = ({
|
|
|
158
170
|
? (currentDocument.versionId as string)
|
|
159
171
|
: null
|
|
160
172
|
|
|
173
|
+
function handleTabChange(name: string): void {
|
|
174
|
+
// Switching tabs resets pagination; 'versions' (the default) drops the
|
|
175
|
+
// `tab` param entirely to keep the URL clean.
|
|
176
|
+
const params = structuredClone(location.search)
|
|
177
|
+
delete params.page
|
|
178
|
+
if (name === 'document') {
|
|
179
|
+
params.tab = 'document'
|
|
180
|
+
} else {
|
|
181
|
+
delete params.tab
|
|
182
|
+
}
|
|
183
|
+
navigate({
|
|
184
|
+
to: '/admin/collections/$collection/$id/history' as never,
|
|
185
|
+
params: { collection, id } as never,
|
|
186
|
+
search: params,
|
|
187
|
+
})
|
|
188
|
+
}
|
|
189
|
+
|
|
161
190
|
function handleOnPageSizeChange(value: string | null): void {
|
|
162
191
|
if (typeof value !== 'string' || value.length === 0) return
|
|
163
192
|
const params = structuredClone(location.search)
|
|
@@ -177,7 +206,9 @@ export const HistoryView = ({
|
|
|
177
206
|
<div className={cx('byline-coll-history-head', styles.head)}>
|
|
178
207
|
<h2 className={cx('byline-coll-history-title', styles.title)}>
|
|
179
208
|
{t('collections.history.title', { label: labels.singular })}{' '}
|
|
180
|
-
<Stats
|
|
209
|
+
<Stats
|
|
210
|
+
total={activeTab === 'document' ? (auditLog?.meta.total ?? 0) : data?.meta.total}
|
|
211
|
+
/>
|
|
181
212
|
</h2>
|
|
182
213
|
<ViewMenu
|
|
183
214
|
collection={collection}
|
|
@@ -188,293 +219,312 @@ export const HistoryView = ({
|
|
|
188
219
|
defaultContentLocale={defaultContentLocale}
|
|
189
220
|
/>
|
|
190
221
|
</div>
|
|
222
|
+
<AdminTabs
|
|
223
|
+
tabs={[
|
|
224
|
+
{ name: 'versions', label: t('collections.history.tabs.versions') },
|
|
225
|
+
{ name: 'document', label: t('collections.history.tabs.document') },
|
|
226
|
+
]}
|
|
227
|
+
activeTab={activeTab}
|
|
228
|
+
onChange={handleTabChange}
|
|
229
|
+
className={cx('byline-coll-history-tabs', styles.tabs)}
|
|
230
|
+
/>
|
|
191
231
|
</Container>
|
|
192
232
|
</Section>
|
|
193
|
-
|
|
194
|
-
<
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
key="__restore"
|
|
233
|
+
{activeTab === 'document' && (
|
|
234
|
+
<DocumentHistoryView
|
|
235
|
+
data={
|
|
236
|
+
auditLog ?? { entries: [], meta: { total: 0, page: 1, pageSize: 0, totalPages: 0 } }
|
|
237
|
+
}
|
|
238
|
+
/>
|
|
239
|
+
)}
|
|
240
|
+
|
|
241
|
+
{activeTab !== 'document' && (
|
|
242
|
+
<Section>
|
|
243
|
+
<Container>
|
|
244
|
+
<div className={cx('byline-coll-history-options', styles.options)}>
|
|
245
|
+
<RouterPager
|
|
246
|
+
page={data?.meta.page}
|
|
247
|
+
count={data?.meta.totalPages}
|
|
248
|
+
showFirstButton
|
|
249
|
+
showLastButton
|
|
250
|
+
componentName="pagerTop"
|
|
251
|
+
aria-label={t('collections.list.pagerTopAriaLabel')}
|
|
252
|
+
/>
|
|
253
|
+
</div>
|
|
254
|
+
<Table.Container className={cx('byline-coll-history-table-wrap', styles.tableWrap)}>
|
|
255
|
+
<Table>
|
|
256
|
+
<Table.Header>
|
|
257
|
+
<Table.Row>
|
|
258
|
+
<th
|
|
259
|
+
scope="col"
|
|
260
|
+
className={cx('byline-coll-history-col-version', styles.colVersion)}
|
|
261
|
+
/>
|
|
262
|
+
{columns.flatMap((column) => {
|
|
263
|
+
const cell = (
|
|
264
|
+
<TableHeadingCellSortable
|
|
265
|
+
key={String(column.fieldName)}
|
|
266
|
+
fieldName={String(column.fieldName)}
|
|
267
|
+
label={column.label}
|
|
268
|
+
sortable={column.sortable}
|
|
230
269
|
scope="col"
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
270
|
+
align={column.align}
|
|
271
|
+
className={column.className}
|
|
272
|
+
/>
|
|
273
|
+
)
|
|
274
|
+
if (titleFieldName != null && column.fieldName === titleFieldName) {
|
|
275
|
+
return [
|
|
276
|
+
cell,
|
|
277
|
+
<th
|
|
278
|
+
key="__restore"
|
|
279
|
+
scope="col"
|
|
280
|
+
className={cx('byline-coll-history-col-restore', styles.colRestore)}
|
|
281
|
+
/>,
|
|
282
|
+
]
|
|
283
|
+
}
|
|
284
|
+
return [cell]
|
|
285
|
+
})}
|
|
286
|
+
</Table.Row>
|
|
287
|
+
</Table.Header>
|
|
239
288
|
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
className={cx(
|
|
282
|
-
'byline-coll-history-version-button',
|
|
283
|
-
styles.versionButton
|
|
284
|
-
)}
|
|
285
|
-
onClick={() =>
|
|
286
|
-
setSelectedVersion({
|
|
287
|
-
versionId,
|
|
288
|
-
label: new Date(document.createdAt).toLocaleString(),
|
|
289
|
-
})
|
|
290
|
-
}
|
|
291
|
-
>
|
|
292
|
-
{versionNumber}
|
|
293
|
-
</IconButton>
|
|
294
|
-
) : null}
|
|
295
|
-
</Table.Cell>
|
|
296
|
-
{columns.flatMap((column) => {
|
|
297
|
-
const dataCell = (
|
|
298
|
-
<Table.Cell
|
|
299
|
-
key={String(column.fieldName)}
|
|
300
|
-
className={cx({
|
|
301
|
-
'byline-coll-history-cell-right': column.align === 'right',
|
|
302
|
-
[styles.cellRight]: column.align === 'right',
|
|
303
|
-
'byline-coll-history-cell-center': column.align === 'center',
|
|
304
|
-
[styles.cellCenter]: column.align === 'center',
|
|
305
|
-
})}
|
|
306
|
-
>
|
|
307
|
-
{titleFieldName != null && column.fieldName === titleFieldName ? (
|
|
308
|
-
versionId && currentDocument ? (
|
|
309
|
-
<button
|
|
310
|
-
type="button"
|
|
311
|
-
className={cx(
|
|
312
|
-
'byline-coll-history-title-button',
|
|
313
|
-
styles.titleButton
|
|
314
|
-
)}
|
|
315
|
-
onClick={() =>
|
|
316
|
-
setSelectedVersion({
|
|
317
|
-
versionId,
|
|
318
|
-
label: new Date(document.createdAt).toLocaleString(),
|
|
319
|
-
})
|
|
320
|
-
}
|
|
321
|
-
>
|
|
322
|
-
{column.formatter
|
|
323
|
-
? renderFormatted(
|
|
324
|
-
getColumnValue(document, column.fieldName as string),
|
|
325
|
-
document,
|
|
326
|
-
column.formatter
|
|
327
|
-
)
|
|
328
|
-
: resolveDisplayValue(
|
|
329
|
-
getColumnValue(document, column.fieldName as string),
|
|
330
|
-
locale,
|
|
331
|
-
defaultContentLocale
|
|
332
|
-
) || '------'}
|
|
333
|
-
</button>
|
|
334
|
-
) : (
|
|
335
|
-
<Link
|
|
336
|
-
to={'/admin/collections/$collection/$id' as never}
|
|
337
|
-
params={{
|
|
338
|
-
collection,
|
|
339
|
-
id: document.id,
|
|
340
|
-
}}
|
|
341
|
-
>
|
|
342
|
-
{column.formatter
|
|
343
|
-
? renderFormatted(
|
|
344
|
-
getColumnValue(document, column.fieldName as string),
|
|
345
|
-
document,
|
|
346
|
-
column.formatter
|
|
347
|
-
)
|
|
348
|
-
: resolveDisplayValue(
|
|
349
|
-
getColumnValue(document, column.fieldName as string),
|
|
350
|
-
locale,
|
|
351
|
-
defaultContentLocale
|
|
352
|
-
) || '------'}
|
|
353
|
-
</Link>
|
|
354
|
-
)
|
|
355
|
-
) : column.formatter ? (
|
|
356
|
-
renderFormatted(
|
|
357
|
-
getColumnValue(document, column.fieldName as string),
|
|
358
|
-
document,
|
|
359
|
-
column.formatter
|
|
360
|
-
)
|
|
361
|
-
) : column.fieldName === 'status' && workflowStatuses ? (
|
|
362
|
-
<StatusBadge
|
|
363
|
-
status={document.status}
|
|
364
|
-
workflowStatuses={workflowStatuses}
|
|
365
|
-
/>
|
|
366
|
-
) : (
|
|
367
|
-
resolveDisplayValue(
|
|
368
|
-
getColumnValue(document, column.fieldName as string),
|
|
369
|
-
locale,
|
|
370
|
-
defaultContentLocale
|
|
371
|
-
) || ''
|
|
372
|
-
)}
|
|
373
|
-
</Table.Cell>
|
|
374
|
-
)
|
|
375
|
-
if (titleFieldName != null && column.fieldName === titleFieldName) {
|
|
376
|
-
return [
|
|
377
|
-
dataCell,
|
|
378
|
-
<Table.Cell
|
|
379
|
-
key="__restore"
|
|
289
|
+
<Table.Body>
|
|
290
|
+
{data?.docs?.map((document, rowIndex) => {
|
|
291
|
+
const versionId = document.versionId
|
|
292
|
+
const { total, page, pageSize, desc } = data.meta
|
|
293
|
+
const versionNumber = desc
|
|
294
|
+
? total - (page - 1) * pageSize - rowIndex
|
|
295
|
+
: (page - 1) * pageSize + rowIndex + 1
|
|
296
|
+
// Audit strip (docs/AUDIT.md — W1): who created this
|
|
297
|
+
// version, via which action. A present-but-unresolved id
|
|
298
|
+
// is a deleted user; an absent id is a row written before
|
|
299
|
+
// audit wiring or an internal-tooling write.
|
|
300
|
+
const actorLabel = document.createdBy
|
|
301
|
+
? (data.actors?.[document.createdBy]?.label ??
|
|
302
|
+
t('collections.history.audit.formerUser'))
|
|
303
|
+
: t('collections.history.audit.unknown')
|
|
304
|
+
const actionKey = document.eventType
|
|
305
|
+
? AUDIT_ACTION_KEYS[document.eventType]
|
|
306
|
+
: undefined
|
|
307
|
+
const actionLabel = actionKey ? t(actionKey) : (document.eventType ?? '')
|
|
308
|
+
// The strip starts on the second column — an empty spacer
|
|
309
|
+
// cell sits under the version-number column, then one cell
|
|
310
|
+
// spans the data columns plus the restore cell appended
|
|
311
|
+
// after the identity column when present.
|
|
312
|
+
const auditColSpan =
|
|
313
|
+
columns.length +
|
|
314
|
+
(titleFieldName != null && columns.some((c) => c.fieldName === titleFieldName)
|
|
315
|
+
? 1
|
|
316
|
+
: 0)
|
|
317
|
+
return (
|
|
318
|
+
<Fragment key={versionId ?? document.id}>
|
|
319
|
+
<Table.Row className={cx('byline-coll-history-row', styles.historyRow)}>
|
|
320
|
+
<Table.Cell
|
|
321
|
+
className={cx('byline-coll-history-version-cell', styles.versionCell)}
|
|
322
|
+
>
|
|
323
|
+
{versionId && currentDocument ? (
|
|
324
|
+
<IconButton
|
|
325
|
+
size="xs"
|
|
326
|
+
variant="outlined"
|
|
327
|
+
intent="noeffect"
|
|
328
|
+
aria-label={t('collections.history.compareAriaLabel')}
|
|
329
|
+
title={t('collections.history.compareTitle')}
|
|
380
330
|
className={cx(
|
|
381
|
-
'byline-coll-history-
|
|
382
|
-
styles.
|
|
331
|
+
'byline-coll-history-version-button',
|
|
332
|
+
styles.versionButton
|
|
383
333
|
)}
|
|
334
|
+
onClick={() =>
|
|
335
|
+
setSelectedVersion({
|
|
336
|
+
versionId,
|
|
337
|
+
label: new Date(document.createdAt).toLocaleString(),
|
|
338
|
+
})
|
|
339
|
+
}
|
|
384
340
|
>
|
|
385
|
-
{
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
341
|
+
{versionNumber}
|
|
342
|
+
</IconButton>
|
|
343
|
+
) : null}
|
|
344
|
+
</Table.Cell>
|
|
345
|
+
{columns.flatMap((column) => {
|
|
346
|
+
const dataCell = (
|
|
347
|
+
<Table.Cell
|
|
348
|
+
key={String(column.fieldName)}
|
|
349
|
+
className={cx({
|
|
350
|
+
'byline-coll-history-cell-right': column.align === 'right',
|
|
351
|
+
[styles.cellRight]: column.align === 'right',
|
|
352
|
+
'byline-coll-history-cell-center': column.align === 'center',
|
|
353
|
+
[styles.cellCenter]: column.align === 'center',
|
|
354
|
+
})}
|
|
355
|
+
>
|
|
356
|
+
{titleFieldName != null && column.fieldName === titleFieldName ? (
|
|
357
|
+
versionId && currentDocument ? (
|
|
358
|
+
<button
|
|
359
|
+
type="button"
|
|
360
|
+
className={cx(
|
|
361
|
+
'byline-coll-history-title-button',
|
|
362
|
+
styles.titleButton
|
|
363
|
+
)}
|
|
364
|
+
onClick={() =>
|
|
365
|
+
setSelectedVersion({
|
|
366
|
+
versionId,
|
|
367
|
+
label: new Date(document.createdAt).toLocaleString(),
|
|
368
|
+
})
|
|
369
|
+
}
|
|
370
|
+
>
|
|
371
|
+
{column.formatter
|
|
372
|
+
? renderFormatted(
|
|
373
|
+
getColumnValue(document, column.fieldName as string),
|
|
374
|
+
document,
|
|
375
|
+
column.formatter
|
|
376
|
+
)
|
|
377
|
+
: resolveDisplayValue(
|
|
378
|
+
getColumnValue(document, column.fieldName as string),
|
|
379
|
+
locale,
|
|
380
|
+
defaultContentLocale
|
|
381
|
+
) || '------'}
|
|
382
|
+
</button>
|
|
383
|
+
) : (
|
|
384
|
+
<Link
|
|
385
|
+
to={'/admin/collections/$collection/$id' as never}
|
|
386
|
+
params={{
|
|
387
|
+
collection,
|
|
388
|
+
id: document.id,
|
|
389
|
+
}}
|
|
390
|
+
>
|
|
391
|
+
{column.formatter
|
|
392
|
+
? renderFormatted(
|
|
393
|
+
getColumnValue(document, column.fieldName as string),
|
|
394
|
+
document,
|
|
395
|
+
column.formatter
|
|
396
|
+
)
|
|
397
|
+
: resolveDisplayValue(
|
|
398
|
+
getColumnValue(document, column.fieldName as string),
|
|
399
|
+
locale,
|
|
400
|
+
defaultContentLocale
|
|
401
|
+
) || '------'}
|
|
402
|
+
</Link>
|
|
403
|
+
)
|
|
404
|
+
) : column.formatter ? (
|
|
405
|
+
renderFormatted(
|
|
406
|
+
getColumnValue(document, column.fieldName as string),
|
|
407
|
+
document,
|
|
408
|
+
column.formatter
|
|
409
|
+
)
|
|
410
|
+
) : column.fieldName === 'status' && workflowStatuses ? (
|
|
411
|
+
<StatusBadge
|
|
412
|
+
status={document.status}
|
|
413
|
+
workflowStatuses={workflowStatuses}
|
|
414
|
+
/>
|
|
415
|
+
) : (
|
|
416
|
+
resolveDisplayValue(
|
|
417
|
+
getColumnValue(document, column.fieldName as string),
|
|
418
|
+
locale,
|
|
419
|
+
defaultContentLocale
|
|
420
|
+
) || ''
|
|
421
|
+
)}
|
|
422
|
+
</Table.Cell>
|
|
423
|
+
)
|
|
424
|
+
if (titleFieldName != null && column.fieldName === titleFieldName) {
|
|
425
|
+
return [
|
|
426
|
+
dataCell,
|
|
427
|
+
<Table.Cell
|
|
428
|
+
key="__restore"
|
|
429
|
+
className={cx(
|
|
430
|
+
'byline-coll-history-restore-cell',
|
|
431
|
+
styles.restoreCell
|
|
432
|
+
)}
|
|
433
|
+
>
|
|
434
|
+
{versionId && versionId !== currentVersionId ? (
|
|
435
|
+
<Button
|
|
436
|
+
type="button"
|
|
437
|
+
variant="outlined"
|
|
438
|
+
size="xs"
|
|
439
|
+
intent="noeffect"
|
|
440
|
+
onClick={() =>
|
|
441
|
+
setRestoreTarget({
|
|
442
|
+
versionId,
|
|
443
|
+
label: new Date(document.createdAt).toLocaleString(),
|
|
444
|
+
versionNumber,
|
|
445
|
+
})
|
|
446
|
+
}
|
|
447
|
+
className={cx(
|
|
448
|
+
'byline-coll-history-restore-button',
|
|
449
|
+
styles.restoreButton
|
|
450
|
+
)}
|
|
451
|
+
title={t('collections.history.restoreButtonTitle')}
|
|
452
|
+
>
|
|
453
|
+
{t('collections.history.restoreButton')}
|
|
454
|
+
</Button>
|
|
455
|
+
) : null}
|
|
456
|
+
</Table.Cell>,
|
|
457
|
+
]
|
|
458
|
+
}
|
|
459
|
+
return [dataCell]
|
|
460
|
+
})}
|
|
461
|
+
</Table.Row>
|
|
462
|
+
<Table.Row
|
|
463
|
+
className={cx('byline-coll-history-audit-row', styles.auditRow)}
|
|
464
|
+
aria-label={t('collections.history.audit.createdBy', {
|
|
465
|
+
label: actorLabel,
|
|
466
|
+
})}
|
|
428
467
|
>
|
|
429
|
-
<
|
|
430
|
-
{
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
468
|
+
<Table.Cell
|
|
469
|
+
className={cx(
|
|
470
|
+
'byline-coll-history-audit-spacer-cell',
|
|
471
|
+
styles.auditSpacerCell
|
|
472
|
+
)}
|
|
473
|
+
/>
|
|
474
|
+
<Table.Cell
|
|
475
|
+
colSpan={auditColSpan}
|
|
476
|
+
className={cx('byline-coll-history-audit-cell', styles.auditCell)}
|
|
477
|
+
>
|
|
478
|
+
<span className={cx('byline-coll-history-audit', styles.audit)}>
|
|
479
|
+
{actionLabel}
|
|
480
|
+
{' · '}
|
|
481
|
+
{t('collections.history.audit.createdBy', { label: actorLabel })}
|
|
482
|
+
{' · '}
|
|
483
|
+
{new Date(document.createdAt).toLocaleString()}
|
|
484
|
+
</span>
|
|
485
|
+
</Table.Cell>
|
|
486
|
+
</Table.Row>
|
|
487
|
+
</Fragment>
|
|
488
|
+
)
|
|
489
|
+
})}
|
|
490
|
+
</Table.Body>
|
|
491
|
+
</Table>
|
|
492
|
+
{padRows(6 - (data?.docs?.length ?? 0))}
|
|
493
|
+
</Table.Container>
|
|
494
|
+
<div
|
|
495
|
+
className={cx(
|
|
496
|
+
'byline-coll-history-options byline-coll-history-options-bottom',
|
|
497
|
+
styles.options,
|
|
498
|
+
styles.optionsBottom
|
|
499
|
+
)}
|
|
500
|
+
>
|
|
501
|
+
<Select<string>
|
|
502
|
+
containerClassName={cx('byline-coll-history-page-size', styles.pageSize)}
|
|
503
|
+
id="page_size"
|
|
504
|
+
name="page_size"
|
|
505
|
+
size="sm"
|
|
506
|
+
defaultValue="15"
|
|
507
|
+
items={[
|
|
508
|
+
{ value: '15', label: '15' },
|
|
509
|
+
{ value: '30', label: '30' },
|
|
510
|
+
{ value: '50', label: '50' },
|
|
511
|
+
{ value: '100', label: '100' },
|
|
512
|
+
]}
|
|
513
|
+
onValueChange={handleOnPageSizeChange}
|
|
514
|
+
/>
|
|
515
|
+
<RouterPager
|
|
516
|
+
smoothScrollToTop={true}
|
|
517
|
+
page={data?.meta.page}
|
|
518
|
+
count={data?.meta.totalPages}
|
|
519
|
+
showFirstButton
|
|
520
|
+
showLastButton
|
|
521
|
+
componentName="pagerBottom"
|
|
522
|
+
aria-label={t('collections.list.pagerBottomAriaLabel')}
|
|
523
|
+
/>
|
|
524
|
+
</div>
|
|
525
|
+
</Container>
|
|
526
|
+
</Section>
|
|
527
|
+
)}
|
|
478
528
|
|
|
479
529
|
{selectedVersion && currentDocument && (
|
|
480
530
|
<Suspense fallback={null}>
|