quidproquo-web-admin 0.1.10 → 0.1.11

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.
Files changed (163) hide show
  1. package/lib/commonjs/ActionSearch/ActionSearch.d.ts +1 -0
  2. package/lib/commonjs/ActionSearch/ActionSearch.js +80 -0
  3. package/lib/commonjs/ActionSearch/ActionSearch.js.map +1 -0
  4. package/lib/commonjs/ActionSearch/components/ActionSearchFilterForm.d.ts +8 -0
  5. package/lib/commonjs/ActionSearch/components/ActionSearchFilterForm.js +36 -0
  6. package/lib/commonjs/ActionSearch/components/ActionSearchFilterForm.js.map +1 -0
  7. package/lib/commonjs/ActionSearch/components/ActionSearchGrid.d.ts +10 -0
  8. package/lib/commonjs/ActionSearch/components/ActionSearchGrid.js +39 -0
  9. package/lib/commonjs/ActionSearch/components/ActionSearchGrid.js.map +1 -0
  10. package/lib/commonjs/ActionSearch/components/EntityTimelineDialog.d.ts +9 -0
  11. package/lib/commonjs/ActionSearch/components/EntityTimelineDialog.js +27 -0
  12. package/lib/commonjs/ActionSearch/components/EntityTimelineDialog.js.map +1 -0
  13. package/lib/commonjs/ActionSearch/hooks/useActionSearch.d.ts +9 -0
  14. package/lib/commonjs/ActionSearch/hooks/useActionSearch.js +52 -0
  15. package/lib/commonjs/ActionSearch/hooks/useActionSearch.js.map +1 -0
  16. package/lib/commonjs/ActionSearch/hooks/useActionSearchViews.d.ts +2 -0
  17. package/lib/commonjs/ActionSearch/hooks/useActionSearchViews.js +31 -0
  18. package/lib/commonjs/ActionSearch/hooks/useActionSearchViews.js.map +1 -0
  19. package/lib/commonjs/ActionSearch/index.d.ts +1 -0
  20. package/lib/commonjs/ActionSearch/index.js +18 -0
  21. package/lib/commonjs/ActionSearch/index.js.map +1 -0
  22. package/lib/commonjs/ActionSearch/types/ActionSearchView.d.ts +7 -0
  23. package/lib/commonjs/ActionSearch/types/ActionSearchView.js +3 -0
  24. package/lib/commonjs/ActionSearch/types/ActionSearchView.js.map +1 -0
  25. package/lib/commonjs/ActionSearch/types/EntityTimeline.d.ts +5 -0
  26. package/lib/commonjs/ActionSearch/types/EntityTimeline.js +3 -0
  27. package/lib/commonjs/ActionSearch/types/EntityTimeline.js.map +1 -0
  28. package/lib/commonjs/ActionSearch/types/index.d.ts +2 -0
  29. package/lib/commonjs/ActionSearch/types/index.js +19 -0
  30. package/lib/commonjs/ActionSearch/types/index.js.map +1 -0
  31. package/lib/commonjs/LogViewer/actionComponents/custom/WebserverEmailSendEmailCustomAction.d.ts +3 -0
  32. package/lib/commonjs/LogViewer/actionComponents/custom/WebserverEmailSendEmailCustomAction.js +61 -0
  33. package/lib/commonjs/LogViewer/actionComponents/custom/WebserverEmailSendEmailCustomAction.js.map +1 -0
  34. package/lib/commonjs/LogViewer/actionComponents/custom/index.d.ts +1 -0
  35. package/lib/commonjs/LogViewer/actionComponents/custom/index.js +1 -0
  36. package/lib/commonjs/LogViewer/actionComponents/custom/index.js.map +1 -1
  37. package/lib/commonjs/LogViewer/actionComponents/customActionsMap/index.js +2 -1
  38. package/lib/commonjs/LogViewer/actionComponents/customActionsMap/index.js.map +1 -1
  39. package/lib/commonjs/LogViewer/actionComponents/customActionsMap/webserver/index.d.ts +4 -0
  40. package/lib/commonjs/LogViewer/actionComponents/customActionsMap/webserver/index.js +8 -0
  41. package/lib/commonjs/LogViewer/actionComponents/customActionsMap/webserver/index.js.map +1 -0
  42. package/lib/commonjs/LogViewer/actionComponents/customActionsMap/webserver/webserverEmailActionComponentMap.d.ts +3 -0
  43. package/lib/commonjs/LogViewer/actionComponents/customActionsMap/webserver/webserverEmailActionComponentMap.js +9 -0
  44. package/lib/commonjs/LogViewer/actionComponents/customActionsMap/webserver/webserverEmailActionComponentMap.js.map +1 -0
  45. package/lib/commonjs/LogViewer/logic/actionComponentMap/webserver/index.js +2 -1
  46. package/lib/commonjs/LogViewer/logic/actionComponentMap/webserver/index.js.map +1 -1
  47. package/lib/commonjs/LogViewer/logic/actionComponentMap/webserver/webserverEmailActionComponentMap.d.ts +2 -0
  48. package/lib/commonjs/LogViewer/logic/actionComponentMap/webserver/webserverEmailActionComponentMap.js +9 -0
  49. package/lib/commonjs/LogViewer/logic/actionComponentMap/webserver/webserverEmailActionComponentMap.js.map +1 -0
  50. package/lib/commonjs/Maintenance/Maintenance.d.ts +1 -0
  51. package/lib/commonjs/Maintenance/Maintenance.js +17 -0
  52. package/lib/commonjs/Maintenance/Maintenance.js.map +1 -0
  53. package/lib/commonjs/Maintenance/MaintenanceEditor.d.ts +6 -0
  54. package/lib/commonjs/Maintenance/MaintenanceEditor.js +124 -0
  55. package/lib/commonjs/Maintenance/MaintenanceEditor.js.map +1 -0
  56. package/lib/commonjs/Maintenance/MaintenanceList.d.ts +5 -0
  57. package/lib/commonjs/Maintenance/MaintenanceList.js +86 -0
  58. package/lib/commonjs/Maintenance/MaintenanceList.js.map +1 -0
  59. package/lib/commonjs/Maintenance/MaintenanceUserPreview.d.ts +9 -0
  60. package/lib/commonjs/Maintenance/MaintenanceUserPreview.js +52 -0
  61. package/lib/commonjs/Maintenance/MaintenanceUserPreview.js.map +1 -0
  62. package/lib/commonjs/Maintenance/UpdateDialog.d.ts +37 -0
  63. package/lib/commonjs/Maintenance/UpdateDialog.js +51 -0
  64. package/lib/commonjs/Maintenance/UpdateDialog.js.map +1 -0
  65. package/lib/commonjs/Maintenance/index.d.ts +1 -0
  66. package/lib/commonjs/Maintenance/index.js +18 -0
  67. package/lib/commonjs/Maintenance/index.js.map +1 -0
  68. package/lib/commonjs/Maintenance/logic/etaOptions.d.ts +6 -0
  69. package/lib/commonjs/Maintenance/logic/etaOptions.js +14 -0
  70. package/lib/commonjs/Maintenance/logic/etaOptions.js.map +1 -0
  71. package/lib/commonjs/Maintenance/logic/index.d.ts +2 -0
  72. package/lib/commonjs/Maintenance/logic/index.js +19 -0
  73. package/lib/commonjs/Maintenance/logic/index.js.map +1 -0
  74. package/lib/commonjs/Maintenance/logic/maintenanceApi.d.ts +5 -0
  75. package/lib/commonjs/Maintenance/logic/maintenanceApi.js +49 -0
  76. package/lib/commonjs/Maintenance/logic/maintenanceApi.js.map +1 -0
  77. package/lib/commonjs/components/MainLayout/hooks/useTabs.js +14 -0
  78. package/lib/commonjs/components/MainLayout/hooks/useTabs.js.map +1 -1
  79. package/lib/commonjs/view/hooks/useAsyncRequest.d.ts +8 -0
  80. package/lib/commonjs/view/hooks/useAsyncRequest.js +18 -1
  81. package/lib/commonjs/view/hooks/useAsyncRequest.js.map +1 -1
  82. package/lib/esm/ActionSearch/ActionSearch.d.ts +1 -0
  83. package/lib/esm/ActionSearch/ActionSearch.js +63 -0
  84. package/lib/esm/ActionSearch/ActionSearch.js.map +1 -0
  85. package/lib/esm/ActionSearch/components/ActionSearchFilterForm.d.ts +8 -0
  86. package/lib/esm/ActionSearch/components/ActionSearchFilterForm.js +33 -0
  87. package/lib/esm/ActionSearch/components/ActionSearchFilterForm.js.map +1 -0
  88. package/lib/esm/ActionSearch/components/ActionSearchGrid.d.ts +10 -0
  89. package/lib/esm/ActionSearch/components/ActionSearchGrid.js +35 -0
  90. package/lib/esm/ActionSearch/components/ActionSearchGrid.js.map +1 -0
  91. package/lib/esm/ActionSearch/components/EntityTimelineDialog.d.ts +9 -0
  92. package/lib/esm/ActionSearch/components/EntityTimelineDialog.js +14 -0
  93. package/lib/esm/ActionSearch/components/EntityTimelineDialog.js.map +1 -0
  94. package/lib/esm/ActionSearch/hooks/useActionSearch.d.ts +9 -0
  95. package/lib/esm/ActionSearch/hooks/useActionSearch.js +42 -0
  96. package/lib/esm/ActionSearch/hooks/useActionSearch.js.map +1 -0
  97. package/lib/esm/ActionSearch/hooks/useActionSearchViews.d.ts +2 -0
  98. package/lib/esm/ActionSearch/hooks/useActionSearchViews.js +27 -0
  99. package/lib/esm/ActionSearch/hooks/useActionSearchViews.js.map +1 -0
  100. package/lib/esm/ActionSearch/index.d.ts +1 -0
  101. package/lib/esm/ActionSearch/index.js +2 -0
  102. package/lib/esm/ActionSearch/index.js.map +1 -0
  103. package/lib/esm/ActionSearch/types/ActionSearchView.d.ts +7 -0
  104. package/lib/esm/ActionSearch/types/ActionSearchView.js +2 -0
  105. package/lib/esm/ActionSearch/types/ActionSearchView.js.map +1 -0
  106. package/lib/esm/ActionSearch/types/EntityTimeline.d.ts +5 -0
  107. package/lib/esm/ActionSearch/types/EntityTimeline.js +2 -0
  108. package/lib/esm/ActionSearch/types/EntityTimeline.js.map +1 -0
  109. package/lib/esm/ActionSearch/types/index.d.ts +2 -0
  110. package/lib/esm/ActionSearch/types/index.js +3 -0
  111. package/lib/esm/ActionSearch/types/index.js.map +1 -0
  112. package/lib/esm/LogViewer/actionComponents/custom/WebserverEmailSendEmailCustomAction.d.ts +3 -0
  113. package/lib/esm/LogViewer/actionComponents/custom/WebserverEmailSendEmailCustomAction.js +54 -0
  114. package/lib/esm/LogViewer/actionComponents/custom/WebserverEmailSendEmailCustomAction.js.map +1 -0
  115. package/lib/esm/LogViewer/actionComponents/custom/index.d.ts +1 -0
  116. package/lib/esm/LogViewer/actionComponents/custom/index.js +1 -0
  117. package/lib/esm/LogViewer/actionComponents/custom/index.js.map +1 -1
  118. package/lib/esm/LogViewer/actionComponents/customActionsMap/index.js +2 -0
  119. package/lib/esm/LogViewer/actionComponents/customActionsMap/index.js.map +1 -1
  120. package/lib/esm/LogViewer/actionComponents/customActionsMap/webserver/index.d.ts +4 -0
  121. package/lib/esm/LogViewer/actionComponents/customActionsMap/webserver/index.js +5 -0
  122. package/lib/esm/LogViewer/actionComponents/customActionsMap/webserver/index.js.map +1 -0
  123. package/lib/esm/LogViewer/actionComponents/customActionsMap/webserver/webserverEmailActionComponentMap.d.ts +3 -0
  124. package/lib/esm/LogViewer/actionComponents/customActionsMap/webserver/webserverEmailActionComponentMap.js +7 -0
  125. package/lib/esm/LogViewer/actionComponents/customActionsMap/webserver/webserverEmailActionComponentMap.js.map +1 -0
  126. package/lib/esm/LogViewer/logic/actionComponentMap/webserver/index.js +2 -0
  127. package/lib/esm/LogViewer/logic/actionComponentMap/webserver/index.js.map +1 -1
  128. package/lib/esm/LogViewer/logic/actionComponentMap/webserver/webserverEmailActionComponentMap.d.ts +2 -0
  129. package/lib/esm/LogViewer/logic/actionComponentMap/webserver/webserverEmailActionComponentMap.js +7 -0
  130. package/lib/esm/LogViewer/logic/actionComponentMap/webserver/webserverEmailActionComponentMap.js.map +1 -0
  131. package/lib/esm/Maintenance/Maintenance.d.ts +1 -0
  132. package/lib/esm/Maintenance/Maintenance.js +14 -0
  133. package/lib/esm/Maintenance/Maintenance.js.map +1 -0
  134. package/lib/esm/Maintenance/MaintenanceEditor.d.ts +6 -0
  135. package/lib/esm/Maintenance/MaintenanceEditor.js +111 -0
  136. package/lib/esm/Maintenance/MaintenanceEditor.js.map +1 -0
  137. package/lib/esm/Maintenance/MaintenanceList.d.ts +5 -0
  138. package/lib/esm/Maintenance/MaintenanceList.js +71 -0
  139. package/lib/esm/Maintenance/MaintenanceList.js.map +1 -0
  140. package/lib/esm/Maintenance/MaintenanceUserPreview.d.ts +9 -0
  141. package/lib/esm/Maintenance/MaintenanceUserPreview.js +49 -0
  142. package/lib/esm/Maintenance/MaintenanceUserPreview.js.map +1 -0
  143. package/lib/esm/Maintenance/UpdateDialog.d.ts +37 -0
  144. package/lib/esm/Maintenance/UpdateDialog.js +52 -0
  145. package/lib/esm/Maintenance/UpdateDialog.js.map +1 -0
  146. package/lib/esm/Maintenance/index.d.ts +1 -0
  147. package/lib/esm/Maintenance/index.js +2 -0
  148. package/lib/esm/Maintenance/index.js.map +1 -0
  149. package/lib/esm/Maintenance/logic/etaOptions.d.ts +6 -0
  150. package/lib/esm/Maintenance/logic/etaOptions.js +11 -0
  151. package/lib/esm/Maintenance/logic/etaOptions.js.map +1 -0
  152. package/lib/esm/Maintenance/logic/index.d.ts +2 -0
  153. package/lib/esm/Maintenance/logic/index.js +3 -0
  154. package/lib/esm/Maintenance/logic/index.js.map +1 -0
  155. package/lib/esm/Maintenance/logic/maintenanceApi.d.ts +5 -0
  156. package/lib/esm/Maintenance/logic/maintenanceApi.js +33 -0
  157. package/lib/esm/Maintenance/logic/maintenanceApi.js.map +1 -0
  158. package/lib/esm/components/MainLayout/hooks/useTabs.js +14 -0
  159. package/lib/esm/components/MainLayout/hooks/useTabs.js.map +1 -1
  160. package/lib/esm/view/hooks/useAsyncRequest.d.ts +8 -0
  161. package/lib/esm/view/hooks/useAsyncRequest.js +17 -1
  162. package/lib/esm/view/hooks/useAsyncRequest.js.map +1 -1
  163. package/package.json +7 -7
@@ -0,0 +1 @@
1
+ export declare const ActionSearch: () => import("react").JSX.Element;
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ exports.ActionSearch = void 0;
16
+ const jsx_runtime_1 = require("react/jsx-runtime");
17
+ const react_1 = require("react");
18
+ const FormControl_1 = __importDefault(require("@mui/material/FormControl"));
19
+ const Grid_1 = __importDefault(require("@mui/material/Grid"));
20
+ const InputLabel_1 = __importDefault(require("@mui/material/InputLabel"));
21
+ const MenuItem_1 = __importDefault(require("@mui/material/MenuItem"));
22
+ const Select_1 = __importDefault(require("@mui/material/Select"));
23
+ const x_date_pickers_1 = require("@mui/x-date-pickers");
24
+ const AdapterDateFns_1 = require("@mui/x-date-pickers/AdapterDateFns");
25
+ const adminApp_1 = require("../adminApp");
26
+ const AsyncButton_1 = require("../components/AsyncButton");
27
+ const TabViewBox_1 = require("../components/TabViewBox");
28
+ const LogDialog_1 = require("../LogViewer/LogDialog");
29
+ const useAsyncRequest_1 = require("../view/hooks/useAsyncRequest");
30
+ const ActionSearchFilterForm_1 = require("./components/ActionSearchFilterForm");
31
+ const ActionSearchGrid_1 = require("./components/ActionSearchGrid");
32
+ const EntityTimelineDialog_1 = require("./components/EntityTimelineDialog");
33
+ const useActionSearch_1 = require("./hooks/useActionSearch");
34
+ const useActionSearchViews_1 = require("./hooks/useActionSearchViews");
35
+ const DAY_IN_MS = 24 * 60 * 60 * 1000;
36
+ const ActionSearch = () => {
37
+ var _a, _b, _c, _d;
38
+ const [api] = (0, adminApp_1.useAdminApp)();
39
+ const session = (0, adminApp_1.useSessionState)();
40
+ const views = (0, useActionSearchViews_1.useActionSearchViews)();
41
+ const [viewKey, setViewKey] = (0, react_1.useState)((_b = (_a = views[0]) === null || _a === void 0 ? void 0 : _a.key) !== null && _b !== void 0 ? _b : '');
42
+ const [startDate, setStartDate] = (0, react_1.useState)(() => new Date(Date.now() - DAY_IN_MS));
43
+ const [endDate, setEndDate] = (0, react_1.useState)(() => new Date());
44
+ const [filters, setFilters] = (0, react_1.useState)([]);
45
+ const [timeline, setTimeline] = (0, react_1.useState)(null);
46
+ const getEntityTimeline = (0, useAsyncRequest_1.usePlatformApiPost)('/actionSearch/entity/timeline');
47
+ const view = (_c = views.find((searchView) => searchView.key === viewKey)) !== null && _c !== void 0 ? _c : null;
48
+ const { rows, isSearching, runSearch } = (0, useActionSearch_1.useActionSearch)(view);
49
+ const handleViewChange = (event) => {
50
+ setViewKey(event.target.value);
51
+ setFilters([]);
52
+ };
53
+ const handleSearch = () => __awaiter(void 0, void 0, void 0, function* () {
54
+ if (!startDate || !endDate) {
55
+ return;
56
+ }
57
+ yield runSearch(startDate.toISOString(), endDate.toISOString(), filters);
58
+ });
59
+ const openLog = (correlation) => api.applyCorrelationOpened(correlation, adminApp_1.CorrelationOpenSource.grid);
60
+ // Fetch here, in the event that creates the need, so the dialog stays presentational
61
+ const openEntityTimeline = (linkKey) => __awaiter(void 0, void 0, void 0, function* () {
62
+ const rows = yield getEntityTimeline({ linkKey });
63
+ setTimeline({ linkKey, rows });
64
+ });
65
+ const handleRowClick = (row) => {
66
+ if ((view === null || view === void 0 ? void 0 : view.kind) === 'entity') {
67
+ openEntityTimeline(String(row.linkKey));
68
+ return;
69
+ }
70
+ openLog(String(row.correlation));
71
+ };
72
+ const selectedLogCorrelation = (_d = session.openCorrelation) !== null && _d !== void 0 ? _d : '';
73
+ const clearSelectedLogCorrelation = () => api.applyCorrelationClosed();
74
+ const setSelectedLogCorrelation = (correlation) => api.applyCorrelationOpened(correlation, adminApp_1.CorrelationOpenSource.tree);
75
+ const renderHeader = () => ((0, jsx_runtime_1.jsx)(x_date_pickers_1.LocalizationProvider, { dateAdapter: AdapterDateFns_1.AdapterDateFns, children: (0, jsx_runtime_1.jsxs)(Grid_1.default, { columns: 12, container: true, spacing: 2, children: [(0, jsx_runtime_1.jsx)(Grid_1.default, { item: true, xs: 3, children: (0, jsx_runtime_1.jsxs)(FormControl_1.default, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(InputLabel_1.default, { id: "action-search-view-label", children: "View" }), (0, jsx_runtime_1.jsx)(Select_1.default, { label: "View", labelId: "action-search-view-label", onChange: handleViewChange, value: viewKey, children: views.map((searchView) => ((0, jsx_runtime_1.jsx)(MenuItem_1.default, { value: searchView.key, children: searchView.viewName }, searchView.key))) })] }) }), (0, jsx_runtime_1.jsx)(Grid_1.default, { item: true, xs: 3, children: (0, jsx_runtime_1.jsx)(FormControl_1.default, { fullWidth: true, children: (0, jsx_runtime_1.jsx)(x_date_pickers_1.DateTimePicker, { label: "Start DateTime", onChange: setStartDate, value: startDate }) }) }), (0, jsx_runtime_1.jsx)(Grid_1.default, { item: true, xs: 3, children: (0, jsx_runtime_1.jsx)(FormControl_1.default, { fullWidth: true, children: (0, jsx_runtime_1.jsx)(x_date_pickers_1.DateTimePicker, { label: "End DateTime", onChange: setEndDate, value: endDate }) }) }), (0, jsx_runtime_1.jsx)(Grid_1.default, { item: true, xs: 3, children: (0, jsx_runtime_1.jsx)(AsyncButton_1.AsyncButton, { onClick: handleSearch, children: "Search" }) }), (0, jsx_runtime_1.jsx)(Grid_1.default, { item: true, xs: 12, children: view && (0, jsx_runtime_1.jsx)(ActionSearchFilterForm_1.ActionSearchFilterForm, { fields: view.fields, filters: filters, onFiltersChange: setFilters }) })] }) }));
76
+ const renderBody = () => ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [view && (0, jsx_runtime_1.jsx)(ActionSearchGrid_1.ActionSearchGrid, { isLoading: isSearching, onRowClick: handleRowClick, rows: rows, view: view }), (0, jsx_runtime_1.jsx)(EntityTimelineDialog_1.EntityTimelineDialog, { onClose: () => setTimeline(null), onOpenLog: openLog, timeline: timeline }), (0, jsx_runtime_1.jsx)(LogDialog_1.LogDialog, { handleClose: clearSelectedLogCorrelation, logCorrelation: selectedLogCorrelation, open: !!selectedLogCorrelation, setSelectedLogCorrelation: setSelectedLogCorrelation, storyResultMetadatas: [] })] }));
77
+ return (0, jsx_runtime_1.jsx)(TabViewBox_1.TabViewBox, { body: renderBody, header: renderHeader });
78
+ };
79
+ exports.ActionSearch = ActionSearch;
80
+ //# sourceMappingURL=ActionSearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionSearch.js","sourceRoot":"","sources":["../../../src/ActionSearch/ActionSearch.tsx"],"names":[],"mappings":"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","sourcesContent":["import { Nullable } from 'quidproquo-core';\nimport { ActionSearchActionRow, ActionSearchFilter } from 'quidproquo-features';\n\nimport { useState } from 'react';\nimport FormControl from '@mui/material/FormControl';\nimport Grid from '@mui/material/Grid';\nimport InputLabel from '@mui/material/InputLabel';\nimport MenuItem from '@mui/material/MenuItem';\nimport Select, { SelectChangeEvent } from '@mui/material/Select';\nimport { DateTimePicker, LocalizationProvider } from '@mui/x-date-pickers';\nimport { AdapterDateFns } from '@mui/x-date-pickers/AdapterDateFns';\n\nimport { CorrelationOpenSource, useAdminApp, useSessionState } from '../adminApp';\nimport { AsyncButton } from '../components/AsyncButton';\nimport { TabViewBox } from '../components/TabViewBox';\nimport { LogDialog } from '../LogViewer/LogDialog';\nimport { usePlatformApiPost } from '../view/hooks/useAsyncRequest';\nimport { ActionSearchFilterForm } from './components/ActionSearchFilterForm';\nimport { ActionSearchGrid } from './components/ActionSearchGrid';\nimport { EntityTimelineDialog } from './components/EntityTimelineDialog';\nimport { ActionSearchResultRow, useActionSearch } from './hooks/useActionSearch';\nimport { useActionSearchViews } from './hooks/useActionSearchViews';\nimport { EntityTimeline } from './types/EntityTimeline';\n\nconst DAY_IN_MS = 24 * 60 * 60 * 1000;\n\nexport const ActionSearch = () => {\n const [api] = useAdminApp();\n const session = useSessionState();\n\n const views = useActionSearchViews();\n\n const [viewKey, setViewKey] = useState(views[0]?.key ?? '');\n const [startDate, setStartDate] = useState<Nullable<Date>>(() => new Date(Date.now() - DAY_IN_MS));\n const [endDate, setEndDate] = useState<Nullable<Date>>(() => new Date());\n const [filters, setFilters] = useState<ActionSearchFilter[]>([]);\n const [timeline, setTimeline] = useState<Nullable<EntityTimeline>>(null);\n\n const getEntityTimeline = usePlatformApiPost<ActionSearchActionRow[]>('/actionSearch/entity/timeline');\n\n const view = views.find((searchView) => searchView.key === viewKey) ?? null;\n\n const { rows, isSearching, runSearch } = useActionSearch(view);\n\n const handleViewChange = (event: SelectChangeEvent) => {\n setViewKey(event.target.value);\n setFilters([]);\n };\n\n const handleSearch = async () => {\n if (!startDate || !endDate) {\n return;\n }\n\n await runSearch(startDate.toISOString(), endDate.toISOString(), filters);\n };\n\n const openLog = (correlation: string) => api.applyCorrelationOpened(correlation, CorrelationOpenSource.grid);\n\n // Fetch here, in the event that creates the need, so the dialog stays presentational\n const openEntityTimeline = async (linkKey: string) => {\n const rows = await getEntityTimeline({ linkKey });\n\n setTimeline({ linkKey, rows });\n };\n\n const handleRowClick = (row: ActionSearchResultRow) => {\n if (view?.kind === 'entity') {\n openEntityTimeline(String(row.linkKey));\n return;\n }\n\n openLog(String(row.correlation));\n };\n\n const selectedLogCorrelation = session.openCorrelation ?? '';\n const clearSelectedLogCorrelation = () => api.applyCorrelationClosed();\n const setSelectedLogCorrelation = (correlation: string) => api.applyCorrelationOpened(correlation, CorrelationOpenSource.tree);\n\n const renderHeader = () => (\n <LocalizationProvider dateAdapter={AdapterDateFns}>\n <Grid columns={12} container spacing={2}>\n <Grid item xs={3}>\n <FormControl fullWidth>\n <InputLabel id=\"action-search-view-label\">View</InputLabel>\n <Select label=\"View\" labelId=\"action-search-view-label\" onChange={handleViewChange} value={viewKey}>\n {views.map((searchView) => (\n <MenuItem key={searchView.key} value={searchView.key}>\n {searchView.viewName}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n <Grid item xs={3}>\n <FormControl fullWidth>\n <DateTimePicker label=\"Start DateTime\" onChange={setStartDate} value={startDate} />\n </FormControl>\n </Grid>\n <Grid item xs={3}>\n <FormControl fullWidth>\n <DateTimePicker label=\"End DateTime\" onChange={setEndDate} value={endDate} />\n </FormControl>\n </Grid>\n <Grid item xs={3}>\n <AsyncButton onClick={handleSearch}>Search</AsyncButton>\n </Grid>\n <Grid item xs={12}>\n {view && <ActionSearchFilterForm fields={view.fields} filters={filters} onFiltersChange={setFilters} />}\n </Grid>\n </Grid>\n </LocalizationProvider>\n );\n\n const renderBody = () => (\n <>\n {view && <ActionSearchGrid isLoading={isSearching} onRowClick={handleRowClick} rows={rows} view={view} />}\n <EntityTimelineDialog onClose={() => setTimeline(null)} onOpenLog={openLog} timeline={timeline} />\n <LogDialog\n handleClose={clearSelectedLogCorrelation}\n logCorrelation={selectedLogCorrelation}\n open={!!selectedLogCorrelation}\n setSelectedLogCorrelation={setSelectedLogCorrelation}\n storyResultMetadatas={[]}\n />\n </>\n );\n\n return <TabViewBox body={renderBody} header={renderHeader} />;\n};\n"]}
@@ -0,0 +1,8 @@
1
+ import { ActionSearchFieldDefinition, ActionSearchFilter } from 'quidproquo-features';
2
+ type ActionSearchFilterFormProps = {
3
+ fields: ActionSearchFieldDefinition[];
4
+ filters: ActionSearchFilter[];
5
+ onFiltersChange: (filters: ActionSearchFilter[]) => void;
6
+ };
7
+ export declare const ActionSearchFilterForm: ({ fields, filters, onFiltersChange }: ActionSearchFilterFormProps) => import("react").JSX.Element;
8
+ export {};
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.ActionSearchFilterForm = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const quidproquo_features_1 = require("quidproquo-features");
9
+ const FormControl_1 = __importDefault(require("@mui/material/FormControl"));
10
+ const Grid_1 = __importDefault(require("@mui/material/Grid"));
11
+ const InputLabel_1 = __importDefault(require("@mui/material/InputLabel"));
12
+ const MenuItem_1 = __importDefault(require("@mui/material/MenuItem"));
13
+ const Select_1 = __importDefault(require("@mui/material/Select"));
14
+ const TextField_1 = __importDefault(require("@mui/material/TextField"));
15
+ const FilterFieldControl = ({ field, filter, onFilterChange }) => {
16
+ var _a, _b, _c, _d, _e;
17
+ const inputType = field.type === quidproquo_features_1.ActionSearchFieldType.Number ? 'number' : 'text';
18
+ if (field.operator === quidproquo_features_1.ActionSearchFilterOperator.Range) {
19
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(Grid_1.default, { item: true, xs: 2, children: (0, jsx_runtime_1.jsx)(FormControl_1.default, { fullWidth: true, children: (0, jsx_runtime_1.jsx)(TextField_1.default, { InputLabelProps: { shrink: true }, label: `${field.label} (min)`, onChange: (event) => onFilterChange(field, { rangeStart: event.target.value }), type: inputType, value: (_a = filter === null || filter === void 0 ? void 0 : filter.rangeStart) !== null && _a !== void 0 ? _a : '' }) }) }), (0, jsx_runtime_1.jsx)(Grid_1.default, { item: true, xs: 2, children: (0, jsx_runtime_1.jsx)(FormControl_1.default, { fullWidth: true, children: (0, jsx_runtime_1.jsx)(TextField_1.default, { InputLabelProps: { shrink: true }, label: `${field.label} (max)`, onChange: (event) => onFilterChange(field, { rangeEnd: event.target.value }), type: inputType, value: (_b = filter === null || filter === void 0 ? void 0 : filter.rangeEnd) !== null && _b !== void 0 ? _b : '' }) }) })] }));
20
+ }
21
+ if (field.type === quidproquo_features_1.ActionSearchFieldType.Enum) {
22
+ return ((0, jsx_runtime_1.jsx)(Grid_1.default, { item: true, xs: 2, children: (0, jsx_runtime_1.jsxs)(FormControl_1.default, { fullWidth: true, children: [(0, jsx_runtime_1.jsx)(InputLabel_1.default, { id: `filter-${field.name}-label`, children: field.label }), (0, jsx_runtime_1.jsxs)(Select_1.default, { label: field.label, labelId: `filter-${field.name}-label`, onChange: (event) => onFilterChange(field, { value: event.target.value }), value: (_c = filter === null || filter === void 0 ? void 0 : filter.value) !== null && _c !== void 0 ? _c : '', children: [(0, jsx_runtime_1.jsx)(MenuItem_1.default, { value: "", children: "Any" }), ((_d = field.enumValues) !== null && _d !== void 0 ? _d : []).map((enumValue) => ((0, jsx_runtime_1.jsx)(MenuItem_1.default, { value: enumValue, children: enumValue }, enumValue)))] })] }) }));
23
+ }
24
+ return ((0, jsx_runtime_1.jsx)(Grid_1.default, { item: true, xs: 2, children: (0, jsx_runtime_1.jsx)(FormControl_1.default, { fullWidth: true, children: (0, jsx_runtime_1.jsx)(TextField_1.default, { InputLabelProps: { shrink: true }, label: field.label, onChange: (event) => onFilterChange(field, { value: event.target.value }), type: inputType, value: (_e = filter === null || filter === void 0 ? void 0 : filter.value) !== null && _e !== void 0 ? _e : '' }) }) }));
25
+ };
26
+ const ActionSearchFilterForm = ({ fields, filters, onFiltersChange }) => {
27
+ const getFilter = (fieldName) => filters.find((filter) => filter.fieldName === fieldName);
28
+ const handleFilterChange = (field, partial) => {
29
+ const existing = getFilter(field.name);
30
+ const updated = Object.assign(Object.assign({ fieldName: field.name, operator: field.operator }, existing), partial);
31
+ onFiltersChange([...filters.filter((filter) => filter.fieldName !== field.name), updated]);
32
+ };
33
+ return ((0, jsx_runtime_1.jsx)(Grid_1.default, { columns: 12, container: true, spacing: 2, children: fields.map((field) => ((0, jsx_runtime_1.jsx)(FilterFieldControl, { field: field, filter: getFilter(field.name), onFilterChange: handleFilterChange }, field.name))) }));
34
+ };
35
+ exports.ActionSearchFilterForm = ActionSearchFilterForm;
36
+ //# sourceMappingURL=ActionSearchFilterForm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionSearchFilterForm.js","sourceRoot":"","sources":["../../../../src/ActionSearch/components/ActionSearchFilterForm.tsx"],"names":[],"mappings":"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","sourcesContent":["import { ActionSearchFieldDefinition, ActionSearchFieldType, ActionSearchFilter, ActionSearchFilterOperator } from 'quidproquo-features';\n\nimport FormControl from '@mui/material/FormControl';\nimport Grid from '@mui/material/Grid';\nimport InputLabel from '@mui/material/InputLabel';\nimport MenuItem from '@mui/material/MenuItem';\nimport Select from '@mui/material/Select';\nimport TextField from '@mui/material/TextField';\n\ntype FilterFieldControlProps = {\n field: ActionSearchFieldDefinition;\n filter?: ActionSearchFilter;\n onFilterChange: (field: ActionSearchFieldDefinition, partial: Partial<ActionSearchFilter>) => void;\n};\n\nconst FilterFieldControl = ({ field, filter, onFilterChange }: FilterFieldControlProps) => {\n const inputType = field.type === ActionSearchFieldType.Number ? 'number' : 'text';\n\n if (field.operator === ActionSearchFilterOperator.Range) {\n return (\n <>\n <Grid item xs={2}>\n <FormControl fullWidth>\n <TextField\n InputLabelProps={{ shrink: true }}\n label={`${field.label} (min)`}\n onChange={(event) => onFilterChange(field, { rangeStart: event.target.value })}\n type={inputType}\n value={filter?.rangeStart ?? ''}\n />\n </FormControl>\n </Grid>\n <Grid item xs={2}>\n <FormControl fullWidth>\n <TextField\n InputLabelProps={{ shrink: true }}\n label={`${field.label} (max)`}\n onChange={(event) => onFilterChange(field, { rangeEnd: event.target.value })}\n type={inputType}\n value={filter?.rangeEnd ?? ''}\n />\n </FormControl>\n </Grid>\n </>\n );\n }\n\n if (field.type === ActionSearchFieldType.Enum) {\n return (\n <Grid item xs={2}>\n <FormControl fullWidth>\n <InputLabel id={`filter-${field.name}-label`}>{field.label}</InputLabel>\n <Select\n label={field.label}\n labelId={`filter-${field.name}-label`}\n onChange={(event) => onFilterChange(field, { value: event.target.value })}\n value={filter?.value ?? ''}\n >\n <MenuItem value=\"\">Any</MenuItem>\n {(field.enumValues ?? []).map((enumValue) => (\n <MenuItem key={enumValue} value={enumValue}>\n {enumValue}\n </MenuItem>\n ))}\n </Select>\n </FormControl>\n </Grid>\n );\n }\n\n return (\n <Grid item xs={2}>\n <FormControl fullWidth>\n <TextField\n InputLabelProps={{ shrink: true }}\n label={field.label}\n onChange={(event) => onFilterChange(field, { value: event.target.value })}\n type={inputType}\n value={filter?.value ?? ''}\n />\n </FormControl>\n </Grid>\n );\n};\n\ntype ActionSearchFilterFormProps = {\n fields: ActionSearchFieldDefinition[];\n filters: ActionSearchFilter[];\n onFiltersChange: (filters: ActionSearchFilter[]) => void;\n};\n\nexport const ActionSearchFilterForm = ({ fields, filters, onFiltersChange }: ActionSearchFilterFormProps) => {\n const getFilter = (fieldName: string) => filters.find((filter) => filter.fieldName === fieldName);\n\n const handleFilterChange = (field: ActionSearchFieldDefinition, partial: Partial<ActionSearchFilter>) => {\n const existing = getFilter(field.name);\n const updated: ActionSearchFilter = {\n fieldName: field.name,\n operator: field.operator,\n ...existing,\n ...partial,\n };\n\n onFiltersChange([...filters.filter((filter) => filter.fieldName !== field.name), updated]);\n };\n\n return (\n <Grid columns={12} container spacing={2}>\n {fields.map((field) => (\n <FilterFieldControl key={field.name} field={field} filter={getFilter(field.name)} onFilterChange={handleFilterChange} />\n ))}\n </Grid>\n );\n};\n"]}
@@ -0,0 +1,10 @@
1
+ import { ActionSearchResultRow } from '../hooks/useActionSearch';
2
+ import { ActionSearchView } from '../types/ActionSearchView';
3
+ type ActionSearchGridProps = {
4
+ view: ActionSearchView;
5
+ rows: ActionSearchResultRow[];
6
+ isLoading: boolean;
7
+ onRowClick: (row: ActionSearchResultRow) => void;
8
+ };
9
+ export declare const ActionSearchGrid: ({ view, rows, isLoading, onRowClick }: ActionSearchGridProps) => import("react").JSX.Element;
10
+ export {};
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ActionSearchGrid = void 0;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const x_data_grid_1 = require("@mui/x-data-grid");
6
+ const DataGridPagination_1 = require("../../components/DataGridPagination/DataGridPagination");
7
+ const DateCell_1 = require("../../components/DateCell/DateCell");
8
+ const dateColumn = (field, headerName) => ({
9
+ field,
10
+ headerName,
11
+ flex: 1,
12
+ // Guarded so one row with a missing date can't crash the whole grid
13
+ renderCell: (params) => (params.value ? (0, jsx_runtime_1.jsx)(DateCell_1.DateCell, { isoDateTime: params.value }) : null),
14
+ });
15
+ const buildColumns = (view) => {
16
+ // Lookup-only fields (e.g. email recipient) have no row attribute to show
17
+ const fieldColumns = view.fields
18
+ .filter((field) => !field.hasLookup)
19
+ .map((field) => ({ field: field.name, headerName: field.label, flex: 1 }));
20
+ if (view.kind === 'action') {
21
+ return [
22
+ dateColumn('startedAt', 'Started at'),
23
+ { field: 'moduleName', headerName: 'Service', flex: 1 },
24
+ ...fieldColumns,
25
+ { field: 'error', headerName: 'Error', flex: 2 },
26
+ ];
27
+ }
28
+ return [dateColumn('createdAt', 'Created at'), ...fieldColumns];
29
+ };
30
+ const getRowId = (view, row) => view.kind === 'action' ? `${row.correlation}#${row.actionIndex}` : String(row.linkKey);
31
+ const ActionSearchGrid = ({ view, rows, isLoading, onRowClick }) => {
32
+ const columns = buildColumns(view);
33
+ const handleRowClick = (params) => onRowClick(params.row);
34
+ return ((0, jsx_runtime_1.jsx)(x_data_grid_1.DataGrid, { autoPageSize: true, columns: columns, components: {
35
+ Pagination: DataGridPagination_1.DataGridPagination,
36
+ }, loading: isLoading, onRowClick: handleRowClick, rows: rows.map((row) => (Object.assign(Object.assign({}, row), { id: getRowId(view, row) }))) }));
37
+ };
38
+ exports.ActionSearchGrid = ActionSearchGrid;
39
+ //# sourceMappingURL=ActionSearchGrid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionSearchGrid.js","sourceRoot":"","sources":["../../../../src/ActionSearch/components/ActionSearchGrid.tsx"],"names":[],"mappings":";;;;AAAA,kDAA6F;AAE7F,+FAA4F;AAC5F,iEAA8D;AAI9D,MAAM,UAAU,GAAG,CAAC,KAAa,EAAE,UAAkB,EAAc,EAAE,CAAC,CAAC;IACrE,KAAK;IACL,UAAU;IACV,IAAI,EAAE,CAAC;IACP,oEAAoE;IACpE,UAAU,EAAE,CAAC,MAA4B,EAAE,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,uBAAC,mBAAQ,IAAC,WAAW,EAAE,MAAM,CAAC,KAAK,GAAI,CAAC,CAAC,CAAC,IAAI,CAAC;CAC9G,CAAC,CAAC;AAEH,MAAM,YAAY,GAAG,CAAC,IAAsB,EAAgB,EAAE;IAC5D,0EAA0E;IAC1E,MAAM,YAAY,GAAiB,IAAI,CAAC,MAAM;SAC3C,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC;SACnC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,IAAI,EAAE,UAAU,EAAE,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;IAE7E,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,OAAO;YACL,UAAU,CAAC,WAAW,EAAE,YAAY,CAAC;YACrC,EAAE,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,EAAE;YACvD,GAAG,YAAY;YACf,EAAE,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE;SACjD,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,UAAU,CAAC,WAAW,EAAE,YAAY,CAAC,EAAE,GAAG,YAAY,CAAC,CAAC;AAClE,CAAC,CAAC;AAEF,MAAM,QAAQ,GAAG,CAAC,IAAsB,EAAE,GAA0B,EAAU,EAAE,CAC9E,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AASlF,MAAM,gBAAgB,GAAG,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,UAAU,EAAyB,EAAE,EAAE;IAC/F,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAEnC,MAAM,cAAc,GAAG,CAAC,MAAqB,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,GAA4B,CAAC,CAAC;IAElG,OAAO,CACL,uBAAC,sBAAQ,IACP,YAAY,QACZ,OAAO,EAAE,OAAO,EAChB,UAAU,EAAE;YACV,UAAU,EAAE,uCAAkB;SAC/B,EACD,OAAO,EAAE,SAAS,EAClB,UAAU,EAAE,cAAc,EAC1B,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,iCAAM,GAAG,KAAE,EAAE,EAAE,QAAQ,CAAC,IAAI,EAAE,GAAG,CAAC,IAAG,CAAC,GAC9D,CACH,CAAC;AACJ,CAAC,CAAC;AAjBW,QAAA,gBAAgB,oBAiB3B","sourcesContent":["import { DataGrid, GridColDef, GridRenderCellParams, GridRowParams } from '@mui/x-data-grid';\n\nimport { DataGridPagination } from '../../components/DataGridPagination/DataGridPagination';\nimport { DateCell } from '../../components/DateCell/DateCell';\nimport { ActionSearchResultRow } from '../hooks/useActionSearch';\nimport { ActionSearchView } from '../types/ActionSearchView';\n\nconst dateColumn = (field: string, headerName: string): GridColDef => ({\n field,\n headerName,\n flex: 1,\n // Guarded so one row with a missing date can't crash the whole grid\n renderCell: (params: GridRenderCellParams) => (params.value ? <DateCell isoDateTime={params.value} /> : null),\n});\n\nconst buildColumns = (view: ActionSearchView): GridColDef[] => {\n // Lookup-only fields (e.g. email recipient) have no row attribute to show\n const fieldColumns: GridColDef[] = view.fields\n .filter((field) => !field.hasLookup)\n .map((field) => ({ field: field.name, headerName: field.label, flex: 1 }));\n\n if (view.kind === 'action') {\n return [\n dateColumn('startedAt', 'Started at'),\n { field: 'moduleName', headerName: 'Service', flex: 1 },\n ...fieldColumns,\n { field: 'error', headerName: 'Error', flex: 2 },\n ];\n }\n\n return [dateColumn('createdAt', 'Created at'), ...fieldColumns];\n};\n\nconst getRowId = (view: ActionSearchView, row: ActionSearchResultRow): string =>\n view.kind === 'action' ? `${row.correlation}#${row.actionIndex}` : String(row.linkKey);\n\ntype ActionSearchGridProps = {\n view: ActionSearchView;\n rows: ActionSearchResultRow[];\n isLoading: boolean;\n onRowClick: (row: ActionSearchResultRow) => void;\n};\n\nexport const ActionSearchGrid = ({ view, rows, isLoading, onRowClick }: ActionSearchGridProps) => {\n const columns = buildColumns(view);\n\n const handleRowClick = (params: GridRowParams) => onRowClick(params.row as ActionSearchResultRow);\n\n return (\n <DataGrid\n autoPageSize\n columns={columns}\n components={{\n Pagination: DataGridPagination,\n }}\n loading={isLoading}\n onRowClick={handleRowClick}\n rows={rows.map((row) => ({ ...row, id: getRowId(view, row) }))}\n />\n );\n};\n"]}
@@ -0,0 +1,9 @@
1
+ import { Nullable } from 'quidproquo-core';
2
+ import { EntityTimeline } from '../types/EntityTimeline';
3
+ type EntityTimelineDialogProps = {
4
+ timeline: Nullable<EntityTimeline>;
5
+ onClose: () => void;
6
+ onOpenLog: (correlation: string) => void;
7
+ };
8
+ export declare const EntityTimelineDialog: ({ timeline, onClose, onOpenLog }: EntityTimelineDialogProps) => import("react").JSX.Element;
9
+ export {};
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.EntityTimelineDialog = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const Button_1 = __importDefault(require("@mui/material/Button"));
9
+ const Dialog_1 = __importDefault(require("@mui/material/Dialog"));
10
+ const DialogContent_1 = __importDefault(require("@mui/material/DialogContent"));
11
+ const DialogTitle_1 = __importDefault(require("@mui/material/DialogTitle"));
12
+ const Table_1 = __importDefault(require("@mui/material/Table"));
13
+ const TableBody_1 = __importDefault(require("@mui/material/TableBody"));
14
+ const TableCell_1 = __importDefault(require("@mui/material/TableCell"));
15
+ const TableHead_1 = __importDefault(require("@mui/material/TableHead"));
16
+ const TableRow_1 = __importDefault(require("@mui/material/TableRow"));
17
+ const DateCell_1 = require("../../components/DateCell/DateCell");
18
+ // Presentational only: the parent fetches the timeline in the row-click handler
19
+ const EntityTimelineDialog = ({ timeline, onClose, onOpenLog }) => {
20
+ var _a;
21
+ return ((0, jsx_runtime_1.jsxs)(Dialog_1.default, { fullWidth: true, maxWidth: "md", onClose: onClose, open: !!timeline, children: [(0, jsx_runtime_1.jsx)(DialogTitle_1.default, { children: "Timeline" }), (0, jsx_runtime_1.jsx)(DialogContent_1.default, { children: (0, jsx_runtime_1.jsxs)(Table_1.default, { size: "small", children: [(0, jsx_runtime_1.jsx)(TableHead_1.default, { children: (0, jsx_runtime_1.jsxs)(TableRow_1.default, { children: [(0, jsx_runtime_1.jsx)(TableCell_1.default, { children: "Time" }), (0, jsx_runtime_1.jsx)(TableCell_1.default, { children: "Action" }), (0, jsx_runtime_1.jsx)(TableCell_1.default, { children: "Service" }), (0, jsx_runtime_1.jsx)(TableCell_1.default, { children: "Error" }), (0, jsx_runtime_1.jsx)(TableCell_1.default, {})] }) }), (0, jsx_runtime_1.jsx)(TableBody_1.default, { children: ((_a = timeline === null || timeline === void 0 ? void 0 : timeline.rows) !== null && _a !== void 0 ? _a : []).map((row) => {
22
+ var _a;
23
+ return ((0, jsx_runtime_1.jsxs)(TableRow_1.default, { children: [(0, jsx_runtime_1.jsx)(TableCell_1.default, { children: (0, jsx_runtime_1.jsx)(DateCell_1.DateCell, { isoDateTime: row.startedAt }) }), (0, jsx_runtime_1.jsx)(TableCell_1.default, { children: row.actionType }), (0, jsx_runtime_1.jsx)(TableCell_1.default, { children: row.moduleName }), (0, jsx_runtime_1.jsx)(TableCell_1.default, { children: (_a = row.error) !== null && _a !== void 0 ? _a : '' }), (0, jsx_runtime_1.jsx)(TableCell_1.default, { children: (0, jsx_runtime_1.jsx)(Button_1.default, { onClick: () => onOpenLog(row.correlation), size: "small", children: "Open log" }) })] }, `${row.correlation}#${row.actionIndex}`));
24
+ }) })] }) })] }));
25
+ };
26
+ exports.EntityTimelineDialog = EntityTimelineDialog;
27
+ //# sourceMappingURL=EntityTimelineDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityTimelineDialog.js","sourceRoot":"","sources":["../../../../src/ActionSearch/components/EntityTimelineDialog.tsx"],"names":[],"mappings":";;;;;;;AAEA,kEAA0C;AAC1C,kEAA0C;AAC1C,gFAAwD;AACxD,4EAAoD;AACpD,gEAAwC;AACxC,wEAAgD;AAChD,wEAAgD;AAChD,wEAAgD;AAChD,sEAA8C;AAE9C,iEAA8D;AAS9D,gFAAgF;AACzE,MAAM,oBAAoB,GAAG,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAA6B,EAAE,EAAE;;IAAC,OAAA,CACnG,wBAAC,gBAAM,IAAC,SAAS,QAAC,QAAQ,EAAC,IAAI,EAAC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,QAAQ,aAChE,uBAAC,qBAAW,2BAAuB,EACnC,uBAAC,uBAAa,cACZ,wBAAC,eAAK,IAAC,IAAI,EAAC,OAAO,aACjB,uBAAC,mBAAS,cACR,wBAAC,kBAAQ,eACP,uBAAC,mBAAS,uBAAiB,EAC3B,uBAAC,mBAAS,yBAAmB,EAC7B,uBAAC,mBAAS,0BAAoB,EAC9B,uBAAC,mBAAS,wBAAkB,EAC5B,uBAAC,mBAAS,KAAG,IACJ,GACD,EACZ,uBAAC,mBAAS,cACP,CAAC,MAAA,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,IAAI,mCAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;;gCAAC,OAAA,CACnC,wBAAC,kBAAQ,eACP,uBAAC,mBAAS,cACR,uBAAC,mBAAQ,IAAC,WAAW,EAAE,GAAG,CAAC,SAAS,GAAI,GAC9B,EACZ,uBAAC,mBAAS,cAAE,GAAG,CAAC,UAAU,GAAa,EACvC,uBAAC,mBAAS,cAAE,GAAG,CAAC,UAAU,GAAa,EACvC,uBAAC,mBAAS,cAAE,MAAA,GAAG,CAAC,KAAK,mCAAI,EAAE,GAAa,EACxC,uBAAC,mBAAS,cACR,uBAAC,gBAAM,IAAC,OAAO,EAAE,GAAG,EAAE,CAAC,SAAS,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,IAAI,EAAC,OAAO,yBAEtD,GACC,KAXC,GAAG,GAAG,CAAC,WAAW,IAAI,GAAG,CAAC,WAAW,EAAE,CAY3C,CACZ,CAAA;6BAAA,CAAC,GACQ,IACN,GACM,IACT,CACV,CAAA;CAAA,CAAC;AAlCW,QAAA,oBAAoB,wBAkC/B","sourcesContent":["import { Nullable } from 'quidproquo-core';\n\nimport Button from '@mui/material/Button';\nimport Dialog from '@mui/material/Dialog';\nimport DialogContent from '@mui/material/DialogContent';\nimport DialogTitle from '@mui/material/DialogTitle';\nimport Table from '@mui/material/Table';\nimport TableBody from '@mui/material/TableBody';\nimport TableCell from '@mui/material/TableCell';\nimport TableHead from '@mui/material/TableHead';\nimport TableRow from '@mui/material/TableRow';\n\nimport { DateCell } from '../../components/DateCell/DateCell';\nimport { EntityTimeline } from '../types/EntityTimeline';\n\ntype EntityTimelineDialogProps = {\n timeline: Nullable<EntityTimeline>;\n onClose: () => void;\n onOpenLog: (correlation: string) => void;\n};\n\n// Presentational only: the parent fetches the timeline in the row-click handler\nexport const EntityTimelineDialog = ({ timeline, onClose, onOpenLog }: EntityTimelineDialogProps) => (\n <Dialog fullWidth maxWidth=\"md\" onClose={onClose} open={!!timeline}>\n <DialogTitle>Timeline</DialogTitle>\n <DialogContent>\n <Table size=\"small\">\n <TableHead>\n <TableRow>\n <TableCell>Time</TableCell>\n <TableCell>Action</TableCell>\n <TableCell>Service</TableCell>\n <TableCell>Error</TableCell>\n <TableCell />\n </TableRow>\n </TableHead>\n <TableBody>\n {(timeline?.rows ?? []).map((row) => (\n <TableRow key={`${row.correlation}#${row.actionIndex}`}>\n <TableCell>\n <DateCell isoDateTime={row.startedAt} />\n </TableCell>\n <TableCell>{row.actionType}</TableCell>\n <TableCell>{row.moduleName}</TableCell>\n <TableCell>{row.error ?? ''}</TableCell>\n <TableCell>\n <Button onClick={() => onOpenLog(row.correlation)} size=\"small\">\n Open log\n </Button>\n </TableCell>\n </TableRow>\n ))}\n </TableBody>\n </Table>\n </DialogContent>\n </Dialog>\n);\n"]}
@@ -0,0 +1,9 @@
1
+ import { Nullable } from 'quidproquo-core';
2
+ import { ActionSearchFilter } from 'quidproquo-features';
3
+ import { ActionSearchView } from '../types/ActionSearchView';
4
+ export type ActionSearchResultRow = Record<string, unknown>;
5
+ export declare const useActionSearch: (view: Nullable<ActionSearchView>) => {
6
+ rows: ActionSearchResultRow[];
7
+ isSearching: boolean;
8
+ runSearch: (startIsoDateTime: string, endIsoDateTime: string, filters: ActionSearchFilter[]) => Promise<void>;
9
+ };
@@ -0,0 +1,52 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.useActionSearch = void 0;
13
+ const react_1 = require("react");
14
+ const useAsyncRequest_1 = require("../../view/hooks/useAsyncRequest");
15
+ // Matches the events search cap so a wide-open query can't page forever
16
+ const MAX_RESULTS = 3000;
17
+ const useActionSearch = (view) => {
18
+ const listActionRows = (0, useAsyncRequest_1.usePlatformApiPost)('/actionSearch/actions/list');
19
+ const listEntityRows = (0, useAsyncRequest_1.usePlatformApiPost)('/actionSearch/entities/list');
20
+ const [results, setResults] = (0, react_1.useState)({ viewKey: '', rows: [] });
21
+ const [isSearching, setIsSearching] = (0, react_1.useState)(false);
22
+ const runSearch = (startIsoDateTime, endIsoDateTime, filters) => __awaiter(void 0, void 0, void 0, function* () {
23
+ if (!view) {
24
+ return;
25
+ }
26
+ setIsSearching(true);
27
+ try {
28
+ const collected = [];
29
+ let nextPageKey = undefined;
30
+ do {
31
+ const request = Object.assign(Object.assign({}, (view.kind === 'action' ? { actionType: view.key } : { entityType: view.key })), { startIsoDateTime,
32
+ endIsoDateTime,
33
+ filters,
34
+ nextPageKey });
35
+ const page = view.kind === 'action' ? yield listActionRows(request) : yield listEntityRows(request);
36
+ collected.push(...page.items);
37
+ nextPageKey = page.nextPageKey;
38
+ } while (nextPageKey && collected.length < MAX_RESULTS);
39
+ setResults({ viewKey: view.key, rows: collected });
40
+ }
41
+ finally {
42
+ setIsSearching(false);
43
+ }
44
+ });
45
+ // Rows are tagged with the view that produced them. Deriving (not clearing in an
46
+ // effect) matters: an effect runs after render, so the first render after a view
47
+ // switch would still hand the old rows to the new view's columns and crash.
48
+ const rows = view && results.viewKey === view.key ? results.rows : [];
49
+ return { rows, isSearching, runSearch };
50
+ };
51
+ exports.useActionSearch = useActionSearch;
52
+ //# sourceMappingURL=useActionSearch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useActionSearch.js","sourceRoot":"","sources":["../../../../src/ActionSearch/hooks/useActionSearch.ts"],"names":[],"mappings":";;;;;;;;;;;;AAGA,iCAAiC;AAEjC,sEAAsE;AAGtE,wEAAwE;AACxE,MAAM,WAAW,GAAG,IAAI,CAAC;AASlB,MAAM,eAAe,GAAG,CAAC,IAAgC,EAAE,EAAE;IAClE,MAAM,cAAc,GAAG,IAAA,oCAAkB,EAAsC,4BAA4B,CAAC,CAAC;IAC7G,MAAM,cAAc,GAAG,IAAA,oCAAkB,EAAsC,6BAA6B,CAAC,CAAC;IAE9G,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,IAAA,gBAAQ,EAAsB,EAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;IACvF,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,IAAA,gBAAQ,EAAC,KAAK,CAAC,CAAC;IAEtD,MAAM,SAAS,GAAG,CAAO,gBAAwB,EAAE,cAAsB,EAAE,OAA6B,EAAiB,EAAE;QACzH,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,cAAc,CAAC,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC;YACH,MAAM,SAAS,GAA4B,EAAE,CAAC;YAC9C,IAAI,WAAW,GAAuB,SAAS,CAAC;YAEhD,GAAG,CAAC;gBACF,MAAM,OAAO,mCACR,CAAC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,KACjF,gBAAgB;oBAChB,cAAc;oBACd,OAAO;oBACP,WAAW,GACZ,CAAC;gBAEF,MAAM,IAAI,GAAwC,IAAI,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,MAAM,cAAc,CAAC,OAAO,CAAC,CAAC;gBAEzI,SAAS,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;gBAC9B,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC;YACjC,CAAC,QAAQ,WAAW,IAAI,SAAS,CAAC,MAAM,GAAG,WAAW,EAAE;YAExD,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC;QACrD,CAAC;gBAAS,CAAC;YACT,cAAc,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;IACH,CAAC,CAAA,CAAC;IAEF,iFAAiF;IACjF,iFAAiF;IACjF,4EAA4E;IAC5E,MAAM,IAAI,GAAG,IAAI,IAAI,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAEtE,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;AAC1C,CAAC,CAAC;AA5CW,QAAA,eAAe,mBA4C1B","sourcesContent":["import { Nullable, QpqPagedData } from 'quidproquo-core';\nimport { ActionSearchFilter } from 'quidproquo-features';\n\nimport { useState } from 'react';\n\nimport { usePlatformApiPost } from '../../view/hooks/useAsyncRequest';\nimport { ActionSearchView } from '../types/ActionSearchView';\n\n// Matches the events search cap so a wide-open query can't page forever\nconst MAX_RESULTS = 3000;\n\nexport type ActionSearchResultRow = Record<string, unknown>;\n\ntype ActionSearchResults = {\n viewKey: string;\n rows: ActionSearchResultRow[];\n};\n\nexport const useActionSearch = (view: Nullable<ActionSearchView>) => {\n const listActionRows = usePlatformApiPost<QpqPagedData<ActionSearchResultRow>>('/actionSearch/actions/list');\n const listEntityRows = usePlatformApiPost<QpqPagedData<ActionSearchResultRow>>('/actionSearch/entities/list');\n\n const [results, setResults] = useState<ActionSearchResults>({ viewKey: '', rows: [] });\n const [isSearching, setIsSearching] = useState(false);\n\n const runSearch = async (startIsoDateTime: string, endIsoDateTime: string, filters: ActionSearchFilter[]): Promise<void> => {\n if (!view) {\n return;\n }\n\n setIsSearching(true);\n try {\n const collected: ActionSearchResultRow[] = [];\n let nextPageKey: string | undefined = undefined;\n\n do {\n const request: Record<string, unknown> = {\n ...(view.kind === 'action' ? { actionType: view.key } : { entityType: view.key }),\n startIsoDateTime,\n endIsoDateTime,\n filters,\n nextPageKey,\n };\n\n const page: QpqPagedData<ActionSearchResultRow> = view.kind === 'action' ? await listActionRows(request) : await listEntityRows(request);\n\n collected.push(...page.items);\n nextPageKey = page.nextPageKey;\n } while (nextPageKey && collected.length < MAX_RESULTS);\n\n setResults({ viewKey: view.key, rows: collected });\n } finally {\n setIsSearching(false);\n }\n };\n\n // Rows are tagged with the view that produced them. Deriving (not clearing in an\n // effect) matters: an effect runs after render, so the first render after a view\n // switch would still hand the old rows to the new view's columns and crash.\n const rows = view && results.viewKey === view.key ? results.rows : [];\n\n return { rows, isSearching, runSearch };\n};\n"]}
@@ -0,0 +1,2 @@
1
+ import { ActionSearchView } from '../types/ActionSearchView';
2
+ export declare const useActionSearchViews: () => ActionSearchView[];
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.useActionSearchViews = void 0;
4
+ const quidproquo_features_1 = require("quidproquo-features");
5
+ const react_1 = require("react");
6
+ const buildViews = () => {
7
+ const views = [];
8
+ // Definitions can share an entity (e.g. email send + status updates); one view each
9
+ const seenEntityTypes = new Set();
10
+ for (const definition of quidproquo_features_1.actionSearchRegistry) {
11
+ views.push({
12
+ kind: 'action',
13
+ key: definition.action.actionType,
14
+ viewName: definition.action.viewName,
15
+ fields: definition.action.fields,
16
+ });
17
+ if (definition.entity && !seenEntityTypes.has(definition.entity.entityType)) {
18
+ seenEntityTypes.add(definition.entity.entityType);
19
+ views.push({
20
+ kind: 'entity',
21
+ key: definition.entity.entityType,
22
+ viewName: definition.entity.viewName,
23
+ fields: definition.entity.fields,
24
+ });
25
+ }
26
+ }
27
+ return views;
28
+ };
29
+ const useActionSearchViews = () => (0, react_1.useMemo)(buildViews, []);
30
+ exports.useActionSearchViews = useActionSearchViews;
31
+ //# sourceMappingURL=useActionSearchViews.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useActionSearchViews.js","sourceRoot":"","sources":["../../../../src/ActionSearch/hooks/useActionSearchViews.ts"],"names":[],"mappings":";;;AAAA,6DAA2D;AAE3D,iCAAgC;AAIhC,MAAM,UAAU,GAAG,GAAuB,EAAE;IAC1C,MAAM,KAAK,GAAuB,EAAE,CAAC;IAErC,oFAAoF;IACpF,MAAM,eAAe,GAAG,IAAI,GAAG,EAAU,CAAC;IAE1C,KAAK,MAAM,UAAU,IAAI,0CAAoB,EAAE,CAAC;QAC9C,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,QAAQ;YACd,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,UAAU;YACjC,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,QAAQ;YACpC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM;SACjC,CAAC,CAAC;QAEH,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5E,eAAe,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YAElD,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,QAAQ;gBACd,GAAG,EAAE,UAAU,CAAC,MAAM,CAAC,UAAU;gBACjC,QAAQ,EAAE,UAAU,CAAC,MAAM,CAAC,QAAQ;gBACpC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,MAAM;aACjC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEK,MAAM,oBAAoB,GAAG,GAAuB,EAAE,CAAC,IAAA,eAAO,EAAC,UAAU,EAAE,EAAE,CAAC,CAAC;AAAzE,QAAA,oBAAoB,wBAAqD","sourcesContent":["import { actionSearchRegistry } from 'quidproquo-features';\n\nimport { useMemo } from 'react';\n\nimport { ActionSearchView } from '../types/ActionSearchView';\n\nconst buildViews = (): ActionSearchView[] => {\n const views: ActionSearchView[] = [];\n\n // Definitions can share an entity (e.g. email send + status updates); one view each\n const seenEntityTypes = new Set<string>();\n\n for (const definition of actionSearchRegistry) {\n views.push({\n kind: 'action',\n key: definition.action.actionType,\n viewName: definition.action.viewName,\n fields: definition.action.fields,\n });\n\n if (definition.entity && !seenEntityTypes.has(definition.entity.entityType)) {\n seenEntityTypes.add(definition.entity.entityType);\n\n views.push({\n kind: 'entity',\n key: definition.entity.entityType,\n viewName: definition.entity.viewName,\n fields: definition.entity.fields,\n });\n }\n }\n\n return views;\n};\n\nexport const useActionSearchViews = (): ActionSearchView[] => useMemo(buildViews, []);\n"]}
@@ -0,0 +1 @@
1
+ export * from './ActionSearch';
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./ActionSearch"), exports);
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ActionSearch/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,iDAA+B","sourcesContent":["export * from './ActionSearch';\n"]}
@@ -0,0 +1,7 @@
1
+ import { ActionSearchFieldDefinition } from 'quidproquo-features';
2
+ export type ActionSearchView = {
3
+ kind: 'action' | 'entity';
4
+ key: string;
5
+ viewName: string;
6
+ fields: ActionSearchFieldDefinition[];
7
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=ActionSearchView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ActionSearchView.js","sourceRoot":"","sources":["../../../../src/ActionSearch/types/ActionSearchView.ts"],"names":[],"mappings":"","sourcesContent":["import { ActionSearchFieldDefinition } from 'quidproquo-features';\n\nexport type ActionSearchView = {\n kind: 'action' | 'entity';\n\n // actionType for action views, entityType for entity views\n key: string;\n\n viewName: string;\n fields: ActionSearchFieldDefinition[];\n};\n"]}
@@ -0,0 +1,5 @@
1
+ import { ActionSearchActionRow } from 'quidproquo-features';
2
+ export type EntityTimeline = {
3
+ linkKey: string;
4
+ rows: ActionSearchActionRow[];
5
+ };
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=EntityTimeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"EntityTimeline.js","sourceRoot":"","sources":["../../../../src/ActionSearch/types/EntityTimeline.ts"],"names":[],"mappings":"","sourcesContent":["import { ActionSearchActionRow } from 'quidproquo-features';\n\nexport type EntityTimeline = {\n linkKey: string;\n rows: ActionSearchActionRow[];\n};\n"]}
@@ -0,0 +1,2 @@
1
+ export * from './ActionSearchView';
2
+ export * from './EntityTimeline';
@@ -0,0 +1,19 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./ActionSearchView"), exports);
18
+ __exportStar(require("./EntityTimeline"), exports);
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/ActionSearch/types/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,qDAAmC;AACnC,mDAAiC","sourcesContent":["export * from './ActionSearchView';\nexport * from './EntityTimeline';\n"]}
@@ -0,0 +1,3 @@
1
+ import { EmailSendEmailActionPayload } from 'quidproquo-webserver';
2
+ import { ActionComponent } from '../types';
3
+ export declare const WebserverEmailSendEmailCustomAction: ActionComponent<EmailSendEmailActionPayload, string>;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.WebserverEmailSendEmailCustomAction = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const material_1 = require("@mui/material");
9
+ const ActionResultDisplay_1 = __importDefault(require("../genericActionRenderer/ActionResultDisplay"));
10
+ const headerStyles = {
11
+ card: {
12
+ backgroundColor: '#1F1F1F',
13
+ borderRadius: '5px',
14
+ padding: '10px 12px',
15
+ marginBottom: '8px',
16
+ },
17
+ label: {
18
+ color: '#68CDFE',
19
+ fontWeight: 600,
20
+ minWidth: 72,
21
+ },
22
+ value: {
23
+ color: '#CE834A',
24
+ wordBreak: 'break-word',
25
+ },
26
+ iframe: {
27
+ width: '100%',
28
+ minHeight: 320,
29
+ border: 'thin solid #333',
30
+ borderRadius: '5px',
31
+ background: '#ffffff',
32
+ },
33
+ textBody: {
34
+ backgroundColor: '#1F1F1F',
35
+ color: '#68CDFE',
36
+ padding: '10px',
37
+ borderRadius: '5px',
38
+ whiteSpace: 'pre-wrap',
39
+ wordWrap: 'break-word',
40
+ margin: 0,
41
+ },
42
+ };
43
+ const HeaderRow = ({ label, value }) => {
44
+ const text = Array.isArray(value) ? value.join(', ') : value;
45
+ if (!text) {
46
+ return null;
47
+ }
48
+ return ((0, jsx_runtime_1.jsxs)(material_1.Box, { display: "flex", gap: 1, sx: { my: 0.25 }, children: [(0, jsx_runtime_1.jsx)(material_1.Typography, { component: "span", sx: headerStyles.label, variant: "body2", children: label }), (0, jsx_runtime_1.jsx)(material_1.Typography, { component: "span", sx: headerStyles.value, variant: "body2", children: text })] }));
49
+ };
50
+ const WebserverEmailSendEmailCustomAction = ({ action, result, expanded }) => {
51
+ if (!action.payload) {
52
+ return null;
53
+ }
54
+ const { from, to, cc, bcc, replyTo, subject, bodyHtml, bodyText, attachments } = action.payload;
55
+ return ((0, jsx_runtime_1.jsxs)(material_1.Box, { sx: { width: '100%', my: 1 }, children: [(0, jsx_runtime_1.jsxs)(material_1.Box, { sx: headerStyles.card, children: [(0, jsx_runtime_1.jsx)(HeaderRow, { label: "To:", value: to }), (0, jsx_runtime_1.jsx)(HeaderRow, { label: "From:", value: from }), (0, jsx_runtime_1.jsx)(HeaderRow, { label: "Cc:", value: cc }), (0, jsx_runtime_1.jsx)(HeaderRow, { label: "Bcc:", value: bcc }), (0, jsx_runtime_1.jsx)(HeaderRow, { label: "Reply-To:", value: replyTo }), (0, jsx_runtime_1.jsx)(HeaderRow, { label: "Subject:", value: subject }), attachments && attachments.length > 0 && (0, jsx_runtime_1.jsx)(HeaderRow, { label: "Attachments:", value: `${attachments.length}` })] }), bodyHtml ? (
56
+ // Sandbox with no allow-list: renders the email markup but blocks scripts,
57
+ // form submission and same-origin access to the admin.
58
+ (0, jsx_runtime_1.jsx)("iframe", { sandbox: "", srcDoc: bodyHtml, style: headerStyles.iframe, title: "Email HTML body" })) : ((0, jsx_runtime_1.jsx)("pre", { style: headerStyles.textBody, children: bodyText })), (0, jsx_runtime_1.jsx)(ActionResultDisplay_1.default, { action: action, expanded: expanded, result: result })] }));
59
+ };
60
+ exports.WebserverEmailSendEmailCustomAction = WebserverEmailSendEmailCustomAction;
61
+ //# sourceMappingURL=WebserverEmailSendEmailCustomAction.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WebserverEmailSendEmailCustomAction.js","sourceRoot":"","sources":["../../../../../src/LogViewer/actionComponents/custom/WebserverEmailSendEmailCustomAction.tsx"],"names":[],"mappings":"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","sourcesContent":["import { EmailSendEmailActionPayload } from 'quidproquo-webserver';\n\nimport { Box, Typography } from '@mui/material';\n\nimport ActionResultDisplay from '../genericActionRenderer/ActionResultDisplay';\nimport { ActionComponent } from '../types';\n\nconst headerStyles = {\n card: {\n backgroundColor: '#1F1F1F',\n borderRadius: '5px',\n padding: '10px 12px',\n marginBottom: '8px',\n },\n label: {\n color: '#68CDFE',\n fontWeight: 600,\n minWidth: 72,\n },\n value: {\n color: '#CE834A',\n wordBreak: 'break-word' as const,\n },\n iframe: {\n width: '100%',\n minHeight: 320,\n border: 'thin solid #333',\n borderRadius: '5px',\n background: '#ffffff',\n },\n textBody: {\n backgroundColor: '#1F1F1F',\n color: '#68CDFE',\n padding: '10px',\n borderRadius: '5px',\n whiteSpace: 'pre-wrap' as const,\n wordWrap: 'break-word' as const,\n margin: 0,\n },\n};\n\ntype HeaderRowProps = {\n label: string;\n value?: string[] | string;\n};\n\nconst HeaderRow = ({ label, value }: HeaderRowProps) => {\n const text = Array.isArray(value) ? value.join(', ') : value;\n\n if (!text) {\n return null;\n }\n\n return (\n <Box display=\"flex\" gap={1} sx={{ my: 0.25 }}>\n <Typography component=\"span\" sx={headerStyles.label} variant=\"body2\">\n {label}\n </Typography>\n <Typography component=\"span\" sx={headerStyles.value} variant=\"body2\">\n {text}\n </Typography>\n </Box>\n );\n};\n\nexport const WebserverEmailSendEmailCustomAction: ActionComponent<EmailSendEmailActionPayload, string> = ({ action, result, expanded }) => {\n if (!action.payload) {\n return null;\n }\n\n const { from, to, cc, bcc, replyTo, subject, bodyHtml, bodyText, attachments } = action.payload;\n\n return (\n <Box sx={{ width: '100%', my: 1 }}>\n <Box sx={headerStyles.card}>\n <HeaderRow label=\"To:\" value={to} />\n <HeaderRow label=\"From:\" value={from} />\n <HeaderRow label=\"Cc:\" value={cc} />\n <HeaderRow label=\"Bcc:\" value={bcc} />\n <HeaderRow label=\"Reply-To:\" value={replyTo} />\n <HeaderRow label=\"Subject:\" value={subject} />\n {attachments && attachments.length > 0 && <HeaderRow label=\"Attachments:\" value={`${attachments.length}`} />}\n </Box>\n\n {bodyHtml ? (\n // Sandbox with no allow-list: renders the email markup but blocks scripts,\n // form submission and same-origin access to the admin.\n <iframe sandbox=\"\" srcDoc={bodyHtml} style={headerStyles.iframe} title=\"Email HTML body\" />\n ) : (\n <pre style={headerStyles.textBody}>{bodyText}</pre>\n )}\n\n <ActionResultDisplay action={action} expanded={expanded} result={result} />\n </Box>\n );\n};\n"]}
@@ -3,3 +3,4 @@ export * from './CoreLogCreateCustomAction';
3
3
  export * from './CoreLogDisableEventHistoryCustomAction';
4
4
  export * from './CoreLogTemplateLiteralCustomAction';
5
5
  export * from './CoreNetworkRequestCustomAction';
6
+ export * from './WebserverEmailSendEmailCustomAction';