@strapi/admin 5.57.0 → 5.58.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/components/FormInputs/Boolean.js +3 -2
- package/dist/admin/admin/src/components/FormInputs/Boolean.js.map +1 -1
- package/dist/admin/admin/src/components/FormInputs/Boolean.mjs +3 -2
- package/dist/admin/admin/src/components/FormInputs/Boolean.mjs.map +1 -1
- package/dist/admin/admin/src/constants.js +14 -0
- package/dist/admin/admin/src/constants.js.map +1 -1
- package/dist/admin/admin/src/constants.mjs +14 -0
- package/dist/admin/admin/src/constants.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Auth/components/ResetPassword.js +6 -12
- package/dist/admin/admin/src/pages/Auth/components/ResetPassword.js.map +1 -1
- package/dist/admin/admin/src/pages/Auth/components/ResetPassword.mjs +6 -12
- package/dist/admin/admin/src/pages/Auth/components/ResetPassword.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js +10 -2
- package/dist/admin/admin/src/pages/Settings/components/SettingsNav.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/components/SettingsNav.mjs +10 -2
- package/dist/admin/admin/src/pages/Settings/components/SettingsNav.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js +6 -56
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.js.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs +6 -56
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.mjs.map +1 -1
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.js +217 -0
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.js.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.mjs +195 -0
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.mjs.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.js +185 -0
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.js.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.mjs +162 -0
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.mjs.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.js +342 -0
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.js.map +1 -0
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.mjs +320 -0
- package/dist/admin/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.mjs.map +1 -0
- package/dist/admin/admin/src/services/admin.js +11 -1
- package/dist/admin/admin/src/services/admin.js.map +1 -1
- package/dist/admin/admin/src/services/admin.mjs +11 -2
- package/dist/admin/admin/src/services/admin.mjs.map +1 -1
- package/dist/admin/admin/src/translations/en.json.js +71 -4
- package/dist/admin/admin/src/translations/en.json.js.map +1 -1
- package/dist/admin/admin/src/translations/en.json.mjs +71 -4
- package/dist/admin/admin/src/translations/en.json.mjs.map +1 -1
- package/dist/admin/admin/src/utils/browserStrapi.js +1 -1
- package/dist/admin/admin/src/utils/browserStrapi.js.map +1 -1
- package/dist/admin/admin/src/utils/browserStrapi.mjs +1 -1
- package/dist/admin/admin/src/utils/browserStrapi.mjs.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.js +24 -0
- package/dist/admin/admin/src/utils/getFetchClient.js.map +1 -1
- package/dist/admin/admin/src/utils/getFetchClient.mjs +24 -1
- package/dist/admin/admin/src/utils/getFetchClient.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js +52 -22
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs +53 -23
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.js +16 -29
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.js.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.mjs +18 -31
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AdminSeatInfo.mjs.map +1 -1
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.js +473 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.js.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.mjs +471 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.mjs.map +1 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.js +2 -0
- 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 +2 -0
- package/dist/admin/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.mjs.map +1 -1
- package/dist/admin/index.js +1 -0
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +1 -1
- package/dist/admin/shared/utils/get-project-type.js +49 -0
- package/dist/admin/shared/utils/get-project-type.js.map +1 -0
- package/dist/admin/shared/utils/get-project-type.mjs +46 -0
- package/dist/admin/shared/utils/get-project-type.mjs.map +1 -0
- package/dist/admin/src/constants.d.ts +10 -0
- package/dist/admin/src/pages/Settings/pages/ApplicationInfo/ApplicationInfoPage.d.ts +1 -1
- package/dist/admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.d.ts +12 -0
- package/dist/admin/src/pages/Settings/pages/ApplicationInfo/components/PlanCard.d.ts +14 -0
- package/dist/admin/src/pages/Settings/pages/ApplicationInfo/components/SupportCard.d.ts +2 -0
- package/dist/admin/src/services/admin.d.ts +2 -2
- package/dist/admin/src/types/permissions.d.ts +1 -0
- package/dist/admin/src/utils/getFetchClient.d.ts +25 -0
- package/dist/ee/admin/src/hooks/useLicenseLimits.d.ts +29 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/AIUsage.d.ts +6 -1
- package/dist/ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.d.ts +2 -0
- package/dist/ee/admin/src/pages/SettingsPage/pages/AuditLogs/utils/getActionTypesDefaultMessages.d.ts +2 -0
- package/dist/ee/server/src/audit-logs/entitlements.d.ts +8 -0
- package/dist/ee/server/src/audit-logs/entitlements.d.ts.map +1 -0
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts +16 -0
- package/dist/ee/server/src/audit-logs/services/lifecycles.d.ts.map +1 -1
- package/dist/ee/server/src/controllers/admin.d.ts +36 -10
- package/dist/ee/server/src/controllers/admin.d.ts.map +1 -1
- package/dist/ee/server/src/controllers/authentication-utils/middlewares.d.ts.map +1 -1
- package/dist/ee/server/src/controllers/index.d.ts +36 -10
- package/dist/ee/server/src/controllers/index.d.ts.map +1 -1
- package/dist/ee/server/src/index.d.ts +36 -10
- package/dist/ee/server/src/index.d.ts.map +1 -1
- package/dist/server/ee/server/src/audit-logs/entitlements.js +25 -0
- package/dist/server/ee/server/src/audit-logs/entitlements.js.map +1 -0
- package/dist/server/ee/server/src/audit-logs/entitlements.mjs +23 -0
- package/dist/server/ee/server/src/audit-logs/entitlements.mjs.map +1 -0
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.js +20 -8
- 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 +19 -9
- package/dist/server/ee/server/src/audit-logs/services/lifecycles.mjs.map +1 -1
- package/dist/server/ee/server/src/controllers/admin.js +76 -3
- package/dist/server/ee/server/src/controllers/admin.js.map +1 -1
- package/dist/server/ee/server/src/controllers/admin.mjs +76 -3
- package/dist/server/ee/server/src/controllers/admin.mjs.map +1 -1
- package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js +28 -10
- package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.js.map +1 -1
- package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs +28 -10
- package/dist/server/ee/server/src/controllers/authentication-utils/middlewares.mjs.map +1 -1
- package/dist/server/ee/server/src/index.js +2 -0
- package/dist/server/ee/server/src/index.js.map +1 -1
- package/dist/server/ee/server/src/index.mjs +2 -0
- package/dist/server/ee/server/src/index.mjs.map +1 -1
- package/dist/server/server/src/audit-logs/auth.js +72 -0
- package/dist/server/server/src/audit-logs/auth.js.map +1 -0
- package/dist/server/server/src/audit-logs/auth.mjs +67 -0
- package/dist/server/server/src/audit-logs/auth.mjs.map +1 -0
- package/dist/server/server/src/config/admin-actions.js +7 -0
- package/dist/server/server/src/config/admin-actions.js.map +1 -1
- package/dist/server/server/src/config/admin-actions.mjs +7 -0
- package/dist/server/server/src/config/admin-actions.mjs.map +1 -1
- package/dist/server/server/src/controllers/admin.js +6 -0
- package/dist/server/server/src/controllers/admin.js.map +1 -1
- package/dist/server/server/src/controllers/admin.mjs +6 -0
- package/dist/server/server/src/controllers/admin.mjs.map +1 -1
- package/dist/server/server/src/controllers/authentication.js +34 -8
- package/dist/server/server/src/controllers/authentication.js.map +1 -1
- package/dist/server/server/src/controllers/authentication.mjs +34 -8
- package/dist/server/server/src/controllers/authentication.mjs.map +1 -1
- package/dist/server/server/src/register.js +4 -0
- package/dist/server/server/src/register.js.map +1 -1
- package/dist/server/server/src/register.mjs +4 -0
- package/dist/server/server/src/register.mjs.map +1 -1
- package/dist/server/server/src/routes/admin.js +18 -0
- package/dist/server/server/src/routes/admin.js.map +1 -1
- package/dist/server/server/src/routes/admin.mjs +18 -0
- package/dist/server/server/src/routes/admin.mjs.map +1 -1
- package/dist/server/server/src/services/auth.js +4 -2
- package/dist/server/server/src/services/auth.js.map +1 -1
- package/dist/server/server/src/services/auth.mjs +4 -3
- package/dist/server/server/src/services/auth.mjs.map +1 -1
- package/dist/server/server/src/services/debug-dump.js +173 -0
- package/dist/server/server/src/services/debug-dump.js.map +1 -0
- package/dist/server/server/src/services/debug-dump.mjs +166 -0
- package/dist/server/server/src/services/debug-dump.mjs.map +1 -0
- package/dist/server/server/src/services/index.js +3 -1
- package/dist/server/server/src/services/index.js.map +1 -1
- package/dist/server/server/src/services/index.mjs +3 -1
- package/dist/server/server/src/services/index.mjs.map +1 -1
- package/dist/server/server/src/utils/debug-dump/redact.js +197 -0
- package/dist/server/server/src/utils/debug-dump/redact.js.map +1 -0
- package/dist/server/server/src/utils/debug-dump/redact.mjs +194 -0
- package/dist/server/server/src/utils/debug-dump/redact.mjs.map +1 -0
- package/dist/server/shared/utils/get-project-type.js +49 -0
- package/dist/server/shared/utils/get-project-type.js.map +1 -0
- package/dist/server/shared/utils/get-project-type.mjs +46 -0
- package/dist/server/shared/utils/get-project-type.mjs.map +1 -0
- package/dist/server/src/audit-logs/auth.d.ts +72 -0
- package/dist/server/src/audit-logs/auth.d.ts.map +1 -0
- package/dist/server/src/config/admin-actions.d.ts.map +1 -1
- package/dist/server/src/controllers/admin.d.ts +3 -0
- package/dist/server/src/controllers/admin.d.ts.map +1 -1
- package/dist/server/src/controllers/authentication.d.ts.map +1 -1
- package/dist/server/src/controllers/index.d.ts +3 -0
- package/dist/server/src/controllers/index.d.ts.map +1 -1
- package/dist/server/src/index.d.ts +8 -0
- package/dist/server/src/index.d.ts.map +1 -1
- package/dist/server/src/register.d.ts.map +1 -1
- package/dist/server/src/routes/admin.d.ts.map +1 -1
- package/dist/server/src/services/auth.d.ts +6 -0
- package/dist/server/src/services/auth.d.ts.map +1 -1
- package/dist/server/src/services/debug-dump.d.ts +9 -0
- package/dist/server/src/services/debug-dump.d.ts.map +1 -0
- package/dist/server/src/services/index.d.ts +5 -0
- package/dist/server/src/services/index.d.ts.map +1 -1
- package/dist/server/src/utils/debug-dump/redact.d.ts +8 -0
- package/dist/server/src/utils/debug-dump/redact.d.ts.map +1 -0
- package/dist/shared/contracts/admin.d.ts +106 -0
- package/dist/shared/contracts/admin.d.ts.map +1 -1
- package/dist/shared/utils/__tests__/get-project-type.test.d.ts +1 -0
- package/dist/shared/utils/__tests__/get-project-type.test.d.ts.map +1 -0
- package/dist/shared/utils/get-project-type.d.ts +37 -0
- package/dist/shared/utils/get-project-type.d.ts.map +1 -0
- package/package.json +8 -8
- package/dist/admin/admin/src/utils/getProjectType.js +0 -22
- package/dist/admin/admin/src/utils/getProjectType.js.map +0 -1
- package/dist/admin/admin/src/utils/getProjectType.mjs +0 -20
- package/dist/admin/admin/src/utils/getProjectType.mjs.map +0 -1
- package/dist/admin/src/utils/getProjectType.d.ts +0 -16
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var designSystem = require('@strapi/design-system');
|
|
6
|
+
var icons = require('@strapi/icons');
|
|
7
|
+
var reactIntl = require('react-intl');
|
|
8
|
+
var Notifications = require('../../../../../features/Notifications.js');
|
|
9
|
+
var useClipboard = require('../../../../../hooks/useClipboard.js');
|
|
10
|
+
var admin = require('../../../../../services/admin.js');
|
|
11
|
+
|
|
12
|
+
function _interopNamespace(e) {
|
|
13
|
+
if (e && e.__esModule) return e;
|
|
14
|
+
var n = Object.create(null);
|
|
15
|
+
if (e) {
|
|
16
|
+
Object.keys(e).forEach(function (k) {
|
|
17
|
+
if (k !== 'default') {
|
|
18
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
19
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return e[k]; }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
n.default = e;
|
|
27
|
+
return Object.freeze(n);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Generates the redacted diagnostic snapshot behind the Support card's "Generate snapshot" action.
|
|
34
|
+
* The fetch is triggered as soon as the modal opens, so the user only ever sees a spinner followed
|
|
35
|
+
* by the payload (or, on failure, a notification while the modal closes itself).
|
|
36
|
+
*/ const DiagnosticSnapshotModal = ({ isOpen, onClose })=>{
|
|
37
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
38
|
+
const { toggleNotification } = Notifications.useNotification();
|
|
39
|
+
const { copy } = useClipboard.useClipboard();
|
|
40
|
+
const [triggerGetDump, { data, isFetching }] = admin.useLazyGetDebugDumpQuery();
|
|
41
|
+
// Failure is read from this open's own request. The lazy query keeps `isError` from an earlier
|
|
42
|
+
// failed request while a new one is in flight, which closed the next open straight away.
|
|
43
|
+
React__namespace.useEffect(()=>{
|
|
44
|
+
if (!isOpen) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
let active = true;
|
|
48
|
+
triggerGetDump().unwrap().catch(()=>{
|
|
49
|
+
if (!active) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
toggleNotification({
|
|
53
|
+
type: 'danger',
|
|
54
|
+
message: formatMessage({
|
|
55
|
+
id: 'Settings.debug-dump.error',
|
|
56
|
+
defaultMessage: 'Failed to generate the debug dump. Check the server logs and try again.'
|
|
57
|
+
})
|
|
58
|
+
});
|
|
59
|
+
onClose();
|
|
60
|
+
});
|
|
61
|
+
return ()=>{
|
|
62
|
+
active = false;
|
|
63
|
+
};
|
|
64
|
+
}, [
|
|
65
|
+
isOpen,
|
|
66
|
+
triggerGetDump,
|
|
67
|
+
toggleNotification,
|
|
68
|
+
formatMessage,
|
|
69
|
+
onClose
|
|
70
|
+
]);
|
|
71
|
+
const serialized = React__namespace.useMemo(()=>data === undefined ? '' : JSON.stringify(data, null, 2), [
|
|
72
|
+
data
|
|
73
|
+
]);
|
|
74
|
+
const isReady = !isFetching && data !== undefined;
|
|
75
|
+
const handleCopy = async ()=>{
|
|
76
|
+
const didCopy = await copy(serialized);
|
|
77
|
+
toggleNotification({
|
|
78
|
+
type: didCopy ? 'success' : 'danger',
|
|
79
|
+
message: didCopy ? formatMessage({
|
|
80
|
+
id: 'Settings.debug-dump.copied',
|
|
81
|
+
defaultMessage: 'Copied to clipboard'
|
|
82
|
+
}) : formatMessage({
|
|
83
|
+
id: 'Settings.debug-dump.copy-failed',
|
|
84
|
+
defaultMessage: 'Could not copy to clipboard'
|
|
85
|
+
})
|
|
86
|
+
});
|
|
87
|
+
};
|
|
88
|
+
const handleDownload = ()=>{
|
|
89
|
+
const blob = new Blob([
|
|
90
|
+
serialized
|
|
91
|
+
], {
|
|
92
|
+
type: 'application/json'
|
|
93
|
+
});
|
|
94
|
+
const url = URL.createObjectURL(blob);
|
|
95
|
+
const anchor = document.createElement('a');
|
|
96
|
+
anchor.href = url;
|
|
97
|
+
anchor.download = `strapi-debug-dump-${new Date().toISOString().replaceAll(':', '-')}.json`;
|
|
98
|
+
// In the document for the click and revoked on a later turn, as the audit-log export does:
|
|
99
|
+
// some browsers cancel a click on a detached anchor or a download whose URL is gone.
|
|
100
|
+
document.body.appendChild(anchor);
|
|
101
|
+
anchor.click();
|
|
102
|
+
anchor.remove();
|
|
103
|
+
setTimeout(()=>URL.revokeObjectURL(url), 60000);
|
|
104
|
+
};
|
|
105
|
+
return /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Root, {
|
|
106
|
+
open: isOpen,
|
|
107
|
+
onOpenChange: onClose,
|
|
108
|
+
children: /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Modal.Content, {
|
|
109
|
+
children: [
|
|
110
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Header, {
|
|
111
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Title, {
|
|
112
|
+
children: formatMessage({
|
|
113
|
+
id: 'Settings.debug-dump.snapshot-modal.title',
|
|
114
|
+
defaultMessage: 'Diagnostic snapshot'
|
|
115
|
+
})
|
|
116
|
+
})
|
|
117
|
+
}),
|
|
118
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Body, {
|
|
119
|
+
children: isReady ? /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
|
|
120
|
+
direction: "column",
|
|
121
|
+
alignItems: "stretch",
|
|
122
|
+
gap: 4,
|
|
123
|
+
children: [
|
|
124
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
125
|
+
children: formatMessage({
|
|
126
|
+
id: 'Settings.debug-dump.snapshot-modal.description',
|
|
127
|
+
defaultMessage: "This snapshot describes how your project is built so a third party can reproduce the bug locally. It does not contain any of your app's content and no credentials."
|
|
128
|
+
})
|
|
129
|
+
}),
|
|
130
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
131
|
+
variant: "sigma",
|
|
132
|
+
children: formatMessage({
|
|
133
|
+
id: 'Settings.debug-dump.payload-label',
|
|
134
|
+
defaultMessage: 'payload'
|
|
135
|
+
})
|
|
136
|
+
}),
|
|
137
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Box, {
|
|
138
|
+
hasRadius: true,
|
|
139
|
+
padding: 4,
|
|
140
|
+
maxHeight: "26rem",
|
|
141
|
+
overflow: "auto",
|
|
142
|
+
// A code surface that stays dark in BOTH themes. The design-system neutrals invert
|
|
143
|
+
// between themes (`neutral800` is #32324d in light but #ffffff in dark, and
|
|
144
|
+
// `neutral0` inverts with it), so tokens here flip the block to white on dark.
|
|
145
|
+
// These are the same fixed values the WYSIWYG preview uses for its code surface.
|
|
146
|
+
style: {
|
|
147
|
+
backgroundColor: '#32324d'
|
|
148
|
+
},
|
|
149
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
150
|
+
tag: "pre",
|
|
151
|
+
variant: "pi",
|
|
152
|
+
style: {
|
|
153
|
+
color: '#ffffff',
|
|
154
|
+
whiteSpace: 'pre-wrap',
|
|
155
|
+
wordBreak: 'break-word',
|
|
156
|
+
margin: 0
|
|
157
|
+
},
|
|
158
|
+
children: serialized
|
|
159
|
+
})
|
|
160
|
+
})
|
|
161
|
+
]
|
|
162
|
+
}) : /*#__PURE__*/ jsxRuntime.jsx(designSystem.Flex, {
|
|
163
|
+
justifyContent: "center",
|
|
164
|
+
alignItems: "center",
|
|
165
|
+
padding: 7,
|
|
166
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Loader, {
|
|
167
|
+
children: formatMessage({
|
|
168
|
+
id: 'Settings.debug-dump.generating',
|
|
169
|
+
defaultMessage: 'Generating diagnostic snapshot'
|
|
170
|
+
})
|
|
171
|
+
})
|
|
172
|
+
})
|
|
173
|
+
}),
|
|
174
|
+
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Modal.Footer, {
|
|
175
|
+
children: [
|
|
176
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Modal.Close, {
|
|
177
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
|
|
178
|
+
variant: "tertiary",
|
|
179
|
+
children: formatMessage({
|
|
180
|
+
id: 'app.components.Button.cancel',
|
|
181
|
+
defaultMessage: 'Cancel'
|
|
182
|
+
})
|
|
183
|
+
})
|
|
184
|
+
}),
|
|
185
|
+
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
|
|
186
|
+
gap: 2,
|
|
187
|
+
children: [
|
|
188
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
|
|
189
|
+
variant: "secondary",
|
|
190
|
+
onClick: handleCopy,
|
|
191
|
+
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Duplicate, {}),
|
|
192
|
+
disabled: !isReady,
|
|
193
|
+
children: formatMessage({
|
|
194
|
+
id: 'Settings.debug-dump.copy',
|
|
195
|
+
defaultMessage: 'Copy'
|
|
196
|
+
})
|
|
197
|
+
}),
|
|
198
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Button, {
|
|
199
|
+
onClick: handleDownload,
|
|
200
|
+
startIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.Download, {}),
|
|
201
|
+
disabled: !isReady,
|
|
202
|
+
children: formatMessage({
|
|
203
|
+
id: 'Settings.debug-dump.download',
|
|
204
|
+
defaultMessage: 'Download'
|
|
205
|
+
})
|
|
206
|
+
})
|
|
207
|
+
]
|
|
208
|
+
})
|
|
209
|
+
]
|
|
210
|
+
})
|
|
211
|
+
]
|
|
212
|
+
})
|
|
213
|
+
});
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
exports.DiagnosticSnapshotModal = DiagnosticSnapshotModal;
|
|
217
|
+
//# sourceMappingURL=DiagnosticSnapshotModal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiagnosticSnapshotModal.js","sources":["../../../../../../../../../admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Button, Flex, Loader, Modal, Typography } from '@strapi/design-system';\nimport { Download, Duplicate } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useNotification } from '../../../../../features/Notifications';\nimport { useClipboard } from '../../../../../hooks/useClipboard';\nimport { useLazyGetDebugDumpQuery } from '../../../../../services/admin';\n\n/* -------------------------------------------------------------------------------------------------\n * DiagnosticSnapshotModal\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DiagnosticSnapshotModalProps {\n isOpen: boolean;\n onClose: () => void;\n}\n\n/**\n * Generates the redacted diagnostic snapshot behind the Support card's \"Generate snapshot\" action.\n * The fetch is triggered as soon as the modal opens, so the user only ever sees a spinner followed\n * by the payload (or, on failure, a notification while the modal closes itself).\n */\nconst DiagnosticSnapshotModal = ({ isOpen, onClose }: DiagnosticSnapshotModalProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { copy } = useClipboard();\n const [triggerGetDump, { data, isFetching }] = useLazyGetDebugDumpQuery();\n\n // Failure is read from this open's own request. The lazy query keeps `isError` from an earlier\n // failed request while a new one is in flight, which closed the next open straight away.\n React.useEffect(() => {\n if (!isOpen) {\n return undefined;\n }\n\n let active = true;\n\n triggerGetDump()\n .unwrap()\n .catch(() => {\n if (!active) {\n return;\n }\n\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: 'Settings.debug-dump.error',\n defaultMessage:\n 'Failed to generate the debug dump. Check the server logs and try again.',\n }),\n });\n onClose();\n });\n\n return () => {\n active = false;\n };\n }, [isOpen, triggerGetDump, toggleNotification, formatMessage, onClose]);\n\n const serialized = React.useMemo(\n () => (data === undefined ? '' : JSON.stringify(data, null, 2)),\n [data]\n );\n\n const isReady = !isFetching && data !== undefined;\n\n const handleCopy = async () => {\n const didCopy = await copy(serialized);\n toggleNotification({\n type: didCopy ? 'success' : 'danger',\n message: didCopy\n ? formatMessage({ id: 'Settings.debug-dump.copied', defaultMessage: 'Copied to clipboard' })\n : formatMessage({\n id: 'Settings.debug-dump.copy-failed',\n defaultMessage: 'Could not copy to clipboard',\n }),\n });\n };\n\n const handleDownload = () => {\n const blob = new Blob([serialized], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = `strapi-debug-dump-${new Date().toISOString().replaceAll(':', '-')}.json`;\n // In the document for the click and revoked on a later turn, as the audit-log export does:\n // some browsers cancel a click on a detached anchor or a download whose URL is gone.\n document.body.appendChild(anchor);\n anchor.click();\n anchor.remove();\n setTimeout(() => URL.revokeObjectURL(url), 60000);\n };\n\n return (\n <Modal.Root open={isOpen} onOpenChange={onClose}>\n <Modal.Content>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: 'Settings.debug-dump.snapshot-modal.title',\n defaultMessage: 'Diagnostic snapshot',\n })}\n </Modal.Title>\n </Modal.Header>\n <Modal.Body>\n {isReady ? (\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Typography>\n {formatMessage({\n id: 'Settings.debug-dump.snapshot-modal.description',\n defaultMessage:\n \"This snapshot describes how your project is built so a third party can reproduce the bug locally. It does not contain any of your app's content and no credentials.\",\n })}\n </Typography>\n <Typography variant=\"sigma\">\n {formatMessage({\n id: 'Settings.debug-dump.payload-label',\n defaultMessage: 'payload',\n })}\n </Typography>\n <Box\n hasRadius\n padding={4}\n maxHeight=\"26rem\"\n overflow=\"auto\"\n // A code surface that stays dark in BOTH themes. The design-system neutrals invert\n // between themes (`neutral800` is #32324d in light but #ffffff in dark, and\n // `neutral0` inverts with it), so tokens here flip the block to white on dark.\n // These are the same fixed values the WYSIWYG preview uses for its code surface.\n style={{ backgroundColor: '#32324d' }}\n >\n <Typography\n tag=\"pre\"\n variant=\"pi\"\n style={{\n color: '#ffffff',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n margin: 0,\n }}\n >\n {serialized}\n </Typography>\n </Box>\n </Flex>\n ) : (\n <Flex justifyContent=\"center\" alignItems=\"center\" padding={7}>\n <Loader>\n {formatMessage({\n id: 'Settings.debug-dump.generating',\n defaultMessage: 'Generating diagnostic snapshot',\n })}\n </Loader>\n </Flex>\n )}\n </Modal.Body>\n <Modal.Footer>\n <Modal.Close>\n <Button variant=\"tertiary\">\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n </Modal.Close>\n {/* Grouped so Copy and Download stay together on the right rather than being pushed to\n opposite edges by the footer's `space-between`. */}\n <Flex gap={2}>\n <Button\n variant=\"secondary\"\n onClick={handleCopy}\n startIcon={<Duplicate />}\n disabled={!isReady}\n >\n {formatMessage({ id: 'Settings.debug-dump.copy', defaultMessage: 'Copy' })}\n </Button>\n <Button onClick={handleDownload} startIcon={<Download />} disabled={!isReady}>\n {formatMessage({ id: 'Settings.debug-dump.download', defaultMessage: 'Download' })}\n </Button>\n </Flex>\n </Modal.Footer>\n </Modal.Content>\n </Modal.Root>\n );\n};\n\nexport { DiagnosticSnapshotModal };\nexport type { DiagnosticSnapshotModalProps };\n"],"names":["DiagnosticSnapshotModal","isOpen","onClose","formatMessage","useIntl","toggleNotification","useNotification","copy","useClipboard","triggerGetDump","data","isFetching","useLazyGetDebugDumpQuery","React","useEffect","undefined","active","unwrap","catch","type","message","id","defaultMessage","serialized","useMemo","JSON","stringify","isReady","handleCopy","didCopy","handleDownload","blob","Blob","url","URL","createObjectURL","anchor","document","createElement","href","download","Date","toISOString","replaceAll","body","appendChild","click","remove","setTimeout","revokeObjectURL","_jsx","Modal","Root","open","onOpenChange","_jsxs","Content","Header","Title","Body","Flex","direction","alignItems","gap","Typography","variant","Box","hasRadius","padding","maxHeight","overflow","style","backgroundColor","tag","color","whiteSpace","wordBreak","margin","justifyContent","Loader","Footer","Close","Button","onClick","startIcon","Duplicate","disabled","Download"],"mappings":"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"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { Modal, Flex, Typography, Box, Loader, Button } from '@strapi/design-system';
|
|
4
|
+
import { Duplicate, Download } from '@strapi/icons';
|
|
5
|
+
import { useIntl } from 'react-intl';
|
|
6
|
+
import { useNotification } from '../../../../../features/Notifications.mjs';
|
|
7
|
+
import { useClipboard } from '../../../../../hooks/useClipboard.mjs';
|
|
8
|
+
import { useLazyGetDebugDumpQuery } from '../../../../../services/admin.mjs';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Generates the redacted diagnostic snapshot behind the Support card's "Generate snapshot" action.
|
|
12
|
+
* The fetch is triggered as soon as the modal opens, so the user only ever sees a spinner followed
|
|
13
|
+
* by the payload (or, on failure, a notification while the modal closes itself).
|
|
14
|
+
*/ const DiagnosticSnapshotModal = ({ isOpen, onClose })=>{
|
|
15
|
+
const { formatMessage } = useIntl();
|
|
16
|
+
const { toggleNotification } = useNotification();
|
|
17
|
+
const { copy } = useClipboard();
|
|
18
|
+
const [triggerGetDump, { data, isFetching }] = useLazyGetDebugDumpQuery();
|
|
19
|
+
// Failure is read from this open's own request. The lazy query keeps `isError` from an earlier
|
|
20
|
+
// failed request while a new one is in flight, which closed the next open straight away.
|
|
21
|
+
React.useEffect(()=>{
|
|
22
|
+
if (!isOpen) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
let active = true;
|
|
26
|
+
triggerGetDump().unwrap().catch(()=>{
|
|
27
|
+
if (!active) {
|
|
28
|
+
return;
|
|
29
|
+
}
|
|
30
|
+
toggleNotification({
|
|
31
|
+
type: 'danger',
|
|
32
|
+
message: formatMessage({
|
|
33
|
+
id: 'Settings.debug-dump.error',
|
|
34
|
+
defaultMessage: 'Failed to generate the debug dump. Check the server logs and try again.'
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
onClose();
|
|
38
|
+
});
|
|
39
|
+
return ()=>{
|
|
40
|
+
active = false;
|
|
41
|
+
};
|
|
42
|
+
}, [
|
|
43
|
+
isOpen,
|
|
44
|
+
triggerGetDump,
|
|
45
|
+
toggleNotification,
|
|
46
|
+
formatMessage,
|
|
47
|
+
onClose
|
|
48
|
+
]);
|
|
49
|
+
const serialized = React.useMemo(()=>data === undefined ? '' : JSON.stringify(data, null, 2), [
|
|
50
|
+
data
|
|
51
|
+
]);
|
|
52
|
+
const isReady = !isFetching && data !== undefined;
|
|
53
|
+
const handleCopy = async ()=>{
|
|
54
|
+
const didCopy = await copy(serialized);
|
|
55
|
+
toggleNotification({
|
|
56
|
+
type: didCopy ? 'success' : 'danger',
|
|
57
|
+
message: didCopy ? formatMessage({
|
|
58
|
+
id: 'Settings.debug-dump.copied',
|
|
59
|
+
defaultMessage: 'Copied to clipboard'
|
|
60
|
+
}) : formatMessage({
|
|
61
|
+
id: 'Settings.debug-dump.copy-failed',
|
|
62
|
+
defaultMessage: 'Could not copy to clipboard'
|
|
63
|
+
})
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
const handleDownload = ()=>{
|
|
67
|
+
const blob = new Blob([
|
|
68
|
+
serialized
|
|
69
|
+
], {
|
|
70
|
+
type: 'application/json'
|
|
71
|
+
});
|
|
72
|
+
const url = URL.createObjectURL(blob);
|
|
73
|
+
const anchor = document.createElement('a');
|
|
74
|
+
anchor.href = url;
|
|
75
|
+
anchor.download = `strapi-debug-dump-${new Date().toISOString().replaceAll(':', '-')}.json`;
|
|
76
|
+
// In the document for the click and revoked on a later turn, as the audit-log export does:
|
|
77
|
+
// some browsers cancel a click on a detached anchor or a download whose URL is gone.
|
|
78
|
+
document.body.appendChild(anchor);
|
|
79
|
+
anchor.click();
|
|
80
|
+
anchor.remove();
|
|
81
|
+
setTimeout(()=>URL.revokeObjectURL(url), 60000);
|
|
82
|
+
};
|
|
83
|
+
return /*#__PURE__*/ jsx(Modal.Root, {
|
|
84
|
+
open: isOpen,
|
|
85
|
+
onOpenChange: onClose,
|
|
86
|
+
children: /*#__PURE__*/ jsxs(Modal.Content, {
|
|
87
|
+
children: [
|
|
88
|
+
/*#__PURE__*/ jsx(Modal.Header, {
|
|
89
|
+
children: /*#__PURE__*/ jsx(Modal.Title, {
|
|
90
|
+
children: formatMessage({
|
|
91
|
+
id: 'Settings.debug-dump.snapshot-modal.title',
|
|
92
|
+
defaultMessage: 'Diagnostic snapshot'
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
}),
|
|
96
|
+
/*#__PURE__*/ jsx(Modal.Body, {
|
|
97
|
+
children: isReady ? /*#__PURE__*/ jsxs(Flex, {
|
|
98
|
+
direction: "column",
|
|
99
|
+
alignItems: "stretch",
|
|
100
|
+
gap: 4,
|
|
101
|
+
children: [
|
|
102
|
+
/*#__PURE__*/ jsx(Typography, {
|
|
103
|
+
children: formatMessage({
|
|
104
|
+
id: 'Settings.debug-dump.snapshot-modal.description',
|
|
105
|
+
defaultMessage: "This snapshot describes how your project is built so a third party can reproduce the bug locally. It does not contain any of your app's content and no credentials."
|
|
106
|
+
})
|
|
107
|
+
}),
|
|
108
|
+
/*#__PURE__*/ jsx(Typography, {
|
|
109
|
+
variant: "sigma",
|
|
110
|
+
children: formatMessage({
|
|
111
|
+
id: 'Settings.debug-dump.payload-label',
|
|
112
|
+
defaultMessage: 'payload'
|
|
113
|
+
})
|
|
114
|
+
}),
|
|
115
|
+
/*#__PURE__*/ jsx(Box, {
|
|
116
|
+
hasRadius: true,
|
|
117
|
+
padding: 4,
|
|
118
|
+
maxHeight: "26rem",
|
|
119
|
+
overflow: "auto",
|
|
120
|
+
// A code surface that stays dark in BOTH themes. The design-system neutrals invert
|
|
121
|
+
// between themes (`neutral800` is #32324d in light but #ffffff in dark, and
|
|
122
|
+
// `neutral0` inverts with it), so tokens here flip the block to white on dark.
|
|
123
|
+
// These are the same fixed values the WYSIWYG preview uses for its code surface.
|
|
124
|
+
style: {
|
|
125
|
+
backgroundColor: '#32324d'
|
|
126
|
+
},
|
|
127
|
+
children: /*#__PURE__*/ jsx(Typography, {
|
|
128
|
+
tag: "pre",
|
|
129
|
+
variant: "pi",
|
|
130
|
+
style: {
|
|
131
|
+
color: '#ffffff',
|
|
132
|
+
whiteSpace: 'pre-wrap',
|
|
133
|
+
wordBreak: 'break-word',
|
|
134
|
+
margin: 0
|
|
135
|
+
},
|
|
136
|
+
children: serialized
|
|
137
|
+
})
|
|
138
|
+
})
|
|
139
|
+
]
|
|
140
|
+
}) : /*#__PURE__*/ jsx(Flex, {
|
|
141
|
+
justifyContent: "center",
|
|
142
|
+
alignItems: "center",
|
|
143
|
+
padding: 7,
|
|
144
|
+
children: /*#__PURE__*/ jsx(Loader, {
|
|
145
|
+
children: formatMessage({
|
|
146
|
+
id: 'Settings.debug-dump.generating',
|
|
147
|
+
defaultMessage: 'Generating diagnostic snapshot'
|
|
148
|
+
})
|
|
149
|
+
})
|
|
150
|
+
})
|
|
151
|
+
}),
|
|
152
|
+
/*#__PURE__*/ jsxs(Modal.Footer, {
|
|
153
|
+
children: [
|
|
154
|
+
/*#__PURE__*/ jsx(Modal.Close, {
|
|
155
|
+
children: /*#__PURE__*/ jsx(Button, {
|
|
156
|
+
variant: "tertiary",
|
|
157
|
+
children: formatMessage({
|
|
158
|
+
id: 'app.components.Button.cancel',
|
|
159
|
+
defaultMessage: 'Cancel'
|
|
160
|
+
})
|
|
161
|
+
})
|
|
162
|
+
}),
|
|
163
|
+
/*#__PURE__*/ jsxs(Flex, {
|
|
164
|
+
gap: 2,
|
|
165
|
+
children: [
|
|
166
|
+
/*#__PURE__*/ jsx(Button, {
|
|
167
|
+
variant: "secondary",
|
|
168
|
+
onClick: handleCopy,
|
|
169
|
+
startIcon: /*#__PURE__*/ jsx(Duplicate, {}),
|
|
170
|
+
disabled: !isReady,
|
|
171
|
+
children: formatMessage({
|
|
172
|
+
id: 'Settings.debug-dump.copy',
|
|
173
|
+
defaultMessage: 'Copy'
|
|
174
|
+
})
|
|
175
|
+
}),
|
|
176
|
+
/*#__PURE__*/ jsx(Button, {
|
|
177
|
+
onClick: handleDownload,
|
|
178
|
+
startIcon: /*#__PURE__*/ jsx(Download, {}),
|
|
179
|
+
disabled: !isReady,
|
|
180
|
+
children: formatMessage({
|
|
181
|
+
id: 'Settings.debug-dump.download',
|
|
182
|
+
defaultMessage: 'Download'
|
|
183
|
+
})
|
|
184
|
+
})
|
|
185
|
+
]
|
|
186
|
+
})
|
|
187
|
+
]
|
|
188
|
+
})
|
|
189
|
+
]
|
|
190
|
+
})
|
|
191
|
+
});
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
export { DiagnosticSnapshotModal };
|
|
195
|
+
//# sourceMappingURL=DiagnosticSnapshotModal.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DiagnosticSnapshotModal.mjs","sources":["../../../../../../../../../admin/src/pages/Settings/pages/ApplicationInfo/components/DiagnosticSnapshotModal.tsx"],"sourcesContent":["import * as React from 'react';\n\nimport { Box, Button, Flex, Loader, Modal, Typography } from '@strapi/design-system';\nimport { Download, Duplicate } from '@strapi/icons';\nimport { useIntl } from 'react-intl';\n\nimport { useNotification } from '../../../../../features/Notifications';\nimport { useClipboard } from '../../../../../hooks/useClipboard';\nimport { useLazyGetDebugDumpQuery } from '../../../../../services/admin';\n\n/* -------------------------------------------------------------------------------------------------\n * DiagnosticSnapshotModal\n * -----------------------------------------------------------------------------------------------*/\n\ninterface DiagnosticSnapshotModalProps {\n isOpen: boolean;\n onClose: () => void;\n}\n\n/**\n * Generates the redacted diagnostic snapshot behind the Support card's \"Generate snapshot\" action.\n * The fetch is triggered as soon as the modal opens, so the user only ever sees a spinner followed\n * by the payload (or, on failure, a notification while the modal closes itself).\n */\nconst DiagnosticSnapshotModal = ({ isOpen, onClose }: DiagnosticSnapshotModalProps) => {\n const { formatMessage } = useIntl();\n const { toggleNotification } = useNotification();\n const { copy } = useClipboard();\n const [triggerGetDump, { data, isFetching }] = useLazyGetDebugDumpQuery();\n\n // Failure is read from this open's own request. The lazy query keeps `isError` from an earlier\n // failed request while a new one is in flight, which closed the next open straight away.\n React.useEffect(() => {\n if (!isOpen) {\n return undefined;\n }\n\n let active = true;\n\n triggerGetDump()\n .unwrap()\n .catch(() => {\n if (!active) {\n return;\n }\n\n toggleNotification({\n type: 'danger',\n message: formatMessage({\n id: 'Settings.debug-dump.error',\n defaultMessage:\n 'Failed to generate the debug dump. Check the server logs and try again.',\n }),\n });\n onClose();\n });\n\n return () => {\n active = false;\n };\n }, [isOpen, triggerGetDump, toggleNotification, formatMessage, onClose]);\n\n const serialized = React.useMemo(\n () => (data === undefined ? '' : JSON.stringify(data, null, 2)),\n [data]\n );\n\n const isReady = !isFetching && data !== undefined;\n\n const handleCopy = async () => {\n const didCopy = await copy(serialized);\n toggleNotification({\n type: didCopy ? 'success' : 'danger',\n message: didCopy\n ? formatMessage({ id: 'Settings.debug-dump.copied', defaultMessage: 'Copied to clipboard' })\n : formatMessage({\n id: 'Settings.debug-dump.copy-failed',\n defaultMessage: 'Could not copy to clipboard',\n }),\n });\n };\n\n const handleDownload = () => {\n const blob = new Blob([serialized], { type: 'application/json' });\n const url = URL.createObjectURL(blob);\n const anchor = document.createElement('a');\n anchor.href = url;\n anchor.download = `strapi-debug-dump-${new Date().toISOString().replaceAll(':', '-')}.json`;\n // In the document for the click and revoked on a later turn, as the audit-log export does:\n // some browsers cancel a click on a detached anchor or a download whose URL is gone.\n document.body.appendChild(anchor);\n anchor.click();\n anchor.remove();\n setTimeout(() => URL.revokeObjectURL(url), 60000);\n };\n\n return (\n <Modal.Root open={isOpen} onOpenChange={onClose}>\n <Modal.Content>\n <Modal.Header>\n <Modal.Title>\n {formatMessage({\n id: 'Settings.debug-dump.snapshot-modal.title',\n defaultMessage: 'Diagnostic snapshot',\n })}\n </Modal.Title>\n </Modal.Header>\n <Modal.Body>\n {isReady ? (\n <Flex direction=\"column\" alignItems=\"stretch\" gap={4}>\n <Typography>\n {formatMessage({\n id: 'Settings.debug-dump.snapshot-modal.description',\n defaultMessage:\n \"This snapshot describes how your project is built so a third party can reproduce the bug locally. It does not contain any of your app's content and no credentials.\",\n })}\n </Typography>\n <Typography variant=\"sigma\">\n {formatMessage({\n id: 'Settings.debug-dump.payload-label',\n defaultMessage: 'payload',\n })}\n </Typography>\n <Box\n hasRadius\n padding={4}\n maxHeight=\"26rem\"\n overflow=\"auto\"\n // A code surface that stays dark in BOTH themes. The design-system neutrals invert\n // between themes (`neutral800` is #32324d in light but #ffffff in dark, and\n // `neutral0` inverts with it), so tokens here flip the block to white on dark.\n // These are the same fixed values the WYSIWYG preview uses for its code surface.\n style={{ backgroundColor: '#32324d' }}\n >\n <Typography\n tag=\"pre\"\n variant=\"pi\"\n style={{\n color: '#ffffff',\n whiteSpace: 'pre-wrap',\n wordBreak: 'break-word',\n margin: 0,\n }}\n >\n {serialized}\n </Typography>\n </Box>\n </Flex>\n ) : (\n <Flex justifyContent=\"center\" alignItems=\"center\" padding={7}>\n <Loader>\n {formatMessage({\n id: 'Settings.debug-dump.generating',\n defaultMessage: 'Generating diagnostic snapshot',\n })}\n </Loader>\n </Flex>\n )}\n </Modal.Body>\n <Modal.Footer>\n <Modal.Close>\n <Button variant=\"tertiary\">\n {formatMessage({ id: 'app.components.Button.cancel', defaultMessage: 'Cancel' })}\n </Button>\n </Modal.Close>\n {/* Grouped so Copy and Download stay together on the right rather than being pushed to\n opposite edges by the footer's `space-between`. */}\n <Flex gap={2}>\n <Button\n variant=\"secondary\"\n onClick={handleCopy}\n startIcon={<Duplicate />}\n disabled={!isReady}\n >\n {formatMessage({ id: 'Settings.debug-dump.copy', defaultMessage: 'Copy' })}\n </Button>\n <Button onClick={handleDownload} startIcon={<Download />} disabled={!isReady}>\n {formatMessage({ id: 'Settings.debug-dump.download', defaultMessage: 'Download' })}\n </Button>\n </Flex>\n </Modal.Footer>\n </Modal.Content>\n </Modal.Root>\n );\n};\n\nexport { DiagnosticSnapshotModal };\nexport type { DiagnosticSnapshotModalProps };\n"],"names":["DiagnosticSnapshotModal","isOpen","onClose","formatMessage","useIntl","toggleNotification","useNotification","copy","useClipboard","triggerGetDump","data","isFetching","useLazyGetDebugDumpQuery","React","useEffect","undefined","active","unwrap","catch","type","message","id","defaultMessage","serialized","useMemo","JSON","stringify","isReady","handleCopy","didCopy","handleDownload","blob","Blob","url","URL","createObjectURL","anchor","document","createElement","href","download","Date","toISOString","replaceAll","body","appendChild","click","remove","setTimeout","revokeObjectURL","_jsx","Modal","Root","open","onOpenChange","_jsxs","Content","Header","Title","Body","Flex","direction","alignItems","gap","Typography","variant","Box","hasRadius","padding","maxHeight","overflow","style","backgroundColor","tag","color","whiteSpace","wordBreak","margin","justifyContent","Loader","Footer","Close","Button","onClick","startIcon","Duplicate","disabled","Download"],"mappings":"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"}
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var React = require('react');
|
|
5
|
+
var designSystem = require('@strapi/design-system');
|
|
6
|
+
var icons = require('@strapi/icons');
|
|
7
|
+
var reactIntl = require('react-intl');
|
|
8
|
+
var getProjectType = require('../../../../../../../shared/utils/get-project-type.js');
|
|
9
|
+
var admin = require('../../../../../services/admin.js');
|
|
10
|
+
|
|
11
|
+
function _interopNamespace(e) {
|
|
12
|
+
if (e && e.__esModule) return e;
|
|
13
|
+
var n = Object.create(null);
|
|
14
|
+
if (e) {
|
|
15
|
+
Object.keys(e).forEach(function (k) {
|
|
16
|
+
if (k !== 'default') {
|
|
17
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
18
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
19
|
+
enumerable: true,
|
|
20
|
+
get: function () { return e[k]; }
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
n.default = e;
|
|
26
|
+
return Object.freeze(n);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* A single labelled value rendered inside the Plan card's `<dl>`. Shared between the CE fallback
|
|
33
|
+
* body (current plan only) and the EE body (license details), so both stay visually consistent.
|
|
34
|
+
*/ const PlanDetail = ({ label, value })=>{
|
|
35
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
36
|
+
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Grid.Item, {
|
|
37
|
+
col: 6,
|
|
38
|
+
xs: 12,
|
|
39
|
+
direction: "column",
|
|
40
|
+
alignItems: "start",
|
|
41
|
+
children: [
|
|
42
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
43
|
+
variant: "sigma",
|
|
44
|
+
textColor: "neutral600",
|
|
45
|
+
tag: "dt",
|
|
46
|
+
children: formatMessage(label)
|
|
47
|
+
}),
|
|
48
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
49
|
+
tag: "dd",
|
|
50
|
+
children: value
|
|
51
|
+
})
|
|
52
|
+
]
|
|
53
|
+
});
|
|
54
|
+
};
|
|
55
|
+
/* -------------------------------------------------------------------------------------------------
|
|
56
|
+
* PlanCard
|
|
57
|
+
* -----------------------------------------------------------------------------------------------*/ /**
|
|
58
|
+
* The billing link's label and destination depend on the current plan: Community links out to the
|
|
59
|
+
* public pricing page, while Growth and Enterprise link to the billing portal.
|
|
60
|
+
*/ const PLAN_LINK = {
|
|
61
|
+
Community: {
|
|
62
|
+
label: {
|
|
63
|
+
id: 'Settings.application.plan.see-all-plans',
|
|
64
|
+
defaultMessage: 'See all plans'
|
|
65
|
+
},
|
|
66
|
+
href: 'https://strapi.io/pricing-self-hosted'
|
|
67
|
+
},
|
|
68
|
+
Growth: {
|
|
69
|
+
label: {
|
|
70
|
+
id: 'Settings.application.plan.manage-subscription',
|
|
71
|
+
defaultMessage: 'Manage subscription'
|
|
72
|
+
},
|
|
73
|
+
href: 'https://billing.strapi.io'
|
|
74
|
+
},
|
|
75
|
+
Enterprise: {
|
|
76
|
+
label: {
|
|
77
|
+
id: 'Settings.application.plan.view-subscription',
|
|
78
|
+
defaultMessage: 'View subscription'
|
|
79
|
+
},
|
|
80
|
+
href: 'https://billing.strapi.io'
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
const PlanCardBodyCE = ()=>/*#__PURE__*/ jsxRuntime.jsx(designSystem.Grid.Root, {
|
|
84
|
+
gap: 5,
|
|
85
|
+
tag: "dl",
|
|
86
|
+
children: /*#__PURE__*/ jsxRuntime.jsx(PlanDetail, {
|
|
87
|
+
label: {
|
|
88
|
+
id: 'Settings.application.plan.current',
|
|
89
|
+
defaultMessage: 'current plan'
|
|
90
|
+
},
|
|
91
|
+
value: window.strapi.projectType
|
|
92
|
+
})
|
|
93
|
+
});
|
|
94
|
+
const PlanCard = ()=>{
|
|
95
|
+
const { formatMessage } = reactIntl.useIntl();
|
|
96
|
+
// The authenticated license-limit-information endpoint is EE-only, so a CE instance gets a
|
|
97
|
+
// 404 here; treat that (or any other error/missing data) the same as "no license".
|
|
98
|
+
// Until the first response, there is no telling which plan this is: painting the Community
|
|
99
|
+
// fallback and then swapping it out would name the wrong plan for a moment.
|
|
100
|
+
const { data: licenseLimitsData, isLoading: isLicenseLoading } = admin.useGetLicenseLimitsQuery();
|
|
101
|
+
const licenseStatus = licenseLimitsData?.data?.licenseStatus ?? 'none';
|
|
102
|
+
const planPriceId = licenseLimitsData?.data?.planPriceId ?? undefined;
|
|
103
|
+
// `useEnterprise`'s `enabled` option only ANDs with `isEE` - it can never force the EE body
|
|
104
|
+
// on for a non-EE instance. An expired/unknown license still needs to show its retained
|
|
105
|
+
// details even though `isEE` is (correctly) false, and an active one must show too when
|
|
106
|
+
// /admin/project-type failed and left `isEE` false. So the license body is loaded manually
|
|
107
|
+
// here instead, gated on this wider predicate.
|
|
108
|
+
// Deliberately an allowlist rather than `!== 'none'`: if `licenseStatus` is ever missing
|
|
109
|
+
// (an older bundle, a consumer building `window.strapi` itself), this must fall back to the
|
|
110
|
+
// Community body instead of loading the license section.
|
|
111
|
+
const shouldShowLicenseDetails = window.strapi.isEE || licenseStatus === 'active' || licenseStatus === 'expired' || licenseStatus === 'unknown';
|
|
112
|
+
const [LicenseBody, setLicenseBody] = React__namespace.useState(null);
|
|
113
|
+
React__namespace.useEffect(()=>{
|
|
114
|
+
if (!shouldShowLicenseDetails) {
|
|
115
|
+
return undefined;
|
|
116
|
+
}
|
|
117
|
+
let active = true;
|
|
118
|
+
Promise.resolve().then(function () { return require('../../../../../../../ee/admin/src/pages/SettingsPage/pages/ApplicationInfoPage/components/LicenseInfo.js'); }).then((mod)=>{
|
|
119
|
+
if (active) {
|
|
120
|
+
setLicenseBody(()=>mod.LicenseInfoEE);
|
|
121
|
+
}
|
|
122
|
+
}).catch((err)=>{
|
|
123
|
+
// A chunk can stop loading mid-session (a redeploy replaced the bundle). The body stays
|
|
124
|
+
// empty rather than falling back to the CE body, which would label this instance
|
|
125
|
+
// Community.
|
|
126
|
+
console.error(err);
|
|
127
|
+
});
|
|
128
|
+
return ()=>{
|
|
129
|
+
active = false;
|
|
130
|
+
};
|
|
131
|
+
}, [
|
|
132
|
+
shouldShowLicenseDetails
|
|
133
|
+
]);
|
|
134
|
+
// Render nothing for the body while the EE module is still loading (rather than the CE
|
|
135
|
+
// body) so the card never briefly shows "Community" before swapping to the actual license
|
|
136
|
+
// details. Once we know for certain there is no license to show, fall back to the CE body.
|
|
137
|
+
const PlanCardBody = isLicenseLoading ? null : LicenseBody ?? (shouldShowLicenseDetails ? null : PlanCardBodyCE);
|
|
138
|
+
const licensedPlan = getProjectType.getLicensedPlan({
|
|
139
|
+
licenseStatus,
|
|
140
|
+
type: licenseLimitsData?.data?.type,
|
|
141
|
+
planPriceId
|
|
142
|
+
});
|
|
143
|
+
const { label, href } = PLAN_LINK[licensedPlan] ?? PLAN_LINK.Community;
|
|
144
|
+
return /*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
|
|
145
|
+
direction: "column",
|
|
146
|
+
alignItems: "stretch",
|
|
147
|
+
gap: 4,
|
|
148
|
+
hasRadius: true,
|
|
149
|
+
background: "neutral0",
|
|
150
|
+
shadow: "tableShadow",
|
|
151
|
+
paddingTop: 6,
|
|
152
|
+
paddingBottom: 6,
|
|
153
|
+
paddingRight: 7,
|
|
154
|
+
paddingLeft: 7,
|
|
155
|
+
children: [
|
|
156
|
+
/*#__PURE__*/ jsxRuntime.jsxs(designSystem.Flex, {
|
|
157
|
+
justifyContent: "space-between",
|
|
158
|
+
alignItems: "center",
|
|
159
|
+
children: [
|
|
160
|
+
/*#__PURE__*/ jsxRuntime.jsx(designSystem.Typography, {
|
|
161
|
+
variant: "delta",
|
|
162
|
+
tag: "h3",
|
|
163
|
+
children: formatMessage({
|
|
164
|
+
id: 'Settings.application.plan.title',
|
|
165
|
+
defaultMessage: 'Plan'
|
|
166
|
+
})
|
|
167
|
+
}),
|
|
168
|
+
!isLicenseLoading && /*#__PURE__*/ jsxRuntime.jsx(designSystem.LinkButton, {
|
|
169
|
+
variant: "secondary",
|
|
170
|
+
endIcon: /*#__PURE__*/ jsxRuntime.jsx(icons.ExternalLink, {}),
|
|
171
|
+
href: href,
|
|
172
|
+
target: "_blank",
|
|
173
|
+
rel: "noopener noreferrer",
|
|
174
|
+
children: formatMessage(label)
|
|
175
|
+
})
|
|
176
|
+
]
|
|
177
|
+
}),
|
|
178
|
+
PlanCardBody && /*#__PURE__*/ jsxRuntime.jsx(PlanCardBody, {})
|
|
179
|
+
]
|
|
180
|
+
});
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
exports.PlanCard = PlanCard;
|
|
184
|
+
exports.PlanDetail = PlanDetail;
|
|
185
|
+
//# sourceMappingURL=PlanCard.js.map
|