@strapi/admin 5.52.3 → 5.53.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/admin/src/translations/en.json.js +18 -0
- package/dist/admin/admin/src/translations/en.json.js.map +1 -1
- package/dist/admin/admin/src/translations/en.json.mjs +18 -0
- package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.js +118 -43
- package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.mjs +118 -45
- package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
- package/dist/admin/ee/admin/src/constants.js +6 -0
- package/dist/admin/ee/admin/src/constants.js.map +1 -1
- package/dist/admin/ee/admin/src/constants.mjs +6 -0
- package/dist/admin/ee/admin/src/constants.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js +31 -3
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs +33 -5
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/ListPage.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.js +177 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.js.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.mjs +175 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.mjs.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js +173 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs +151 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +10 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs +10 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
- package/dist/admin/index.js +2 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/shared/utils/audit-log-export.js +16 -0
- package/dist/admin/shared/utils/audit-log-export.js.map +1 -0
- package/dist/admin/shared/utils/audit-log-export.mjs +9 -0
- package/dist/admin/shared/utils/audit-log-export.mjs.map +1 -0
- package/dist/admin/src/utils/getFetchClient.d.ts +9 -2
- package/dist/admin/tests/store.d.ts +4 -0
- package/dist/admin/tests/utils.d.ts +4 -0
- package/dist/ee/admin/src/constants.d.ts +4 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.d.ts +10 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.d.ts +18 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +9 -0
- package/dist/ee/server/src/audit-logs/controllers/audit-logs.d.ts +1 -0
- package/dist/ee/server/src/audit-logs/controllers/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/routes/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/services/audit-logs.d.ts +24 -3
- package/dist/ee/server/src/audit-logs/services/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +8 -2
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
- package/dist/ee/server/src/audit-logs/utils/csv.d.ts +5 -0
- package/dist/ee/server/src/audit-logs/utils/csv.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/utils/export-token.d.ts +5 -0
- package/dist/ee/server/src/audit-logs/utils/export-token.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/utils.d.ts +10 -0
- package/dist/ee/server/src/audit-logs/utils.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/validation/audit-logs.d.ts +2 -0
- package/dist/ee/server/src/audit-logs/validation/audit-logs.d.ts.map +1 -1
- package/dist/ee/server/src/config/admin-actions.d.ts.map +1 -1
- package/dist/ee/server/src/index.d.ts +1 -0
- package/dist/ee/server/src/index.d.ts.map +1 -1
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.js +50 -0
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.mjs +51 -1
- package/dist/server/ee/server/src/audit-logs/controllers/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.js +13 -4
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.mjs +13 -4
- package/dist/server/ee/server/src/audit-logs/routes/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.js +201 -7
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.mjs +201 -8
- package/dist/server/ee/server/src/audit-logs/services/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +119 -34
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs +119 -34
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
- package/dist/server/ee/server/src/audit-logs/utils/csv.js +33 -0
- package/dist/server/ee/server/src/audit-logs/utils/csv.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils/csv.mjs +29 -0
- package/dist/server/ee/server/src/audit-logs/utils/csv.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.js +33 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.mjs +29 -0
- package/dist/server/ee/server/src/audit-logs/utils/export-token.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils.js +14 -0
- package/dist/server/ee/server/src/audit-logs/utils.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/utils.mjs +12 -0
- package/dist/server/ee/server/src/audit-logs/utils.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.js +11 -0
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.js.map +1 -1
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.mjs +11 -1
- package/dist/server/ee/server/src/audit-logs/validation/audit-logs.mjs.map +1 -1
- package/dist/server/ee/server/src/config/admin-actions.js +8 -0
- package/dist/server/ee/server/src/config/admin-actions.js.map +1 -1
- package/dist/server/ee/server/src/config/admin-actions.mjs +8 -0
- package/dist/server/ee/server/src/config/admin-actions.mjs.map +1 -1
- package/dist/server/ee/server/src/index.js +10 -0
- package/dist/server/ee/server/src/index.js.map +1 -1
- package/dist/server/ee/server/src/index.mjs +10 -0
- package/dist/server/ee/server/src/index.mjs.map +1 -1
- package/dist/server/shared/utils/audit-log-export.js +22 -0
- package/dist/server/shared/utils/audit-log-export.js.map +1 -0
- package/dist/server/shared/utils/audit-log-export.mjs +12 -0
- package/dist/server/shared/utils/audit-log-export.mjs.map +1 -0
- package/dist/shared/contracts/audit-logs.d.ts +15 -1
- package/dist/shared/contracts/audit-logs.d.ts.map +1 -1
- package/dist/shared/utils/audit-log-export.d.ts +9 -0
- package/dist/shared/utils/audit-log-export.d.ts.map +1 -0
- package/package.json +7 -7
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { Portal, Box, Flex, Typography, Button, Dialog, ProgressBar } from '@strapi/design-system';
|
|
3
|
+
import { CheckCircle, Download, WarningCircle } from '@strapi/icons';
|
|
4
|
+
import { useIntl } from 'react-intl';
|
|
5
|
+
import { useBlocker } from 'react-router-dom';
|
|
6
|
+
import { styled } from 'styled-components';
|
|
7
|
+
import { useWarnIfUnsavedChanges } from '../../../../../../../../admin/src/hooks/useWarnIfUnsavedChanges.mjs';
|
|
8
|
+
|
|
9
|
+
const ExportProgressBar = styled(ProgressBar)`
|
|
10
|
+
width: 100%;
|
|
11
|
+
background-color: ${({ theme })=>theme.colors.neutral150};
|
|
12
|
+
|
|
13
|
+
> div {
|
|
14
|
+
background-color: ${({ theme })=>theme.colors.primary600};
|
|
15
|
+
}
|
|
16
|
+
`;
|
|
17
|
+
const ExportCard = ({ progress, exportResult, onDownload, onDismiss })=>{
|
|
18
|
+
const { formatMessage } = useIntl();
|
|
19
|
+
const isExportPending = Boolean(progress || exportResult);
|
|
20
|
+
useWarnIfUnsavedChanges(isExportPending);
|
|
21
|
+
const blocker = useBlocker(({ currentLocation, nextLocation })=>isExportPending && currentLocation.pathname !== nextLocation.pathname);
|
|
22
|
+
if (!progress && !exportResult) {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
const progressCaption = progress ? formatMessage({
|
|
26
|
+
id: 'Settings.permissions.auditLogs.listview.export.progress.caption',
|
|
27
|
+
defaultMessage: 'Preparing your export - {fetched, number} out of {total, plural, one {# event} other {# events}}'
|
|
28
|
+
}, {
|
|
29
|
+
fetched: progress.fetched,
|
|
30
|
+
total: progress.total
|
|
31
|
+
}) : null;
|
|
32
|
+
return /*#__PURE__*/ jsxs(Portal, {
|
|
33
|
+
children: [
|
|
34
|
+
/*#__PURE__*/ jsx(Box, {
|
|
35
|
+
position: "fixed",
|
|
36
|
+
bottom: 4,
|
|
37
|
+
right: 4,
|
|
38
|
+
zIndex: 200,
|
|
39
|
+
width: "32rem",
|
|
40
|
+
role: "status",
|
|
41
|
+
children: /*#__PURE__*/ jsx(Flex, {
|
|
42
|
+
direction: "column",
|
|
43
|
+
alignItems: "stretch",
|
|
44
|
+
gap: 2,
|
|
45
|
+
padding: 4,
|
|
46
|
+
hasRadius: true,
|
|
47
|
+
background: "neutral0",
|
|
48
|
+
borderColor: "neutral150",
|
|
49
|
+
shadow: "popupShadow",
|
|
50
|
+
children: progress ? /*#__PURE__*/ jsxs(Fragment, {
|
|
51
|
+
children: [
|
|
52
|
+
/*#__PURE__*/ jsx(Typography, {
|
|
53
|
+
fontWeight: "bold",
|
|
54
|
+
children: formatMessage({
|
|
55
|
+
id: 'Settings.permissions.auditLogs.listview.export.progress.title',
|
|
56
|
+
defaultMessage: 'Exporting audit logs'
|
|
57
|
+
})
|
|
58
|
+
}),
|
|
59
|
+
/*#__PURE__*/ jsx(ExportProgressBar, {
|
|
60
|
+
size: "S",
|
|
61
|
+
value: progress.total > 0 ? Math.round(progress.fetched / progress.total * 100) : 0,
|
|
62
|
+
"aria-label": progressCaption ?? undefined
|
|
63
|
+
}),
|
|
64
|
+
/*#__PURE__*/ jsx(Typography, {
|
|
65
|
+
variant: "pi",
|
|
66
|
+
textColor: "neutral600",
|
|
67
|
+
children: progressCaption
|
|
68
|
+
})
|
|
69
|
+
]
|
|
70
|
+
}) : exportResult && /*#__PURE__*/ jsxs(Fragment, {
|
|
71
|
+
children: [
|
|
72
|
+
/*#__PURE__*/ jsxs(Flex, {
|
|
73
|
+
gap: 2,
|
|
74
|
+
children: [
|
|
75
|
+
/*#__PURE__*/ jsx(CheckCircle, {
|
|
76
|
+
fill: "success500"
|
|
77
|
+
}),
|
|
78
|
+
/*#__PURE__*/ jsx(Typography, {
|
|
79
|
+
fontWeight: "bold",
|
|
80
|
+
children: formatMessage({
|
|
81
|
+
id: 'Settings.permissions.auditLogs.listview.export.ready.title',
|
|
82
|
+
defaultMessage: 'Export ready'
|
|
83
|
+
})
|
|
84
|
+
})
|
|
85
|
+
]
|
|
86
|
+
}),
|
|
87
|
+
/*#__PURE__*/ jsx(Typography, {
|
|
88
|
+
variant: "pi",
|
|
89
|
+
textColor: "neutral600",
|
|
90
|
+
children: exportResult.fileName
|
|
91
|
+
}),
|
|
92
|
+
/*#__PURE__*/ jsxs(Flex, {
|
|
93
|
+
gap: 2,
|
|
94
|
+
children: [
|
|
95
|
+
/*#__PURE__*/ jsx(Button, {
|
|
96
|
+
startIcon: /*#__PURE__*/ jsx(Download, {}),
|
|
97
|
+
onClick: onDownload,
|
|
98
|
+
children: formatMessage({
|
|
99
|
+
id: 'Settings.permissions.auditLogs.listview.export.ready.download',
|
|
100
|
+
defaultMessage: 'Download CSV'
|
|
101
|
+
})
|
|
102
|
+
}),
|
|
103
|
+
/*#__PURE__*/ jsx(Button, {
|
|
104
|
+
variant: "tertiary",
|
|
105
|
+
onClick: onDismiss,
|
|
106
|
+
children: formatMessage({
|
|
107
|
+
id: 'app.components.Button.cancel',
|
|
108
|
+
defaultMessage: 'Cancel'
|
|
109
|
+
})
|
|
110
|
+
})
|
|
111
|
+
]
|
|
112
|
+
})
|
|
113
|
+
]
|
|
114
|
+
})
|
|
115
|
+
})
|
|
116
|
+
}),
|
|
117
|
+
blocker.state === 'blocked' && /*#__PURE__*/ jsx(Dialog.Root, {
|
|
118
|
+
open: true,
|
|
119
|
+
onOpenChange: (isOpen)=>{
|
|
120
|
+
if (!isOpen) {
|
|
121
|
+
blocker.reset();
|
|
122
|
+
}
|
|
123
|
+
},
|
|
124
|
+
children: /*#__PURE__*/ jsxs(Dialog.Content, {
|
|
125
|
+
children: [
|
|
126
|
+
/*#__PURE__*/ jsx(Dialog.Header, {
|
|
127
|
+
children: formatMessage({
|
|
128
|
+
id: 'app.components.ConfirmDialog.title',
|
|
129
|
+
defaultMessage: 'Confirmation'
|
|
130
|
+
})
|
|
131
|
+
}),
|
|
132
|
+
/*#__PURE__*/ jsx(Dialog.Body, {
|
|
133
|
+
icon: /*#__PURE__*/ jsx(WarningCircle, {
|
|
134
|
+
width: "24px",
|
|
135
|
+
height: "24px",
|
|
136
|
+
fill: "danger600"
|
|
137
|
+
}),
|
|
138
|
+
textAlign: "center",
|
|
139
|
+
children: formatMessage({
|
|
140
|
+
id: 'Settings.permissions.auditLogs.listview.export.leave',
|
|
141
|
+
defaultMessage: 'Are you sure you want to leave? Your ongoing export will be canceled.'
|
|
142
|
+
})
|
|
143
|
+
}),
|
|
144
|
+
/*#__PURE__*/ jsxs(Dialog.Footer, {
|
|
145
|
+
children: [
|
|
146
|
+
/*#__PURE__*/ jsx(Dialog.Cancel, {
|
|
147
|
+
children: /*#__PURE__*/ jsx(Button, {
|
|
148
|
+
variant: "tertiary",
|
|
149
|
+
fullWidth: true,
|
|
150
|
+
children: formatMessage({
|
|
151
|
+
id: 'app.components.Button.cancel',
|
|
152
|
+
defaultMessage: 'Cancel'
|
|
153
|
+
})
|
|
154
|
+
})
|
|
155
|
+
}),
|
|
156
|
+
/*#__PURE__*/ jsx(Button, {
|
|
157
|
+
onClick: ()=>blocker.proceed(),
|
|
158
|
+
variant: "danger-light",
|
|
159
|
+
fullWidth: true,
|
|
160
|
+
children: formatMessage({
|
|
161
|
+
id: 'app.components.Button.confirm',
|
|
162
|
+
defaultMessage: 'Confirm'
|
|
163
|
+
})
|
|
164
|
+
})
|
|
165
|
+
]
|
|
166
|
+
})
|
|
167
|
+
]
|
|
168
|
+
})
|
|
169
|
+
})
|
|
170
|
+
]
|
|
171
|
+
});
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
export { ExportCard };
|
|
175
|
+
//# sourceMappingURL=ExportCard.mjs.map
|
package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ExportCard.mjs","sources":["../../../../../../../../../../ee/admin/src/pages/SettingsPage/pages/AuditLogs/components/ExportCard.tsx"],"sourcesContent":["import { Box, Button, Dialog, Flex, Portal, ProgressBar, Typography } from '@strapi/design-system';\nimport { CheckCircle, Download, WarningCircle } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\nimport { useBlocker } from 'react-router-dom';\nimport { styled } from 'styled-components';\n\nimport { useWarnIfUnsavedChanges } from '../../../../../../../../admin/src/hooks/useWarnIfUnsavedChanges';\n\nimport type { ExportProgress, ExportResult } from '../hooks/useExportAuditLogs';\n\nconst ExportProgressBar = styled(ProgressBar)`\n width: 100%;\n background-color: ${({ theme }) => theme.colors.neutral150};\n\n > div {\n background-color: ${({ theme }) => theme.colors.primary600};\n }\n`;\n\ninterface ExportCardProps {\n progress: ExportProgress | null;\n exportResult: ExportResult | null;\n onDownload: () => void;\n onDismiss: () => void;\n}\n\nconst ExportCard = ({ progress, exportResult, onDownload, onDismiss }: ExportCardProps) => {\n const { formatMessage } = useIntl();\n\n const isExportPending = Boolean(progress || exportResult);\n\n useWarnIfUnsavedChanges(isExportPending);\n\n const blocker = useBlocker(\n ({ currentLocation, nextLocation }) =>\n isExportPending && currentLocation.pathname !== nextLocation.pathname\n );\n\n if (!progress && !exportResult) {\n return null;\n }\n\n const progressCaption = progress\n ? formatMessage(\n {\n id: 'Settings.permissions.auditLogs.listview.export.progress.caption',\n defaultMessage:\n 'Preparing your export - {fetched, number} out of {total, plural, one {# event} other {# events}}',\n },\n { fetched: progress.fetched, total: progress.total }\n )\n : null;\n\n return (\n <Portal>\n <Box position=\"fixed\" bottom={4} right={4} zIndex={200} width=\"32rem\" role=\"status\">\n <Flex\n direction=\"column\"\n alignItems=\"stretch\"\n gap={2}\n padding={4}\n hasRadius\n background=\"neutral0\"\n borderColor=\"neutral150\"\n shadow=\"popupShadow\"\n >\n {progress ? (\n <>\n <Typography fontWeight=\"bold\">\n {formatMessage({\n id: 'Settings.permissions.auditLogs.listview.export.progress.title',\n defaultMessage: 'Exporting audit logs',\n })}\n </Typography>\n <ExportProgressBar\n size=\"S\"\n value={\n progress.total > 0 ? Math.round((progress.fetched / progress.total) * 100) : 0\n }\n aria-label={progressCaption ?? undefined}\n />\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {progressCaption}\n </Typography>\n </>\n ) : (\n exportResult && (\n <>\n <Flex gap={2}>\n <CheckCircle fill=\"success500\" />\n <Typography fontWeight=\"bold\">\n {formatMessage({\n id: 'Settings.permissions.auditLogs.listview.export.ready.title',\n defaultMessage: 'Export ready',\n })}\n </Typography>\n </Flex>\n <Typography variant=\"pi\" textColor=\"neutral600\">\n {exportResult.fileName}\n </Typography>\n <Flex gap={2}>\n <Button startIcon={<Download />} onClick={onDownload}>\n {formatMessage({\n id: 'Settings.permissions.auditLogs.listview.export.ready.download',\n defaultMessage: 'Download CSV',\n })}\n </Button>\n <Button variant=\"tertiary\" onClick={onDismiss}>\n {formatMessage({\n id: 'app.components.Button.cancel',\n defaultMessage: 'Cancel',\n })}\n </Button>\n </Flex>\n </>\n )\n )}\n </Flex>\n </Box>\n {blocker.state === 'blocked' && (\n <Dialog.Root\n open\n onOpenChange={(isOpen) => {\n if (!isOpen) {\n blocker.reset();\n }\n }}\n >\n <Dialog.Content>\n <Dialog.Header>\n {formatMessage({\n id: 'app.components.ConfirmDialog.title',\n defaultMessage: 'Confirmation',\n })}\n </Dialog.Header>\n <Dialog.Body\n icon={<WarningCircle width=\"24px\" height=\"24px\" fill=\"danger600\" />}\n textAlign=\"center\"\n >\n {formatMessage({\n id: 'Settings.permissions.auditLogs.listview.export.leave',\n defaultMessage:\n 'Are you sure you want to leave? Your ongoing export will be canceled.',\n })}\n </Dialog.Body>\n <Dialog.Footer>\n <Dialog.Cancel>\n <Button variant=\"tertiary\" fullWidth>\n {formatMessage({\n id: 'app.components.Button.cancel',\n defaultMessage: 'Cancel',\n })}\n </Button>\n </Dialog.Cancel>\n <Button onClick={() => blocker.proceed()} variant=\"danger-light\" fullWidth>\n {formatMessage({\n id: 'app.components.Button.confirm',\n defaultMessage: 'Confirm',\n })}\n </Button>\n </Dialog.Footer>\n </Dialog.Content>\n </Dialog.Root>\n )}\n </Portal>\n );\n};\n\nexport { ExportCard };\nexport type { ExportCardProps };\n"],"names":["ExportProgressBar","styled","ProgressBar","theme","colors","neutral150","primary600","ExportCard","progress","exportResult","onDownload","onDismiss","formatMessage","useIntl","isExportPending","Boolean","useWarnIfUnsavedChanges","blocker","useBlocker","currentLocation","nextLocation","pathname","progressCaption","id","defaultMessage","fetched","total","_jsxs","Portal","_jsx","Box","position","bottom","right","zIndex","width","role","Flex","direction","alignItems","gap","padding","hasRadius","background","borderColor","shadow","_Fragment","Typography","fontWeight","size","value","Math","round","aria-label","undefined","variant","textColor","CheckCircle","fill","fileName","Button","startIcon","Download","onClick","state","Dialog","Root","open","onOpenChange","isOpen","reset","Content","Header","Body","icon","WarningCircle","height","textAlign","Footer","Cancel","fullWidth","proceed"],"mappings":"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"}
|
package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var React = require('react');
|
|
4
|
+
var reactIntl = require('react-intl');
|
|
5
|
+
var Notifications = require('../../../../../../../../admin/src/features/Notifications.js');
|
|
6
|
+
var getFetchClient = require('../../../../../../../../admin/src/utils/getFetchClient.js');
|
|
7
|
+
var auditLogExport = require('../../../../../../../../shared/utils/audit-log-export.js');
|
|
8
|
+
|
|
9
|
+
function _interopNamespace(e) {
|
|
10
|
+
if (e && e.__esModule) return e;
|
|
11
|
+
var n = Object.create(null);
|
|
12
|
+
if (e) {
|
|
13
|
+
Object.keys(e).forEach(function (k) {
|
|
14
|
+
if (k !== 'default') {
|
|
15
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
16
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
17
|
+
enumerable: true,
|
|
18
|
+
get: function () { return e[k]; }
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
n.default = e;
|
|
24
|
+
return Object.freeze(n);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
28
|
+
|
|
29
|
+
const DEFAULT_FILE_NAME = 'audit-logs.csv';
|
|
30
|
+
const getFileName = (contentDisposition)=>{
|
|
31
|
+
const match = contentDisposition?.match(/filename="([^"]+)"/);
|
|
32
|
+
return match?.[1] ?? DEFAULT_FILE_NAME;
|
|
33
|
+
};
|
|
34
|
+
const downloadFile = (blob, fileName)=>{
|
|
35
|
+
const url = URL.createObjectURL(blob);
|
|
36
|
+
const link = document.createElement('a');
|
|
37
|
+
link.href = url;
|
|
38
|
+
link.download = fileName;
|
|
39
|
+
document.body.appendChild(link);
|
|
40
|
+
link.click();
|
|
41
|
+
link.remove();
|
|
42
|
+
// Revoking during a later tick to avoid aborting the download
|
|
43
|
+
setTimeout(()=>URL.revokeObjectURL(url), 60000);
|
|
44
|
+
};
|
|
45
|
+
const useExportAuditLogs = ()=>{
|
|
46
|
+
const [isExporting, setIsExporting] = React__namespace.useState(false);
|
|
47
|
+
const [progress, setProgress] = React__namespace.useState(null);
|
|
48
|
+
const [exportResult, setExportResult] = React__namespace.useState(null);
|
|
49
|
+
const { toggleNotification } = Notifications.useNotification();
|
|
50
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
51
|
+
const isExportingRef = React__namespace.useRef(false);
|
|
52
|
+
const isMountedRef = React__namespace.useRef(true);
|
|
53
|
+
React__namespace.useEffect(()=>{
|
|
54
|
+
isMountedRef.current = true;
|
|
55
|
+
return ()=>{
|
|
56
|
+
isMountedRef.current = false;
|
|
57
|
+
};
|
|
58
|
+
}, []);
|
|
59
|
+
const exportAuditLogs = async (filters, totalEntries)=>{
|
|
60
|
+
if (isExportingRef.current) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
isExportingRef.current = true;
|
|
64
|
+
setIsExporting(true);
|
|
65
|
+
setExportResult(null);
|
|
66
|
+
setProgress({
|
|
67
|
+
fetched: 0,
|
|
68
|
+
total: totalEntries
|
|
69
|
+
});
|
|
70
|
+
const { get } = getFetchClient.getFetchClient();
|
|
71
|
+
let cursor = null;
|
|
72
|
+
let until = null;
|
|
73
|
+
let token = null;
|
|
74
|
+
let fileName = DEFAULT_FILE_NAME;
|
|
75
|
+
const parts = [];
|
|
76
|
+
try {
|
|
77
|
+
do {
|
|
78
|
+
const { data, headers } = await get('/admin/audit-logs/export', {
|
|
79
|
+
params: {
|
|
80
|
+
...filters ? {
|
|
81
|
+
filters
|
|
82
|
+
} : {},
|
|
83
|
+
...cursor ? {
|
|
84
|
+
cursor
|
|
85
|
+
} : {},
|
|
86
|
+
...until ? {
|
|
87
|
+
until
|
|
88
|
+
} : {},
|
|
89
|
+
...token ? {
|
|
90
|
+
token
|
|
91
|
+
} : {}
|
|
92
|
+
},
|
|
93
|
+
responseType: 'blob'
|
|
94
|
+
});
|
|
95
|
+
if (!isMountedRef.current) {
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const nextCursorHeader = headers?.get(auditLogExport.AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER) ?? null;
|
|
99
|
+
const untilHeader = headers?.get(auditLogExport.AUDIT_LOGS_EXPORT_UNTIL_HEADER) ?? null;
|
|
100
|
+
const tokenHeader = headers?.get(auditLogExport.AUDIT_LOGS_EXPORT_TOKEN_HEADER) ?? null;
|
|
101
|
+
if (!nextCursorHeader || !untilHeader || !tokenHeader) {
|
|
102
|
+
throw new Error('The audit logs export part headers are missing');
|
|
103
|
+
}
|
|
104
|
+
cursor = nextCursorHeader === auditLogExport.AUDIT_LOGS_EXPORT_CURSOR_DONE ? null : nextCursorHeader;
|
|
105
|
+
until = untilHeader;
|
|
106
|
+
token = tokenHeader;
|
|
107
|
+
if (parts.length === 0) {
|
|
108
|
+
fileName = getFileName(headers?.get('Content-Disposition') ?? null);
|
|
109
|
+
}
|
|
110
|
+
parts.push(data);
|
|
111
|
+
const partRows = Number(headers?.get(auditLogExport.AUDIT_LOGS_EXPORT_PART_SIZE_HEADER)) || auditLogExport.AUDIT_LOGS_EXPORT_PART_ROWS;
|
|
112
|
+
setProgress({
|
|
113
|
+
fetched: Math.min(parts.length * partRows, totalEntries),
|
|
114
|
+
total: totalEntries
|
|
115
|
+
});
|
|
116
|
+
}while (cursor)
|
|
117
|
+
setExportResult({
|
|
118
|
+
blob: new Blob(parts, {
|
|
119
|
+
type: 'text/csv;charset=utf-8'
|
|
120
|
+
}),
|
|
121
|
+
fileName
|
|
122
|
+
});
|
|
123
|
+
} catch (error) {
|
|
124
|
+
const message = ()=>{
|
|
125
|
+
if (getFetchClient.isFetchError(error) && error.status === 413) {
|
|
126
|
+
return formatMessage({
|
|
127
|
+
id: 'Settings.permissions.auditLogs.listview.export.error.tooLarge',
|
|
128
|
+
defaultMessage: 'Table too large to export. Please add filters and try again.'
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
if (getFetchClient.isFetchError(error) && error.status === 403) {
|
|
132
|
+
return formatMessage({
|
|
133
|
+
id: 'Settings.permissions.auditLogs.listview.export.error.forbidden',
|
|
134
|
+
defaultMessage: "You don't have the permissions to export audit logs."
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
return formatMessage({
|
|
138
|
+
id: 'Settings.permissions.auditLogs.listview.export.error',
|
|
139
|
+
defaultMessage: 'The export failed. Please try again.'
|
|
140
|
+
});
|
|
141
|
+
};
|
|
142
|
+
toggleNotification({
|
|
143
|
+
type: 'danger',
|
|
144
|
+
message: message()
|
|
145
|
+
});
|
|
146
|
+
} finally{
|
|
147
|
+
isExportingRef.current = false;
|
|
148
|
+
setIsExporting(false);
|
|
149
|
+
setProgress(null);
|
|
150
|
+
}
|
|
151
|
+
};
|
|
152
|
+
const downloadExport = ()=>{
|
|
153
|
+
if (!exportResult) {
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
downloadFile(exportResult.blob, exportResult.fileName);
|
|
157
|
+
setExportResult(null);
|
|
158
|
+
};
|
|
159
|
+
const dismissExport = ()=>{
|
|
160
|
+
setExportResult(null);
|
|
161
|
+
};
|
|
162
|
+
return {
|
|
163
|
+
exportAuditLogs,
|
|
164
|
+
downloadExport,
|
|
165
|
+
dismissExport,
|
|
166
|
+
isExporting,
|
|
167
|
+
progress,
|
|
168
|
+
exportResult
|
|
169
|
+
};
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
exports.useExportAuditLogs = useExportAuditLogs;
|
|
173
|
+
//# sourceMappingURL=useExportAuditLogs.js.map
|
package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useExportAuditLogs.js","sources":["../../../../../../../../../../ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { useNotification } from '../../../../../../../../admin/src/features/Notifications';\nimport {\n getFetchClient,\n isFetchError,\n type FetchResponse,\n} from '../../../../../../../../admin/src/utils/getFetchClient';\nimport {\n AUDIT_LOGS_EXPORT_CURSOR_DONE,\n AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER,\n AUDIT_LOGS_EXPORT_PART_ROWS,\n AUDIT_LOGS_EXPORT_PART_SIZE_HEADER,\n AUDIT_LOGS_EXPORT_TOKEN_HEADER,\n AUDIT_LOGS_EXPORT_UNTIL_HEADER,\n} from '../../../../../../../../shared/utils/audit-log-export';\n\nconst DEFAULT_FILE_NAME = 'audit-logs.csv';\n\ninterface ExportProgress {\n fetched: number;\n total: number;\n}\n\ninterface ExportResult {\n blob: Blob;\n fileName: string;\n}\n\nconst getFileName = (contentDisposition: string | null) => {\n const match = contentDisposition?.match(/filename=\"([^\"]+)\"/);\n\n return match?.[1] ?? DEFAULT_FILE_NAME;\n};\n\nconst downloadFile = (blob: Blob, fileName: string) => {\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = fileName;\n document.body.appendChild(link);\n link.click();\n link.remove();\n\n // Revoking during a later tick to avoid aborting the download\n setTimeout(() => URL.revokeObjectURL(url), 60000);\n};\n\nconst useExportAuditLogs = () => {\n const [isExporting, setIsExporting] = React.useState(false);\n const [progress, setProgress] = React.useState<ExportProgress | null>(null);\n const [exportResult, setExportResult] = React.useState<ExportResult | null>(null);\n const { toggleNotification } = useNotification();\n const { formatMessage } = useIntl();\n\n const isExportingRef = React.useRef(false);\n\n const isMountedRef = React.useRef(true);\n React.useEffect(() => {\n isMountedRef.current = true;\n\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n const exportAuditLogs = async (filters: unknown, totalEntries: number) => {\n if (isExportingRef.current) {\n return;\n }\n\n isExportingRef.current = true;\n setIsExporting(true);\n setExportResult(null);\n setProgress({ fetched: 0, total: totalEntries });\n\n const { get } = getFetchClient();\n\n let cursor: string | null = null;\n let until: string | null = null;\n let token: string | null = null;\n let fileName = DEFAULT_FILE_NAME;\n const parts: Blob[] = [];\n\n try {\n do {\n const { data, headers }: FetchResponse<Blob> = await get<Blob>('/admin/audit-logs/export', {\n params: {\n ...(filters ? { filters } : {}),\n ...(cursor ? { cursor } : {}),\n ...(until ? { until } : {}),\n ...(token ? { token } : {}),\n },\n responseType: 'blob',\n });\n\n if (!isMountedRef.current) {\n return;\n }\n\n const nextCursorHeader: string | null =\n headers?.get(AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER) ?? null;\n const untilHeader: string | null = headers?.get(AUDIT_LOGS_EXPORT_UNTIL_HEADER) ?? null;\n const tokenHeader: string | null = headers?.get(AUDIT_LOGS_EXPORT_TOKEN_HEADER) ?? null;\n\n if (!nextCursorHeader || !untilHeader || !tokenHeader) {\n throw new Error('The audit logs export part headers are missing');\n }\n\n cursor = nextCursorHeader === AUDIT_LOGS_EXPORT_CURSOR_DONE ? null : nextCursorHeader;\n until = untilHeader;\n token = tokenHeader;\n\n if (parts.length === 0) {\n fileName = getFileName(headers?.get('Content-Disposition') ?? null);\n }\n\n parts.push(data);\n\n const partRows =\n Number(headers?.get(AUDIT_LOGS_EXPORT_PART_SIZE_HEADER)) || AUDIT_LOGS_EXPORT_PART_ROWS;\n setProgress({\n fetched: Math.min(parts.length * partRows, totalEntries),\n total: totalEntries,\n });\n } while (cursor);\n\n setExportResult({ blob: new Blob(parts, { type: 'text/csv;charset=utf-8' }), fileName });\n } catch (error) {\n const message = () => {\n if (isFetchError(error) && error.status === 413) {\n return formatMessage({\n id: 'Settings.permissions.auditLogs.listview.export.error.tooLarge',\n defaultMessage: 'Table too large to export. Please add filters and try again.',\n });\n }\n\n if (isFetchError(error) && error.status === 403) {\n return formatMessage({\n id: 'Settings.permissions.auditLogs.listview.export.error.forbidden',\n defaultMessage: \"You don't have the permissions to export audit logs.\",\n });\n }\n\n return formatMessage({\n id: 'Settings.permissions.auditLogs.listview.export.error',\n defaultMessage: 'The export failed. Please try again.',\n });\n };\n\n toggleNotification({ type: 'danger', message: message() });\n } finally {\n isExportingRef.current = false;\n setIsExporting(false);\n setProgress(null);\n }\n };\n\n const downloadExport = () => {\n if (!exportResult) {\n return;\n }\n\n downloadFile(exportResult.blob, exportResult.fileName);\n setExportResult(null);\n };\n\n const dismissExport = () => {\n setExportResult(null);\n };\n\n return { exportAuditLogs, downloadExport, dismissExport, isExporting, progress, exportResult };\n};\n\nexport { useExportAuditLogs };\nexport type { ExportProgress, ExportResult };\n"],"names":["DEFAULT_FILE_NAME","getFileName","contentDisposition","match","downloadFile","blob","fileName","url","URL","createObjectURL","link","document","createElement","href","download","body","appendChild","click","remove","setTimeout","revokeObjectURL","useExportAuditLogs","isExporting","setIsExporting","React","useState","progress","setProgress","exportResult","setExportResult","toggleNotification","useNotification","formatMessage","useIntl","isExportingRef","useRef","isMountedRef","useEffect","current","exportAuditLogs","filters","totalEntries","fetched","total","get","getFetchClient","cursor","until","token","parts","data","headers","params","responseType","nextCursorHeader","AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER","untilHeader","AUDIT_LOGS_EXPORT_UNTIL_HEADER","tokenHeader","AUDIT_LOGS_EXPORT_TOKEN_HEADER","Error","AUDIT_LOGS_EXPORT_CURSOR_DONE","length","push","partRows","Number","AUDIT_LOGS_EXPORT_PART_SIZE_HEADER","AUDIT_LOGS_EXPORT_PART_ROWS","Math","min","Blob","type","error","message","isFetchError","status","id","defaultMessage","downloadExport","dismissExport"],"mappings":"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"}
|
package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs
ADDED
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { useIntl } from 'react-intl';
|
|
3
|
+
import { useNotification } from '../../../../../../../../admin/src/features/Notifications.mjs';
|
|
4
|
+
import { getFetchClient, isFetchError } from '../../../../../../../../admin/src/utils/getFetchClient.mjs';
|
|
5
|
+
import { AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER, AUDIT_LOGS_EXPORT_UNTIL_HEADER, AUDIT_LOGS_EXPORT_TOKEN_HEADER, AUDIT_LOGS_EXPORT_CURSOR_DONE, AUDIT_LOGS_EXPORT_PART_SIZE_HEADER, AUDIT_LOGS_EXPORT_PART_ROWS } from '../../../../../../../../shared/utils/audit-log-export.mjs';
|
|
6
|
+
|
|
7
|
+
const DEFAULT_FILE_NAME = 'audit-logs.csv';
|
|
8
|
+
const getFileName = (contentDisposition)=>{
|
|
9
|
+
const match = contentDisposition?.match(/filename="([^"]+)"/);
|
|
10
|
+
return match?.[1] ?? DEFAULT_FILE_NAME;
|
|
11
|
+
};
|
|
12
|
+
const downloadFile = (blob, fileName)=>{
|
|
13
|
+
const url = URL.createObjectURL(blob);
|
|
14
|
+
const link = document.createElement('a');
|
|
15
|
+
link.href = url;
|
|
16
|
+
link.download = fileName;
|
|
17
|
+
document.body.appendChild(link);
|
|
18
|
+
link.click();
|
|
19
|
+
link.remove();
|
|
20
|
+
// Revoking during a later tick to avoid aborting the download
|
|
21
|
+
setTimeout(()=>URL.revokeObjectURL(url), 60000);
|
|
22
|
+
};
|
|
23
|
+
const useExportAuditLogs = ()=>{
|
|
24
|
+
const [isExporting, setIsExporting] = React.useState(false);
|
|
25
|
+
const [progress, setProgress] = React.useState(null);
|
|
26
|
+
const [exportResult, setExportResult] = React.useState(null);
|
|
27
|
+
const { toggleNotification } = useNotification();
|
|
28
|
+
const { formatMessage } = useIntl();
|
|
29
|
+
const isExportingRef = React.useRef(false);
|
|
30
|
+
const isMountedRef = React.useRef(true);
|
|
31
|
+
React.useEffect(()=>{
|
|
32
|
+
isMountedRef.current = true;
|
|
33
|
+
return ()=>{
|
|
34
|
+
isMountedRef.current = false;
|
|
35
|
+
};
|
|
36
|
+
}, []);
|
|
37
|
+
const exportAuditLogs = async (filters, totalEntries)=>{
|
|
38
|
+
if (isExportingRef.current) {
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
41
|
+
isExportingRef.current = true;
|
|
42
|
+
setIsExporting(true);
|
|
43
|
+
setExportResult(null);
|
|
44
|
+
setProgress({
|
|
45
|
+
fetched: 0,
|
|
46
|
+
total: totalEntries
|
|
47
|
+
});
|
|
48
|
+
const { get } = getFetchClient();
|
|
49
|
+
let cursor = null;
|
|
50
|
+
let until = null;
|
|
51
|
+
let token = null;
|
|
52
|
+
let fileName = DEFAULT_FILE_NAME;
|
|
53
|
+
const parts = [];
|
|
54
|
+
try {
|
|
55
|
+
do {
|
|
56
|
+
const { data, headers } = await get('/admin/audit-logs/export', {
|
|
57
|
+
params: {
|
|
58
|
+
...filters ? {
|
|
59
|
+
filters
|
|
60
|
+
} : {},
|
|
61
|
+
...cursor ? {
|
|
62
|
+
cursor
|
|
63
|
+
} : {},
|
|
64
|
+
...until ? {
|
|
65
|
+
until
|
|
66
|
+
} : {},
|
|
67
|
+
...token ? {
|
|
68
|
+
token
|
|
69
|
+
} : {}
|
|
70
|
+
},
|
|
71
|
+
responseType: 'blob'
|
|
72
|
+
});
|
|
73
|
+
if (!isMountedRef.current) {
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
const nextCursorHeader = headers?.get(AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER) ?? null;
|
|
77
|
+
const untilHeader = headers?.get(AUDIT_LOGS_EXPORT_UNTIL_HEADER) ?? null;
|
|
78
|
+
const tokenHeader = headers?.get(AUDIT_LOGS_EXPORT_TOKEN_HEADER) ?? null;
|
|
79
|
+
if (!nextCursorHeader || !untilHeader || !tokenHeader) {
|
|
80
|
+
throw new Error('The audit logs export part headers are missing');
|
|
81
|
+
}
|
|
82
|
+
cursor = nextCursorHeader === AUDIT_LOGS_EXPORT_CURSOR_DONE ? null : nextCursorHeader;
|
|
83
|
+
until = untilHeader;
|
|
84
|
+
token = tokenHeader;
|
|
85
|
+
if (parts.length === 0) {
|
|
86
|
+
fileName = getFileName(headers?.get('Content-Disposition') ?? null);
|
|
87
|
+
}
|
|
88
|
+
parts.push(data);
|
|
89
|
+
const partRows = Number(headers?.get(AUDIT_LOGS_EXPORT_PART_SIZE_HEADER)) || AUDIT_LOGS_EXPORT_PART_ROWS;
|
|
90
|
+
setProgress({
|
|
91
|
+
fetched: Math.min(parts.length * partRows, totalEntries),
|
|
92
|
+
total: totalEntries
|
|
93
|
+
});
|
|
94
|
+
}while (cursor)
|
|
95
|
+
setExportResult({
|
|
96
|
+
blob: new Blob(parts, {
|
|
97
|
+
type: 'text/csv;charset=utf-8'
|
|
98
|
+
}),
|
|
99
|
+
fileName
|
|
100
|
+
});
|
|
101
|
+
} catch (error) {
|
|
102
|
+
const message = ()=>{
|
|
103
|
+
if (isFetchError(error) && error.status === 413) {
|
|
104
|
+
return formatMessage({
|
|
105
|
+
id: 'Settings.permissions.auditLogs.listview.export.error.tooLarge',
|
|
106
|
+
defaultMessage: 'Table too large to export. Please add filters and try again.'
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
if (isFetchError(error) && error.status === 403) {
|
|
110
|
+
return formatMessage({
|
|
111
|
+
id: 'Settings.permissions.auditLogs.listview.export.error.forbidden',
|
|
112
|
+
defaultMessage: "You don't have the permissions to export audit logs."
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
return formatMessage({
|
|
116
|
+
id: 'Settings.permissions.auditLogs.listview.export.error',
|
|
117
|
+
defaultMessage: 'The export failed. Please try again.'
|
|
118
|
+
});
|
|
119
|
+
};
|
|
120
|
+
toggleNotification({
|
|
121
|
+
type: 'danger',
|
|
122
|
+
message: message()
|
|
123
|
+
});
|
|
124
|
+
} finally{
|
|
125
|
+
isExportingRef.current = false;
|
|
126
|
+
setIsExporting(false);
|
|
127
|
+
setProgress(null);
|
|
128
|
+
}
|
|
129
|
+
};
|
|
130
|
+
const downloadExport = ()=>{
|
|
131
|
+
if (!exportResult) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
downloadFile(exportResult.blob, exportResult.fileName);
|
|
135
|
+
setExportResult(null);
|
|
136
|
+
};
|
|
137
|
+
const dismissExport = ()=>{
|
|
138
|
+
setExportResult(null);
|
|
139
|
+
};
|
|
140
|
+
return {
|
|
141
|
+
exportAuditLogs,
|
|
142
|
+
downloadExport,
|
|
143
|
+
dismissExport,
|
|
144
|
+
isExporting,
|
|
145
|
+
progress,
|
|
146
|
+
exportResult
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export { useExportAuditLogs };
|
|
151
|
+
//# sourceMappingURL=useExportAuditLogs.mjs.map
|
package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.mjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useExportAuditLogs.mjs","sources":["../../../../../../../../../../ee/admin/src/pages/SettingsPage/pages/AuditLogs/hooks/useExportAuditLogs.ts"],"sourcesContent":["import * as React from 'react';\n\nimport { useIntl } from 'react-intl';\n\nimport { useNotification } from '../../../../../../../../admin/src/features/Notifications';\nimport {\n getFetchClient,\n isFetchError,\n type FetchResponse,\n} from '../../../../../../../../admin/src/utils/getFetchClient';\nimport {\n AUDIT_LOGS_EXPORT_CURSOR_DONE,\n AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER,\n AUDIT_LOGS_EXPORT_PART_ROWS,\n AUDIT_LOGS_EXPORT_PART_SIZE_HEADER,\n AUDIT_LOGS_EXPORT_TOKEN_HEADER,\n AUDIT_LOGS_EXPORT_UNTIL_HEADER,\n} from '../../../../../../../../shared/utils/audit-log-export';\n\nconst DEFAULT_FILE_NAME = 'audit-logs.csv';\n\ninterface ExportProgress {\n fetched: number;\n total: number;\n}\n\ninterface ExportResult {\n blob: Blob;\n fileName: string;\n}\n\nconst getFileName = (contentDisposition: string | null) => {\n const match = contentDisposition?.match(/filename=\"([^\"]+)\"/);\n\n return match?.[1] ?? DEFAULT_FILE_NAME;\n};\n\nconst downloadFile = (blob: Blob, fileName: string) => {\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = fileName;\n document.body.appendChild(link);\n link.click();\n link.remove();\n\n // Revoking during a later tick to avoid aborting the download\n setTimeout(() => URL.revokeObjectURL(url), 60000);\n};\n\nconst useExportAuditLogs = () => {\n const [isExporting, setIsExporting] = React.useState(false);\n const [progress, setProgress] = React.useState<ExportProgress | null>(null);\n const [exportResult, setExportResult] = React.useState<ExportResult | null>(null);\n const { toggleNotification } = useNotification();\n const { formatMessage } = useIntl();\n\n const isExportingRef = React.useRef(false);\n\n const isMountedRef = React.useRef(true);\n React.useEffect(() => {\n isMountedRef.current = true;\n\n return () => {\n isMountedRef.current = false;\n };\n }, []);\n\n const exportAuditLogs = async (filters: unknown, totalEntries: number) => {\n if (isExportingRef.current) {\n return;\n }\n\n isExportingRef.current = true;\n setIsExporting(true);\n setExportResult(null);\n setProgress({ fetched: 0, total: totalEntries });\n\n const { get } = getFetchClient();\n\n let cursor: string | null = null;\n let until: string | null = null;\n let token: string | null = null;\n let fileName = DEFAULT_FILE_NAME;\n const parts: Blob[] = [];\n\n try {\n do {\n const { data, headers }: FetchResponse<Blob> = await get<Blob>('/admin/audit-logs/export', {\n params: {\n ...(filters ? { filters } : {}),\n ...(cursor ? { cursor } : {}),\n ...(until ? { until } : {}),\n ...(token ? { token } : {}),\n },\n responseType: 'blob',\n });\n\n if (!isMountedRef.current) {\n return;\n }\n\n const nextCursorHeader: string | null =\n headers?.get(AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER) ?? null;\n const untilHeader: string | null = headers?.get(AUDIT_LOGS_EXPORT_UNTIL_HEADER) ?? null;\n const tokenHeader: string | null = headers?.get(AUDIT_LOGS_EXPORT_TOKEN_HEADER) ?? null;\n\n if (!nextCursorHeader || !untilHeader || !tokenHeader) {\n throw new Error('The audit logs export part headers are missing');\n }\n\n cursor = nextCursorHeader === AUDIT_LOGS_EXPORT_CURSOR_DONE ? null : nextCursorHeader;\n until = untilHeader;\n token = tokenHeader;\n\n if (parts.length === 0) {\n fileName = getFileName(headers?.get('Content-Disposition') ?? null);\n }\n\n parts.push(data);\n\n const partRows =\n Number(headers?.get(AUDIT_LOGS_EXPORT_PART_SIZE_HEADER)) || AUDIT_LOGS_EXPORT_PART_ROWS;\n setProgress({\n fetched: Math.min(parts.length * partRows, totalEntries),\n total: totalEntries,\n });\n } while (cursor);\n\n setExportResult({ blob: new Blob(parts, { type: 'text/csv;charset=utf-8' }), fileName });\n } catch (error) {\n const message = () => {\n if (isFetchError(error) && error.status === 413) {\n return formatMessage({\n id: 'Settings.permissions.auditLogs.listview.export.error.tooLarge',\n defaultMessage: 'Table too large to export. Please add filters and try again.',\n });\n }\n\n if (isFetchError(error) && error.status === 403) {\n return formatMessage({\n id: 'Settings.permissions.auditLogs.listview.export.error.forbidden',\n defaultMessage: \"You don't have the permissions to export audit logs.\",\n });\n }\n\n return formatMessage({\n id: 'Settings.permissions.auditLogs.listview.export.error',\n defaultMessage: 'The export failed. Please try again.',\n });\n };\n\n toggleNotification({ type: 'danger', message: message() });\n } finally {\n isExportingRef.current = false;\n setIsExporting(false);\n setProgress(null);\n }\n };\n\n const downloadExport = () => {\n if (!exportResult) {\n return;\n }\n\n downloadFile(exportResult.blob, exportResult.fileName);\n setExportResult(null);\n };\n\n const dismissExport = () => {\n setExportResult(null);\n };\n\n return { exportAuditLogs, downloadExport, dismissExport, isExporting, progress, exportResult };\n};\n\nexport { useExportAuditLogs };\nexport type { ExportProgress, ExportResult };\n"],"names":["DEFAULT_FILE_NAME","getFileName","contentDisposition","match","downloadFile","blob","fileName","url","URL","createObjectURL","link","document","createElement","href","download","body","appendChild","click","remove","setTimeout","revokeObjectURL","useExportAuditLogs","isExporting","setIsExporting","React","useState","progress","setProgress","exportResult","setExportResult","toggleNotification","useNotification","formatMessage","useIntl","isExportingRef","useRef","isMountedRef","useEffect","current","exportAuditLogs","filters","totalEntries","fetched","total","get","getFetchClient","cursor","until","token","parts","data","headers","params","responseType","nextCursorHeader","AUDIT_LOGS_EXPORT_NEXT_CURSOR_HEADER","untilHeader","AUDIT_LOGS_EXPORT_UNTIL_HEADER","tokenHeader","AUDIT_LOGS_EXPORT_TOKEN_HEADER","Error","AUDIT_LOGS_EXPORT_CURSOR_DONE","length","push","partRows","Number","AUDIT_LOGS_EXPORT_PART_SIZE_HEADER","AUDIT_LOGS_EXPORT_PART_ROWS","Math","min","Blob","type","error","message","isFetchError","status","id","defaultMessage","downloadExport","dismissExport"],"mappings":"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"}
|
|
@@ -28,7 +28,16 @@ const actionTypes = {
|
|
|
28
28
|
'role.delete': 'Delete role',
|
|
29
29
|
'permission.create': 'Create permission',
|
|
30
30
|
'permission.update': 'Update permission',
|
|
31
|
-
'permission.delete': 'Delete permission'
|
|
31
|
+
'permission.delete': 'Delete permission',
|
|
32
|
+
'release.create': 'Create release',
|
|
33
|
+
'release.update': 'Update release',
|
|
34
|
+
'release.delete': 'Delete release',
|
|
35
|
+
'release.trigger': 'Trigger release',
|
|
36
|
+
'release.entry.add': 'Add entry to release',
|
|
37
|
+
'release.entry.update': 'Change entry on release',
|
|
38
|
+
'release.entry.remove': 'Remove entry from release',
|
|
39
|
+
'release.settings.update': 'Update release settings',
|
|
40
|
+
'audit-log.export': 'Export audit logs'
|
|
32
41
|
};
|
|
33
42
|
const getDefaultMessage = (value)=>{
|
|
34
43
|
return actionTypes[value] || value;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getActionTypesDefaultMessages.js","sources":["../../../../../../../../../../ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.ts"],"sourcesContent":["export const actionTypes = {\n 'entry.create': 'Create entry{model, select, undefined {} other { ({model})}}',\n 'entry.update': 'Update entry{model, select, undefined {} other { ({model})}}',\n 'entry.delete': 'Delete entry{model, select, undefined {} other { ({model})}}',\n 'entry.publish': 'Publish entry{model, select, undefined {} other { ({model})}}',\n 'entry.unpublish': 'Unpublish entry{model, select, undefined {} other { ({model})}}',\n 'media.create': 'Create media',\n 'media.update': 'Update media',\n 'media.delete': 'Delete media',\n 'media-folder.create': 'Create media folder',\n 'media-folder.update': 'Update media folder',\n 'media-folder.delete': 'Delete media folder',\n 'user.create': 'Create user',\n 'user.update': 'Update user',\n 'user.delete': 'Delete user',\n 'admin.auth.success': 'Admin login',\n 'admin.logout': 'Admin logout',\n 'content-type.create': 'Create content type',\n 'content-type.update': 'Update content type',\n 'content-type.delete': 'Delete content type',\n 'component.create': 'Create component',\n 'component.update': 'Update component',\n 'component.delete': 'Delete component',\n 'role.create': 'Create role',\n 'role.update': 'Update role',\n 'role.delete': 'Delete role',\n 'permission.create': 'Create permission',\n 'permission.update': 'Update permission',\n 'permission.delete': 'Delete permission',\n};\n\nexport const getDefaultMessage = (value: keyof typeof actionTypes) => {\n return actionTypes[value] || value;\n};\n"],"names":["actionTypes","getDefaultMessage","value"],"mappings":";;MAAaA,WAAAA,GAAc;IACzB,cAAA,EAAgB,8DAAA;IAChB,cAAA,EAAgB,8DAAA;IAChB,cAAA,EAAgB,8DAAA;IAChB,eAAA,EAAiB,+DAAA;IACjB,iBAAA,EAAmB,iEAAA;IACnB,cAAA,EAAgB,cAAA;IAChB,cAAA,EAAgB,cAAA;IAChB,cAAA,EAAgB,cAAA;IAChB,qBAAA,EAAuB,qBAAA;IACvB,qBAAA,EAAuB,qBAAA;IACvB,qBAAA,EAAuB,qBAAA;IACvB,aAAA,EAAe,aAAA;IACf,aAAA,EAAe,aAAA;IACf,aAAA,EAAe,aAAA;IACf,oBAAA,EAAsB,aAAA;IACtB,cAAA,EAAgB,cAAA;IAChB,qBAAA,EAAuB,qBAAA;IACvB,qBAAA,EAAuB,qBAAA;IACvB,qBAAA,EAAuB,qBAAA;IACvB,kBAAA,EAAoB,kBAAA;IACpB,kBAAA,EAAoB,kBAAA;IACpB,kBAAA,EAAoB,kBAAA;IACpB,aAAA,EAAe,aAAA;IACf,aAAA,EAAe,aAAA;IACf,aAAA,EAAe,aAAA;IACf,mBAAA,EAAqB,mBAAA;IACrB,mBAAA,EAAqB,mBAAA;IACrB,mBAAA,EAAqB;
|
|
1
|
+
{"version":3,"file":"getActionTypesDefaultMessages.js","sources":["../../../../../../../../../../ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.ts"],"sourcesContent":["export const actionTypes = {\n 'entry.create': 'Create entry{model, select, undefined {} other { ({model})}}',\n 'entry.update': 'Update entry{model, select, undefined {} other { ({model})}}',\n 'entry.delete': 'Delete entry{model, select, undefined {} other { ({model})}}',\n 'entry.publish': 'Publish entry{model, select, undefined {} other { ({model})}}',\n 'entry.unpublish': 'Unpublish entry{model, select, undefined {} other { ({model})}}',\n 'media.create': 'Create media',\n 'media.update': 'Update media',\n 'media.delete': 'Delete media',\n 'media-folder.create': 'Create media folder',\n 'media-folder.update': 'Update media folder',\n 'media-folder.delete': 'Delete media folder',\n 'user.create': 'Create user',\n 'user.update': 'Update user',\n 'user.delete': 'Delete user',\n 'admin.auth.success': 'Admin login',\n 'admin.logout': 'Admin logout',\n 'content-type.create': 'Create content type',\n 'content-type.update': 'Update content type',\n 'content-type.delete': 'Delete content type',\n 'component.create': 'Create component',\n 'component.update': 'Update component',\n 'component.delete': 'Delete component',\n 'role.create': 'Create role',\n 'role.update': 'Update role',\n 'role.delete': 'Delete role',\n 'permission.create': 'Create permission',\n 'permission.update': 'Update permission',\n 'permission.delete': 'Delete permission',\n 'release.create': 'Create release',\n 'release.update': 'Update release',\n 'release.delete': 'Delete release',\n 'release.trigger': 'Trigger release',\n 'release.entry.add': 'Add entry to release',\n 'release.entry.update': 'Change entry on release',\n 'release.entry.remove': 'Remove entry from release',\n 'release.settings.update': 'Update release settings',\n 'audit-log.export': 'Export audit logs',\n};\n\nexport const getDefaultMessage = (value: keyof typeof actionTypes) => {\n return actionTypes[value] || value;\n};\n"],"names":["actionTypes","getDefaultMessage","value"],"mappings":";;MAAaA,WAAAA,GAAc;IACzB,cAAA,EAAgB,8DAAA;IAChB,cAAA,EAAgB,8DAAA;IAChB,cAAA,EAAgB,8DAAA;IAChB,eAAA,EAAiB,+DAAA;IACjB,iBAAA,EAAmB,iEAAA;IACnB,cAAA,EAAgB,cAAA;IAChB,cAAA,EAAgB,cAAA;IAChB,cAAA,EAAgB,cAAA;IAChB,qBAAA,EAAuB,qBAAA;IACvB,qBAAA,EAAuB,qBAAA;IACvB,qBAAA,EAAuB,qBAAA;IACvB,aAAA,EAAe,aAAA;IACf,aAAA,EAAe,aAAA;IACf,aAAA,EAAe,aAAA;IACf,oBAAA,EAAsB,aAAA;IACtB,cAAA,EAAgB,cAAA;IAChB,qBAAA,EAAuB,qBAAA;IACvB,qBAAA,EAAuB,qBAAA;IACvB,qBAAA,EAAuB,qBAAA;IACvB,kBAAA,EAAoB,kBAAA;IACpB,kBAAA,EAAoB,kBAAA;IACpB,kBAAA,EAAoB,kBAAA;IACpB,aAAA,EAAe,aAAA;IACf,aAAA,EAAe,aAAA;IACf,aAAA,EAAe,aAAA;IACf,mBAAA,EAAqB,mBAAA;IACrB,mBAAA,EAAqB,mBAAA;IACrB,mBAAA,EAAqB,mBAAA;IACrB,gBAAA,EAAkB,gBAAA;IAClB,gBAAA,EAAkB,gBAAA;IAClB,gBAAA,EAAkB,gBAAA;IAClB,iBAAA,EAAmB,iBAAA;IACnB,mBAAA,EAAqB,sBAAA;IACrB,sBAAA,EAAwB,yBAAA;IACxB,sBAAA,EAAwB,2BAAA;IACxB,yBAAA,EAA2B,yBAAA;IAC3B,kBAAA,EAAoB;AACtB;AAEO,MAAMC,oBAAoB,CAACC,KAAAA,GAAAA;IAChC,OAAOF,WAAW,CAACE,KAAAA,CAAM,IAAIA,KAAAA;AAC/B;;;;;"}
|
|
@@ -26,7 +26,16 @@ const actionTypes = {
|
|
|
26
26
|
'role.delete': 'Delete role',
|
|
27
27
|
'permission.create': 'Create permission',
|
|
28
28
|
'permission.update': 'Update permission',
|
|
29
|
-
'permission.delete': 'Delete permission'
|
|
29
|
+
'permission.delete': 'Delete permission',
|
|
30
|
+
'release.create': 'Create release',
|
|
31
|
+
'release.update': 'Update release',
|
|
32
|
+
'release.delete': 'Delete release',
|
|
33
|
+
'release.trigger': 'Trigger release',
|
|
34
|
+
'release.entry.add': 'Add entry to release',
|
|
35
|
+
'release.entry.update': 'Change entry on release',
|
|
36
|
+
'release.entry.remove': 'Remove entry from release',
|
|
37
|
+
'release.settings.update': 'Update release settings',
|
|
38
|
+
'audit-log.export': 'Export audit logs'
|
|
30
39
|
};
|
|
31
40
|
const getDefaultMessage = (value)=>{
|
|
32
41
|
return actionTypes[value] || value;
|