@mkt-loitd/react-table-grid-custom 1.4.5 → 1.4.7
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/index.d.mts +6 -7
- package/dist/index.d.ts +6 -7
- package/dist/index.js +103 -70
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +103 -72
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { Dispatch, SetStateAction, Key, ReactNode } from 'react';
|
|
2
3
|
import { ColumnOrColumnGroup, SortColumn } from 'react-data-grid';
|
|
3
|
-
export { Column, ColumnOrColumnGroup
|
|
4
|
+
export { Column, ColumnOrColumnGroup } from 'react-data-grid';
|
|
4
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
6
|
|
|
6
7
|
type TColumnsTable<T = unknown, SR = unknown> = readonly ColumnOrColumnGroup<NoInfer<T>, NoInfer<SR>>[];
|
|
@@ -49,10 +50,8 @@ interface TableStyleWapperProps {
|
|
|
49
50
|
clsTablecustom?: string;
|
|
50
51
|
idWapper?: string;
|
|
51
52
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
declare const TableStyleContextMenuWapper: TableStyleContextMenuWapperComponent;
|
|
53
|
+
declare const TableStyleContextWapper: react.NamedExoticComponent<TableStyleWapperProps>;
|
|
54
|
+
declare const getTableStyleWapperId: (externalId?: string) => string;
|
|
56
55
|
|
|
57
56
|
interface IPaginationParams {
|
|
58
57
|
pageSize?: number;
|
|
@@ -60,4 +59,4 @@ interface IPaginationParams {
|
|
|
60
59
|
}
|
|
61
60
|
type Maybe<T> = T | undefined | null;
|
|
62
61
|
|
|
63
|
-
export { type IPaginationParams, type IReactTableGridCustom, type Maybe, ReactTableGridCustom, type TColumnsTable,
|
|
62
|
+
export { type IPaginationParams, type IReactTableGridCustom, type Maybe, ReactTableGridCustom, type TColumnsTable, TableStyleContextWapper, type TableStyleWapperProps, getTableStyleWapperId, useShowHideColumn };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { Dispatch, SetStateAction, Key, ReactNode } from 'react';
|
|
2
3
|
import { ColumnOrColumnGroup, SortColumn } from 'react-data-grid';
|
|
3
|
-
export { Column, ColumnOrColumnGroup
|
|
4
|
+
export { Column, ColumnOrColumnGroup } from 'react-data-grid';
|
|
4
5
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
5
6
|
|
|
6
7
|
type TColumnsTable<T = unknown, SR = unknown> = readonly ColumnOrColumnGroup<NoInfer<T>, NoInfer<SR>>[];
|
|
@@ -49,10 +50,8 @@ interface TableStyleWapperProps {
|
|
|
49
50
|
clsTablecustom?: string;
|
|
50
51
|
idWapper?: string;
|
|
51
52
|
}
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
}
|
|
55
|
-
declare const TableStyleContextMenuWapper: TableStyleContextMenuWapperComponent;
|
|
53
|
+
declare const TableStyleContextWapper: react.NamedExoticComponent<TableStyleWapperProps>;
|
|
54
|
+
declare const getTableStyleWapperId: (externalId?: string) => string;
|
|
56
55
|
|
|
57
56
|
interface IPaginationParams {
|
|
58
57
|
pageSize?: number;
|
|
@@ -60,4 +59,4 @@ interface IPaginationParams {
|
|
|
60
59
|
}
|
|
61
60
|
type Maybe<T> = T | undefined | null;
|
|
62
61
|
|
|
63
|
-
export { type IPaginationParams, type IReactTableGridCustom, type Maybe, ReactTableGridCustom, type TColumnsTable,
|
|
62
|
+
export { type IPaginationParams, type IReactTableGridCustom, type Maybe, ReactTableGridCustom, type TColumnsTable, TableStyleContextWapper, type TableStyleWapperProps, getTableStyleWapperId, useShowHideColumn };
|
package/dist/index.js
CHANGED
|
@@ -31,7 +31,8 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
ReactTableGridCustom: () => ReactTableGridCustom,
|
|
34
|
-
|
|
34
|
+
TableStyleContextWapper: () => TableStyleContextWapper,
|
|
35
|
+
getTableStyleWapperId: () => getTableStyleWapperId,
|
|
35
36
|
useShowHideColumn: () => useShowHideColumn
|
|
36
37
|
});
|
|
37
38
|
module.exports = __toCommonJS(index_exports);
|
|
@@ -203,34 +204,7 @@ var import_lodash3 = require("lodash");
|
|
|
203
204
|
var import_react2 = require("react");
|
|
204
205
|
var import_react_data_grid = require("react-data-grid");
|
|
205
206
|
var import_styles = require("react-data-grid/lib/styles.css");
|
|
206
|
-
|
|
207
|
-
// src/component/Icons.tsx
|
|
208
207
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
209
|
-
var LoadingIcon = ({
|
|
210
|
-
isSpin = false,
|
|
211
|
-
h = 30,
|
|
212
|
-
w = 30,
|
|
213
|
-
size = 30,
|
|
214
|
-
className
|
|
215
|
-
}) => {
|
|
216
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
217
|
-
"svg",
|
|
218
|
-
{
|
|
219
|
-
className: `${isSpin ? "animate-spin" : ""} ${className != null ? className : ""}`,
|
|
220
|
-
viewBox: "0 0 1024 1024",
|
|
221
|
-
focusable: "false",
|
|
222
|
-
"data-icon": "loading",
|
|
223
|
-
width: size || w,
|
|
224
|
-
height: size || h,
|
|
225
|
-
fill: "currentColor",
|
|
226
|
-
"aria-hidden": "true",
|
|
227
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z" })
|
|
228
|
-
}
|
|
229
|
-
);
|
|
230
|
-
};
|
|
231
|
-
|
|
232
|
-
// src/component/ui/Table/ReactTableGridCustom.tsx
|
|
233
|
-
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
234
208
|
var ReactTableGridCustomInner = (props) => {
|
|
235
209
|
const {
|
|
236
210
|
classNameWapperTable,
|
|
@@ -250,54 +224,115 @@ var ReactTableGridCustomInner = (props) => {
|
|
|
250
224
|
onRowDoubleClick
|
|
251
225
|
} = props;
|
|
252
226
|
const isSelectRow = enableSelectRow && selectedRows !== void 0;
|
|
227
|
+
const customRowKeyGetter = (0, import_react2.useCallback)(
|
|
228
|
+
(row) => {
|
|
229
|
+
if (typeof rowKeyGetter === "function") {
|
|
230
|
+
return rowKeyGetter(row);
|
|
231
|
+
}
|
|
232
|
+
return (0, import_lodash3.get)(row, rowKeyGetter);
|
|
233
|
+
},
|
|
234
|
+
[rowKeyGetter]
|
|
235
|
+
);
|
|
236
|
+
const selectColumn = (0, import_react2.useMemo)(
|
|
237
|
+
() => ({
|
|
238
|
+
key: "__select__",
|
|
239
|
+
name: "",
|
|
240
|
+
width: 44,
|
|
241
|
+
frozen: true,
|
|
242
|
+
sortable: false,
|
|
243
|
+
resizable: false,
|
|
244
|
+
renderHeaderCell: () => {
|
|
245
|
+
if (!onSelectedRowsChange) return null;
|
|
246
|
+
const allSelected = (selectedRows == null ? void 0 : selectedRows.size) === data.length && data.length > 0;
|
|
247
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
248
|
+
"input",
|
|
249
|
+
{
|
|
250
|
+
type: "checkbox",
|
|
251
|
+
checked: allSelected,
|
|
252
|
+
onChange: (e) => {
|
|
253
|
+
if (e.target.checked) {
|
|
254
|
+
onSelectedRowsChange(
|
|
255
|
+
new Set(data.map(customRowKeyGetter))
|
|
256
|
+
);
|
|
257
|
+
} else {
|
|
258
|
+
onSelectedRowsChange(/* @__PURE__ */ new Set());
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
);
|
|
263
|
+
},
|
|
264
|
+
renderCell: ({ row }) => {
|
|
265
|
+
const key = customRowKeyGetter(row);
|
|
266
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
267
|
+
"input",
|
|
268
|
+
{
|
|
269
|
+
type: "checkbox",
|
|
270
|
+
checked: selectedRows == null ? void 0 : selectedRows.has(key),
|
|
271
|
+
onChange: () => {
|
|
272
|
+
if (!onSelectedRowsChange) return;
|
|
273
|
+
const next = new Set(selectedRows);
|
|
274
|
+
if (next.has(key)) {
|
|
275
|
+
next.delete(key);
|
|
276
|
+
} else {
|
|
277
|
+
next.add(key);
|
|
278
|
+
}
|
|
279
|
+
onSelectedRowsChange(next);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
);
|
|
283
|
+
}
|
|
284
|
+
}),
|
|
285
|
+
[
|
|
286
|
+
customRowKeyGetter,
|
|
287
|
+
data,
|
|
288
|
+
selectedRows,
|
|
289
|
+
onSelectedRowsChange
|
|
290
|
+
]
|
|
291
|
+
);
|
|
253
292
|
const newColumns = (0, import_react2.useMemo)(() => {
|
|
254
293
|
const cols = [...columns];
|
|
255
294
|
if (isSelectRow) {
|
|
256
|
-
cols.unshift(
|
|
295
|
+
cols.unshift(selectColumn);
|
|
257
296
|
}
|
|
258
297
|
if (!hiddenSTT) {
|
|
259
298
|
cols.unshift({
|
|
260
299
|
key: "__index__",
|
|
261
300
|
name: "STT",
|
|
262
301
|
width: 80,
|
|
302
|
+
sortable: false,
|
|
263
303
|
renderCell: ({ rowIdx }) => STT({ page, pageSize }, rowIdx)
|
|
264
304
|
});
|
|
265
305
|
}
|
|
266
306
|
return cols;
|
|
267
|
-
}, [
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
);
|
|
277
|
-
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
307
|
+
}, [
|
|
308
|
+
columns,
|
|
309
|
+
hiddenSTT,
|
|
310
|
+
isSelectRow,
|
|
311
|
+
page,
|
|
312
|
+
pageSize,
|
|
313
|
+
selectColumn
|
|
314
|
+
]);
|
|
315
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
278
316
|
"div",
|
|
279
317
|
{
|
|
280
318
|
className: cn(
|
|
281
319
|
"wapper_table flex flex-col h-full min-h-0 relative",
|
|
282
320
|
classNameWapperTable
|
|
283
321
|
),
|
|
284
|
-
children:
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
),
|
|
299
|
-
fetching && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "absolute inset-0 flex items-center justify-center bg-white/60 z-10", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(LoadingIcon, { isSpin: true }) })
|
|
300
|
-
]
|
|
322
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
323
|
+
import_react_data_grid.DataGrid,
|
|
324
|
+
{
|
|
325
|
+
rows: data,
|
|
326
|
+
columns: newColumns,
|
|
327
|
+
selectedRows,
|
|
328
|
+
onSelectedRowsChange,
|
|
329
|
+
rowKeyGetter: isSelectRow ? customRowKeyGetter : void 0,
|
|
330
|
+
sortColumns,
|
|
331
|
+
onSortColumnsChange,
|
|
332
|
+
onCellClick: ({ row, rowIdx }) => onRowClick == null ? void 0 : onRowClick(row, rowIdx),
|
|
333
|
+
onCellDoubleClick: ({ row, rowIdx }) => onRowDoubleClick == null ? void 0 : onRowDoubleClick(row, rowIdx)
|
|
334
|
+
}
|
|
335
|
+
)
|
|
301
336
|
}
|
|
302
337
|
);
|
|
303
338
|
};
|
|
@@ -307,20 +342,19 @@ var ReactTableGridCustom = (0, import_react2.memo)(
|
|
|
307
342
|
|
|
308
343
|
// src/component/ui/Table/TableStyleContextWapper.tsx
|
|
309
344
|
var import_react3 = require("react");
|
|
310
|
-
var
|
|
345
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
311
346
|
var isClient = typeof window !== "undefined";
|
|
312
|
-
var
|
|
347
|
+
var TableStyleContextWapperInner = ({
|
|
313
348
|
children,
|
|
314
|
-
// contextMenuProps,
|
|
315
349
|
clsTablecustom,
|
|
316
|
-
// renderContext,
|
|
317
350
|
idWapper: externalId
|
|
318
351
|
}) => {
|
|
319
352
|
if (!isClient) {
|
|
320
|
-
return /* @__PURE__ */ (0,
|
|
353
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
|
|
321
354
|
}
|
|
322
|
-
const
|
|
323
|
-
|
|
355
|
+
const reactId = (0, import_react3.useId)();
|
|
356
|
+
const idWapper = externalId != null ? externalId : reactId;
|
|
357
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
324
358
|
"div",
|
|
325
359
|
{
|
|
326
360
|
id: `wapper_menu_context-${idWapper}`,
|
|
@@ -329,16 +363,15 @@ var TableStyleContextWapper = ({
|
|
|
329
363
|
}
|
|
330
364
|
);
|
|
331
365
|
};
|
|
332
|
-
var
|
|
333
|
-
|
|
366
|
+
var TableStyleContextWapper = (0, import_react3.memo)(
|
|
367
|
+
TableStyleContextWapperInner
|
|
334
368
|
);
|
|
335
|
-
|
|
336
|
-
return `wapper_menu_context-${externalId != null ? externalId : "default-id"}`;
|
|
337
|
-
};
|
|
369
|
+
var getTableStyleWapperId = (externalId) => `wapper_menu_context-${externalId != null ? externalId : "default"}`;
|
|
338
370
|
// Annotate the CommonJS export names for ESM import in node:
|
|
339
371
|
0 && (module.exports = {
|
|
340
372
|
ReactTableGridCustom,
|
|
341
|
-
|
|
373
|
+
TableStyleContextWapper,
|
|
374
|
+
getTableStyleWapperId,
|
|
342
375
|
useShowHideColumn
|
|
343
376
|
});
|
|
344
377
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/helpers/functions.ts","../src/helpers/table.ts","../src/utils.ts","../src/hooks/useShowHideColumn.ts","../src/type/table.ts","../src/component/ui/Table/ReactTableGridCustom.tsx","../src/component/Icons.tsx","../src/component/ui/Table/TableStyleContextWapper.tsx"],"sourcesContent":["/* =========================\n * Common types\n * ========================= */\nexport interface IPaginationParams {\n pageSize?: number\n page?: number\n}\n\nexport type Maybe<T> = T | undefined | null\n\n/* =========================\n * Hooks (safe)\n * ========================= */\nexport { useShowHideColumn } from './hooks/useShowHideColumn'\n\n/* =========================\n * Components (runtime-safe)\n * ========================= */\nexport { ReactTableGridCustom } from './component/ui/Table/ReactTableGridCustom'\n\n/* =========================\n * EXPORT TYPES (100% SAFE)\n * ========================= */\n\n// table\nexport type {\n IReactTableGridCustom\n} from './component/ui/Table/table-type'\n\n// columns\nexport type {\n TColumnsTable\n} from './type/table-type'\n\n// react-data-grid re-export types\nexport type {\n Column,\n ColumnOrColumnGroup,\n DataGridProps\n} from 'react-data-grid'\n\n/* =========================\n * TableStyleContextMenuWapper\n * ========================= */\nexport { TableStyleContextMenuWapper } from './component/ui/Table/TableStyleContextWapper'\nexport type { TableStyleWapperProps } from './component/ui/Table/TableStyleContextWapper'\n","import { deleteDB, IDBPDatabase, openDB } from 'idb'\nimport { pickBy } from 'lodash'\nimport moment from 'moment'\nimport { optionSelect } from '../type/preload-stubs'\nimport { IObjectParams, IToggleValues } from '../type/renderer'\nexport const setLocalStore = (key: string, value: string): void => {\n if (typeof window !== 'undefined') {\n localStorage.setItem(key, value)\n }\n}\n\nexport const getLocalStore = (key: string): string | null => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem(key)\n } else {\n return null\n }\n}\n\nexport function convertViToEn(str: string, toUpperCase = false): string {\n str = str.toLowerCase()\n str = str.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, 'a')\n str = str.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ/g, 'e')\n str = str.replace(/ì|í|ị|ỉ|ĩ/g, 'i')\n str = str.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, 'o')\n str = str.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, 'u')\n str = str.replace(/ỳ|ý|ỵ|ỷ|ỹ/g, 'y')\n str = str.replace(/đ/g, 'd')\n // Some system encode vietnamese combining accent as individual utf-8 characters\n str = str.replace(/\\u0300|\\u0301|\\u0303|\\u0309|\\u0323/g, '') // Huyền sắc hỏi ngã nặng\n str = str.replace(/\\u02C6|\\u0306|\\u031B/g, '') // Â, Ê, Ă, Ơ, Ư\n\n return toUpperCase ? str.toUpperCase() : str\n}\n\nexport const convertNumber = (value: number | string): { value: number; check: boolean } => {\n let num = 0\n if (value) {\n value = value.toString().replace(/[.]/g, '')\n value = value.trim()\n num = Number(value)\n }\n\n const regex = /^-?\\d*$/\n const check = regex.test(num.toString())\n return {\n value: num,\n check\n }\n}\n\nexport const changeTitleDocmemt = (title?: string): void => {\n document.title = `${title} - Phần Mềm MKT`\n}\n\nexport const numberConvert = (num: string | number): string => {\n let t = '0'\n if (num) {\n if (typeof num === 'string') {\n num = Number(num)\n }\n t = num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, '.')\n }\n return t\n}\n\nexport const pickBySearch = <T extends Record<string, unknown>>(obj: T): Partial<T> => {\n const filteredObj = pickBy(obj, (value) => value !== '')\n return filteredObj as Partial<T>\n}\n\nexport const getValueSelected = (value?: unknown, options?: optionSelect[]): optionSelect[] => {\n const currentValue = (options ?? [])?.filter((otp) => {\n return Array.isArray(value) ? value?.includes(otp.value) : otp?.value === value\n })\n return currentValue\n}\n\nexport const toggleValues = ({ array, value }: IToggleValues): string[] => {\n if (array.includes(value)) {\n return array.filter((item) => item !== value)\n } else {\n return [...array, value]\n }\n}\n\nexport const arrayLocal = (array?: string): string[] => {\n try {\n const data = array ? JSON.parse(array) : []\n return Array.isArray(data) ? data : []\n } catch {\n return []\n }\n}\n\nexport const formatDate = (\n date?: string | number | Date,\n format: string = 'DD/MM/YYYY HH:mm:ss A'\n): string => {\n return moment(date).format(format)\n}\n\nexport const parseObject = (obj?: string): object => {\n try {\n const data = obj ? JSON.parse(obj) : {}\n return typeof data === 'object' ? data : {}\n } catch {\n return {}\n }\n}\nexport const bufferToBlob = (buffer: ArrayBuffer | Uint8Array, type: string): Blob => {\n return new Blob([buffer as BlobPart], { type })\n}\nconst DB_NAME = 'appDB'\nconst DB_VERSION = 5\nconst STORE_NAME = 'selectedRecords'\nconst HISTORY_STORE = 'recordHistory'\ninterface SelectedRecordEntry {\n actionType: string\n selectedRecords: string[]\n}\n\ninterface RecordHistoryEntry {\n id: string\n previousAction: string[]\n}\n\ntype AppDBSchema = {\n selectedRecords: SelectedRecordEntry\n recordHistory: RecordHistoryEntry\n}\n\nconst requiredStores = [STORE_NAME, HISTORY_STORE]\n\nconst createAppDB = async (): Promise<IDBPDatabase<AppDBSchema>> => {\n return openDB<AppDBSchema>(DB_NAME, DB_VERSION, {\n upgrade(db) {\n for (const storeName of Array.from(db.objectStoreNames)) {\n db.deleteObjectStore(storeName)\n }\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n const store = db.createObjectStore(STORE_NAME, {\n keyPath: 'actionType'\n })\n store.createIndex('by_actionType', 'actionType')\n }\n\n if (!db.objectStoreNames.contains(HISTORY_STORE)) {\n db.createObjectStore(HISTORY_STORE, { keyPath: 'id' })\n }\n }\n })\n}\n\nexport const openAppDB = async (): Promise<IDBPDatabase<AppDBSchema>> => {\n try {\n const db = await createAppDB()\n const hasAllStores = requiredStores.every((store) => db.objectStoreNames.contains(store))\n if (!hasAllStores) {\n console.warn('[IndexedDB] Missing required stores. Resetting DB...')\n db.close()\n await deleteDB(DB_NAME)\n return await createAppDB()\n }\n return db\n } catch (error) {\n if ((error as { name: string })?.name === 'VersionError') {\n console.warn('[IndexedDB] Version downgrade detected. Resetting DB...')\n await deleteDB(DB_NAME)\n return await createAppDB()\n }\n\n console.error('[IndexedDB] Failed to open DB:', error)\n throw error\n }\n}\n\nexport const saveSelectedRecords = async (\n ACTION_TYPE: string,\n selectedRecords: Set<string>\n): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction(STORE_NAME, 'readwrite')\n const store = tx.objectStore(STORE_NAME)\n\n const data: SelectedRecordEntry = {\n actionType: ACTION_TYPE,\n selectedRecords: Array.from(selectedRecords)\n }\n\n await store.put(data)\n await tx.done\n}\n\nexport const getSelectedRecords = async (ACTION_TYPE: string): Promise<Set<string>> => {\n const db = await openAppDB()\n const store = db.transaction(STORE_NAME).objectStore(STORE_NAME)\n\n const record = await store.get(ACTION_TYPE)\n\n return new Set(record?.selectedRecords ?? [])\n}\nexport const removeUidsFromAllPathsAndSaveHistory = async (uids: string[]): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction([STORE_NAME, HISTORY_STORE], 'readwrite')\n const store = tx.objectStore(STORE_NAME)\n const historyStore = tx.objectStore(HISTORY_STORE)\n\n const allRecords = await store.getAll()\n\n const historyMap: Record<string, string[]> = {}\n\n for (const uid of uids) {\n historyMap[uid] = []\n }\n\n for (const record of allRecords) {\n let updated = false\n\n for (const uid of uids) {\n if (record.selectedRecords.includes(uid)) {\n record.selectedRecords = record.selectedRecords.filter((id: string) => id !== uid)\n historyMap[uid].push(record.actionType)\n updated = true\n }\n }\n\n if (updated) {\n await store.put(record)\n }\n }\n\n // Ghi lại lịch sử path đã bị xóa cho từng UID\n for (const [uid, paths] of Object.entries(historyMap)) {\n if (paths.length > 0) {\n await historyStore.put({ id: uid, previousAction: paths })\n }\n }\n\n await tx.done\n}\n\nexport const restoreUidsToPreviousPaths = async (uids: string[]): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction([STORE_NAME, HISTORY_STORE], 'readwrite')\n const store = tx.objectStore(STORE_NAME)\n const historyStore = tx.objectStore(HISTORY_STORE)\n\n for (const uid of uids) {\n const history = await historyStore.get(uid)\n if (history?.previousAction?.length) {\n for (const actionType of history.previousAction) {\n const record = (await store.get(actionType)) || {\n actionType,\n selectedRecords: []\n }\n\n if (!record.selectedRecords.includes(uid)) {\n record.selectedRecords.push(uid)\n }\n\n await store.put(record)\n }\n\n await historyStore.delete(uid)\n }\n }\n\n await tx.done\n}\nexport const deleteUidsCompletely = async (uids: string[]): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction(['selectedRecords', 'recordHistory'], 'readwrite')\n const store = tx.objectStore('selectedRecords')\n const historyStore = tx.objectStore('recordHistory')\n\n const allRecords = await store.getAll()\n\n for (const record of allRecords) {\n const originalLength = record.selectedRecords.length\n record.selectedRecords = record.selectedRecords.filter((id: string) => !uids.includes(id))\n\n if (record.selectedRecords.length !== originalLength) {\n await store.put(record)\n }\n }\n for (const uid of uids) {\n await historyStore.delete(uid)\n }\n\n await tx.done\n}\n\nexport const getSelectedCategoryDataByPath = (): string[] => {\n try {\n const saved = localStorage.getItem('selectedCategoryData')\n if (saved) {\n const data = JSON.parse(saved)\n const localPath = window.location.hash.replace(/^#/, '') || '/'\n const categoryData = data[localPath]\n if (categoryData && Array.isArray(categoryData.categoryIds)) {\n return categoryData.categoryIds\n }\n }\n } catch (err) {\n console.warn('Failed to parse localStorage category data:', err)\n }\n\n return []\n}\n\nexport const handleAsyncConfigSearchInitialValue = (): IObjectParams => {\n const defaultConfig: IObjectParams = {\n page: 1,\n pageSize: 1000,\n filterType: 'all'\n }\n\n const categoryIds = getSelectedCategoryDataByPath()\n if (categoryIds.length > 0) {\n return {\n ...defaultConfig,\n categoryId: categoryIds\n }\n }\n\n return defaultConfig\n}\n","import { ICalculatorTotalPage, IPaginationParams } from \"../type/table-type\"\n\nexport const calculatorTotalPage = ({ total = 0, pageSize = 0 }: ICalculatorTotalPage): number => {\n if (!pageSize || (pageSize && pageSize <= 0)) return 0\n return Math.ceil(total / pageSize)\n}\n\nexport const STT = (data?: IPaginationParams, index?: number): number => {\n let stt = 1\n let current_page = 0\n let per_page = 0\n\n if (data?.page !== undefined && data?.pageSize !== undefined) {\n current_page = data.page\n per_page = data.pageSize\n }\n\n let i = (current_page - 1) * per_page\n i = isNaN(i) ? 0 : i\n stt = i + (index ?? 0) + 1\n\n return stt\n}\n","import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs))\n}\n","import { arrayLocal, getLocalStore, setLocalStore, toggleValues } from '../helpers'\nimport { useCallback, useMemo, useState } from 'react'\nimport { Column } from 'react-data-grid'\nimport { TColumnsTable, useShowHideColumnParameter, useShowHideColumnReturn } from '../type/table-type'\nimport { uniq } from 'lodash'\nimport { isColumn } from '../type/table'\n\nconst useShowHideColumn = <T, SR = unknown>({\n nameLocal = 'table',\n columns,\n ignoreColumns\n}: useShowHideColumnParameter<T, SR>): useShowHideColumnReturn<T, SR> => {\n const nameLocalLocation = `${nameLocal}_location`\n const [locationColumns, setLocationColumns] = useState<string[]>(() => {\n const dataLocal = getLocalStore(nameLocalLocation)\n if (dataLocal) {\n return arrayLocal(dataLocal)\n }\n return []\n })\n const [hiddenColumns, setHiddenColumns] = useState<string[]>(() => {\n const dataLocal = getLocalStore(nameLocal)\n if (dataLocal) {\n return arrayLocal(dataLocal)\n }\n return []\n })\n\n const handleFindLocation = useCallback(\n (filterColumns: TColumnsTable<T, SR>, arrLoctions = locationColumns) => {\n return arrLoctions?.length > 0\n ? arrLoctions?.reduce(\n (total, current) => {\n const currentColumns = filterColumns?.find((item) => {\n const newItem = item as Column<T>\n return newItem?.key === current\n })\n\n if (currentColumns) {\n total = [...total, currentColumns]\n }\n return total\n },\n [] as TColumnsTable<T, SR>\n )\n : filterColumns\n },\n [locationColumns]\n )\n\n const newCloumnKeys = useMemo(\n () =>\n columns\n ?.filter(isColumn)\n .map(column => column.key),\n [columns]\n )\n\n\n const newColumns = useMemo(() => {\n const filterColumns: TColumnsTable<T, SR> =\n columns?.filter(column => {\n if (!isColumn(column)) return true\n\n const key = column.key\n\n if (ignoreColumns?.includes(key)) return true\n if (hiddenColumns?.includes(key)) return false\n\n return true\n }) ?? []\n\n return handleFindLocation(filterColumns)\n }, [columns, hiddenColumns, locationColumns, ignoreColumns])\n\n const newShowhideColumns = useMemo(() => {\n if (!ignoreColumns) return columns\n\n return (\n columns?.filter(column => {\n if (!isColumn(column)) return true\n return !ignoreColumns.includes(column.key)\n }) ?? []\n )\n }, [columns, ignoreColumns])\n\n const changeHiddenColumn = useCallback(\n (key: string | string[]) => {\n let newData = [...hiddenColumns]\n if (typeof key === 'string') {\n newData = toggleValues({\n array: newData,\n value: key\n })\n } else {\n newData = key\n }\n setLocalStore(nameLocal, JSON.stringify(newData))\n setHiddenColumns(newData)\n },\n [hiddenColumns, nameLocalLocation]\n )\n\n const handleChangeLocation = useCallback(\n (key: string[]) => {\n let newKey = key\n newKey = uniq([...key, ...newCloumnKeys])\n setLocationColumns(newKey)\n setLocalStore(nameLocalLocation, JSON.stringify(newKey))\n },\n [newCloumnKeys]\n )\n\n return {\n hiddenColumns,\n setHiddenColumns,\n columnsTable: newColumns,\n changeHiddenColumn,\n newShowhideColumns,\n locationColumns,\n handleFindLocation,\n handleChangeLocation\n }\n}\n\nexport { useShowHideColumn }\n","import { UseMutateFunction } from '@tanstack/react-query'\nimport { FormikProps } from 'formik'\nimport { Dispatch, HTMLAttributes, ReactNode, SetStateAction } from 'react'\nimport { Props } from 'react-select'\nimport type { IFieldUpdateAndCheck, IMainResponse, ISettingSystem } from './preload-stubs'\nimport type { JobDetail, Proxy } from './vitechgroup-stubs'\n\nimport type { Column, ColumnOrColumnGroup } from 'react-data-grid'\n\nexport function isColumn<T, SR>(\n column: ColumnOrColumnGroup<T, SR>\n): column is Column<T, SR> {\n return 'key' in column\n}\n\nexport interface ITableData {\n t: any\n dataJobDetail?: JobDetail[]\n totalAction?: number\n settingSystem?: ISettingSystem\n readProxyByField?: UseMutateFunction<\n IMainResponse<Proxy[]>,\n Error,\n IFieldUpdateAndCheck<Proxy, undefined, string[]>[],\n unknown\n >\n}\n\nexport interface CustomSelectProps<T> extends Props, Omit<WapperLabelFormProps, 'children'> {\n className?: string\n height?: string\n name: string\n formik?: FormikProps<T>\n msgError?: string\n changeSelected?: (selected?: Record<string, string>) => void\n setValueSearch?: Dispatch<SetStateAction<string>>\n positionMenu?: string\n}\n\nexport interface WapperLabelFormProps {\n classWapper?: HTMLAttributes<HTMLDivElement>['className']\n label?: string\n clsLabelWrapper?: string\n isRequired?: boolean\n children?: ReactNode\n isVertical?: boolean\n}\n","'use client'\n\nimport { get } from 'lodash'\nimport {\n Key,\n memo,\n useCallback,\n useMemo\n} from 'react'\nimport {\n DataGrid,\n SelectColumn,\n type Column,\n type ColumnOrColumnGroup\n} from 'react-data-grid'\nimport 'react-data-grid/lib/styles.css'\n\nimport { cn } from '../../../helpers'\nimport { STT } from '../../../helpers/table'\nimport { LoadingIcon } from '../../Icons'\nimport type { IReactTableGridCustom } from './table-type'\nimport './ReactTableGridCustom.css'\n\nconst ReactTableGridCustomInner = <\n T,\n SR = unknown,\n K extends Key = Key\n>(\n props: IReactTableGridCustom<T, SR, K>\n) => {\n const {\n classNameWapperTable,\n hiddenSTT,\n data,\n page,\n pageSize,\n columns,\n rowKeyGetter = 'uid',\n\n enableSelectRow,\n selectedRows,\n onSelectedRowsChange,\n\n sortColumns,\n onSortColumnsChange,\n\n fetching,\n onRowClick,\n onRowDoubleClick\n } = props\n\n const isSelectRow =\n enableSelectRow && selectedRows !== undefined\n\n /* =========================\n * Columns\n * ========================= */\n const newColumns = useMemo<\n readonly ColumnOrColumnGroup<T, SR>[]\n >(() => {\n const cols = [...columns]\n\n if (isSelectRow) {\n cols.unshift(SelectColumn as Column<T, SR>)\n }\n\n if (!hiddenSTT) {\n cols.unshift({\n key: '__index__',\n name: 'STT',\n width: 80,\n renderCell: ({ rowIdx }) =>\n STT({ page, pageSize }, rowIdx)\n })\n }\n\n return cols\n }, [columns, hiddenSTT, isSelectRow, page, pageSize])\n\n /* =========================\n * Row key\n * ========================= */\n const customRowKeyGetter = useCallback(\n (row: T): K => {\n if (typeof rowKeyGetter === 'function') {\n return rowKeyGetter(row)\n }\n return get(row, rowKeyGetter) as K\n },\n [rowKeyGetter]\n )\n\n return (\n <div\n className={cn(\n 'wapper_table flex flex-col h-full min-h-0 relative',\n classNameWapperTable\n )}\n >\n <DataGrid<T, SR, K>\n rows={data}\n columns={newColumns}\n selectedRows={selectedRows}\n onSelectedRowsChange={onSelectedRowsChange}\n rowKeyGetter={isSelectRow ? customRowKeyGetter : undefined}\n sortColumns={sortColumns}\n onSortColumnsChange={onSortColumnsChange}\n onCellClick={({ row, rowIdx }) =>\n onRowClick?.(row, rowIdx)\n }\n onCellDoubleClick={({ row, rowIdx }) =>\n onRowDoubleClick?.(row, rowIdx)\n }\n />\n\n {fetching && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-white/60 z-10\">\n <LoadingIcon isSpin />\n </div>\n )}\n </div>\n )\n}\n\nexport const ReactTableGridCustom = memo(\n ReactTableGridCustomInner\n) as typeof ReactTableGridCustomInner\n","import { JSX } from \"react\"\n\nexport const LoadingIcon = ({\n isSpin = false,\n h = 30,\n w = 30,\n size = 30,\n className\n}: {\n isSpin?: boolean\n w?: number\n h?: number\n size?: number\n className?: string\n}): JSX.Element => {\n return (\n <svg\n className={`${isSpin ? 'animate-spin' : ''} ${className ?? ''}`}\n viewBox=\"0 0 1024 1024\"\n focusable=\"false\"\n data-icon=\"loading\"\n width={size || w}\n height={size || h}\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path d=\"M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z\"></path>\n </svg>\n )\n}\n\nexport const ArrowIcon = ({\n h,\n w,\n size,\n className\n}: {\n w?: number\n h?: number\n size?: number\n className?: string\n}): JSX.Element => {\n return (\n <svg\n className={className}\n stroke=\"currentColor\"\n fill=\"currentColor\"\n strokeWidth=\"0\"\n viewBox=\"0 0 16 16\"\n height={size ?? h}\n width={size ?? w}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M8 4a.5.5 0 0 1 .5.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5A.5.5 0 0 1 8 4\"\n ></path>\n </svg>\n )\n}\n","import { FC, memo, ReactNode, useId } from 'react'\n// import ContextMenu, { ContextMenuProps } from '../ContextMenu/ContextMenu'\n// import RenderContextMenu, { RenderContextMenuProps } from '../ContextMenu/RenderContextMenu'\n\n/* =========================\n * Props\n * ========================= */\nexport interface TableStyleWapperProps {\n children?: ReactNode\n // contextMenuProps?: Omit<ContextMenuProps, 'selector' | 'children'> & {\n // selector?: string\n // }\n // renderContext?: RenderContextMenuProps\n clsTablecustom?: string\n idWapper?: string // 🔹 có thể truyền id từ ngoài\n}\n\n/* =========================\n * Client guard\n * ========================= */\nconst isClient = typeof window !== 'undefined'\n\n/* =========================\n * Component\n * ========================= */\nconst TableStyleContextWapper: FC<TableStyleWapperProps> = ({\n children,\n // contextMenuProps,\n clsTablecustom,\n // renderContext,\n idWapper: externalId\n}) => {\n // ⛔ server / electron preload → không render gì\n if (!isClient) {\n return <>{children}</>\n }\n\n // Nếu có id bên ngoài truyền vào thì dùng, nếu không thì sinh tự động\n const idWapper = externalId ?? \"12\"\n\n return (\n <div\n id={`wapper_menu_context-${idWapper}`}\n className={`border border-[#dedede] rounded-xl overflow-hidden bg-white flex-1 h-full flex flex-col min-h-[360px] ${clsTablecustom ?? ''}`}\n >\n {/* {renderContext?.renderData && (\n <ContextMenu\n selector={`[id=\"wapper_menu_context-${idWapper}\"] .rdg`}\n {...contextMenuProps}\n >\n <RenderContextMenu {...renderContext} />\n </ContextMenu>\n )} */}\n\n {children}\n </div>\n )\n}\n\n/* =========================\n * Type cho component export\n * ========================= */\nexport interface TableStyleContextMenuWapperComponent extends FC<TableStyleWapperProps> {\n getIdFromOutside?: (externalId?: string) => string\n}\n\n/* =========================\n * Export (SAFE) + cast type\n * ========================= */\nexport const TableStyleContextMenuWapper = memo(\n TableStyleContextWapper\n) as TableStyleContextMenuWapperComponent\n\n/* =========================\n * Static helper function (tuỳ chọn)\n * ========================= */\nTableStyleContextMenuWapper.getIdFromOutside = (externalId?: string) => {\n return `wapper_menu_context-${externalId ?? 'default-id'}`\n}\n"],"mappings":"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","names":["import_lodash","import_lodash","import_react","import_jsx_runtime","import_react","import_jsx_runtime"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/helpers/functions.ts","../src/helpers/table.ts","../src/utils.ts","../src/hooks/useShowHideColumn.ts","../src/type/table.ts","../src/component/ui/Table/ReactTableGridCustom.tsx","../src/component/ui/Table/TableStyleContextWapper.tsx"],"sourcesContent":["/* =========================\n * Common types\n * ========================= */\nexport interface IPaginationParams {\n pageSize?: number\n page?: number\n}\n\nexport type Maybe<T> = T | undefined | null\n\n/* =========================\n * Hooks\n * ========================= */\nexport { useShowHideColumn } from './hooks/useShowHideColumn'\n\n/* =========================\n * Components (runtime-safe)\n * ========================= */\nexport { ReactTableGridCustom } \nfrom './component/ui/Table/ReactTableGridCustom'\n\n/* =========================\n * EXPORT TYPES (100% SAFE)\n * ========================= */\n\n// table\nexport type {\n IReactTableGridCustom\n} from './component/ui/Table/table-type'\n\n// columns\nexport type {\n TColumnsTable\n} from './type/table-type'\n\n// react-data-grid (types only)\nexport type {\n Column,\n ColumnOrColumnGroup\n} from 'react-data-grid'\n\n/* =========================\n * TableStyleContextWapper\n * ========================= */\nexport { TableStyleContextWapper }\nfrom './component/ui/Table/TableStyleContextWapper'\n\nexport type { TableStyleWapperProps }\nfrom './component/ui/Table/TableStyleContextWapper'\n\nexport { getTableStyleWapperId }\nfrom './component/ui/Table/TableStyleContextWapper'\n\n","import { deleteDB, IDBPDatabase, openDB } from 'idb'\nimport { pickBy } from 'lodash'\nimport moment from 'moment'\nimport { optionSelect } from '../type/preload-stubs'\nimport { IObjectParams, IToggleValues } from '../type/renderer'\nexport const setLocalStore = (key: string, value: string): void => {\n if (typeof window !== 'undefined') {\n localStorage.setItem(key, value)\n }\n}\n\nexport const getLocalStore = (key: string): string | null => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem(key)\n } else {\n return null\n }\n}\n\nexport function convertViToEn(str: string, toUpperCase = false): string {\n str = str.toLowerCase()\n str = str.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, 'a')\n str = str.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ/g, 'e')\n str = str.replace(/ì|í|ị|ỉ|ĩ/g, 'i')\n str = str.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, 'o')\n str = str.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, 'u')\n str = str.replace(/ỳ|ý|ỵ|ỷ|ỹ/g, 'y')\n str = str.replace(/đ/g, 'd')\n // Some system encode vietnamese combining accent as individual utf-8 characters\n str = str.replace(/\\u0300|\\u0301|\\u0303|\\u0309|\\u0323/g, '') // Huyền sắc hỏi ngã nặng\n str = str.replace(/\\u02C6|\\u0306|\\u031B/g, '') // Â, Ê, Ă, Ơ, Ư\n\n return toUpperCase ? str.toUpperCase() : str\n}\n\nexport const convertNumber = (value: number | string): { value: number; check: boolean } => {\n let num = 0\n if (value) {\n value = value.toString().replace(/[.]/g, '')\n value = value.trim()\n num = Number(value)\n }\n\n const regex = /^-?\\d*$/\n const check = regex.test(num.toString())\n return {\n value: num,\n check\n }\n}\n\nexport const changeTitleDocmemt = (title?: string): void => {\n document.title = `${title} - Phần Mềm MKT`\n}\n\nexport const numberConvert = (num: string | number): string => {\n let t = '0'\n if (num) {\n if (typeof num === 'string') {\n num = Number(num)\n }\n t = num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, '.')\n }\n return t\n}\n\nexport const pickBySearch = <T extends Record<string, unknown>>(obj: T): Partial<T> => {\n const filteredObj = pickBy(obj, (value) => value !== '')\n return filteredObj as Partial<T>\n}\n\nexport const getValueSelected = (value?: unknown, options?: optionSelect[]): optionSelect[] => {\n const currentValue = (options ?? [])?.filter((otp) => {\n return Array.isArray(value) ? value?.includes(otp.value) : otp?.value === value\n })\n return currentValue\n}\n\nexport const toggleValues = ({ array, value }: IToggleValues): string[] => {\n if (array.includes(value)) {\n return array.filter((item) => item !== value)\n } else {\n return [...array, value]\n }\n}\n\nexport const arrayLocal = (array?: string): string[] => {\n try {\n const data = array ? JSON.parse(array) : []\n return Array.isArray(data) ? data : []\n } catch {\n return []\n }\n}\n\nexport const formatDate = (\n date?: string | number | Date,\n format: string = 'DD/MM/YYYY HH:mm:ss A'\n): string => {\n return moment(date).format(format)\n}\n\nexport const parseObject = (obj?: string): object => {\n try {\n const data = obj ? JSON.parse(obj) : {}\n return typeof data === 'object' ? data : {}\n } catch {\n return {}\n }\n}\nexport const bufferToBlob = (buffer: ArrayBuffer | Uint8Array, type: string): Blob => {\n return new Blob([buffer as BlobPart], { type })\n}\nconst DB_NAME = 'appDB'\nconst DB_VERSION = 5\nconst STORE_NAME = 'selectedRecords'\nconst HISTORY_STORE = 'recordHistory'\ninterface SelectedRecordEntry {\n actionType: string\n selectedRecords: string[]\n}\n\ninterface RecordHistoryEntry {\n id: string\n previousAction: string[]\n}\n\ntype AppDBSchema = {\n selectedRecords: SelectedRecordEntry\n recordHistory: RecordHistoryEntry\n}\n\nconst requiredStores = [STORE_NAME, HISTORY_STORE]\n\nconst createAppDB = async (): Promise<IDBPDatabase<AppDBSchema>> => {\n return openDB<AppDBSchema>(DB_NAME, DB_VERSION, {\n upgrade(db) {\n for (const storeName of Array.from(db.objectStoreNames)) {\n db.deleteObjectStore(storeName)\n }\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n const store = db.createObjectStore(STORE_NAME, {\n keyPath: 'actionType'\n })\n store.createIndex('by_actionType', 'actionType')\n }\n\n if (!db.objectStoreNames.contains(HISTORY_STORE)) {\n db.createObjectStore(HISTORY_STORE, { keyPath: 'id' })\n }\n }\n })\n}\n\nexport const openAppDB = async (): Promise<IDBPDatabase<AppDBSchema>> => {\n try {\n const db = await createAppDB()\n const hasAllStores = requiredStores.every((store) => db.objectStoreNames.contains(store))\n if (!hasAllStores) {\n console.warn('[IndexedDB] Missing required stores. Resetting DB...')\n db.close()\n await deleteDB(DB_NAME)\n return await createAppDB()\n }\n return db\n } catch (error) {\n if ((error as { name: string })?.name === 'VersionError') {\n console.warn('[IndexedDB] Version downgrade detected. Resetting DB...')\n await deleteDB(DB_NAME)\n return await createAppDB()\n }\n\n console.error('[IndexedDB] Failed to open DB:', error)\n throw error\n }\n}\n\nexport const saveSelectedRecords = async (\n ACTION_TYPE: string,\n selectedRecords: Set<string>\n): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction(STORE_NAME, 'readwrite')\n const store = tx.objectStore(STORE_NAME)\n\n const data: SelectedRecordEntry = {\n actionType: ACTION_TYPE,\n selectedRecords: Array.from(selectedRecords)\n }\n\n await store.put(data)\n await tx.done\n}\n\nexport const getSelectedRecords = async (ACTION_TYPE: string): Promise<Set<string>> => {\n const db = await openAppDB()\n const store = db.transaction(STORE_NAME).objectStore(STORE_NAME)\n\n const record = await store.get(ACTION_TYPE)\n\n return new Set(record?.selectedRecords ?? [])\n}\nexport const removeUidsFromAllPathsAndSaveHistory = async (uids: string[]): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction([STORE_NAME, HISTORY_STORE], 'readwrite')\n const store = tx.objectStore(STORE_NAME)\n const historyStore = tx.objectStore(HISTORY_STORE)\n\n const allRecords = await store.getAll()\n\n const historyMap: Record<string, string[]> = {}\n\n for (const uid of uids) {\n historyMap[uid] = []\n }\n\n for (const record of allRecords) {\n let updated = false\n\n for (const uid of uids) {\n if (record.selectedRecords.includes(uid)) {\n record.selectedRecords = record.selectedRecords.filter((id: string) => id !== uid)\n historyMap[uid].push(record.actionType)\n updated = true\n }\n }\n\n if (updated) {\n await store.put(record)\n }\n }\n\n // Ghi lại lịch sử path đã bị xóa cho từng UID\n for (const [uid, paths] of Object.entries(historyMap)) {\n if (paths.length > 0) {\n await historyStore.put({ id: uid, previousAction: paths })\n }\n }\n\n await tx.done\n}\n\nexport const restoreUidsToPreviousPaths = async (uids: string[]): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction([STORE_NAME, HISTORY_STORE], 'readwrite')\n const store = tx.objectStore(STORE_NAME)\n const historyStore = tx.objectStore(HISTORY_STORE)\n\n for (const uid of uids) {\n const history = await historyStore.get(uid)\n if (history?.previousAction?.length) {\n for (const actionType of history.previousAction) {\n const record = (await store.get(actionType)) || {\n actionType,\n selectedRecords: []\n }\n\n if (!record.selectedRecords.includes(uid)) {\n record.selectedRecords.push(uid)\n }\n\n await store.put(record)\n }\n\n await historyStore.delete(uid)\n }\n }\n\n await tx.done\n}\nexport const deleteUidsCompletely = async (uids: string[]): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction(['selectedRecords', 'recordHistory'], 'readwrite')\n const store = tx.objectStore('selectedRecords')\n const historyStore = tx.objectStore('recordHistory')\n\n const allRecords = await store.getAll()\n\n for (const record of allRecords) {\n const originalLength = record.selectedRecords.length\n record.selectedRecords = record.selectedRecords.filter((id: string) => !uids.includes(id))\n\n if (record.selectedRecords.length !== originalLength) {\n await store.put(record)\n }\n }\n for (const uid of uids) {\n await historyStore.delete(uid)\n }\n\n await tx.done\n}\n\nexport const getSelectedCategoryDataByPath = (): string[] => {\n try {\n const saved = localStorage.getItem('selectedCategoryData')\n if (saved) {\n const data = JSON.parse(saved)\n const localPath = window.location.hash.replace(/^#/, '') || '/'\n const categoryData = data[localPath]\n if (categoryData && Array.isArray(categoryData.categoryIds)) {\n return categoryData.categoryIds\n }\n }\n } catch (err) {\n console.warn('Failed to parse localStorage category data:', err)\n }\n\n return []\n}\n\nexport const handleAsyncConfigSearchInitialValue = (): IObjectParams => {\n const defaultConfig: IObjectParams = {\n page: 1,\n pageSize: 1000,\n filterType: 'all'\n }\n\n const categoryIds = getSelectedCategoryDataByPath()\n if (categoryIds.length > 0) {\n return {\n ...defaultConfig,\n categoryId: categoryIds\n }\n }\n\n return defaultConfig\n}\n","import { ICalculatorTotalPage, IPaginationParams } from \"../type/table-type\"\n\nexport const calculatorTotalPage = ({ total = 0, pageSize = 0 }: ICalculatorTotalPage): number => {\n if (!pageSize || (pageSize && pageSize <= 0)) return 0\n return Math.ceil(total / pageSize)\n}\n\nexport const STT = (data?: IPaginationParams, index?: number): number => {\n let stt = 1\n let current_page = 0\n let per_page = 0\n\n if (data?.page !== undefined && data?.pageSize !== undefined) {\n current_page = data.page\n per_page = data.pageSize\n }\n\n let i = (current_page - 1) * per_page\n i = isNaN(i) ? 0 : i\n stt = i + (index ?? 0) + 1\n\n return stt\n}\n","import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs))\n}\n","import { arrayLocal, getLocalStore, setLocalStore, toggleValues } from '../helpers'\nimport { useCallback, useMemo, useState } from 'react'\nimport { Column } from 'react-data-grid'\nimport { TColumnsTable, useShowHideColumnParameter, useShowHideColumnReturn } from '../type/table-type'\nimport { uniq } from 'lodash'\nimport { isColumn } from '../type/table'\n\nconst useShowHideColumn = <T, SR = unknown>({\n nameLocal = 'table',\n columns,\n ignoreColumns\n}: useShowHideColumnParameter<T, SR>): useShowHideColumnReturn<T, SR> => {\n const nameLocalLocation = `${nameLocal}_location`\n const [locationColumns, setLocationColumns] = useState<string[]>(() => {\n const dataLocal = getLocalStore(nameLocalLocation)\n if (dataLocal) {\n return arrayLocal(dataLocal)\n }\n return []\n })\n const [hiddenColumns, setHiddenColumns] = useState<string[]>(() => {\n const dataLocal = getLocalStore(nameLocal)\n if (dataLocal) {\n return arrayLocal(dataLocal)\n }\n return []\n })\n\n const handleFindLocation = useCallback(\n (filterColumns: TColumnsTable<T, SR>, arrLoctions = locationColumns) => {\n return arrLoctions?.length > 0\n ? arrLoctions?.reduce(\n (total, current) => {\n const currentColumns = filterColumns?.find((item) => {\n const newItem = item as Column<T>\n return newItem?.key === current\n })\n\n if (currentColumns) {\n total = [...total, currentColumns]\n }\n return total\n },\n [] as TColumnsTable<T, SR>\n )\n : filterColumns\n },\n [locationColumns]\n )\n\n const newCloumnKeys = useMemo(\n () =>\n columns\n ?.filter(isColumn)\n .map(column => column.key),\n [columns]\n )\n\n\n const newColumns = useMemo(() => {\n const filterColumns: TColumnsTable<T, SR> =\n columns?.filter(column => {\n if (!isColumn(column)) return true\n\n const key = column.key\n\n if (ignoreColumns?.includes(key)) return true\n if (hiddenColumns?.includes(key)) return false\n\n return true\n }) ?? []\n\n return handleFindLocation(filterColumns)\n }, [columns, hiddenColumns, locationColumns, ignoreColumns])\n\n const newShowhideColumns = useMemo(() => {\n if (!ignoreColumns) return columns\n\n return (\n columns?.filter(column => {\n if (!isColumn(column)) return true\n return !ignoreColumns.includes(column.key)\n }) ?? []\n )\n }, [columns, ignoreColumns])\n\n const changeHiddenColumn = useCallback(\n (key: string | string[]) => {\n let newData = [...hiddenColumns]\n if (typeof key === 'string') {\n newData = toggleValues({\n array: newData,\n value: key\n })\n } else {\n newData = key\n }\n setLocalStore(nameLocal, JSON.stringify(newData))\n setHiddenColumns(newData)\n },\n [hiddenColumns, nameLocalLocation]\n )\n\n const handleChangeLocation = useCallback(\n (key: string[]) => {\n let newKey = key\n newKey = uniq([...key, ...newCloumnKeys])\n setLocationColumns(newKey)\n setLocalStore(nameLocalLocation, JSON.stringify(newKey))\n },\n [newCloumnKeys]\n )\n\n return {\n hiddenColumns,\n setHiddenColumns,\n columnsTable: newColumns,\n changeHiddenColumn,\n newShowhideColumns,\n locationColumns,\n handleFindLocation,\n handleChangeLocation\n }\n}\n\nexport { useShowHideColumn }\n","import { UseMutateFunction } from '@tanstack/react-query'\nimport { FormikProps } from 'formik'\nimport { Dispatch, HTMLAttributes, ReactNode, SetStateAction } from 'react'\nimport { Props } from 'react-select'\nimport type { IFieldUpdateAndCheck, IMainResponse, ISettingSystem } from './preload-stubs'\nimport type { JobDetail, Proxy } from './vitechgroup-stubs'\n\nimport type { Column, ColumnOrColumnGroup } from 'react-data-grid'\n\nexport function isColumn<T, SR>(\n column: ColumnOrColumnGroup<T, SR>\n): column is Column<T, SR> {\n return 'key' in column\n}\n\nexport interface ITableData {\n t: any\n dataJobDetail?: JobDetail[]\n totalAction?: number\n settingSystem?: ISettingSystem\n readProxyByField?: UseMutateFunction<\n IMainResponse<Proxy[]>,\n Error,\n IFieldUpdateAndCheck<Proxy, undefined, string[]>[],\n unknown\n >\n}\n\nexport interface CustomSelectProps<T> extends Props, Omit<WapperLabelFormProps, 'children'> {\n className?: string\n height?: string\n name: string\n formik?: FormikProps<T>\n msgError?: string\n changeSelected?: (selected?: Record<string, string>) => void\n setValueSearch?: Dispatch<SetStateAction<string>>\n positionMenu?: string\n}\n\nexport interface WapperLabelFormProps {\n classWapper?: HTMLAttributes<HTMLDivElement>['className']\n label?: string\n clsLabelWrapper?: string\n isRequired?: boolean\n children?: ReactNode\n isVertical?: boolean\n}\n","'use client'\n\nimport { get } from 'lodash'\nimport {\n Key,\n memo,\n useCallback,\n useMemo\n} from 'react'\nimport {\n DataGrid,\n type Column,\n type ColumnOrColumnGroup\n} from 'react-data-grid'\nimport 'react-data-grid/lib/styles.css'\n\nimport { cn } from '../../../helpers'\nimport { STT } from '../../../helpers/table'\nimport { LoadingIcon } from '../../Icons'\nimport type { IReactTableGridCustom } from './table-type'\nimport './ReactTableGridCustom.css'\n\nconst ReactTableGridCustomInner = <\n T,\n SR = unknown,\n K extends Key = Key\n>(\n props: IReactTableGridCustom<T, SR, K>\n) => {\n const {\n classNameWapperTable,\n hiddenSTT,\n data,\n page,\n pageSize,\n columns,\n rowKeyGetter = 'uid',\n\n enableSelectRow,\n selectedRows,\n onSelectedRowsChange,\n\n sortColumns,\n onSortColumnsChange,\n\n fetching,\n onRowClick,\n onRowDoubleClick\n } = props\n\n const isSelectRow =\n enableSelectRow && selectedRows !== undefined\n\n /* =========================\n * Row key\n * ========================= */\n const customRowKeyGetter = useCallback(\n (row: T): K => {\n if (typeof rowKeyGetter === 'function') {\n return rowKeyGetter(row)\n }\n return get(row, rowKeyGetter) as K\n },\n [rowKeyGetter]\n )\n\n /* =========================\n * Select column (CUSTOM)\n * ========================= */\n const selectColumn = useMemo<Column<T, SR>>(\n () => ({\n key: '__select__',\n name: '',\n width: 44,\n frozen: true,\n sortable: false,\n resizable: false,\n\n renderHeaderCell: () => {\n if (!onSelectedRowsChange) return null\n\n const allSelected =\n selectedRows?.size === data.length && data.length > 0\n\n return (\n <input\n type=\"checkbox\"\n checked={allSelected}\n onChange={(e) => {\n if (e.target.checked) {\n onSelectedRowsChange(\n new Set(data.map(customRowKeyGetter))\n )\n } else {\n onSelectedRowsChange(new Set())\n }\n }}\n />\n )\n },\n\n renderCell: ({ row }) => {\n const key = customRowKeyGetter(row)\n\n return (\n <input\n type=\"checkbox\"\n checked={selectedRows?.has(key)}\n onChange={() => {\n if (!onSelectedRowsChange) return\n\n const next = new Set(selectedRows)\n if (next.has(key)) {\n next.delete(key)\n } else {\n next.add(key)\n }\n onSelectedRowsChange(next)\n }}\n />\n )\n }\n }),\n [\n customRowKeyGetter,\n data,\n selectedRows,\n onSelectedRowsChange\n ]\n )\n\n /* =========================\n * Columns\n * ========================= */\n const newColumns = useMemo<\n readonly ColumnOrColumnGroup<T, SR>[]\n >(() => {\n const cols = [...columns]\n\n if (isSelectRow) {\n cols.unshift(selectColumn)\n }\n\n if (!hiddenSTT) {\n cols.unshift({\n key: '__index__',\n name: 'STT',\n width: 80,\n sortable: false,\n renderCell: ({ rowIdx }) =>\n STT({ page, pageSize }, rowIdx)\n })\n }\n\n return cols\n }, [\n columns,\n hiddenSTT,\n isSelectRow,\n page,\n pageSize,\n selectColumn\n ])\n\n return (\n <div\n className={cn(\n 'wapper_table flex flex-col h-full min-h-0 relative',\n classNameWapperTable\n )}\n >\n <DataGrid<T, SR, K>\n rows={data}\n columns={newColumns}\n selectedRows={selectedRows}\n onSelectedRowsChange={onSelectedRowsChange}\n rowKeyGetter={isSelectRow ? customRowKeyGetter : undefined}\n sortColumns={sortColumns}\n onSortColumnsChange={onSortColumnsChange}\n onCellClick={({ row, rowIdx }) =>\n onRowClick?.(row, rowIdx)\n }\n onCellDoubleClick={({ row, rowIdx }) =>\n onRowDoubleClick?.(row, rowIdx)\n }\n />\n\n {/* {fetching && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-white/60 z-10\">\n <LoadingIcon isSpin />\n </div>\n )} */}\n </div>\n )\n}\n\n/* =========================\n * Export\n * ========================= */\nexport const ReactTableGridCustom = memo(\n ReactTableGridCustomInner\n) as typeof ReactTableGridCustomInner\n","import { FC, memo, ReactNode, useId } from 'react'\n\n/* =========================\n * Props\n * ========================= */\nexport interface TableStyleWapperProps {\n children?: ReactNode\n clsTablecustom?: string\n idWapper?: string // có thể truyền id từ ngoài\n}\n\n/* =========================\n * Client guard\n * ========================= */\nconst isClient = typeof window !== 'undefined'\n\n/* =========================\n * Component\n * ========================= */\nconst TableStyleContextWapperInner: FC<TableStyleWapperProps> = ({\n children,\n clsTablecustom,\n idWapper: externalId\n}) => {\n // server / electron preload → render children\n if (!isClient) {\n return <>{children}</>\n }\n\n // ƯU TIÊN: id ngoài → useId → fallback\n const reactId = useId()\n const idWapper = externalId ?? reactId\n\n return (\n <div\n id={`wapper_menu_context-${idWapper}`}\n className={`border border-[#dedede] rounded-xl overflow-hidden bg-white flex-1 h-full flex flex-col min-h-[360px] ${clsTablecustom ?? ''}`}\n >\n {children}\n </div>\n )\n}\n\n/* =========================\n * Export component (SAFE)\n * ========================= */\nexport const TableStyleContextWapper = memo(\n TableStyleContextWapperInner\n)\n\n/* =========================\n * Helper (EXPORT RIÊNG – SAFE)\n * ========================= */\nexport const getTableStyleWapperId = (externalId?: string) =>\n `wapper_menu_context-${externalId ?? 'default'}`\n"],"mappings":"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","names":["import_lodash","import_lodash","import_react","import_react","import_jsx_runtime"]}
|
package/dist/index.mjs
CHANGED
|
@@ -168,38 +168,10 @@ import {
|
|
|
168
168
|
useMemo as useMemo2
|
|
169
169
|
} from "react";
|
|
170
170
|
import {
|
|
171
|
-
DataGrid
|
|
172
|
-
SelectColumn
|
|
171
|
+
DataGrid
|
|
173
172
|
} from "react-data-grid";
|
|
174
173
|
import "react-data-grid/lib/styles.css";
|
|
175
|
-
|
|
176
|
-
// src/component/Icons.tsx
|
|
177
174
|
import { jsx } from "react/jsx-runtime";
|
|
178
|
-
var LoadingIcon = ({
|
|
179
|
-
isSpin = false,
|
|
180
|
-
h = 30,
|
|
181
|
-
w = 30,
|
|
182
|
-
size = 30,
|
|
183
|
-
className
|
|
184
|
-
}) => {
|
|
185
|
-
return /* @__PURE__ */ jsx(
|
|
186
|
-
"svg",
|
|
187
|
-
{
|
|
188
|
-
className: `${isSpin ? "animate-spin" : ""} ${className != null ? className : ""}`,
|
|
189
|
-
viewBox: "0 0 1024 1024",
|
|
190
|
-
focusable: "false",
|
|
191
|
-
"data-icon": "loading",
|
|
192
|
-
width: size || w,
|
|
193
|
-
height: size || h,
|
|
194
|
-
fill: "currentColor",
|
|
195
|
-
"aria-hidden": "true",
|
|
196
|
-
children: /* @__PURE__ */ jsx("path", { d: "M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z" })
|
|
197
|
-
}
|
|
198
|
-
);
|
|
199
|
-
};
|
|
200
|
-
|
|
201
|
-
// src/component/ui/Table/ReactTableGridCustom.tsx
|
|
202
|
-
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
203
175
|
var ReactTableGridCustomInner = (props) => {
|
|
204
176
|
const {
|
|
205
177
|
classNameWapperTable,
|
|
@@ -219,54 +191,115 @@ var ReactTableGridCustomInner = (props) => {
|
|
|
219
191
|
onRowDoubleClick
|
|
220
192
|
} = props;
|
|
221
193
|
const isSelectRow = enableSelectRow && selectedRows !== void 0;
|
|
194
|
+
const customRowKeyGetter = useCallback2(
|
|
195
|
+
(row) => {
|
|
196
|
+
if (typeof rowKeyGetter === "function") {
|
|
197
|
+
return rowKeyGetter(row);
|
|
198
|
+
}
|
|
199
|
+
return get(row, rowKeyGetter);
|
|
200
|
+
},
|
|
201
|
+
[rowKeyGetter]
|
|
202
|
+
);
|
|
203
|
+
const selectColumn = useMemo2(
|
|
204
|
+
() => ({
|
|
205
|
+
key: "__select__",
|
|
206
|
+
name: "",
|
|
207
|
+
width: 44,
|
|
208
|
+
frozen: true,
|
|
209
|
+
sortable: false,
|
|
210
|
+
resizable: false,
|
|
211
|
+
renderHeaderCell: () => {
|
|
212
|
+
if (!onSelectedRowsChange) return null;
|
|
213
|
+
const allSelected = (selectedRows == null ? void 0 : selectedRows.size) === data.length && data.length > 0;
|
|
214
|
+
return /* @__PURE__ */ jsx(
|
|
215
|
+
"input",
|
|
216
|
+
{
|
|
217
|
+
type: "checkbox",
|
|
218
|
+
checked: allSelected,
|
|
219
|
+
onChange: (e) => {
|
|
220
|
+
if (e.target.checked) {
|
|
221
|
+
onSelectedRowsChange(
|
|
222
|
+
new Set(data.map(customRowKeyGetter))
|
|
223
|
+
);
|
|
224
|
+
} else {
|
|
225
|
+
onSelectedRowsChange(/* @__PURE__ */ new Set());
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
);
|
|
230
|
+
},
|
|
231
|
+
renderCell: ({ row }) => {
|
|
232
|
+
const key = customRowKeyGetter(row);
|
|
233
|
+
return /* @__PURE__ */ jsx(
|
|
234
|
+
"input",
|
|
235
|
+
{
|
|
236
|
+
type: "checkbox",
|
|
237
|
+
checked: selectedRows == null ? void 0 : selectedRows.has(key),
|
|
238
|
+
onChange: () => {
|
|
239
|
+
if (!onSelectedRowsChange) return;
|
|
240
|
+
const next = new Set(selectedRows);
|
|
241
|
+
if (next.has(key)) {
|
|
242
|
+
next.delete(key);
|
|
243
|
+
} else {
|
|
244
|
+
next.add(key);
|
|
245
|
+
}
|
|
246
|
+
onSelectedRowsChange(next);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
);
|
|
250
|
+
}
|
|
251
|
+
}),
|
|
252
|
+
[
|
|
253
|
+
customRowKeyGetter,
|
|
254
|
+
data,
|
|
255
|
+
selectedRows,
|
|
256
|
+
onSelectedRowsChange
|
|
257
|
+
]
|
|
258
|
+
);
|
|
222
259
|
const newColumns = useMemo2(() => {
|
|
223
260
|
const cols = [...columns];
|
|
224
261
|
if (isSelectRow) {
|
|
225
|
-
cols.unshift(
|
|
262
|
+
cols.unshift(selectColumn);
|
|
226
263
|
}
|
|
227
264
|
if (!hiddenSTT) {
|
|
228
265
|
cols.unshift({
|
|
229
266
|
key: "__index__",
|
|
230
267
|
name: "STT",
|
|
231
268
|
width: 80,
|
|
269
|
+
sortable: false,
|
|
232
270
|
renderCell: ({ rowIdx }) => STT({ page, pageSize }, rowIdx)
|
|
233
271
|
});
|
|
234
272
|
}
|
|
235
273
|
return cols;
|
|
236
|
-
}, [
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
);
|
|
246
|
-
return /* @__PURE__ */ jsxs(
|
|
274
|
+
}, [
|
|
275
|
+
columns,
|
|
276
|
+
hiddenSTT,
|
|
277
|
+
isSelectRow,
|
|
278
|
+
page,
|
|
279
|
+
pageSize,
|
|
280
|
+
selectColumn
|
|
281
|
+
]);
|
|
282
|
+
return /* @__PURE__ */ jsx(
|
|
247
283
|
"div",
|
|
248
284
|
{
|
|
249
285
|
className: cn(
|
|
250
286
|
"wapper_table flex flex-col h-full min-h-0 relative",
|
|
251
287
|
classNameWapperTable
|
|
252
288
|
),
|
|
253
|
-
children:
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
),
|
|
268
|
-
fetching && /* @__PURE__ */ jsx2("div", { className: "absolute inset-0 flex items-center justify-center bg-white/60 z-10", children: /* @__PURE__ */ jsx2(LoadingIcon, { isSpin: true }) })
|
|
269
|
-
]
|
|
289
|
+
children: /* @__PURE__ */ jsx(
|
|
290
|
+
DataGrid,
|
|
291
|
+
{
|
|
292
|
+
rows: data,
|
|
293
|
+
columns: newColumns,
|
|
294
|
+
selectedRows,
|
|
295
|
+
onSelectedRowsChange,
|
|
296
|
+
rowKeyGetter: isSelectRow ? customRowKeyGetter : void 0,
|
|
297
|
+
sortColumns,
|
|
298
|
+
onSortColumnsChange,
|
|
299
|
+
onCellClick: ({ row, rowIdx }) => onRowClick == null ? void 0 : onRowClick(row, rowIdx),
|
|
300
|
+
onCellDoubleClick: ({ row, rowIdx }) => onRowDoubleClick == null ? void 0 : onRowDoubleClick(row, rowIdx)
|
|
301
|
+
}
|
|
302
|
+
)
|
|
270
303
|
}
|
|
271
304
|
);
|
|
272
305
|
};
|
|
@@ -275,21 +308,20 @@ var ReactTableGridCustom = memo(
|
|
|
275
308
|
);
|
|
276
309
|
|
|
277
310
|
// src/component/ui/Table/TableStyleContextWapper.tsx
|
|
278
|
-
import { memo as memo2 } from "react";
|
|
279
|
-
import { Fragment, jsx as
|
|
311
|
+
import { memo as memo2, useId } from "react";
|
|
312
|
+
import { Fragment, jsx as jsx2 } from "react/jsx-runtime";
|
|
280
313
|
var isClient = typeof window !== "undefined";
|
|
281
|
-
var
|
|
314
|
+
var TableStyleContextWapperInner = ({
|
|
282
315
|
children,
|
|
283
|
-
// contextMenuProps,
|
|
284
316
|
clsTablecustom,
|
|
285
|
-
// renderContext,
|
|
286
317
|
idWapper: externalId
|
|
287
318
|
}) => {
|
|
288
319
|
if (!isClient) {
|
|
289
|
-
return /* @__PURE__ */
|
|
320
|
+
return /* @__PURE__ */ jsx2(Fragment, { children });
|
|
290
321
|
}
|
|
291
|
-
const
|
|
292
|
-
|
|
322
|
+
const reactId = useId();
|
|
323
|
+
const idWapper = externalId != null ? externalId : reactId;
|
|
324
|
+
return /* @__PURE__ */ jsx2(
|
|
293
325
|
"div",
|
|
294
326
|
{
|
|
295
327
|
id: `wapper_menu_context-${idWapper}`,
|
|
@@ -298,15 +330,14 @@ var TableStyleContextWapper = ({
|
|
|
298
330
|
}
|
|
299
331
|
);
|
|
300
332
|
};
|
|
301
|
-
var
|
|
302
|
-
|
|
333
|
+
var TableStyleContextWapper = memo2(
|
|
334
|
+
TableStyleContextWapperInner
|
|
303
335
|
);
|
|
304
|
-
|
|
305
|
-
return `wapper_menu_context-${externalId != null ? externalId : "default-id"}`;
|
|
306
|
-
};
|
|
336
|
+
var getTableStyleWapperId = (externalId) => `wapper_menu_context-${externalId != null ? externalId : "default"}`;
|
|
307
337
|
export {
|
|
308
338
|
ReactTableGridCustom,
|
|
309
|
-
|
|
339
|
+
TableStyleContextWapper,
|
|
340
|
+
getTableStyleWapperId,
|
|
310
341
|
useShowHideColumn
|
|
311
342
|
};
|
|
312
343
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/helpers/functions.ts","../src/helpers/table.ts","../src/utils.ts","../src/hooks/useShowHideColumn.ts","../src/type/table.ts","../src/component/ui/Table/ReactTableGridCustom.tsx","../src/component/Icons.tsx","../src/component/ui/Table/TableStyleContextWapper.tsx"],"sourcesContent":["import { deleteDB, IDBPDatabase, openDB } from 'idb'\nimport { pickBy } from 'lodash'\nimport moment from 'moment'\nimport { optionSelect } from '../type/preload-stubs'\nimport { IObjectParams, IToggleValues } from '../type/renderer'\nexport const setLocalStore = (key: string, value: string): void => {\n if (typeof window !== 'undefined') {\n localStorage.setItem(key, value)\n }\n}\n\nexport const getLocalStore = (key: string): string | null => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem(key)\n } else {\n return null\n }\n}\n\nexport function convertViToEn(str: string, toUpperCase = false): string {\n str = str.toLowerCase()\n str = str.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, 'a')\n str = str.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ/g, 'e')\n str = str.replace(/ì|í|ị|ỉ|ĩ/g, 'i')\n str = str.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, 'o')\n str = str.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, 'u')\n str = str.replace(/ỳ|ý|ỵ|ỷ|ỹ/g, 'y')\n str = str.replace(/đ/g, 'd')\n // Some system encode vietnamese combining accent as individual utf-8 characters\n str = str.replace(/\\u0300|\\u0301|\\u0303|\\u0309|\\u0323/g, '') // Huyền sắc hỏi ngã nặng\n str = str.replace(/\\u02C6|\\u0306|\\u031B/g, '') // Â, Ê, Ă, Ơ, Ư\n\n return toUpperCase ? str.toUpperCase() : str\n}\n\nexport const convertNumber = (value: number | string): { value: number; check: boolean } => {\n let num = 0\n if (value) {\n value = value.toString().replace(/[.]/g, '')\n value = value.trim()\n num = Number(value)\n }\n\n const regex = /^-?\\d*$/\n const check = regex.test(num.toString())\n return {\n value: num,\n check\n }\n}\n\nexport const changeTitleDocmemt = (title?: string): void => {\n document.title = `${title} - Phần Mềm MKT`\n}\n\nexport const numberConvert = (num: string | number): string => {\n let t = '0'\n if (num) {\n if (typeof num === 'string') {\n num = Number(num)\n }\n t = num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, '.')\n }\n return t\n}\n\nexport const pickBySearch = <T extends Record<string, unknown>>(obj: T): Partial<T> => {\n const filteredObj = pickBy(obj, (value) => value !== '')\n return filteredObj as Partial<T>\n}\n\nexport const getValueSelected = (value?: unknown, options?: optionSelect[]): optionSelect[] => {\n const currentValue = (options ?? [])?.filter((otp) => {\n return Array.isArray(value) ? value?.includes(otp.value) : otp?.value === value\n })\n return currentValue\n}\n\nexport const toggleValues = ({ array, value }: IToggleValues): string[] => {\n if (array.includes(value)) {\n return array.filter((item) => item !== value)\n } else {\n return [...array, value]\n }\n}\n\nexport const arrayLocal = (array?: string): string[] => {\n try {\n const data = array ? JSON.parse(array) : []\n return Array.isArray(data) ? data : []\n } catch {\n return []\n }\n}\n\nexport const formatDate = (\n date?: string | number | Date,\n format: string = 'DD/MM/YYYY HH:mm:ss A'\n): string => {\n return moment(date).format(format)\n}\n\nexport const parseObject = (obj?: string): object => {\n try {\n const data = obj ? JSON.parse(obj) : {}\n return typeof data === 'object' ? data : {}\n } catch {\n return {}\n }\n}\nexport const bufferToBlob = (buffer: ArrayBuffer | Uint8Array, type: string): Blob => {\n return new Blob([buffer as BlobPart], { type })\n}\nconst DB_NAME = 'appDB'\nconst DB_VERSION = 5\nconst STORE_NAME = 'selectedRecords'\nconst HISTORY_STORE = 'recordHistory'\ninterface SelectedRecordEntry {\n actionType: string\n selectedRecords: string[]\n}\n\ninterface RecordHistoryEntry {\n id: string\n previousAction: string[]\n}\n\ntype AppDBSchema = {\n selectedRecords: SelectedRecordEntry\n recordHistory: RecordHistoryEntry\n}\n\nconst requiredStores = [STORE_NAME, HISTORY_STORE]\n\nconst createAppDB = async (): Promise<IDBPDatabase<AppDBSchema>> => {\n return openDB<AppDBSchema>(DB_NAME, DB_VERSION, {\n upgrade(db) {\n for (const storeName of Array.from(db.objectStoreNames)) {\n db.deleteObjectStore(storeName)\n }\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n const store = db.createObjectStore(STORE_NAME, {\n keyPath: 'actionType'\n })\n store.createIndex('by_actionType', 'actionType')\n }\n\n if (!db.objectStoreNames.contains(HISTORY_STORE)) {\n db.createObjectStore(HISTORY_STORE, { keyPath: 'id' })\n }\n }\n })\n}\n\nexport const openAppDB = async (): Promise<IDBPDatabase<AppDBSchema>> => {\n try {\n const db = await createAppDB()\n const hasAllStores = requiredStores.every((store) => db.objectStoreNames.contains(store))\n if (!hasAllStores) {\n console.warn('[IndexedDB] Missing required stores. Resetting DB...')\n db.close()\n await deleteDB(DB_NAME)\n return await createAppDB()\n }\n return db\n } catch (error) {\n if ((error as { name: string })?.name === 'VersionError') {\n console.warn('[IndexedDB] Version downgrade detected. Resetting DB...')\n await deleteDB(DB_NAME)\n return await createAppDB()\n }\n\n console.error('[IndexedDB] Failed to open DB:', error)\n throw error\n }\n}\n\nexport const saveSelectedRecords = async (\n ACTION_TYPE: string,\n selectedRecords: Set<string>\n): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction(STORE_NAME, 'readwrite')\n const store = tx.objectStore(STORE_NAME)\n\n const data: SelectedRecordEntry = {\n actionType: ACTION_TYPE,\n selectedRecords: Array.from(selectedRecords)\n }\n\n await store.put(data)\n await tx.done\n}\n\nexport const getSelectedRecords = async (ACTION_TYPE: string): Promise<Set<string>> => {\n const db = await openAppDB()\n const store = db.transaction(STORE_NAME).objectStore(STORE_NAME)\n\n const record = await store.get(ACTION_TYPE)\n\n return new Set(record?.selectedRecords ?? [])\n}\nexport const removeUidsFromAllPathsAndSaveHistory = async (uids: string[]): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction([STORE_NAME, HISTORY_STORE], 'readwrite')\n const store = tx.objectStore(STORE_NAME)\n const historyStore = tx.objectStore(HISTORY_STORE)\n\n const allRecords = await store.getAll()\n\n const historyMap: Record<string, string[]> = {}\n\n for (const uid of uids) {\n historyMap[uid] = []\n }\n\n for (const record of allRecords) {\n let updated = false\n\n for (const uid of uids) {\n if (record.selectedRecords.includes(uid)) {\n record.selectedRecords = record.selectedRecords.filter((id: string) => id !== uid)\n historyMap[uid].push(record.actionType)\n updated = true\n }\n }\n\n if (updated) {\n await store.put(record)\n }\n }\n\n // Ghi lại lịch sử path đã bị xóa cho từng UID\n for (const [uid, paths] of Object.entries(historyMap)) {\n if (paths.length > 0) {\n await historyStore.put({ id: uid, previousAction: paths })\n }\n }\n\n await tx.done\n}\n\nexport const restoreUidsToPreviousPaths = async (uids: string[]): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction([STORE_NAME, HISTORY_STORE], 'readwrite')\n const store = tx.objectStore(STORE_NAME)\n const historyStore = tx.objectStore(HISTORY_STORE)\n\n for (const uid of uids) {\n const history = await historyStore.get(uid)\n if (history?.previousAction?.length) {\n for (const actionType of history.previousAction) {\n const record = (await store.get(actionType)) || {\n actionType,\n selectedRecords: []\n }\n\n if (!record.selectedRecords.includes(uid)) {\n record.selectedRecords.push(uid)\n }\n\n await store.put(record)\n }\n\n await historyStore.delete(uid)\n }\n }\n\n await tx.done\n}\nexport const deleteUidsCompletely = async (uids: string[]): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction(['selectedRecords', 'recordHistory'], 'readwrite')\n const store = tx.objectStore('selectedRecords')\n const historyStore = tx.objectStore('recordHistory')\n\n const allRecords = await store.getAll()\n\n for (const record of allRecords) {\n const originalLength = record.selectedRecords.length\n record.selectedRecords = record.selectedRecords.filter((id: string) => !uids.includes(id))\n\n if (record.selectedRecords.length !== originalLength) {\n await store.put(record)\n }\n }\n for (const uid of uids) {\n await historyStore.delete(uid)\n }\n\n await tx.done\n}\n\nexport const getSelectedCategoryDataByPath = (): string[] => {\n try {\n const saved = localStorage.getItem('selectedCategoryData')\n if (saved) {\n const data = JSON.parse(saved)\n const localPath = window.location.hash.replace(/^#/, '') || '/'\n const categoryData = data[localPath]\n if (categoryData && Array.isArray(categoryData.categoryIds)) {\n return categoryData.categoryIds\n }\n }\n } catch (err) {\n console.warn('Failed to parse localStorage category data:', err)\n }\n\n return []\n}\n\nexport const handleAsyncConfigSearchInitialValue = (): IObjectParams => {\n const defaultConfig: IObjectParams = {\n page: 1,\n pageSize: 1000,\n filterType: 'all'\n }\n\n const categoryIds = getSelectedCategoryDataByPath()\n if (categoryIds.length > 0) {\n return {\n ...defaultConfig,\n categoryId: categoryIds\n }\n }\n\n return defaultConfig\n}\n","import { ICalculatorTotalPage, IPaginationParams } from \"../type/table-type\"\n\nexport const calculatorTotalPage = ({ total = 0, pageSize = 0 }: ICalculatorTotalPage): number => {\n if (!pageSize || (pageSize && pageSize <= 0)) return 0\n return Math.ceil(total / pageSize)\n}\n\nexport const STT = (data?: IPaginationParams, index?: number): number => {\n let stt = 1\n let current_page = 0\n let per_page = 0\n\n if (data?.page !== undefined && data?.pageSize !== undefined) {\n current_page = data.page\n per_page = data.pageSize\n }\n\n let i = (current_page - 1) * per_page\n i = isNaN(i) ? 0 : i\n stt = i + (index ?? 0) + 1\n\n return stt\n}\n","import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs))\n}\n","import { arrayLocal, getLocalStore, setLocalStore, toggleValues } from '../helpers'\nimport { useCallback, useMemo, useState } from 'react'\nimport { Column } from 'react-data-grid'\nimport { TColumnsTable, useShowHideColumnParameter, useShowHideColumnReturn } from '../type/table-type'\nimport { uniq } from 'lodash'\nimport { isColumn } from '../type/table'\n\nconst useShowHideColumn = <T, SR = unknown>({\n nameLocal = 'table',\n columns,\n ignoreColumns\n}: useShowHideColumnParameter<T, SR>): useShowHideColumnReturn<T, SR> => {\n const nameLocalLocation = `${nameLocal}_location`\n const [locationColumns, setLocationColumns] = useState<string[]>(() => {\n const dataLocal = getLocalStore(nameLocalLocation)\n if (dataLocal) {\n return arrayLocal(dataLocal)\n }\n return []\n })\n const [hiddenColumns, setHiddenColumns] = useState<string[]>(() => {\n const dataLocal = getLocalStore(nameLocal)\n if (dataLocal) {\n return arrayLocal(dataLocal)\n }\n return []\n })\n\n const handleFindLocation = useCallback(\n (filterColumns: TColumnsTable<T, SR>, arrLoctions = locationColumns) => {\n return arrLoctions?.length > 0\n ? arrLoctions?.reduce(\n (total, current) => {\n const currentColumns = filterColumns?.find((item) => {\n const newItem = item as Column<T>\n return newItem?.key === current\n })\n\n if (currentColumns) {\n total = [...total, currentColumns]\n }\n return total\n },\n [] as TColumnsTable<T, SR>\n )\n : filterColumns\n },\n [locationColumns]\n )\n\n const newCloumnKeys = useMemo(\n () =>\n columns\n ?.filter(isColumn)\n .map(column => column.key),\n [columns]\n )\n\n\n const newColumns = useMemo(() => {\n const filterColumns: TColumnsTable<T, SR> =\n columns?.filter(column => {\n if (!isColumn(column)) return true\n\n const key = column.key\n\n if (ignoreColumns?.includes(key)) return true\n if (hiddenColumns?.includes(key)) return false\n\n return true\n }) ?? []\n\n return handleFindLocation(filterColumns)\n }, [columns, hiddenColumns, locationColumns, ignoreColumns])\n\n const newShowhideColumns = useMemo(() => {\n if (!ignoreColumns) return columns\n\n return (\n columns?.filter(column => {\n if (!isColumn(column)) return true\n return !ignoreColumns.includes(column.key)\n }) ?? []\n )\n }, [columns, ignoreColumns])\n\n const changeHiddenColumn = useCallback(\n (key: string | string[]) => {\n let newData = [...hiddenColumns]\n if (typeof key === 'string') {\n newData = toggleValues({\n array: newData,\n value: key\n })\n } else {\n newData = key\n }\n setLocalStore(nameLocal, JSON.stringify(newData))\n setHiddenColumns(newData)\n },\n [hiddenColumns, nameLocalLocation]\n )\n\n const handleChangeLocation = useCallback(\n (key: string[]) => {\n let newKey = key\n newKey = uniq([...key, ...newCloumnKeys])\n setLocationColumns(newKey)\n setLocalStore(nameLocalLocation, JSON.stringify(newKey))\n },\n [newCloumnKeys]\n )\n\n return {\n hiddenColumns,\n setHiddenColumns,\n columnsTable: newColumns,\n changeHiddenColumn,\n newShowhideColumns,\n locationColumns,\n handleFindLocation,\n handleChangeLocation\n }\n}\n\nexport { useShowHideColumn }\n","import { UseMutateFunction } from '@tanstack/react-query'\nimport { FormikProps } from 'formik'\nimport { Dispatch, HTMLAttributes, ReactNode, SetStateAction } from 'react'\nimport { Props } from 'react-select'\nimport type { IFieldUpdateAndCheck, IMainResponse, ISettingSystem } from './preload-stubs'\nimport type { JobDetail, Proxy } from './vitechgroup-stubs'\n\nimport type { Column, ColumnOrColumnGroup } from 'react-data-grid'\n\nexport function isColumn<T, SR>(\n column: ColumnOrColumnGroup<T, SR>\n): column is Column<T, SR> {\n return 'key' in column\n}\n\nexport interface ITableData {\n t: any\n dataJobDetail?: JobDetail[]\n totalAction?: number\n settingSystem?: ISettingSystem\n readProxyByField?: UseMutateFunction<\n IMainResponse<Proxy[]>,\n Error,\n IFieldUpdateAndCheck<Proxy, undefined, string[]>[],\n unknown\n >\n}\n\nexport interface CustomSelectProps<T> extends Props, Omit<WapperLabelFormProps, 'children'> {\n className?: string\n height?: string\n name: string\n formik?: FormikProps<T>\n msgError?: string\n changeSelected?: (selected?: Record<string, string>) => void\n setValueSearch?: Dispatch<SetStateAction<string>>\n positionMenu?: string\n}\n\nexport interface WapperLabelFormProps {\n classWapper?: HTMLAttributes<HTMLDivElement>['className']\n label?: string\n clsLabelWrapper?: string\n isRequired?: boolean\n children?: ReactNode\n isVertical?: boolean\n}\n","'use client'\n\nimport { get } from 'lodash'\nimport {\n Key,\n memo,\n useCallback,\n useMemo\n} from 'react'\nimport {\n DataGrid,\n SelectColumn,\n type Column,\n type ColumnOrColumnGroup\n} from 'react-data-grid'\nimport 'react-data-grid/lib/styles.css'\n\nimport { cn } from '../../../helpers'\nimport { STT } from '../../../helpers/table'\nimport { LoadingIcon } from '../../Icons'\nimport type { IReactTableGridCustom } from './table-type'\nimport './ReactTableGridCustom.css'\n\nconst ReactTableGridCustomInner = <\n T,\n SR = unknown,\n K extends Key = Key\n>(\n props: IReactTableGridCustom<T, SR, K>\n) => {\n const {\n classNameWapperTable,\n hiddenSTT,\n data,\n page,\n pageSize,\n columns,\n rowKeyGetter = 'uid',\n\n enableSelectRow,\n selectedRows,\n onSelectedRowsChange,\n\n sortColumns,\n onSortColumnsChange,\n\n fetching,\n onRowClick,\n onRowDoubleClick\n } = props\n\n const isSelectRow =\n enableSelectRow && selectedRows !== undefined\n\n /* =========================\n * Columns\n * ========================= */\n const newColumns = useMemo<\n readonly ColumnOrColumnGroup<T, SR>[]\n >(() => {\n const cols = [...columns]\n\n if (isSelectRow) {\n cols.unshift(SelectColumn as Column<T, SR>)\n }\n\n if (!hiddenSTT) {\n cols.unshift({\n key: '__index__',\n name: 'STT',\n width: 80,\n renderCell: ({ rowIdx }) =>\n STT({ page, pageSize }, rowIdx)\n })\n }\n\n return cols\n }, [columns, hiddenSTT, isSelectRow, page, pageSize])\n\n /* =========================\n * Row key\n * ========================= */\n const customRowKeyGetter = useCallback(\n (row: T): K => {\n if (typeof rowKeyGetter === 'function') {\n return rowKeyGetter(row)\n }\n return get(row, rowKeyGetter) as K\n },\n [rowKeyGetter]\n )\n\n return (\n <div\n className={cn(\n 'wapper_table flex flex-col h-full min-h-0 relative',\n classNameWapperTable\n )}\n >\n <DataGrid<T, SR, K>\n rows={data}\n columns={newColumns}\n selectedRows={selectedRows}\n onSelectedRowsChange={onSelectedRowsChange}\n rowKeyGetter={isSelectRow ? customRowKeyGetter : undefined}\n sortColumns={sortColumns}\n onSortColumnsChange={onSortColumnsChange}\n onCellClick={({ row, rowIdx }) =>\n onRowClick?.(row, rowIdx)\n }\n onCellDoubleClick={({ row, rowIdx }) =>\n onRowDoubleClick?.(row, rowIdx)\n }\n />\n\n {fetching && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-white/60 z-10\">\n <LoadingIcon isSpin />\n </div>\n )}\n </div>\n )\n}\n\nexport const ReactTableGridCustom = memo(\n ReactTableGridCustomInner\n) as typeof ReactTableGridCustomInner\n","import { JSX } from \"react\"\n\nexport const LoadingIcon = ({\n isSpin = false,\n h = 30,\n w = 30,\n size = 30,\n className\n}: {\n isSpin?: boolean\n w?: number\n h?: number\n size?: number\n className?: string\n}): JSX.Element => {\n return (\n <svg\n className={`${isSpin ? 'animate-spin' : ''} ${className ?? ''}`}\n viewBox=\"0 0 1024 1024\"\n focusable=\"false\"\n data-icon=\"loading\"\n width={size || w}\n height={size || h}\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path d=\"M988 548c-19.9 0-36-16.1-36-36 0-59.4-11.6-117-34.6-171.3a440.45 440.45 0 00-94.3-139.9 437.71 437.71 0 00-139.9-94.3C629 83.6 571.4 72 512 72c-19.9 0-36-16.1-36-36s16.1-36 36-36c69.1 0 136.2 13.5 199.3 40.3C772.3 66 827 103 874 150c47 47 83.9 101.8 109.7 162.7 26.7 63.1 40.2 130.2 40.2 199.3.1 19.9-16 36-35.9 36z\"></path>\n </svg>\n )\n}\n\nexport const ArrowIcon = ({\n h,\n w,\n size,\n className\n}: {\n w?: number\n h?: number\n size?: number\n className?: string\n}): JSX.Element => {\n return (\n <svg\n className={className}\n stroke=\"currentColor\"\n fill=\"currentColor\"\n strokeWidth=\"0\"\n viewBox=\"0 0 16 16\"\n height={size ?? h}\n width={size ?? w}\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path\n fillRule=\"evenodd\"\n d=\"M8 4a.5.5 0 0 1 .5.5v5.793l2.146-2.147a.5.5 0 0 1 .708.708l-3 3a.5.5 0 0 1-.708 0l-3-3a.5.5 0 1 1 .708-.708L7.5 10.293V4.5A.5.5 0 0 1 8 4\"\n ></path>\n </svg>\n )\n}\n","import { FC, memo, ReactNode, useId } from 'react'\n// import ContextMenu, { ContextMenuProps } from '../ContextMenu/ContextMenu'\n// import RenderContextMenu, { RenderContextMenuProps } from '../ContextMenu/RenderContextMenu'\n\n/* =========================\n * Props\n * ========================= */\nexport interface TableStyleWapperProps {\n children?: ReactNode\n // contextMenuProps?: Omit<ContextMenuProps, 'selector' | 'children'> & {\n // selector?: string\n // }\n // renderContext?: RenderContextMenuProps\n clsTablecustom?: string\n idWapper?: string // 🔹 có thể truyền id từ ngoài\n}\n\n/* =========================\n * Client guard\n * ========================= */\nconst isClient = typeof window !== 'undefined'\n\n/* =========================\n * Component\n * ========================= */\nconst TableStyleContextWapper: FC<TableStyleWapperProps> = ({\n children,\n // contextMenuProps,\n clsTablecustom,\n // renderContext,\n idWapper: externalId\n}) => {\n // ⛔ server / electron preload → không render gì\n if (!isClient) {\n return <>{children}</>\n }\n\n // Nếu có id bên ngoài truyền vào thì dùng, nếu không thì sinh tự động\n const idWapper = externalId ?? \"12\"\n\n return (\n <div\n id={`wapper_menu_context-${idWapper}`}\n className={`border border-[#dedede] rounded-xl overflow-hidden bg-white flex-1 h-full flex flex-col min-h-[360px] ${clsTablecustom ?? ''}`}\n >\n {/* {renderContext?.renderData && (\n <ContextMenu\n selector={`[id=\"wapper_menu_context-${idWapper}\"] .rdg`}\n {...contextMenuProps}\n >\n <RenderContextMenu {...renderContext} />\n </ContextMenu>\n )} */}\n\n {children}\n </div>\n )\n}\n\n/* =========================\n * Type cho component export\n * ========================= */\nexport interface TableStyleContextMenuWapperComponent extends FC<TableStyleWapperProps> {\n getIdFromOutside?: (externalId?: string) => string\n}\n\n/* =========================\n * Export (SAFE) + cast type\n * ========================= */\nexport const TableStyleContextMenuWapper = memo(\n TableStyleContextWapper\n) as TableStyleContextMenuWapperComponent\n\n/* =========================\n * Static helper function (tuỳ chọn)\n * ========================= */\nTableStyleContextMenuWapper.getIdFromOutside = (externalId?: string) => {\n return `wapper_menu_context-${externalId ?? 'default-id'}`\n}\n"],"mappings":"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","names":["useCallback","useMemo","jsx","useMemo","useCallback","memo","jsx"]}
|
|
1
|
+
{"version":3,"sources":["../src/helpers/functions.ts","../src/helpers/table.ts","../src/utils.ts","../src/hooks/useShowHideColumn.ts","../src/type/table.ts","../src/component/ui/Table/ReactTableGridCustom.tsx","../src/component/ui/Table/TableStyleContextWapper.tsx"],"sourcesContent":["import { deleteDB, IDBPDatabase, openDB } from 'idb'\nimport { pickBy } from 'lodash'\nimport moment from 'moment'\nimport { optionSelect } from '../type/preload-stubs'\nimport { IObjectParams, IToggleValues } from '../type/renderer'\nexport const setLocalStore = (key: string, value: string): void => {\n if (typeof window !== 'undefined') {\n localStorage.setItem(key, value)\n }\n}\n\nexport const getLocalStore = (key: string): string | null => {\n if (typeof window !== 'undefined') {\n return localStorage.getItem(key)\n } else {\n return null\n }\n}\n\nexport function convertViToEn(str: string, toUpperCase = false): string {\n str = str.toLowerCase()\n str = str.replace(/à|á|ạ|ả|ã|â|ầ|ấ|ậ|ẩ|ẫ|ă|ằ|ắ|ặ|ẳ|ẵ/g, 'a')\n str = str.replace(/è|é|ẹ|ẻ|ẽ|ê|ề|ế|ệ|ể|ễ/g, 'e')\n str = str.replace(/ì|í|ị|ỉ|ĩ/g, 'i')\n str = str.replace(/ò|ó|ọ|ỏ|õ|ô|ồ|ố|ộ|ổ|ỗ|ơ|ờ|ớ|ợ|ở|ỡ/g, 'o')\n str = str.replace(/ù|ú|ụ|ủ|ũ|ư|ừ|ứ|ự|ử|ữ/g, 'u')\n str = str.replace(/ỳ|ý|ỵ|ỷ|ỹ/g, 'y')\n str = str.replace(/đ/g, 'd')\n // Some system encode vietnamese combining accent as individual utf-8 characters\n str = str.replace(/\\u0300|\\u0301|\\u0303|\\u0309|\\u0323/g, '') // Huyền sắc hỏi ngã nặng\n str = str.replace(/\\u02C6|\\u0306|\\u031B/g, '') // Â, Ê, Ă, Ơ, Ư\n\n return toUpperCase ? str.toUpperCase() : str\n}\n\nexport const convertNumber = (value: number | string): { value: number; check: boolean } => {\n let num = 0\n if (value) {\n value = value.toString().replace(/[.]/g, '')\n value = value.trim()\n num = Number(value)\n }\n\n const regex = /^-?\\d*$/\n const check = regex.test(num.toString())\n return {\n value: num,\n check\n }\n}\n\nexport const changeTitleDocmemt = (title?: string): void => {\n document.title = `${title} - Phần Mềm MKT`\n}\n\nexport const numberConvert = (num: string | number): string => {\n let t = '0'\n if (num) {\n if (typeof num === 'string') {\n num = Number(num)\n }\n t = num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, '.')\n }\n return t\n}\n\nexport const pickBySearch = <T extends Record<string, unknown>>(obj: T): Partial<T> => {\n const filteredObj = pickBy(obj, (value) => value !== '')\n return filteredObj as Partial<T>\n}\n\nexport const getValueSelected = (value?: unknown, options?: optionSelect[]): optionSelect[] => {\n const currentValue = (options ?? [])?.filter((otp) => {\n return Array.isArray(value) ? value?.includes(otp.value) : otp?.value === value\n })\n return currentValue\n}\n\nexport const toggleValues = ({ array, value }: IToggleValues): string[] => {\n if (array.includes(value)) {\n return array.filter((item) => item !== value)\n } else {\n return [...array, value]\n }\n}\n\nexport const arrayLocal = (array?: string): string[] => {\n try {\n const data = array ? JSON.parse(array) : []\n return Array.isArray(data) ? data : []\n } catch {\n return []\n }\n}\n\nexport const formatDate = (\n date?: string | number | Date,\n format: string = 'DD/MM/YYYY HH:mm:ss A'\n): string => {\n return moment(date).format(format)\n}\n\nexport const parseObject = (obj?: string): object => {\n try {\n const data = obj ? JSON.parse(obj) : {}\n return typeof data === 'object' ? data : {}\n } catch {\n return {}\n }\n}\nexport const bufferToBlob = (buffer: ArrayBuffer | Uint8Array, type: string): Blob => {\n return new Blob([buffer as BlobPart], { type })\n}\nconst DB_NAME = 'appDB'\nconst DB_VERSION = 5\nconst STORE_NAME = 'selectedRecords'\nconst HISTORY_STORE = 'recordHistory'\ninterface SelectedRecordEntry {\n actionType: string\n selectedRecords: string[]\n}\n\ninterface RecordHistoryEntry {\n id: string\n previousAction: string[]\n}\n\ntype AppDBSchema = {\n selectedRecords: SelectedRecordEntry\n recordHistory: RecordHistoryEntry\n}\n\nconst requiredStores = [STORE_NAME, HISTORY_STORE]\n\nconst createAppDB = async (): Promise<IDBPDatabase<AppDBSchema>> => {\n return openDB<AppDBSchema>(DB_NAME, DB_VERSION, {\n upgrade(db) {\n for (const storeName of Array.from(db.objectStoreNames)) {\n db.deleteObjectStore(storeName)\n }\n if (!db.objectStoreNames.contains(STORE_NAME)) {\n const store = db.createObjectStore(STORE_NAME, {\n keyPath: 'actionType'\n })\n store.createIndex('by_actionType', 'actionType')\n }\n\n if (!db.objectStoreNames.contains(HISTORY_STORE)) {\n db.createObjectStore(HISTORY_STORE, { keyPath: 'id' })\n }\n }\n })\n}\n\nexport const openAppDB = async (): Promise<IDBPDatabase<AppDBSchema>> => {\n try {\n const db = await createAppDB()\n const hasAllStores = requiredStores.every((store) => db.objectStoreNames.contains(store))\n if (!hasAllStores) {\n console.warn('[IndexedDB] Missing required stores. Resetting DB...')\n db.close()\n await deleteDB(DB_NAME)\n return await createAppDB()\n }\n return db\n } catch (error) {\n if ((error as { name: string })?.name === 'VersionError') {\n console.warn('[IndexedDB] Version downgrade detected. Resetting DB...')\n await deleteDB(DB_NAME)\n return await createAppDB()\n }\n\n console.error('[IndexedDB] Failed to open DB:', error)\n throw error\n }\n}\n\nexport const saveSelectedRecords = async (\n ACTION_TYPE: string,\n selectedRecords: Set<string>\n): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction(STORE_NAME, 'readwrite')\n const store = tx.objectStore(STORE_NAME)\n\n const data: SelectedRecordEntry = {\n actionType: ACTION_TYPE,\n selectedRecords: Array.from(selectedRecords)\n }\n\n await store.put(data)\n await tx.done\n}\n\nexport const getSelectedRecords = async (ACTION_TYPE: string): Promise<Set<string>> => {\n const db = await openAppDB()\n const store = db.transaction(STORE_NAME).objectStore(STORE_NAME)\n\n const record = await store.get(ACTION_TYPE)\n\n return new Set(record?.selectedRecords ?? [])\n}\nexport const removeUidsFromAllPathsAndSaveHistory = async (uids: string[]): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction([STORE_NAME, HISTORY_STORE], 'readwrite')\n const store = tx.objectStore(STORE_NAME)\n const historyStore = tx.objectStore(HISTORY_STORE)\n\n const allRecords = await store.getAll()\n\n const historyMap: Record<string, string[]> = {}\n\n for (const uid of uids) {\n historyMap[uid] = []\n }\n\n for (const record of allRecords) {\n let updated = false\n\n for (const uid of uids) {\n if (record.selectedRecords.includes(uid)) {\n record.selectedRecords = record.selectedRecords.filter((id: string) => id !== uid)\n historyMap[uid].push(record.actionType)\n updated = true\n }\n }\n\n if (updated) {\n await store.put(record)\n }\n }\n\n // Ghi lại lịch sử path đã bị xóa cho từng UID\n for (const [uid, paths] of Object.entries(historyMap)) {\n if (paths.length > 0) {\n await historyStore.put({ id: uid, previousAction: paths })\n }\n }\n\n await tx.done\n}\n\nexport const restoreUidsToPreviousPaths = async (uids: string[]): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction([STORE_NAME, HISTORY_STORE], 'readwrite')\n const store = tx.objectStore(STORE_NAME)\n const historyStore = tx.objectStore(HISTORY_STORE)\n\n for (const uid of uids) {\n const history = await historyStore.get(uid)\n if (history?.previousAction?.length) {\n for (const actionType of history.previousAction) {\n const record = (await store.get(actionType)) || {\n actionType,\n selectedRecords: []\n }\n\n if (!record.selectedRecords.includes(uid)) {\n record.selectedRecords.push(uid)\n }\n\n await store.put(record)\n }\n\n await historyStore.delete(uid)\n }\n }\n\n await tx.done\n}\nexport const deleteUidsCompletely = async (uids: string[]): Promise<void> => {\n const db = await openAppDB()\n const tx = db.transaction(['selectedRecords', 'recordHistory'], 'readwrite')\n const store = tx.objectStore('selectedRecords')\n const historyStore = tx.objectStore('recordHistory')\n\n const allRecords = await store.getAll()\n\n for (const record of allRecords) {\n const originalLength = record.selectedRecords.length\n record.selectedRecords = record.selectedRecords.filter((id: string) => !uids.includes(id))\n\n if (record.selectedRecords.length !== originalLength) {\n await store.put(record)\n }\n }\n for (const uid of uids) {\n await historyStore.delete(uid)\n }\n\n await tx.done\n}\n\nexport const getSelectedCategoryDataByPath = (): string[] => {\n try {\n const saved = localStorage.getItem('selectedCategoryData')\n if (saved) {\n const data = JSON.parse(saved)\n const localPath = window.location.hash.replace(/^#/, '') || '/'\n const categoryData = data[localPath]\n if (categoryData && Array.isArray(categoryData.categoryIds)) {\n return categoryData.categoryIds\n }\n }\n } catch (err) {\n console.warn('Failed to parse localStorage category data:', err)\n }\n\n return []\n}\n\nexport const handleAsyncConfigSearchInitialValue = (): IObjectParams => {\n const defaultConfig: IObjectParams = {\n page: 1,\n pageSize: 1000,\n filterType: 'all'\n }\n\n const categoryIds = getSelectedCategoryDataByPath()\n if (categoryIds.length > 0) {\n return {\n ...defaultConfig,\n categoryId: categoryIds\n }\n }\n\n return defaultConfig\n}\n","import { ICalculatorTotalPage, IPaginationParams } from \"../type/table-type\"\n\nexport const calculatorTotalPage = ({ total = 0, pageSize = 0 }: ICalculatorTotalPage): number => {\n if (!pageSize || (pageSize && pageSize <= 0)) return 0\n return Math.ceil(total / pageSize)\n}\n\nexport const STT = (data?: IPaginationParams, index?: number): number => {\n let stt = 1\n let current_page = 0\n let per_page = 0\n\n if (data?.page !== undefined && data?.pageSize !== undefined) {\n current_page = data.page\n per_page = data.pageSize\n }\n\n let i = (current_page - 1) * per_page\n i = isNaN(i) ? 0 : i\n stt = i + (index ?? 0) + 1\n\n return stt\n}\n","import { clsx, type ClassValue } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]): string {\n return twMerge(clsx(inputs))\n}\n","import { arrayLocal, getLocalStore, setLocalStore, toggleValues } from '../helpers'\nimport { useCallback, useMemo, useState } from 'react'\nimport { Column } from 'react-data-grid'\nimport { TColumnsTable, useShowHideColumnParameter, useShowHideColumnReturn } from '../type/table-type'\nimport { uniq } from 'lodash'\nimport { isColumn } from '../type/table'\n\nconst useShowHideColumn = <T, SR = unknown>({\n nameLocal = 'table',\n columns,\n ignoreColumns\n}: useShowHideColumnParameter<T, SR>): useShowHideColumnReturn<T, SR> => {\n const nameLocalLocation = `${nameLocal}_location`\n const [locationColumns, setLocationColumns] = useState<string[]>(() => {\n const dataLocal = getLocalStore(nameLocalLocation)\n if (dataLocal) {\n return arrayLocal(dataLocal)\n }\n return []\n })\n const [hiddenColumns, setHiddenColumns] = useState<string[]>(() => {\n const dataLocal = getLocalStore(nameLocal)\n if (dataLocal) {\n return arrayLocal(dataLocal)\n }\n return []\n })\n\n const handleFindLocation = useCallback(\n (filterColumns: TColumnsTable<T, SR>, arrLoctions = locationColumns) => {\n return arrLoctions?.length > 0\n ? arrLoctions?.reduce(\n (total, current) => {\n const currentColumns = filterColumns?.find((item) => {\n const newItem = item as Column<T>\n return newItem?.key === current\n })\n\n if (currentColumns) {\n total = [...total, currentColumns]\n }\n return total\n },\n [] as TColumnsTable<T, SR>\n )\n : filterColumns\n },\n [locationColumns]\n )\n\n const newCloumnKeys = useMemo(\n () =>\n columns\n ?.filter(isColumn)\n .map(column => column.key),\n [columns]\n )\n\n\n const newColumns = useMemo(() => {\n const filterColumns: TColumnsTable<T, SR> =\n columns?.filter(column => {\n if (!isColumn(column)) return true\n\n const key = column.key\n\n if (ignoreColumns?.includes(key)) return true\n if (hiddenColumns?.includes(key)) return false\n\n return true\n }) ?? []\n\n return handleFindLocation(filterColumns)\n }, [columns, hiddenColumns, locationColumns, ignoreColumns])\n\n const newShowhideColumns = useMemo(() => {\n if (!ignoreColumns) return columns\n\n return (\n columns?.filter(column => {\n if (!isColumn(column)) return true\n return !ignoreColumns.includes(column.key)\n }) ?? []\n )\n }, [columns, ignoreColumns])\n\n const changeHiddenColumn = useCallback(\n (key: string | string[]) => {\n let newData = [...hiddenColumns]\n if (typeof key === 'string') {\n newData = toggleValues({\n array: newData,\n value: key\n })\n } else {\n newData = key\n }\n setLocalStore(nameLocal, JSON.stringify(newData))\n setHiddenColumns(newData)\n },\n [hiddenColumns, nameLocalLocation]\n )\n\n const handleChangeLocation = useCallback(\n (key: string[]) => {\n let newKey = key\n newKey = uniq([...key, ...newCloumnKeys])\n setLocationColumns(newKey)\n setLocalStore(nameLocalLocation, JSON.stringify(newKey))\n },\n [newCloumnKeys]\n )\n\n return {\n hiddenColumns,\n setHiddenColumns,\n columnsTable: newColumns,\n changeHiddenColumn,\n newShowhideColumns,\n locationColumns,\n handleFindLocation,\n handleChangeLocation\n }\n}\n\nexport { useShowHideColumn }\n","import { UseMutateFunction } from '@tanstack/react-query'\nimport { FormikProps } from 'formik'\nimport { Dispatch, HTMLAttributes, ReactNode, SetStateAction } from 'react'\nimport { Props } from 'react-select'\nimport type { IFieldUpdateAndCheck, IMainResponse, ISettingSystem } from './preload-stubs'\nimport type { JobDetail, Proxy } from './vitechgroup-stubs'\n\nimport type { Column, ColumnOrColumnGroup } from 'react-data-grid'\n\nexport function isColumn<T, SR>(\n column: ColumnOrColumnGroup<T, SR>\n): column is Column<T, SR> {\n return 'key' in column\n}\n\nexport interface ITableData {\n t: any\n dataJobDetail?: JobDetail[]\n totalAction?: number\n settingSystem?: ISettingSystem\n readProxyByField?: UseMutateFunction<\n IMainResponse<Proxy[]>,\n Error,\n IFieldUpdateAndCheck<Proxy, undefined, string[]>[],\n unknown\n >\n}\n\nexport interface CustomSelectProps<T> extends Props, Omit<WapperLabelFormProps, 'children'> {\n className?: string\n height?: string\n name: string\n formik?: FormikProps<T>\n msgError?: string\n changeSelected?: (selected?: Record<string, string>) => void\n setValueSearch?: Dispatch<SetStateAction<string>>\n positionMenu?: string\n}\n\nexport interface WapperLabelFormProps {\n classWapper?: HTMLAttributes<HTMLDivElement>['className']\n label?: string\n clsLabelWrapper?: string\n isRequired?: boolean\n children?: ReactNode\n isVertical?: boolean\n}\n","'use client'\n\nimport { get } from 'lodash'\nimport {\n Key,\n memo,\n useCallback,\n useMemo\n} from 'react'\nimport {\n DataGrid,\n type Column,\n type ColumnOrColumnGroup\n} from 'react-data-grid'\nimport 'react-data-grid/lib/styles.css'\n\nimport { cn } from '../../../helpers'\nimport { STT } from '../../../helpers/table'\nimport { LoadingIcon } from '../../Icons'\nimport type { IReactTableGridCustom } from './table-type'\nimport './ReactTableGridCustom.css'\n\nconst ReactTableGridCustomInner = <\n T,\n SR = unknown,\n K extends Key = Key\n>(\n props: IReactTableGridCustom<T, SR, K>\n) => {\n const {\n classNameWapperTable,\n hiddenSTT,\n data,\n page,\n pageSize,\n columns,\n rowKeyGetter = 'uid',\n\n enableSelectRow,\n selectedRows,\n onSelectedRowsChange,\n\n sortColumns,\n onSortColumnsChange,\n\n fetching,\n onRowClick,\n onRowDoubleClick\n } = props\n\n const isSelectRow =\n enableSelectRow && selectedRows !== undefined\n\n /* =========================\n * Row key\n * ========================= */\n const customRowKeyGetter = useCallback(\n (row: T): K => {\n if (typeof rowKeyGetter === 'function') {\n return rowKeyGetter(row)\n }\n return get(row, rowKeyGetter) as K\n },\n [rowKeyGetter]\n )\n\n /* =========================\n * Select column (CUSTOM)\n * ========================= */\n const selectColumn = useMemo<Column<T, SR>>(\n () => ({\n key: '__select__',\n name: '',\n width: 44,\n frozen: true,\n sortable: false,\n resizable: false,\n\n renderHeaderCell: () => {\n if (!onSelectedRowsChange) return null\n\n const allSelected =\n selectedRows?.size === data.length && data.length > 0\n\n return (\n <input\n type=\"checkbox\"\n checked={allSelected}\n onChange={(e) => {\n if (e.target.checked) {\n onSelectedRowsChange(\n new Set(data.map(customRowKeyGetter))\n )\n } else {\n onSelectedRowsChange(new Set())\n }\n }}\n />\n )\n },\n\n renderCell: ({ row }) => {\n const key = customRowKeyGetter(row)\n\n return (\n <input\n type=\"checkbox\"\n checked={selectedRows?.has(key)}\n onChange={() => {\n if (!onSelectedRowsChange) return\n\n const next = new Set(selectedRows)\n if (next.has(key)) {\n next.delete(key)\n } else {\n next.add(key)\n }\n onSelectedRowsChange(next)\n }}\n />\n )\n }\n }),\n [\n customRowKeyGetter,\n data,\n selectedRows,\n onSelectedRowsChange\n ]\n )\n\n /* =========================\n * Columns\n * ========================= */\n const newColumns = useMemo<\n readonly ColumnOrColumnGroup<T, SR>[]\n >(() => {\n const cols = [...columns]\n\n if (isSelectRow) {\n cols.unshift(selectColumn)\n }\n\n if (!hiddenSTT) {\n cols.unshift({\n key: '__index__',\n name: 'STT',\n width: 80,\n sortable: false,\n renderCell: ({ rowIdx }) =>\n STT({ page, pageSize }, rowIdx)\n })\n }\n\n return cols\n }, [\n columns,\n hiddenSTT,\n isSelectRow,\n page,\n pageSize,\n selectColumn\n ])\n\n return (\n <div\n className={cn(\n 'wapper_table flex flex-col h-full min-h-0 relative',\n classNameWapperTable\n )}\n >\n <DataGrid<T, SR, K>\n rows={data}\n columns={newColumns}\n selectedRows={selectedRows}\n onSelectedRowsChange={onSelectedRowsChange}\n rowKeyGetter={isSelectRow ? customRowKeyGetter : undefined}\n sortColumns={sortColumns}\n onSortColumnsChange={onSortColumnsChange}\n onCellClick={({ row, rowIdx }) =>\n onRowClick?.(row, rowIdx)\n }\n onCellDoubleClick={({ row, rowIdx }) =>\n onRowDoubleClick?.(row, rowIdx)\n }\n />\n\n {/* {fetching && (\n <div className=\"absolute inset-0 flex items-center justify-center bg-white/60 z-10\">\n <LoadingIcon isSpin />\n </div>\n )} */}\n </div>\n )\n}\n\n/* =========================\n * Export\n * ========================= */\nexport const ReactTableGridCustom = memo(\n ReactTableGridCustomInner\n) as typeof ReactTableGridCustomInner\n","import { FC, memo, ReactNode, useId } from 'react'\n\n/* =========================\n * Props\n * ========================= */\nexport interface TableStyleWapperProps {\n children?: ReactNode\n clsTablecustom?: string\n idWapper?: string // có thể truyền id từ ngoài\n}\n\n/* =========================\n * Client guard\n * ========================= */\nconst isClient = typeof window !== 'undefined'\n\n/* =========================\n * Component\n * ========================= */\nconst TableStyleContextWapperInner: FC<TableStyleWapperProps> = ({\n children,\n clsTablecustom,\n idWapper: externalId\n}) => {\n // server / electron preload → render children\n if (!isClient) {\n return <>{children}</>\n }\n\n // ƯU TIÊN: id ngoài → useId → fallback\n const reactId = useId()\n const idWapper = externalId ?? reactId\n\n return (\n <div\n id={`wapper_menu_context-${idWapper}`}\n className={`border border-[#dedede] rounded-xl overflow-hidden bg-white flex-1 h-full flex flex-col min-h-[360px] ${clsTablecustom ?? ''}`}\n >\n {children}\n </div>\n )\n}\n\n/* =========================\n * Export component (SAFE)\n * ========================= */\nexport const TableStyleContextWapper = memo(\n TableStyleContextWapperInner\n)\n\n/* =========================\n * Helper (EXPORT RIÊNG – SAFE)\n * ========================= */\nexport const getTableStyleWapperId = (externalId?: string) =>\n `wapper_menu_context-${externalId ?? 'default'}`\n"],"mappings":"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","names":["useCallback","useMemo","useCallback","useMemo","memo","jsx"]}
|