@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 CHANGED
@@ -1,6 +1,7 @@
1
- import { Dispatch, SetStateAction, Key, FC, ReactNode } from 'react';
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, DataGridProps } from 'react-data-grid';
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
- interface TableStyleContextMenuWapperComponent extends FC<TableStyleWapperProps> {
53
- getIdFromOutside?: (externalId?: string) => string;
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, TableStyleContextMenuWapper, type TableStyleWapperProps, useShowHideColumn };
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 { Dispatch, SetStateAction, Key, FC, ReactNode } from 'react';
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, DataGridProps } from 'react-data-grid';
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
- interface TableStyleContextMenuWapperComponent extends FC<TableStyleWapperProps> {
53
- getIdFromOutside?: (externalId?: string) => string;
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, TableStyleContextMenuWapper, type TableStyleWapperProps, useShowHideColumn };
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
- TableStyleContextMenuWapper: () => TableStyleContextMenuWapper,
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(import_react_data_grid.SelectColumn);
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
- }, [columns, hiddenSTT, isSelectRow, page, pageSize]);
268
- const customRowKeyGetter = (0, import_react2.useCallback)(
269
- (row) => {
270
- if (typeof rowKeyGetter === "function") {
271
- return rowKeyGetter(row);
272
- }
273
- return (0, import_lodash3.get)(row, rowKeyGetter);
274
- },
275
- [rowKeyGetter]
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
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
286
- import_react_data_grid.DataGrid,
287
- {
288
- rows: data,
289
- columns: newColumns,
290
- selectedRows,
291
- onSelectedRowsChange,
292
- rowKeyGetter: isSelectRow ? customRowKeyGetter : void 0,
293
- sortColumns,
294
- onSortColumnsChange,
295
- onCellClick: ({ row, rowIdx }) => onRowClick == null ? void 0 : onRowClick(row, rowIdx),
296
- onCellDoubleClick: ({ row, rowIdx }) => onRowDoubleClick == null ? void 0 : onRowDoubleClick(row, rowIdx)
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 import_jsx_runtime3 = require("react/jsx-runtime");
345
+ var import_jsx_runtime2 = require("react/jsx-runtime");
311
346
  var isClient = typeof window !== "undefined";
312
- var TableStyleContextWapper = ({
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, import_jsx_runtime3.jsx)(import_jsx_runtime3.Fragment, { children });
353
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children });
321
354
  }
322
- const idWapper = externalId != null ? externalId : "12";
323
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
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 TableStyleContextMenuWapper = (0, import_react3.memo)(
333
- TableStyleContextWapper
366
+ var TableStyleContextWapper = (0, import_react3.memo)(
367
+ TableStyleContextWapperInner
334
368
  );
335
- TableStyleContextMenuWapper.getIdFromOutside = (externalId) => {
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
- TableStyleContextMenuWapper,
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(SelectColumn);
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
- }, [columns, hiddenSTT, isSelectRow, page, pageSize]);
237
- const customRowKeyGetter = useCallback2(
238
- (row) => {
239
- if (typeof rowKeyGetter === "function") {
240
- return rowKeyGetter(row);
241
- }
242
- return get(row, rowKeyGetter);
243
- },
244
- [rowKeyGetter]
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
- /* @__PURE__ */ jsx2(
255
- DataGrid,
256
- {
257
- rows: data,
258
- columns: newColumns,
259
- selectedRows,
260
- onSelectedRowsChange,
261
- rowKeyGetter: isSelectRow ? customRowKeyGetter : void 0,
262
- sortColumns,
263
- onSortColumnsChange,
264
- onCellClick: ({ row, rowIdx }) => onRowClick == null ? void 0 : onRowClick(row, rowIdx),
265
- onCellDoubleClick: ({ row, rowIdx }) => onRowDoubleClick == null ? void 0 : onRowDoubleClick(row, rowIdx)
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 jsx3 } from "react/jsx-runtime";
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 TableStyleContextWapper = ({
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__ */ jsx3(Fragment, { children });
320
+ return /* @__PURE__ */ jsx2(Fragment, { children });
290
321
  }
291
- const idWapper = externalId != null ? externalId : "12";
292
- return /* @__PURE__ */ jsx3(
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 TableStyleContextMenuWapper = memo2(
302
- TableStyleContextWapper
333
+ var TableStyleContextWapper = memo2(
334
+ TableStyleContextWapperInner
303
335
  );
304
- TableStyleContextMenuWapper.getIdFromOutside = (externalId) => {
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
- TableStyleContextMenuWapper,
339
+ TableStyleContextWapper,
340
+ getTableStyleWapperId,
310
341
  useShowHideColumn
311
342
  };
312
343
  //# sourceMappingURL=index.mjs.map
@@ -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":";AAAA,SAAS,UAAwB,cAAc;AAC/C,SAAS,cAAc;AACvB,OAAO,YAAY;AAGZ,IAAM,gBAAgB,CAAC,KAAa,UAAwB;AACjE,MAAI,OAAO,WAAW,aAAa;AACjC,iBAAa,QAAQ,KAAK,KAAK;AAAA,EACjC;AACF;AAEO,IAAM,gBAAgB,CAAC,QAA+B;AAC3D,MAAI,OAAO,WAAW,aAAa;AACjC,WAAO,aAAa,QAAQ,GAAG;AAAA,EACjC,OAAO;AACL,WAAO;AAAA,EACT;AACF;AA6DO,IAAM,eAAe,CAAC,EAAE,OAAO,MAAM,MAA+B;AACzE,MAAI,MAAM,SAAS,KAAK,GAAG;AACzB,WAAO,MAAM,OAAO,CAAC,SAAS,SAAS,KAAK;AAAA,EAC9C,OAAO;AACL,WAAO,CAAC,GAAG,OAAO,KAAK;AAAA,EACzB;AACF;AAEO,IAAM,aAAa,CAAC,UAA6B;AACtD,MAAI;AACF,UAAM,OAAO,QAAQ,KAAK,MAAM,KAAK,IAAI,CAAC;AAC1C,WAAO,MAAM,QAAQ,IAAI,IAAI,OAAO,CAAC;AAAA,EACvC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;;;ACtFO,IAAM,MAAM,CAAC,MAA0B,UAA2B;AACvE,MAAI,MAAM;AACV,MAAI,eAAe;AACnB,MAAI,WAAW;AAEf,OAAI,6BAAM,UAAS,WAAa,6BAAM,cAAa,QAAW;AAC5D,mBAAe,KAAK;AACpB,eAAW,KAAK;AAAA,EAClB;AAEA,MAAI,KAAK,eAAe,KAAK;AAC7B,MAAI,MAAM,CAAC,IAAI,IAAI;AACnB,QAAM,KAAK,wBAAS,KAAK;AAEzB,SAAO;AACT;;;ACtBA,SAAS,YAA6B;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAA8B;AAClD,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ACJA,SAAS,aAAa,SAAS,gBAAgB;AAG/C,SAAS,YAAY;;;ACKd,SAAS,SACd,QACyB;AACzB,SAAO,SAAS;AAClB;;;ADNA,IAAM,oBAAoB,CAAkB;AAAA,EAC1C,YAAY;AAAA,EACZ;AAAA,EACA;AACF,MAAyE;AACvE,QAAM,oBAAoB,GAAG,SAAS;AACtC,QAAM,CAAC,iBAAiB,kBAAkB,IAAI,SAAmB,MAAM;AACrE,UAAM,YAAY,cAAc,iBAAiB;AACjD,QAAI,WAAW;AACb,aAAO,WAAW,SAAS;AAAA,IAC7B;AACA,WAAO,CAAC;AAAA,EACV,CAAC;AACD,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAmB,MAAM;AACjE,UAAM,YAAY,cAAc,SAAS;AACzC,QAAI,WAAW;AACb,aAAO,WAAW,SAAS;AAAA,IAC7B;AACA,WAAO,CAAC;AAAA,EACV,CAAC;AAED,QAAM,qBAAqB;AAAA,IACzB,CAAC,eAAqC,cAAc,oBAAoB;AACtE,cAAO,2CAAa,UAAS,IACzB,2CAAa;AAAA,QACX,CAAC,OAAO,YAAY;AAClB,gBAAM,iBAAiB,+CAAe,KAAK,CAAC,SAAS;AACnD,kBAAM,UAAU;AAChB,oBAAO,mCAAS,SAAQ;AAAA,UAC1B;AAEA,cAAI,gBAAgB;AAClB,oBAAQ,CAAC,GAAG,OAAO,cAAc;AAAA,UACnC;AACA,iBAAO;AAAA,QACT;AAAA,QACA,CAAC;AAAA,UAEH;AAAA,IACN;AAAA,IACA,CAAC,eAAe;AAAA,EAClB;AAEA,QAAM,gBAAgB;AAAA,IACpB,MACE,mCACI,OAAO,UACR,IAAI,YAAU,OAAO;AAAA,IAC1B,CAAC,OAAO;AAAA,EACV;AAGA,QAAM,aAAa,QAAQ,MAAM;AA3DnC;AA4DI,UAAM,iBACJ,wCAAS,OAAO,YAAU;AACxB,UAAI,CAAC,SAAS,MAAM,EAAG,QAAO;AAE9B,YAAM,MAAM,OAAO;AAEnB,UAAI,+CAAe,SAAS,KAAM,QAAO;AACzC,UAAI,+CAAe,SAAS,KAAM,QAAO;AAEzC,aAAO;AAAA,IACT,OATA,YASM,CAAC;AAET,WAAO,mBAAmB,aAAa;AAAA,EACzC,GAAG,CAAC,SAAS,eAAe,iBAAiB,aAAa,CAAC;AAE3D,QAAM,qBAAqB,QAAQ,MAAM;AA3E3C;AA4EI,QAAI,CAAC,cAAe,QAAO;AAE3B,YACE,wCAAS,OAAO,YAAU;AACxB,UAAI,CAAC,SAAS,MAAM,EAAG,QAAO;AAC9B,aAAO,CAAC,cAAc,SAAS,OAAO,GAAG;AAAA,IAC3C,OAHA,YAGM,CAAC;AAAA,EAEX,GAAG,CAAC,SAAS,aAAa,CAAC;AAE3B,QAAM,qBAAqB;AAAA,IACzB,CAAC,QAA2B;AAC1B,UAAI,UAAU,CAAC,GAAG,aAAa;AAC/B,UAAI,OAAO,QAAQ,UAAU;AAC3B,kBAAU,aAAa;AAAA,UACrB,OAAO;AAAA,UACP,OAAO;AAAA,QACT,CAAC;AAAA,MACH,OAAO;AACL,kBAAU;AAAA,MACZ;AACA,oBAAc,WAAW,KAAK,UAAU,OAAO,CAAC;AAChD,uBAAiB,OAAO;AAAA,IAC1B;AAAA,IACA,CAAC,eAAe,iBAAiB;AAAA,EACnC;AAEA,QAAM,uBAAuB;AAAA,IAC3B,CAAC,QAAkB;AACjB,UAAI,SAAS;AACb,eAAS,KAAK,CAAC,GAAG,KAAK,GAAG,aAAa,CAAC;AACxC,yBAAmB,MAAM;AACzB,oBAAc,mBAAmB,KAAK,UAAU,MAAM,CAAC;AAAA,IACzD;AAAA,IACA,CAAC,aAAa;AAAA,EAChB;AAEA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,cAAc;AAAA,IACd;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACF;;;AEzHA,SAAS,WAAW;AACpB;AAAA,EAEE;AAAA,EACA,eAAAA;AAAA,EACA,WAAAC;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,OAGK;AACP,OAAO;;;ACWD;AAxBC,IAAM,cAAc,CAAC;AAAA,EAC1B,SAAS;AAAA,EACT,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,OAAO;AAAA,EACP;AACF,MAMmB;AACjB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW,GAAG,SAAS,iBAAiB,EAAE,IAAI,gCAAa,EAAE;AAAA,MAC7D,SAAQ;AAAA,MACR,WAAU;AAAA,MACV,aAAU;AAAA,MACV,OAAO,QAAQ;AAAA,MACf,QAAQ,QAAQ;AAAA,MAChB,MAAK;AAAA,MACL,eAAY;AAAA,MAEZ,8BAAC,UAAK,GAAE,+TAA8T;AAAA;AAAA,EACxU;AAEJ;;;ADgEI,SAME,OAAAC,MANF;AAtEJ,IAAM,4BAA4B,CAKhC,UACG;AACH,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,eAAe;AAAA,IAEf;AAAA,IACA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IAEA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI;AAEJ,QAAM,cACJ,mBAAmB,iBAAiB;AAKtC,QAAM,aAAaC,SAEjB,MAAM;AACN,UAAM,OAAO,CAAC,GAAG,OAAO;AAExB,QAAI,aAAa;AACf,WAAK,QAAQ,YAA6B;AAAA,IAC5C;AAEA,QAAI,CAAC,WAAW;AACd,WAAK,QAAQ;AAAA,QACX,KAAK;AAAA,QACL,MAAM;AAAA,QACN,OAAO;AAAA,QACP,YAAY,CAAC,EAAE,OAAO,MACpB,IAAI,EAAE,MAAM,SAAS,GAAG,MAAM;AAAA,MAClC,CAAC;AAAA,IACH;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,SAAS,WAAW,aAAa,MAAM,QAAQ,CAAC;AAKpD,QAAM,qBAAqBC;AAAA,IACzB,CAAC,QAAc;AACb,UAAI,OAAO,iBAAiB,YAAY;AACtC,eAAO,aAAa,GAAG;AAAA,MACzB;AACA,aAAO,IAAI,KAAK,YAAY;AAAA,IAC9B;AAAA,IACA,CAAC,YAAY;AAAA,EACf;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MAEA;AAAA,wBAAAF;AAAA,UAAC;AAAA;AAAA,YACC,MAAM;AAAA,YACN,SAAS;AAAA,YACT;AAAA,YACA;AAAA,YACA,cAAc,cAAc,qBAAqB;AAAA,YACjD;AAAA,YACA;AAAA,YACA,aAAa,CAAC,EAAE,KAAK,OAAO,MAC1B,yCAAa,KAAK;AAAA,YAEpB,mBAAmB,CAAC,EAAE,KAAK,OAAO,MAChC,qDAAmB,KAAK;AAAA;AAAA,QAE5B;AAAA,QAEC,YACC,gBAAAA,KAAC,SAAI,WAAU,sEACb,0BAAAA,KAAC,eAAY,QAAM,MAAC,GACtB;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEO,IAAM,uBAAuB;AAAA,EAClC;AACF;;;AE9HA,SAAa,QAAAG,aAA8B;AAkChC,0BAAAC,YAAA;AAdX,IAAM,WAAW,OAAO,WAAW;AAKnC,IAAM,0BAAqD,CAAC;AAAA,EAC1D;AAAA;AAAA,EAEA;AAAA;AAAA,EAEA,UAAU;AACZ,MAAM;AAEJ,MAAI,CAAC,UAAU;AACb,WAAO,gBAAAA,KAAA,YAAG,UAAS;AAAA,EACrB;AAGA,QAAM,WAAW,kCAAc;AAE/B,SACE,gBAAAA;AAAA,IAAC;AAAA;AAAA,MACC,IAAI,uBAAuB,QAAQ;AAAA,MACnC,WAAW,yGAAyG,0CAAkB,EAAE;AAAA,MAWvI;AAAA;AAAA,EACH;AAEJ;AAYO,IAAM,8BAA8BD;AAAA,EACzC;AACF;AAKA,4BAA4B,mBAAmB,CAAC,eAAwB;AACtE,SAAO,uBAAuB,kCAAc,YAAY;AAC1D;","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"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mkt-loitd/react-table-grid-custom",
3
- "version": "1.4.5",
3
+ "version": "1.4.7",
4
4
  "description": "React Table Grid Custom component",
5
5
  "license": "ISC",
6
6
  "private": false,