@monolith-forensics/monolith-ui 1.3.116-dev.1 → 1.3.116-dev.2
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/QueryFilter/types.d.ts +2 -3
- package/dist/Table/TableMenu/TableMenu.js +2 -5
- package/dist/Table/TableProvider.js +44 -5
- package/dist/Table/Utils/index.d.ts +1 -0
- package/dist/Table/Utils/index.js +1 -0
- package/dist/Table/Utils/tableExport.d.ts +9 -0
- package/dist/Table/Utils/tableExport.js +102 -0
- package/dist/Table/types.d.ts +1 -0
- package/package.json +2 -1
|
@@ -20,13 +20,13 @@ export type Operator = {
|
|
|
20
20
|
label: string;
|
|
21
21
|
value: string;
|
|
22
22
|
};
|
|
23
|
-
export type
|
|
23
|
+
export type InputType = "text" | "number" | "date" | "datetime" | "multiselect";
|
|
24
24
|
export interface FilterDefinition {
|
|
25
25
|
dataField: string;
|
|
26
26
|
label: string;
|
|
27
27
|
pluralLabel?: string;
|
|
28
28
|
operators?: Operator[];
|
|
29
|
-
inputType?:
|
|
29
|
+
inputType?: InputType;
|
|
30
30
|
resolution?: "day" | "second" | "millisecond";
|
|
31
31
|
isoString?: boolean;
|
|
32
32
|
placeholder?: string;
|
|
@@ -34,7 +34,6 @@ export interface FilterDefinition {
|
|
|
34
34
|
dropDownOptions?: {
|
|
35
35
|
style?: React.CSSProperties;
|
|
36
36
|
};
|
|
37
|
-
editorType?: EditorType;
|
|
38
37
|
query?: DropDownMenuProps["query"];
|
|
39
38
|
}
|
|
40
39
|
export interface Rule {
|
|
@@ -30,7 +30,7 @@ const FlexedRow = styled.div `
|
|
|
30
30
|
`;
|
|
31
31
|
const TableMenu = () => {
|
|
32
32
|
var _a, _b, _c, _d, _e;
|
|
33
|
-
const { data, columnState, searchState, toggleColumnVisibility, tableMenuOptions, runSearch, enableSelection, compactState, toggleCompact, totalRecords, getCalculatedSelectionTotal, filterState, handleFilterChange, clearSearch, } = useTable();
|
|
33
|
+
const { data, columnState, searchState, toggleColumnVisibility, tableMenuOptions, runSearch, enableSelection, compactState, toggleCompact, totalRecords, getCalculatedSelectionTotal, handleTableExport, filterState, handleFilterChange, clearSearch, } = useTable();
|
|
34
34
|
const inputRef = useRef(null);
|
|
35
35
|
if ((tableMenuOptions === null || tableMenuOptions === void 0 ? void 0 : tableMenuOptions.enabled) !== true)
|
|
36
36
|
return null;
|
|
@@ -111,10 +111,7 @@ const TableMenu = () => {
|
|
|
111
111
|
title: "Export List to XLSX",
|
|
112
112
|
size: "xxs",
|
|
113
113
|
style: { padding: "0px 4px" },
|
|
114
|
-
}, onItemSelect: (item) => {
|
|
115
|
-
var _a, _b;
|
|
116
|
-
return (_b = (_a = tableMenuOptions === null || tableMenuOptions === void 0 ? void 0 : tableMenuOptions.exportOptions) === null || _a === void 0 ? void 0 : _a.onExport) === null || _b === void 0 ? void 0 : _b.call(_a, item.value);
|
|
117
|
-
}, dropDownProps: {
|
|
114
|
+
}, onItemSelect: (item) => void handleTableExport(item.value), dropDownProps: {
|
|
118
115
|
style: { width: 175, maxWidth: 400 },
|
|
119
116
|
}, children: _jsx(DownloadIcon, { size: 14 }) })), (compactOptions === null || compactOptions === void 0 ? void 0 : compactOptions.enabled) === true && (_jsx(Button, { variant: "outlined", title: "Toggle Compact", size: "xxs", style: { padding: "0px 4px" }, onClick: () => toggleCompact(), children: compactState ? _jsx(Rows4Icon, { size: 14 }) : _jsx(Rows3Icon, { size: 14 }) })), (columnSelectorOptions === null || columnSelectorOptions === void 0 ? void 0 : columnSelectorOptions.enabled) === true && (_jsx(DropDownMenu, { variant: "outlined", size: "xs", data: columnState.map((col) => ({
|
|
120
117
|
label: (col === null || col === void 0 ? void 0 : col.caption) || col.dataField,
|
|
@@ -1,3 +1,12 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
1
10
|
var __rest = (this && this.__rest) || function (s, e) {
|
|
2
11
|
var t = {};
|
|
3
12
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
@@ -18,6 +27,7 @@ import shortUUID from "short-uuid";
|
|
|
18
27
|
import { SelectionStatus } from "./enums";
|
|
19
28
|
import moment from "moment";
|
|
20
29
|
import { useControlled } from "../Utilities";
|
|
30
|
+
import { exportTableToExcel } from "./Utils";
|
|
21
31
|
const calculateSelectionTotal = (selectionState, totalRecords, dataLength = 0) => {
|
|
22
32
|
if (!selectionState) {
|
|
23
33
|
return 0;
|
|
@@ -37,7 +47,7 @@ const calculateSelectionTotal = (selectionState, totalRecords, dataLength = 0) =
|
|
|
37
47
|
};
|
|
38
48
|
export const TableContext = createContext(null);
|
|
39
49
|
const TableProvider = (_a) => {
|
|
40
|
-
var { children, columns, data, keyField, tableInstanceRef, stateStorage, tableMenuOptions, manualSorting, manualFiltering, manualSearch, height, maxHeight, minHeight, focusedRowId, enableColumnResize, enableSorting, compact, totalRecords, onColumnStateChange, onColumnReorder, onColumnHeaderClick, onSort, onRowUpdated, tableElement, headerRowElm, tableDimensions, targetElm, listElm, defaultSelectionState, selectionState, onSelectionChange, defaultFilterState, filterState, onFilterChange } = _a, props = __rest(_a, ["children", "columns", "data", "keyField", "tableInstanceRef", "stateStorage", "tableMenuOptions", "manualSorting", "manualFiltering", "manualSearch", "height", "maxHeight", "minHeight", "focusedRowId", "enableColumnResize", "enableSorting", "compact", "totalRecords", "onColumnStateChange", "onColumnReorder", "onColumnHeaderClick", "onSort", "onRowUpdated", "tableElement", "headerRowElm", "tableDimensions", "targetElm", "listElm", "defaultSelectionState", "selectionState", "onSelectionChange", "defaultFilterState", "filterState", "onFilterChange"]);
|
|
50
|
+
var { children, columns, data, keyField, tableInstanceRef, stateStorage, tableMenuOptions, manualSorting, manualFiltering, manualSearch, manualExport, height, maxHeight, minHeight, focusedRowId, enableColumnResize, enableSorting, compact, totalRecords, onColumnStateChange, onColumnReorder, onColumnHeaderClick, onSort, onRowUpdated, tableElement, headerRowElm, tableDimensions, targetElm, listElm, defaultSelectionState, selectionState, onSelectionChange, defaultFilterState, filterState, onFilterChange } = _a, props = __rest(_a, ["children", "columns", "data", "keyField", "tableInstanceRef", "stateStorage", "tableMenuOptions", "manualSorting", "manualFiltering", "manualSearch", "manualExport", "height", "maxHeight", "minHeight", "focusedRowId", "enableColumnResize", "enableSorting", "compact", "totalRecords", "onColumnStateChange", "onColumnReorder", "onColumnHeaderClick", "onSort", "onRowUpdated", "tableElement", "headerRowElm", "tableDimensions", "targetElm", "listElm", "defaultSelectionState", "selectionState", "onSelectionChange", "defaultFilterState", "filterState", "onFilterChange"]);
|
|
41
51
|
const _columns = useMemo(() => columns
|
|
42
52
|
.map((child, index) => {
|
|
43
53
|
if (child.dataField === "__key") {
|
|
@@ -192,6 +202,18 @@ const TableProvider = (_a) => {
|
|
|
192
202
|
const clearSearch = () => {
|
|
193
203
|
updateSearchState("");
|
|
194
204
|
};
|
|
205
|
+
const handleTableExport = (exportType) => __awaiter(void 0, void 0, void 0, function* () {
|
|
206
|
+
var _a, _b;
|
|
207
|
+
if (manualExport === true) {
|
|
208
|
+
(_b = (_a = tableMenuOptions === null || tableMenuOptions === void 0 ? void 0 : tableMenuOptions.exportOptions) === null || _a === void 0 ? void 0 : _a.onExport) === null || _b === void 0 ? void 0 : _b.call(_a, exportType);
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
yield exportTableToExcel({
|
|
212
|
+
columns: columnState,
|
|
213
|
+
data: _data,
|
|
214
|
+
exportMode: exportType,
|
|
215
|
+
});
|
|
216
|
+
});
|
|
195
217
|
const updateSortState = (sortState) => {
|
|
196
218
|
var _a;
|
|
197
219
|
setSortState(sortState);
|
|
@@ -209,20 +231,36 @@ const TableProvider = (_a) => {
|
|
|
209
231
|
// sort data
|
|
210
232
|
return data.sort((a, b) => {
|
|
211
233
|
if (sortState) {
|
|
234
|
+
const aValue = a[sortState.dataField];
|
|
235
|
+
const bValue = b[sortState.dataField];
|
|
236
|
+
const aIsEmpty = aValue === null || aValue === undefined;
|
|
237
|
+
const bIsEmpty = bValue === null || bValue === undefined;
|
|
238
|
+
// Treat empty values as the smallest values.
|
|
239
|
+
if (aIsEmpty && bIsEmpty) {
|
|
240
|
+
return 0;
|
|
241
|
+
}
|
|
242
|
+
if (aIsEmpty || bIsEmpty) {
|
|
243
|
+
if (sortState.dir === "asc") {
|
|
244
|
+
return aIsEmpty ? -1 : 1;
|
|
245
|
+
}
|
|
246
|
+
if (sortState.dir === "desc") {
|
|
247
|
+
return aIsEmpty ? 1 : -1;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
212
250
|
if (sortState.dir === "asc") {
|
|
213
|
-
if (
|
|
251
|
+
if (aValue < bValue) {
|
|
214
252
|
return -1;
|
|
215
253
|
}
|
|
216
|
-
if (
|
|
254
|
+
if (aValue > bValue) {
|
|
217
255
|
return 1;
|
|
218
256
|
}
|
|
219
257
|
return 0;
|
|
220
258
|
}
|
|
221
259
|
else if (sortState.dir === "desc") {
|
|
222
|
-
if (
|
|
260
|
+
if (aValue > bValue) {
|
|
223
261
|
return -1;
|
|
224
262
|
}
|
|
225
|
-
if (
|
|
263
|
+
if (aValue < bValue) {
|
|
226
264
|
return 1;
|
|
227
265
|
}
|
|
228
266
|
return 0;
|
|
@@ -583,6 +621,7 @@ const TableProvider = (_a) => {
|
|
|
583
621
|
toggleColumnVisibility,
|
|
584
622
|
runSearch,
|
|
585
623
|
clearSearch,
|
|
624
|
+
handleTableExport,
|
|
586
625
|
handleFilterChange, filterState: _filterState, compactState,
|
|
587
626
|
toggleCompact,
|
|
588
627
|
getCalculatedSelectionTotal,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TableExportOptions } from "../enums";
|
|
2
|
+
import { ColumnState } from "../types";
|
|
3
|
+
type TableExportParams = {
|
|
4
|
+
columns: ColumnState[];
|
|
5
|
+
data: any[];
|
|
6
|
+
exportMode: TableExportOptions;
|
|
7
|
+
};
|
|
8
|
+
export declare const exportTableToExcel: ({ columns, data, exportMode, }: TableExportParams) => Promise<void>;
|
|
9
|
+
export {};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
2
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
3
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
4
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
5
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
6
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
7
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
import { isValidElement } from "react";
|
|
11
|
+
import { TableExportOptions } from "../enums";
|
|
12
|
+
const getColumnHeader = (column) => {
|
|
13
|
+
return column.caption || column.dataField;
|
|
14
|
+
};
|
|
15
|
+
const toExportablePrimitive = (value) => {
|
|
16
|
+
if (value === undefined || value === null)
|
|
17
|
+
return null;
|
|
18
|
+
if (typeof value === "string" ||
|
|
19
|
+
typeof value === "number" ||
|
|
20
|
+
typeof value === "boolean" ||
|
|
21
|
+
value instanceof Date) {
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
if (value instanceof RegExp) {
|
|
25
|
+
return value.toString();
|
|
26
|
+
}
|
|
27
|
+
if (Array.isArray(value)) {
|
|
28
|
+
return value.map((item) => toExportablePrimitive(item)).join(", ");
|
|
29
|
+
}
|
|
30
|
+
if (typeof value === "object") {
|
|
31
|
+
try {
|
|
32
|
+
return JSON.stringify(value);
|
|
33
|
+
}
|
|
34
|
+
catch (_a) {
|
|
35
|
+
return String(value);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return String(value);
|
|
39
|
+
};
|
|
40
|
+
const extractTextFromNode = (node) => {
|
|
41
|
+
if (node === null || node === undefined || typeof node === "boolean") {
|
|
42
|
+
return "";
|
|
43
|
+
}
|
|
44
|
+
if (typeof node === "string" || typeof node === "number") {
|
|
45
|
+
return String(node);
|
|
46
|
+
}
|
|
47
|
+
if (Array.isArray(node)) {
|
|
48
|
+
return node.map((child) => extractTextFromNode(child)).join("");
|
|
49
|
+
}
|
|
50
|
+
if (isValidElement(node)) {
|
|
51
|
+
return extractTextFromNode(node.props.children);
|
|
52
|
+
}
|
|
53
|
+
return "";
|
|
54
|
+
};
|
|
55
|
+
const getExportCellValue = (row, column) => {
|
|
56
|
+
const rawValue = row[column.dataField];
|
|
57
|
+
if (!column.render) {
|
|
58
|
+
return toExportablePrimitive(rawValue);
|
|
59
|
+
}
|
|
60
|
+
const renderedText = extractTextFromNode(column.render({ rowData: row }));
|
|
61
|
+
if (renderedText.trim().length > 0) {
|
|
62
|
+
return renderedText;
|
|
63
|
+
}
|
|
64
|
+
return toExportablePrimitive(rawValue);
|
|
65
|
+
};
|
|
66
|
+
const getColumnsForExport = (columns, exportMode) => {
|
|
67
|
+
return columns
|
|
68
|
+
.filter((column) => {
|
|
69
|
+
if (exportMode === TableExportOptions.ExportVisible) {
|
|
70
|
+
return column.visible !== false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
})
|
|
74
|
+
.sort((a, b) => a.orderValue - b.orderValue);
|
|
75
|
+
};
|
|
76
|
+
const getFileName = () => {
|
|
77
|
+
const timestamp = new Date().toISOString().replaceAll(":", "-");
|
|
78
|
+
return `table-export-${timestamp}.xlsx`;
|
|
79
|
+
};
|
|
80
|
+
const downloadBuffer = (buffer) => {
|
|
81
|
+
const blob = new Blob([buffer], {
|
|
82
|
+
type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
|
|
83
|
+
});
|
|
84
|
+
const url = window.URL.createObjectURL(blob);
|
|
85
|
+
const anchor = document.createElement("a");
|
|
86
|
+
anchor.href = url;
|
|
87
|
+
anchor.download = getFileName();
|
|
88
|
+
anchor.click();
|
|
89
|
+
window.URL.revokeObjectURL(url);
|
|
90
|
+
};
|
|
91
|
+
export const exportTableToExcel = (_a) => __awaiter(void 0, [_a], void 0, function* ({ columns, data, exportMode, }) {
|
|
92
|
+
const { default: ExcelJS } = yield import("exceljs");
|
|
93
|
+
const exportColumns = getColumnsForExport(columns, exportMode);
|
|
94
|
+
const workbook = new ExcelJS.Workbook();
|
|
95
|
+
const worksheet = workbook.addWorksheet("Table Export");
|
|
96
|
+
worksheet.addRow(exportColumns.map((column) => getColumnHeader(column)));
|
|
97
|
+
data.forEach((row) => {
|
|
98
|
+
worksheet.addRow(exportColumns.map((column) => getExportCellValue(row, column)));
|
|
99
|
+
});
|
|
100
|
+
const buffer = yield workbook.xlsx.writeBuffer();
|
|
101
|
+
downloadBuffer(buffer);
|
|
102
|
+
});
|
package/dist/Table/types.d.ts
CHANGED
|
@@ -134,6 +134,7 @@ export type TableContextType = {
|
|
|
134
134
|
toggleColumnVisibility: (dataField: string) => void;
|
|
135
135
|
runSearch: (query: string) => void;
|
|
136
136
|
clearSearch: () => void;
|
|
137
|
+
handleTableExport: (e: TableExportOptions) => Promise<void> | void;
|
|
137
138
|
handleFilterChange: (query: Query) => void;
|
|
138
139
|
selectAllRows: () => void;
|
|
139
140
|
clearSelections: () => void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@monolith-forensics/monolith-ui",
|
|
3
|
-
"version": "1.3.116-dev.
|
|
3
|
+
"version": "1.3.116-dev.2",
|
|
4
4
|
"main": "./dist/index.js",
|
|
5
5
|
"types": "./dist/index.d.ts",
|
|
6
6
|
"author": "Matt Danner (Monolith Forensics LLC)",
|
|
@@ -59,6 +59,7 @@
|
|
|
59
59
|
"@uiw/codemirror-theme-vscode": "^4.23.6",
|
|
60
60
|
"@uiw/react-codemirror": "^4.23.6",
|
|
61
61
|
"deepmerge": "^4.3.1",
|
|
62
|
+
"exceljs": "^4.4.0",
|
|
62
63
|
"lucide-react": "^0.469.0",
|
|
63
64
|
"moment": "^2.29.1",
|
|
64
65
|
"overlayscrollbars": "^2.6.0",
|