@digitaldefiance/express-suite-react-components 4.26.15 → 4.26.16
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/package.json +2 -2
- package/src/components/FakeEmailAdminPanel.d.ts +23 -0
- package/src/components/FakeEmailAdminPanel.d.ts.map +1 -0
- package/src/components/FakeEmailAdminPanel.js +89 -0
- package/src/components/index.d.ts +1 -0
- package/src/components/index.d.ts.map +1 -1
- package/src/components/index.js +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@digitaldefiance/express-suite-react-components",
|
|
3
|
-
"version": "4.26.
|
|
3
|
+
"version": "4.26.16",
|
|
4
4
|
"homepage": "https://github.com/Digital-Defiance/react-components",
|
|
5
5
|
"description": "React MUI components for Digital Defiance Express Suite",
|
|
6
6
|
"repository": {
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@digitaldefiance/i18n-lib": "4.7.3",
|
|
35
|
-
"@digitaldefiance/suite-core-lib": "4.26.
|
|
35
|
+
"@digitaldefiance/suite-core-lib": "4.26.9",
|
|
36
36
|
"@emotion/react": "^11.14.0",
|
|
37
37
|
"@emotion/styled": "^11.14.0",
|
|
38
38
|
"@mui/icons-material": "^7.0.2",
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { FC } from 'react';
|
|
2
|
+
/** Shape of a single captured email as returned by AdminEmailRouter */
|
|
3
|
+
export interface CapturedEmailInfo {
|
|
4
|
+
to: string;
|
|
5
|
+
subject: string;
|
|
6
|
+
text: string;
|
|
7
|
+
html: string;
|
|
8
|
+
timestamp: string;
|
|
9
|
+
}
|
|
10
|
+
/** Shape of a recipient summary as returned by GET /api/admin/emails */
|
|
11
|
+
export interface RecipientSummary {
|
|
12
|
+
address: string;
|
|
13
|
+
count: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const FakeEmailAdminPanel: FC;
|
|
16
|
+
export default FakeEmailAdminPanel;
|
|
17
|
+
export interface FakeEmailAdminButtonsProps {
|
|
18
|
+
onRefresh: () => void;
|
|
19
|
+
onClear: () => void;
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
}
|
|
22
|
+
export declare const FakeEmailAdminButtons: FC<FakeEmailAdminButtonsProps>;
|
|
23
|
+
//# sourceMappingURL=FakeEmailAdminPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FakeEmailAdminPanel.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-express-suite-react-components/src/components/FakeEmailAdminPanel.tsx"],"names":[],"mappings":"AAkCA,OAAO,EAAE,EAAE,EAAoC,MAAM,OAAO,CAAC;AAK7D,uEAAuE;AACvE,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,eAAO,MAAM,mBAAmB,EAAE,EAgLjC,CAAC;AAEF,eAAe,mBAAmB,CAAC;AAGnC,MAAM,WAAW,0BAA0B;IACzC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED,eAAO,MAAM,qBAAqB,EAAE,EAAE,CAAC,0BAA0B,CA8BhE,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FakeEmailAdminButtons = exports.FakeEmailAdminPanel = void 0;
|
|
4
|
+
const tslib_1 = require("tslib");
|
|
5
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
6
|
+
/**
|
|
7
|
+
* FakeEmailAdminPanel — dev-only panel for inspecting captured emails.
|
|
8
|
+
*
|
|
9
|
+
* Renders only in development/test environments where FakeEmailService is
|
|
10
|
+
* active. Calls the AdminEmailRouter endpoints mounted at `baseUrl/api/admin/emails`.
|
|
11
|
+
*
|
|
12
|
+
* Usage (inside AuthenticatedApiProvider + SuiteConfigProvider):
|
|
13
|
+
* <FakeEmailAdminPanel />
|
|
14
|
+
*/
|
|
15
|
+
const suite_core_lib_1 = require("@digitaldefiance/suite-core-lib");
|
|
16
|
+
const Delete_1 = tslib_1.__importDefault(require("@mui/icons-material/Delete"));
|
|
17
|
+
const ExpandLess_1 = tslib_1.__importDefault(require("@mui/icons-material/ExpandLess"));
|
|
18
|
+
const ExpandMore_1 = tslib_1.__importDefault(require("@mui/icons-material/ExpandMore"));
|
|
19
|
+
const Refresh_1 = tslib_1.__importDefault(require("@mui/icons-material/Refresh"));
|
|
20
|
+
const material_1 = require("@mui/material");
|
|
21
|
+
const react_1 = require("react");
|
|
22
|
+
const contexts_1 = require("../contexts");
|
|
23
|
+
const ConfirmationDialog_1 = require("./ConfirmationDialog");
|
|
24
|
+
const useAuthenticatedApi_1 = require("../hooks/useAuthenticatedApi");
|
|
25
|
+
const FakeEmailAdminPanel = () => {
|
|
26
|
+
const api = (0, useAuthenticatedApi_1.useAuthenticatedApi)();
|
|
27
|
+
const { tComponent } = (0, contexts_1.useI18n)();
|
|
28
|
+
const t = (key) => tComponent(suite_core_lib_1.SuiteCoreComponentId, key);
|
|
29
|
+
const [recipients, setRecipients] = (0, react_1.useState)([]);
|
|
30
|
+
const [expanded, setExpanded] = (0, react_1.useState)(null);
|
|
31
|
+
const [emailsByAddress, setEmailsByAddress] = (0, react_1.useState)({});
|
|
32
|
+
const [loading, setLoading] = (0, react_1.useState)(false);
|
|
33
|
+
const [error, setError] = (0, react_1.useState)(null);
|
|
34
|
+
const [clearDialogOpen, setClearDialogOpen] = (0, react_1.useState)(false);
|
|
35
|
+
const loadRecipients = (0, react_1.useCallback)(async () => {
|
|
36
|
+
setLoading(true);
|
|
37
|
+
setError(null);
|
|
38
|
+
try {
|
|
39
|
+
const res = await api.get('/api/admin/emails');
|
|
40
|
+
setRecipients(res.data.recipients);
|
|
41
|
+
}
|
|
42
|
+
catch (err) {
|
|
43
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
44
|
+
}
|
|
45
|
+
finally {
|
|
46
|
+
setLoading(false);
|
|
47
|
+
}
|
|
48
|
+
}, [api]);
|
|
49
|
+
(0, react_1.useEffect)(() => {
|
|
50
|
+
void loadRecipients();
|
|
51
|
+
}, [loadRecipients]);
|
|
52
|
+
const toggleExpand = (0, react_1.useCallback)(async (address) => {
|
|
53
|
+
if (expanded === address) {
|
|
54
|
+
setExpanded(null);
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
setExpanded(address);
|
|
58
|
+
if (!emailsByAddress[address]) {
|
|
59
|
+
try {
|
|
60
|
+
const res = await api.get(`/api/admin/emails/${encodeURIComponent(address)}`);
|
|
61
|
+
setEmailsByAddress((prev) => ({ ...prev, [address]: res.data }));
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}, [api, expanded, emailsByAddress]);
|
|
68
|
+
const handleClearAll = (0, react_1.useCallback)(async () => {
|
|
69
|
+
setClearDialogOpen(false);
|
|
70
|
+
try {
|
|
71
|
+
await api.delete('/api/admin/emails');
|
|
72
|
+
setRecipients([]);
|
|
73
|
+
setEmailsByAddress({});
|
|
74
|
+
setExpanded(null);
|
|
75
|
+
}
|
|
76
|
+
catch (err) {
|
|
77
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
78
|
+
}
|
|
79
|
+
}, [api]);
|
|
80
|
+
return ((0, jsx_runtime_1.jsxs)(material_1.Paper, { variant: "outlined", sx: { p: 2 }, children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { display: 'flex', alignItems: 'center', gap: 1, mb: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "subtitle1", fontWeight: "bold", sx: { flexGrow: 1 }, children: t(suite_core_lib_1.SuiteCoreStringKey.FakeEmail_Admin_Title) }), (0, jsx_runtime_1.jsx)(material_1.Chip, { label: "DEV", size: "small", color: "warning" }), (0, jsx_runtime_1.jsx)(material_1.IconButton, { size: "small", onClick: () => void loadRecipients(), title: t(suite_core_lib_1.SuiteCoreStringKey.FakeEmail_Admin_Refresh), children: (0, jsx_runtime_1.jsx)(Refresh_1.default, { fontSize: "small" }) }), (0, jsx_runtime_1.jsx)(material_1.IconButton, { size: "small", color: "error", onClick: () => setClearDialogOpen(true), title: t(suite_core_lib_1.SuiteCoreStringKey.FakeEmail_Admin_ClearAll), disabled: recipients.length === 0, children: (0, jsx_runtime_1.jsx)(Delete_1.default, { fontSize: "small" }) })] }), (0, jsx_runtime_1.jsx)(material_1.Divider, { sx: { mb: 1 } }), error && ((0, jsx_runtime_1.jsx)(material_1.Alert, { severity: "error", sx: { mb: 1 }, onClose: () => setError(null), children: error })), loading && ((0, jsx_runtime_1.jsx)(material_1.Box, { sx: { display: 'flex', justifyContent: 'center', py: 2 }, children: (0, jsx_runtime_1.jsx)(material_1.CircularProgress, { size: 24 }) })), !loading && recipients.length === 0 && ((0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", children: t(suite_core_lib_1.SuiteCoreStringKey.FakeEmail_Admin_NoRecipients) })), !loading && recipients.length > 0 && ((0, jsx_runtime_1.jsx)(material_1.List, { dense: true, disablePadding: true, children: recipients.map((r) => ((0, jsx_runtime_1.jsxs)(material_1.Box, { children: [(0, jsx_runtime_1.jsxs)(material_1.ListItemButton, { onClick: () => void toggleExpand(r.address), sx: { px: 0, py: 0.5 }, children: [(0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: r.address, secondary: `${r.count} ${t(suite_core_lib_1.SuiteCoreStringKey.FakeEmail_Admin_Recipients)}` }), expanded === r.address ? ((0, jsx_runtime_1.jsx)(ExpandLess_1.default, { fontSize: "small" })) : ((0, jsx_runtime_1.jsx)(ExpandMore_1.default, { fontSize: "small" }))] }), (0, jsx_runtime_1.jsx)(material_1.Collapse, { in: expanded === r.address, unmountOnExit: true, children: emailsByAddress[r.address]?.length === 0 ? ((0, jsx_runtime_1.jsx)(material_1.Typography, { variant: "body2", color: "text.secondary", sx: { pl: 2, py: 0.5 }, children: t(suite_core_lib_1.SuiteCoreStringKey.FakeEmail_Admin_NoEmails) })) : ((0, jsx_runtime_1.jsx)(material_1.List, { dense: true, disablePadding: true, sx: { pl: 2 }, children: (emailsByAddress[r.address] ?? []).map((email, idx) => ((0, jsx_runtime_1.jsx)(material_1.ListItem, { disablePadding: true, sx: { py: 0.25 }, children: (0, jsx_runtime_1.jsx)(material_1.ListItemText, { primary: email.subject || '(no subject)', secondary: `${t(suite_core_lib_1.SuiteCoreStringKey.FakeEmail_Admin_Timestamp)}: ${new Date(email.timestamp).toLocaleString()}`, primaryTypographyProps: { variant: 'body2' }, secondaryTypographyProps: { variant: 'caption' } }) }, idx))) })) }), (0, jsx_runtime_1.jsx)(material_1.Divider, {})] }, r.address))) })), (0, jsx_runtime_1.jsx)(ConfirmationDialog_1.ConfirmationDialog, { open: clearDialogOpen, title: t(suite_core_lib_1.SuiteCoreStringKey.FakeEmail_Admin_ClearAll), message: t(suite_core_lib_1.SuiteCoreStringKey.FakeEmail_Admin_ClearConfirm), onConfirm: () => void handleClearAll(), onCancel: () => setClearDialogOpen(false) })] }));
|
|
81
|
+
};
|
|
82
|
+
exports.FakeEmailAdminPanel = FakeEmailAdminPanel;
|
|
83
|
+
exports.default = exports.FakeEmailAdminPanel;
|
|
84
|
+
const FakeEmailAdminButtons = ({ onRefresh, onClear, disabled = false, }) => {
|
|
85
|
+
const { tComponent } = (0, contexts_1.useI18n)();
|
|
86
|
+
const t = (key) => tComponent(suite_core_lib_1.SuiteCoreComponentId, key);
|
|
87
|
+
return ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { display: 'flex', gap: 1 }, children: [(0, jsx_runtime_1.jsx)(material_1.Button, { size: "small", startIcon: (0, jsx_runtime_1.jsx)(Refresh_1.default, {}), onClick: onRefresh, disabled: disabled, children: t(suite_core_lib_1.SuiteCoreStringKey.FakeEmail_Admin_Refresh) }), (0, jsx_runtime_1.jsx)(material_1.Button, { size: "small", color: "error", startIcon: (0, jsx_runtime_1.jsx)(Delete_1.default, {}), onClick: onClear, disabled: disabled, children: t(suite_core_lib_1.SuiteCoreStringKey.FakeEmail_Admin_ClearAll) })] }));
|
|
88
|
+
};
|
|
89
|
+
exports.FakeEmailAdminButtons = FakeEmailAdminButtons;
|
|
@@ -8,6 +8,7 @@ export * from './CurrencyInput';
|
|
|
8
8
|
export * from './DashboardPage';
|
|
9
9
|
export * from './DropdownMenu';
|
|
10
10
|
export * from './ExpirationSecondsSelector';
|
|
11
|
+
export * from './FakeEmailAdminPanel';
|
|
11
12
|
export * from './Flag';
|
|
12
13
|
export * from './ForgotPasswordForm';
|
|
13
14
|
export * from './LoginForm';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-express-suite-react-components/src/components/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,QAAQ,CAAC;AACvB,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,KAAK,CAAC;AACpB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../packages/digitaldefiance-express-suite-react-components/src/components/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC;AACtC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,6BAA6B,CAAC;AAC5C,cAAc,uBAAuB,CAAC;AACtC,cAAc,QAAQ,CAAC;AACvB,cAAc,sBAAsB,CAAC;AACrC,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC;AACnC,cAAc,YAAY,CAAC;AAC3B,cAAc,oBAAoB,CAAC;AACnC,cAAc,WAAW,CAAC;AAC1B,cAAc,mBAAmB,CAAC;AAClC,cAAc,YAAY,CAAC;AAC3B,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,KAAK,CAAC;AACpB,cAAc,QAAQ,CAAC;AACvB,cAAc,WAAW,CAAC"}
|
package/src/components/index.js
CHANGED
|
@@ -12,6 +12,7 @@ tslib_1.__exportStar(require("./CurrencyInput"), exports);
|
|
|
12
12
|
tslib_1.__exportStar(require("./DashboardPage"), exports);
|
|
13
13
|
tslib_1.__exportStar(require("./DropdownMenu"), exports);
|
|
14
14
|
tslib_1.__exportStar(require("./ExpirationSecondsSelector"), exports);
|
|
15
|
+
tslib_1.__exportStar(require("./FakeEmailAdminPanel"), exports);
|
|
15
16
|
tslib_1.__exportStar(require("./Flag"), exports);
|
|
16
17
|
tslib_1.__exportStar(require("./ForgotPasswordForm"), exports);
|
|
17
18
|
tslib_1.__exportStar(require("./LoginForm"), exports);
|