@byline/host-tanstack-start 3.9.0 → 3.10.1
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/admin-account/change-password.js +1 -1
- package/dist/server-fns/admin-account/get.js +1 -1
- package/dist/server-fns/admin-account/update.js +1 -1
- package/dist/server-fns/admin-permissions/get-role-abilities.js +1 -1
- package/dist/server-fns/admin-permissions/set-role-abilities.js +1 -1
- package/dist/server-fns/admin-permissions/who-has.js +1 -1
- package/dist/server-fns/admin-roles/create.js +1 -1
- package/dist/server-fns/admin-roles/delete.js +1 -1
- package/dist/server-fns/admin-roles/get.js +1 -1
- package/dist/server-fns/admin-roles/reorder.js +1 -1
- package/dist/server-fns/admin-roles/update.js +1 -1
- package/dist/server-fns/admin-users/create.js +1 -1
- package/dist/server-fns/admin-users/delete.js +1 -1
- package/dist/server-fns/admin-users/disable.js +1 -1
- package/dist/server-fns/admin-users/enable.js +1 -1
- package/dist/server-fns/admin-users/get-user-roles.js +1 -1
- package/dist/server-fns/admin-users/get.js +1 -1
- package/dist/server-fns/admin-users/list.js +1 -1
- package/dist/server-fns/admin-users/set-password.js +1 -1
- package/dist/server-fns/admin-users/set-user-roles.js +1 -1
- package/dist/server-fns/admin-users/update.js +1 -1
- package/dist/server-fns/ai/execute.js +1 -1
- package/dist/server-fns/auth/sign-in.js +1 -1
- package/dist/server-fns/collections/audit.d.ts +50 -0
- package/dist/server-fns/collections/audit.js +40 -0
- package/dist/server-fns/collections/copy-to-locale.js +1 -1
- package/dist/server-fns/collections/create.js +1 -1
- package/dist/server-fns/collections/delete-locale.js +1 -1
- package/dist/server-fns/collections/delete.js +1 -1
- package/dist/server-fns/collections/duplicate.js +1 -1
- package/dist/server-fns/collections/get.js +2 -2
- package/dist/server-fns/collections/history.js +1 -1
- package/dist/server-fns/collections/index.d.ts +1 -0
- package/dist/server-fns/collections/index.js +1 -0
- package/dist/server-fns/collections/list.js +1 -1
- package/dist/server-fns/collections/reorder.js +1 -1
- package/dist/server-fns/collections/restore-version.js +1 -1
- package/dist/server-fns/collections/stats.js +1 -1
- package/dist/server-fns/collections/status.js +2 -2
- package/dist/server-fns/collections/update.js +2 -2
- package/dist/server-fns/collections/upload.js +1 -1
- package/dist/server-fns/i18n/set-locale.js +1 -1
- package/package.json +10 -10
- 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/admin-account/change-password.ts +1 -1
- package/src/server-fns/admin-account/get.ts +1 -1
- package/src/server-fns/admin-account/update.ts +1 -1
- package/src/server-fns/admin-permissions/get-role-abilities.ts +1 -1
- package/src/server-fns/admin-permissions/set-role-abilities.ts +1 -1
- package/src/server-fns/admin-permissions/who-has.ts +1 -1
- package/src/server-fns/admin-roles/create.ts +1 -1
- package/src/server-fns/admin-roles/delete.ts +1 -1
- package/src/server-fns/admin-roles/get.ts +1 -1
- package/src/server-fns/admin-roles/reorder.ts +1 -1
- package/src/server-fns/admin-roles/update.ts +1 -1
- package/src/server-fns/admin-users/create.ts +1 -1
- package/src/server-fns/admin-users/delete.ts +1 -1
- package/src/server-fns/admin-users/disable.ts +1 -1
- package/src/server-fns/admin-users/enable.ts +1 -1
- package/src/server-fns/admin-users/get-user-roles.ts +1 -1
- package/src/server-fns/admin-users/get.ts +1 -1
- package/src/server-fns/admin-users/list.ts +1 -1
- package/src/server-fns/admin-users/set-password.ts +1 -1
- package/src/server-fns/admin-users/set-user-roles.ts +1 -1
- package/src/server-fns/admin-users/update.ts +1 -1
- package/src/server-fns/ai/execute.ts +1 -1
- package/src/server-fns/auth/sign-in.ts +1 -1
- package/src/server-fns/collections/audit.ts +95 -0
- package/src/server-fns/collections/copy-to-locale.ts +1 -1
- package/src/server-fns/collections/create.ts +1 -1
- package/src/server-fns/collections/delete-locale.ts +1 -1
- package/src/server-fns/collections/delete.ts +1 -1
- package/src/server-fns/collections/duplicate.ts +1 -1
- package/src/server-fns/collections/get.ts +2 -2
- package/src/server-fns/collections/history.ts +1 -1
- package/src/server-fns/collections/index.ts +1 -0
- package/src/server-fns/collections/list.ts +1 -1
- package/src/server-fns/collections/reorder.ts +1 -1
- package/src/server-fns/collections/restore-version.ts +1 -1
- package/src/server-fns/collections/stats.ts +1 -1
- package/src/server-fns/collections/status.ts +2 -2
- package/src/server-fns/collections/update.ts +2 -2
- package/src/server-fns/collections/upload.ts +1 -1
- package/src/server-fns/i18n/set-locale.ts +1 -1
|
@@ -0,0 +1,53 @@
|
|
|
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
|
+
* One serialised audit-log entry as it reaches the admin UI. Mirrors
|
|
10
|
+
* `@byline/client`'s `AuditLogEntry` but with `occurredAt` as an ISO string —
|
|
11
|
+
* the value crosses the TanStack server-fn boundary through `serialise()`,
|
|
12
|
+
* which turns Dates into strings (docs/AUDIT.md — Workstream 3).
|
|
13
|
+
*/
|
|
14
|
+
export interface AuditLogEntryView {
|
|
15
|
+
id: string;
|
|
16
|
+
documentId: string | null;
|
|
17
|
+
collectionId: string | null;
|
|
18
|
+
actorId: string | null;
|
|
19
|
+
actorRealm: string;
|
|
20
|
+
action: string;
|
|
21
|
+
field: string | null;
|
|
22
|
+
before: unknown;
|
|
23
|
+
after: unknown;
|
|
24
|
+
occurredAt: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* The document-history payload attached to the history loader: the page of
|
|
28
|
+
* audit entries plus the admin-side resolved actor labels (`actors`, keyed by
|
|
29
|
+
* actor id — ids absent from the map belong to deleted users; system/tooling
|
|
30
|
+
* rows carry a NULL actorId).
|
|
31
|
+
*/
|
|
32
|
+
export interface DocumentHistoryData {
|
|
33
|
+
entries: AuditLogEntryView[];
|
|
34
|
+
meta: {
|
|
35
|
+
total: number;
|
|
36
|
+
page: number;
|
|
37
|
+
pageSize: number;
|
|
38
|
+
totalPages: number;
|
|
39
|
+
};
|
|
40
|
+
actors?: Record<string, {
|
|
41
|
+
label: string;
|
|
42
|
+
}>;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Document-grain audit log for a single document (docs/AUDIT.md — Workstream
|
|
46
|
+
* 3, "Document history" tab): a chronological, newest-first list of the
|
|
47
|
+
* non-versioned changes the version stream does not record — path /
|
|
48
|
+
* available-locales writes, in-place status transitions, and the deletion
|
|
49
|
+
* event. No diff viewer; before/after render inline.
|
|
50
|
+
*/
|
|
51
|
+
export declare const DocumentHistoryView: ({ data }: {
|
|
52
|
+
data: DocumentHistoryData;
|
|
53
|
+
}) => import("react").JSX.Element;
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useTranslation } from "@byline/i18n/react";
|
|
3
|
+
import { Container, Section, Table } from "@byline/ui/react";
|
|
4
|
+
import classnames from "classnames";
|
|
5
|
+
import document_history_module from "./document-history.module.js";
|
|
6
|
+
const ACTION_KEYS = {
|
|
7
|
+
'document.path.changed': 'collections.documentHistory.actionPathChanged',
|
|
8
|
+
'document.locales.changed': 'collections.documentHistory.actionLocalesChanged',
|
|
9
|
+
'document.status.changed': 'collections.documentHistory.actionStatusChanged',
|
|
10
|
+
'document.deleted': 'collections.documentHistory.actionDeleted'
|
|
11
|
+
};
|
|
12
|
+
function formatAuditValue(value) {
|
|
13
|
+
if (null == value) return '—';
|
|
14
|
+
if (Array.isArray(value)) return value.length > 0 ? value.join(', ') : '—';
|
|
15
|
+
return String(value);
|
|
16
|
+
}
|
|
17
|
+
const DocumentHistoryView = ({ data })=>{
|
|
18
|
+
const { t } = useTranslation('byline-admin');
|
|
19
|
+
const entries = data?.entries ?? [];
|
|
20
|
+
if (0 === entries.length) return /*#__PURE__*/ jsx(Section, {
|
|
21
|
+
children: /*#__PURE__*/ jsx(Container, {
|
|
22
|
+
children: /*#__PURE__*/ jsx("p", {
|
|
23
|
+
className: classnames('byline-coll-dochistory-empty', document_history_module.empty),
|
|
24
|
+
children: t('collections.documentHistory.empty')
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
});
|
|
28
|
+
return /*#__PURE__*/ jsx(Section, {
|
|
29
|
+
children: /*#__PURE__*/ jsx(Container, {
|
|
30
|
+
children: /*#__PURE__*/ jsx(Table.Container, {
|
|
31
|
+
className: classnames('byline-coll-dochistory-table-wrap', document_history_module.tableWrap),
|
|
32
|
+
children: /*#__PURE__*/ jsxs(Table, {
|
|
33
|
+
children: [
|
|
34
|
+
/*#__PURE__*/ jsx(Table.Header, {
|
|
35
|
+
children: /*#__PURE__*/ jsxs(Table.Row, {
|
|
36
|
+
children: [
|
|
37
|
+
/*#__PURE__*/ jsx(Table.HeadingCell, {
|
|
38
|
+
scope: "col",
|
|
39
|
+
children: t('collections.documentHistory.colWhen')
|
|
40
|
+
}),
|
|
41
|
+
/*#__PURE__*/ jsx(Table.HeadingCell, {
|
|
42
|
+
scope: "col",
|
|
43
|
+
children: t('collections.documentHistory.colAction')
|
|
44
|
+
}),
|
|
45
|
+
/*#__PURE__*/ jsx(Table.HeadingCell, {
|
|
46
|
+
scope: "col",
|
|
47
|
+
children: t('collections.documentHistory.colActor')
|
|
48
|
+
}),
|
|
49
|
+
/*#__PURE__*/ jsx(Table.HeadingCell, {
|
|
50
|
+
scope: "col",
|
|
51
|
+
children: t('collections.documentHistory.colChange')
|
|
52
|
+
})
|
|
53
|
+
]
|
|
54
|
+
})
|
|
55
|
+
}),
|
|
56
|
+
/*#__PURE__*/ jsx(Table.Body, {
|
|
57
|
+
children: entries.map((entry)=>{
|
|
58
|
+
const actionKey = ACTION_KEYS[entry.action];
|
|
59
|
+
const actionLabel = actionKey ? t(actionKey) : entry.action;
|
|
60
|
+
const actorLabel = null == entry.actorId || 'system' === entry.actorRealm ? t('collections.documentHistory.systemActor') : data.actors?.[entry.actorId]?.label ?? t('collections.history.audit.formerUser');
|
|
61
|
+
const hasChange = null != entry.before || null != entry.after;
|
|
62
|
+
return /*#__PURE__*/ jsxs(Table.Row, {
|
|
63
|
+
children: [
|
|
64
|
+
/*#__PURE__*/ jsx(Table.Cell, {
|
|
65
|
+
className: classnames('byline-coll-dochistory-when', document_history_module.when),
|
|
66
|
+
children: new Date(entry.occurredAt).toLocaleString()
|
|
67
|
+
}),
|
|
68
|
+
/*#__PURE__*/ jsx(Table.Cell, {
|
|
69
|
+
children: actionLabel
|
|
70
|
+
}),
|
|
71
|
+
/*#__PURE__*/ jsx(Table.Cell, {
|
|
72
|
+
children: actorLabel
|
|
73
|
+
}),
|
|
74
|
+
/*#__PURE__*/ jsx(Table.Cell, {
|
|
75
|
+
className: classnames('byline-coll-dochistory-change', document_history_module.change),
|
|
76
|
+
children: hasChange ? /*#__PURE__*/ jsxs(Fragment, {
|
|
77
|
+
children: [
|
|
78
|
+
/*#__PURE__*/ jsx("span", {
|
|
79
|
+
className: classnames('byline-coll-dochistory-before', document_history_module.before),
|
|
80
|
+
children: formatAuditValue(entry.before)
|
|
81
|
+
}),
|
|
82
|
+
/*#__PURE__*/ jsx("span", {
|
|
83
|
+
className: classnames('byline-coll-dochistory-arrow', document_history_module.arrow),
|
|
84
|
+
children: ' → '
|
|
85
|
+
}),
|
|
86
|
+
/*#__PURE__*/ jsx("span", {
|
|
87
|
+
className: classnames('byline-coll-dochistory-after', document_history_module.after),
|
|
88
|
+
children: formatAuditValue(entry.after)
|
|
89
|
+
})
|
|
90
|
+
]
|
|
91
|
+
}) : '—'
|
|
92
|
+
})
|
|
93
|
+
]
|
|
94
|
+
}, entry.id);
|
|
95
|
+
})
|
|
96
|
+
})
|
|
97
|
+
]
|
|
98
|
+
})
|
|
99
|
+
})
|
|
100
|
+
})
|
|
101
|
+
});
|
|
102
|
+
};
|
|
103
|
+
export { DocumentHistoryView };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
:is(.empty-qolSIa, .byline-coll-dochistory-empty) {
|
|
2
|
+
color: var(--gray-500);
|
|
3
|
+
margin: 1.5rem 0;
|
|
4
|
+
font-size: .875rem;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
:is(:is([data-theme="dark"], .dark) .empty-qolSIa, :is([data-theme="dark"], .dark) .byline-coll-dochistory-empty) {
|
|
8
|
+
color: var(--gray-400);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
:is(.tableWrap-Cil1ih, .byline-coll-dochistory-table-wrap) {
|
|
12
|
+
margin-top: .5rem;
|
|
13
|
+
margin-bottom: .75rem;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
:is(.when-biWgEw, .byline-coll-dochistory-when) {
|
|
17
|
+
white-space: nowrap;
|
|
18
|
+
font-variant-numeric: tabular-nums;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
:is(.change-xCTn7o, .byline-coll-dochistory-change) {
|
|
22
|
+
font-variant-numeric: tabular-nums;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
:is(.arrow-e1mpOz, .byline-coll-dochistory-arrow) {
|
|
26
|
+
color: var(--gray-400);
|
|
27
|
+
}
|
|
28
|
+
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
*/
|
|
8
8
|
import type { CollectionAdminConfig, CollectionDefinition, WorkflowStatus } from '@byline/core';
|
|
9
9
|
import type { AnyCollectionSchemaTypes } from '@byline/core/zod-schemas';
|
|
10
|
+
import { type DocumentHistoryData } from './document-history.js';
|
|
10
11
|
import type { ContentLocaleOption } from './view-menu.js';
|
|
11
|
-
export declare const HistoryView: ({ collectionDefinition, adminConfig, data, workflowStatuses, currentDocument, contentLocales, defaultContentLocale, }: {
|
|
12
|
+
export declare const HistoryView: ({ collectionDefinition, adminConfig, data, auditLog, workflowStatuses, currentDocument, contentLocales, defaultContentLocale, }: {
|
|
12
13
|
collectionDefinition: CollectionDefinition;
|
|
13
14
|
adminConfig?: CollectionAdminConfig;
|
|
14
15
|
data: AnyCollectionSchemaTypes["HistoryType"] & {
|
|
@@ -21,6 +22,12 @@ export declare const HistoryView: ({ collectionDefinition, adminConfig, data, wo
|
|
|
21
22
|
label: string;
|
|
22
23
|
}>;
|
|
23
24
|
};
|
|
25
|
+
/**
|
|
26
|
+
* Document-grain audit log for the "Document history" tab (docs/AUDIT.md —
|
|
27
|
+
* Workstream 3): the non-versioned path / available-locales / status
|
|
28
|
+
* changes and the deletion event, with admin-resolved actor labels.
|
|
29
|
+
*/
|
|
30
|
+
auditLog?: DocumentHistoryData;
|
|
24
31
|
workflowStatuses?: WorkflowStatus[];
|
|
25
32
|
currentDocument?: Record<string, unknown> | null;
|
|
26
33
|
contentLocales: ReadonlyArray<ContentLocaleOption>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { Fragment as external_react_Fragment, Suspense, lazy, useState } from "react";
|
|
3
3
|
import { useParams, useRouterState } from "@tanstack/react-router";
|
|
4
|
-
import { StatusBadge, renderFormatted } from "@byline/admin/react";
|
|
4
|
+
import { AdminTabs, StatusBadge, renderFormatted } from "@byline/admin/react";
|
|
5
5
|
import { useBylineAdminServices } from "@byline/admin/services";
|
|
6
6
|
import { useTranslation } from "@byline/i18n/react";
|
|
7
7
|
import { Button, CloseIcon, Container, IconButton, Modal, Section, Select, Table } from "@byline/ui/react";
|
|
@@ -10,6 +10,7 @@ import { Link, useNavigate } from "../chrome/loose-router.js";
|
|
|
10
10
|
import { RouterPager } from "../chrome/router-pager.js";
|
|
11
11
|
import { TableHeadingCellSortable } from "../chrome/th-sortable.js";
|
|
12
12
|
import { formatNumber } from "../chrome/utils.js";
|
|
13
|
+
import { DocumentHistoryView } from "./document-history.js";
|
|
13
14
|
import history_module from "./history.module.js";
|
|
14
15
|
import { RestoreVersionModal } from "./restore-version-modal.js";
|
|
15
16
|
import { ViewMenu } from "./view-menu.js";
|
|
@@ -50,7 +51,7 @@ const AUDIT_ACTION_KEYS = {
|
|
|
50
51
|
copy_to_locale: 'collections.history.audit.actionCopyToLocale',
|
|
51
52
|
delete_locale: 'collections.history.audit.actionDeleteLocale'
|
|
52
53
|
};
|
|
53
|
-
const HistoryView = ({ collectionDefinition, adminConfig, data, workflowStatuses, currentDocument, contentLocales, defaultContentLocale })=>{
|
|
54
|
+
const HistoryView = ({ collectionDefinition, adminConfig, data, auditLog, workflowStatuses, currentDocument, contentLocales, defaultContentLocale })=>{
|
|
54
55
|
const { id, collection } = useParams({
|
|
55
56
|
from: '/_byline/admin/collections/$collection/$id/history'
|
|
56
57
|
});
|
|
@@ -64,9 +65,24 @@ const HistoryView = ({ collectionDefinition, adminConfig, data, workflowStatuses
|
|
|
64
65
|
select: (s)=>s.location
|
|
65
66
|
});
|
|
66
67
|
const locale = location.search.locale;
|
|
68
|
+
const activeTab = 'document' === location.search.tab ? 'document' : 'versions';
|
|
67
69
|
const [selectedVersion, setSelectedVersion] = useState(null);
|
|
68
70
|
const [restoreTarget, setRestoreTarget] = useState(null);
|
|
69
71
|
const currentVersionId = currentDocument && 'string' == typeof currentDocument.versionId ? currentDocument.versionId : null;
|
|
72
|
+
function handleTabChange(name) {
|
|
73
|
+
const params = structuredClone(location.search);
|
|
74
|
+
delete params.page;
|
|
75
|
+
if ('document' === name) params.tab = 'document';
|
|
76
|
+
else delete params.tab;
|
|
77
|
+
navigate({
|
|
78
|
+
to: '/admin/collections/$collection/$id/history',
|
|
79
|
+
params: {
|
|
80
|
+
collection,
|
|
81
|
+
id
|
|
82
|
+
},
|
|
83
|
+
search: params
|
|
84
|
+
});
|
|
85
|
+
}
|
|
70
86
|
function handleOnPageSizeChange(value) {
|
|
71
87
|
if ('string' != typeof value || 0 === value.length) return;
|
|
72
88
|
const params = structuredClone(location.search);
|
|
@@ -84,35 +100,63 @@ const HistoryView = ({ collectionDefinition, adminConfig, data, workflowStatuses
|
|
|
84
100
|
return /*#__PURE__*/ jsxs(Fragment, {
|
|
85
101
|
children: [
|
|
86
102
|
/*#__PURE__*/ jsx(Section, {
|
|
87
|
-
children: /*#__PURE__*/
|
|
88
|
-
children:
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
103
|
+
children: /*#__PURE__*/ jsxs(Container, {
|
|
104
|
+
children: [
|
|
105
|
+
/*#__PURE__*/ jsxs("div", {
|
|
106
|
+
className: classnames('byline-coll-history-head', history_module.head),
|
|
107
|
+
children: [
|
|
108
|
+
/*#__PURE__*/ jsxs("h2", {
|
|
109
|
+
className: classnames('byline-coll-history-title', history_module.title),
|
|
110
|
+
children: [
|
|
111
|
+
t('collections.history.title', {
|
|
112
|
+
label: labels.singular
|
|
113
|
+
}),
|
|
114
|
+
' ',
|
|
115
|
+
/*#__PURE__*/ jsx(Stats, {
|
|
116
|
+
total: 'document' === activeTab ? auditLog?.meta.total ?? 0 : data?.meta.total
|
|
117
|
+
})
|
|
118
|
+
]
|
|
119
|
+
}),
|
|
120
|
+
/*#__PURE__*/ jsx(ViewMenu, {
|
|
121
|
+
collection: collection,
|
|
122
|
+
documentId: id,
|
|
123
|
+
activeView: "history",
|
|
124
|
+
locale: locale,
|
|
125
|
+
contentLocales: contentLocales,
|
|
126
|
+
defaultContentLocale: defaultContentLocale
|
|
127
|
+
})
|
|
128
|
+
]
|
|
129
|
+
}),
|
|
130
|
+
/*#__PURE__*/ jsx(AdminTabs, {
|
|
131
|
+
tabs: [
|
|
132
|
+
{
|
|
133
|
+
name: 'versions',
|
|
134
|
+
label: t('collections.history.tabs.versions')
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
name: 'document',
|
|
138
|
+
label: t('collections.history.tabs.document')
|
|
139
|
+
}
|
|
140
|
+
],
|
|
141
|
+
activeTab: activeTab,
|
|
142
|
+
onChange: handleTabChange,
|
|
143
|
+
className: classnames('byline-coll-history-tabs', history_module.tabs)
|
|
144
|
+
})
|
|
145
|
+
]
|
|
113
146
|
})
|
|
114
147
|
}),
|
|
115
|
-
/*#__PURE__*/ jsx(
|
|
148
|
+
'document' === activeTab && /*#__PURE__*/ jsx(DocumentHistoryView, {
|
|
149
|
+
data: auditLog ?? {
|
|
150
|
+
entries: [],
|
|
151
|
+
meta: {
|
|
152
|
+
total: 0,
|
|
153
|
+
page: 1,
|
|
154
|
+
pageSize: 0,
|
|
155
|
+
totalPages: 0
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}),
|
|
159
|
+
'document' !== activeTab && /*#__PURE__*/ jsx(Section, {
|
|
116
160
|
children: /*#__PURE__*/ jsxs(Container, {
|
|
117
161
|
children: [
|
|
118
162
|
/*#__PURE__*/ jsx("div", {
|
|
@@ -5,14 +5,19 @@ import { useTranslation } from "@byline/i18n/react";
|
|
|
5
5
|
import { z } from "zod";
|
|
6
6
|
import { BreadcrumbsClient } from "../admin-shell/chrome/breadcrumbs/breadcrumbs-client.js";
|
|
7
7
|
import { HistoryView } from "../admin-shell/collections/history.js";
|
|
8
|
-
import { getCollectionDocument, getCollectionDocumentHistory } from "../server-fns/collections/index.js";
|
|
8
|
+
import { getCollectionDocument, getCollectionDocumentAuditLog, getCollectionDocumentHistory } from "../server-fns/collections/index.js";
|
|
9
9
|
const searchSchema = z.object({
|
|
10
10
|
page: z.coerce.number().min(1).optional(),
|
|
11
11
|
page_size: z.coerce.number().max(100).optional(),
|
|
12
12
|
order: z.string().optional(),
|
|
13
13
|
desc: z.coerce.boolean().optional(),
|
|
14
|
-
locale: z.string().optional()
|
|
14
|
+
locale: z.string().optional(),
|
|
15
|
+
tab: z["enum"]([
|
|
16
|
+
'versions',
|
|
17
|
+
'document'
|
|
18
|
+
]).optional()
|
|
15
19
|
});
|
|
20
|
+
const AUDIT_LOG_PAGE_SIZE = 100;
|
|
16
21
|
function createCollectionHistoryRoute(path, opts) {
|
|
17
22
|
const Route = createFileRoute(path)({
|
|
18
23
|
validateSearch: searchSchema,
|
|
@@ -26,7 +31,7 @@ function createCollectionHistoryRoute(path, opts) {
|
|
|
26
31
|
loader: async ({ params, deps })=>{
|
|
27
32
|
const collectionDef = getCollectionDefinition(params.collection);
|
|
28
33
|
if (!collectionDef) throw notFound();
|
|
29
|
-
const [history, currentDocument] = await Promise.all([
|
|
34
|
+
const [history, currentDocument, auditLog] = await Promise.all([
|
|
30
35
|
getCollectionDocumentHistory({
|
|
31
36
|
data: {
|
|
32
37
|
collection: params.collection,
|
|
@@ -40,18 +45,29 @@ function createCollectionHistoryRoute(path, opts) {
|
|
|
40
45
|
}
|
|
41
46
|
}
|
|
42
47
|
}),
|
|
43
|
-
getCollectionDocument(params.collection, params.id, deps.locale ?? 'all')
|
|
48
|
+
getCollectionDocument(params.collection, params.id, deps.locale ?? 'all'),
|
|
49
|
+
getCollectionDocumentAuditLog({
|
|
50
|
+
data: {
|
|
51
|
+
collection: params.collection,
|
|
52
|
+
id: params.id,
|
|
53
|
+
params: {
|
|
54
|
+
page: 1,
|
|
55
|
+
page_size: AUDIT_LOG_PAGE_SIZE
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
})
|
|
44
59
|
]);
|
|
45
60
|
return {
|
|
46
61
|
history,
|
|
47
|
-
currentDocument
|
|
62
|
+
currentDocument,
|
|
63
|
+
auditLog
|
|
48
64
|
};
|
|
49
65
|
},
|
|
50
66
|
staleTime: 0,
|
|
51
67
|
gcTime: 0,
|
|
52
68
|
shouldReload: true,
|
|
53
69
|
component: function() {
|
|
54
|
-
const { history, currentDocument } = Route.useLoaderData();
|
|
70
|
+
const { history, currentDocument, auditLog } = Route.useLoaderData();
|
|
55
71
|
const { collection } = Route.useParams();
|
|
56
72
|
const collectionDef = getCollectionDefinition(collection);
|
|
57
73
|
const adminConfig = getCollectionAdminConfig(collection);
|
|
@@ -83,6 +99,7 @@ function createCollectionHistoryRoute(path, opts) {
|
|
|
83
99
|
workflowStatuses: getWorkflowStatuses(collectionDef),
|
|
84
100
|
adminConfig: adminConfig ?? void 0,
|
|
85
101
|
data: history,
|
|
102
|
+
auditLog: auditLog,
|
|
86
103
|
currentDocument: currentDocument,
|
|
87
104
|
contentLocales: opts.contentLocales,
|
|
88
105
|
defaultContentLocale: opts.defaultContentLocale
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const changeAccountPassword = createServerFn({
|
|
6
6
|
method: 'POST'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return changeAccountPasswordCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const getAccount = createServerFn({
|
|
6
6
|
method: 'GET'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input ?? {}).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return getAccountCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const updateAccount = createServerFn({
|
|
6
6
|
method: 'POST'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return updateAccountCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const getRoleAbilities = createServerFn({
|
|
6
6
|
method: 'GET'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return getRoleAbilitiesCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore,
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const setRoleAbilities = createServerFn({
|
|
6
6
|
method: 'POST'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return setRoleAbilitiesCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore,
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const whoHasAbility = createServerFn({
|
|
6
6
|
method: 'GET'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return whoHasAbilityCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore,
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const createAdminRole = createServerFn({
|
|
6
6
|
method: 'POST'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return createAdminRoleCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const deleteAdminRole = createServerFn({
|
|
6
6
|
method: 'POST'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return deleteAdminRoleCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const getAdminRole = createServerFn({
|
|
6
6
|
method: 'GET'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return getAdminRoleCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const reorderAdminRoles = createServerFn({
|
|
6
6
|
method: 'POST'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return reorderAdminRolesCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const updateAdminRole = createServerFn({
|
|
6
6
|
method: 'POST'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return updateAdminRoleCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const createAdminUser = createServerFn({
|
|
6
6
|
method: 'POST'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return createAdminUserCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const deleteAdminUser = createServerFn({
|
|
6
6
|
method: 'POST'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return deleteAdminUserCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const disableAdminUser = createServerFn({
|
|
6
6
|
method: 'POST'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return disableAdminUserCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const enableAdminUser = createServerFn({
|
|
6
6
|
method: 'POST'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return enableAdminUserCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const getUserRoles = createServerFn({
|
|
6
6
|
method: 'GET'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return getRolesForUserCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const getAdminUser = createServerFn({
|
|
6
6
|
method: 'GET'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return getAdminUserCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|
|
@@ -4,7 +4,7 @@ import { getAdminRequestContext } from "../../auth/auth-context.js";
|
|
|
4
4
|
import { bylineCore } from "../../integrations/byline-core.js";
|
|
5
5
|
const listAdminUsers = createServerFn({
|
|
6
6
|
method: 'GET'
|
|
7
|
-
}).
|
|
7
|
+
}).validator((input)=>input ?? {}).handler(async ({ data })=>{
|
|
8
8
|
const context = await getAdminRequestContext();
|
|
9
9
|
return listAdminUsersCommand(context, data, {
|
|
10
10
|
store: bylineCore().adminStore
|