react-table-edit 1.4.23 → 1.4.25

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.mjs CHANGED
@@ -19290,6 +19290,8 @@ const calculateTableStructure = (columns) => {
19290
19290
  const flat = [];
19291
19291
  const objWidthFixLeft = {};
19292
19292
  const objWidthFixRight = {};
19293
+ const objHeaderWidthFixRight = {};
19294
+ const objHeaderWidthFixLeft = {};
19293
19295
  let maxDepth = 0;
19294
19296
  // Tính depth tối đa
19295
19297
  const calculateDepth = (cols, depth = 1) => (Math.max(...cols.map(col => (col.columns?.length ? calculateDepth(col.columns, depth + 1) : depth))));
@@ -19298,7 +19300,7 @@ const calculateTableStructure = (columns) => {
19298
19300
  let rightTotal = 0;
19299
19301
  const traverse = (cols, level = 0) => {
19300
19302
  levels[level] = levels[level] || [];
19301
- return cols.reduce((colspanSum, col) => {
19303
+ return cols.reduce((colspanSum, col, indexCol) => {
19302
19304
  const hasChildren = (col.columns?.length ?? 0) > 0;
19303
19305
  const colspan = hasChildren ? traverse(col.columns, level + 1) : 1;
19304
19306
  const cell = {
@@ -19308,17 +19310,23 @@ const calculateTableStructure = (columns) => {
19308
19310
  rowspan: hasChildren ? 1 : maxDepth - level
19309
19311
  };
19310
19312
  levels[level].push(cell);
19313
+ const headerKey = `${level}-${indexCol}`;
19314
+ if (col.fixedType === 'right' && col.visible !== false) {
19315
+ objHeaderWidthFixRight[headerKey] = rightTotal;
19316
+ }
19317
+ if (col.fixedType === 'left' && col.visible !== false) {
19318
+ objHeaderWidthFixLeft[headerKey] = leftTotal;
19319
+ }
19311
19320
  if (!hasChildren) {
19312
- const visible = col.visible !== false;
19313
19321
  const index = flat.length;
19314
19322
  const width = col.width ?? 40;
19315
19323
  cell.index = index;
19316
19324
  flat.push(cell);
19317
- if (col.fixedType === 'left' && visible) {
19325
+ if (col.fixedType === 'left' && col.visible !== false) {
19318
19326
  objWidthFixLeft[index] = leftTotal;
19319
19327
  leftTotal += width;
19320
19328
  }
19321
- if (col.fixedType === 'right' && visible) {
19329
+ if (col.fixedType === 'right' && col.visible !== false) {
19322
19330
  objWidthFixRight[index] = rightTotal;
19323
19331
  rightTotal += width;
19324
19332
  }
@@ -19330,6 +19338,9 @@ const calculateTableStructure = (columns) => {
19330
19338
  const flatVisble = flat.filter((e) => e.visible !== false);
19331
19339
  const lastObjWidthFixLeft = Math.max(...Object.keys(objWidthFixLeft).map(Number), 0);
19332
19340
  const fisrtObjWidthFixRight = Math.min(...Object.keys(objWidthFixRight).map(Number), flat.length);
19341
+ const editableColumns = flat.filter(item => item.editEnable && item.visible !== false && !item.disabledCondition);
19342
+ const firstEdit = editableColumns[0];
19343
+ const lastEdit = editableColumns[editableColumns.length - 1];
19333
19344
  return {
19334
19345
  levels,
19335
19346
  flat,
@@ -19337,7 +19348,11 @@ const calculateTableStructure = (columns) => {
19337
19348
  objWidthFixLeft,
19338
19349
  objWidthFixRight,
19339
19350
  lastObjWidthFixLeft,
19340
- fisrtObjWidthFixRight
19351
+ fisrtObjWidthFixRight,
19352
+ objHeaderWidthFixRight,
19353
+ objHeaderWidthFixLeft,
19354
+ firstEdit,
19355
+ lastEdit
19341
19356
  };
19342
19357
  };
19343
19358
 
@@ -41783,31 +41798,52 @@ var css_248z$1 = ".react-resizable {\n position: relative;\n}\n.react-resizable
41783
41798
  styleInject(css_248z$1);
41784
41799
 
41785
41800
  const HeaderTableCol$1 = (props) => {
41786
- const { selectEnable, dataSource, setSelectedRows, col, indexCol, indexParent, objWidthFixLeft, objWidthFixRight, totalCount, selectedRows, column, setColumn, fisrtObjWidthFixRight, lastObjWidthFixLeft, isMulti } = props;
41801
+ const { selectEnable, dataSource, setSelectedRows, col, indexCol, indexParent, objHeaderWidthFixLeft, objHeaderWidthFixRight, totalCount, selectedRows, columns, setColumns, orderBy, changeFilter, filterBy, changeOrder, allowFilter, allowOrder, container, fisrtObjWidthFixRight, lastObjWidthFixLeft, formatSetting, optionsFilter, idTable, isMulti } = props;
41787
41802
  const { t } = useTranslation();
41803
+ const headerRef = useRef(null);
41804
+ const order = orderBy.find((item) => item.key === col.field);
41805
+ const [openFilter, setOpenFilter] = useState(false);
41806
+ const filter = filterBy.find((item) => item.key === col.field);
41788
41807
  const handleResize = (e, { size }) => {
41789
41808
  // Update the column width here
41790
41809
  // You might need to update the state or call a callback to update the width
41791
41810
  if (size.width > 50) {
41792
- const newColumns = [...column];
41811
+ const newColumns = [...columns];
41793
41812
  newColumns[indexCol].width = size.width;
41794
- if ((column[indexCol]?.maxWidth ?? 0) < size.width) {
41813
+ if ((columns[indexCol]?.maxWidth ?? 0) < size.width) {
41795
41814
  newColumns[indexCol].maxWidth = size.width;
41796
41815
  }
41797
- if ((column[indexCol]?.minWidth ?? 0) > size.width) {
41816
+ if ((columns[indexCol]?.minWidth ?? 0) > size.width) {
41798
41817
  newColumns[indexCol].minWidth = size.width;
41799
41818
  }
41800
- setColumn(newColumns);
41819
+ if (setColumns) {
41820
+ setColumns(newColumns);
41821
+ }
41801
41822
  }
41802
41823
  };
41803
- return (jsx(Fragment, { children: col.visible !== false && (jsx(Resizable, { className: "r-resize", width: typeof col.width === 'number' ? col.width : Number((col.width ?? "").replaceAll(new RegExp(`[^0-9]`, "g"), '')), height: 0, onResize: handleResize, draggableOpts: { enableUserSelectHack: false }, children: jsx("th", { rowSpan: col.rowspan !== 1 ? col.rowspan : undefined, colSpan: col.columns?.filter(x => x.visible !== false)?.length ?? 1, className: classNames$1(`r-headercell fix-${col.fixedType}`, { 'fixed-last': (col.fixedType === 'left' && indexCol === lastObjWidthFixLeft) || (col.fixedType === 'right' && indexCol === fisrtObjWidthFixRight) }, { 'cell-fixed': col.fixedType }), style: {
41824
+ const checkOverflow = () => {
41825
+ return headerRef.current && headerRef.current.scrollHeight > headerRef.current.clientHeight;
41826
+ };
41827
+ console.log(col);
41828
+ return (jsx(Fragment, { children: col.visible !== false && (jsx(Resizable, { className: "r-resize", width: typeof col.width === 'number' ? col.width : Number((col.width ?? "").replaceAll(new RegExp(`[^0-9]`, "g"), '')), height: 0, onResize: handleResize, draggableOpts: { enableUserSelectHack: false }, children: jsx("th", { rowSpan: col.rowspan !== 1 ? col.rowspan : 1, colSpan: col.columns?.filter(x => x.visible !== false)?.length ?? 1, className: classNames$1(`r-headercell fix-${col.fixedType}`, { 'fixed-last': (col.fixedType === 'left' && indexCol === lastObjWidthFixLeft) || (col.fixedType === 'right' && indexCol === fisrtObjWidthFixRight) }, { 'cell-fixed': col.fixedType }), style: {
41804
41829
  top: `${indexParent * 42}px`,
41805
- left: col.fixedType === 'left' ? objWidthFixLeft[col.index ?? 0] : undefined,
41806
- right: col.fixedType === 'right' ? objWidthFixRight[col.index ?? 0] : undefined,
41807
- width: col.width ? typeof col.width === 'number' ? col.width : col.width?.includes('px') || col.width?.includes('%') ? col.width : `${col.width}px` : 'auto',
41808
- minWidth: col.fixedType ? col.width : col.minWidth ? typeof col.minWidth === 'number' ? col.minWidth : col.minWidth?.includes('px') || col.minWidth?.includes('%') ? col.minWidth : `${col.minWidth}px` : 'auto',
41809
- maxWidth: col.fixedType ? col.width : col.maxWidth ? typeof col.maxWidth === 'number' ? col.maxWidth : col.maxWidth?.includes('px') || col.maxWidth?.includes('%') ? col.maxWidth : `${col.maxWidth}px` : 'auto'
41810
- }, children: jsxs("div", { style: { justifyContent: col.textAlign ?? 'left' }, className: classNames$1('r-headercell-div'), children: [col.field === 'checkbox' && (jsx(Input$1, { checked: !!(totalCount > 0 && selectedRows?.length >= totalCount), type: "checkbox", className: classNames$1('cursor-pointer', { 'd-none': !isMulti }), style: { textAlign: col.textAlign ?? 'left', marginTop: 6 }, onChange: (e) => {
41830
+ left: col.fixedType === 'left' ? objHeaderWidthFixLeft[`${indexParent}-${indexCol ?? 0}`] : undefined,
41831
+ right: col.fixedType === 'right' ? objHeaderWidthFixRight[`${indexParent}-${indexCol ?? 0}`] : undefined
41832
+ }, children: jsxs("div", { style: { justifyContent: 'space-between' }, onClick: () => {
41833
+ if (order) {
41834
+ if (order.direction === 'asc') {
41835
+ order.direction = 'desc';
41836
+ changeOrder(orderBy);
41837
+ }
41838
+ else {
41839
+ changeOrder(orderBy.filter((x) => x.key !== col.field));
41840
+ }
41841
+ }
41842
+ else {
41843
+ orderBy.push({ direction: 'asc', key: col.field });
41844
+ changeOrder(orderBy);
41845
+ }
41846
+ }, className: classNames$1('r-headercell-div', { 'cursor-pointer': allowOrder }), children: [col.field === 'checkbox' && (jsx(Input$1, { checked: !!(totalCount > 0 && selectedRows?.length >= totalCount), type: "checkbox", className: classNames$1('cursor-pointer', { 'd-none': !isMulti }), style: { textAlign: col.textAlign ?? 'left', marginTop: 6 }, onChange: (e) => {
41811
41847
  if (selectEnable) {
41812
41848
  if (e.target.checked) {
41813
41849
  setSelectedRows(dataSource.map((item) => { return item; }));
@@ -41816,7 +41852,89 @@ const HeaderTableCol$1 = (props) => {
41816
41852
  setSelectedRows([]);
41817
41853
  }
41818
41854
  }
41819
- } })), col.field !== 'checkbox' && jsx(Fragment$1, { children: jsx("span", { className: 'header-content', children: t(col.headerText ?? '') }) })] }) }) })) }, `header-${indexCol}`));
41855
+ } })), col.field !== 'checkbox' && jsxs(Fragment$1, { children: [jsxs("div", { className: 'header-content', style: { justifyContent: col.textAlign ?? 'left' }, children: [jsx("span", { id: `header-${idTable}-${indexParent}-${indexCol}`, ref: headerRef, className: 'text-content', children: t(col.headerText ?? '') }), checkOverflow() && jsx(UncontrolledTooltip, { className: "r-tooltip", autohide: false, target: `header-${idTable}-${indexParent}-${indexCol}`, children: t(col.headerText ?? '') })] }), col.field !== '#' && col.field !== 'command' && jsxs("div", { className: 'd-flex', children: [allowOrder && order?.direction === 'asc' && jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: 'ms-25', width: "10", height: "10", viewBox: "0 0 16 18", fill: "none", children: [jsx("g", { "clip-path": "url(#clip0_520_6)", children: jsx("path", { d: "M8.70711 0.292893C8.31658 -0.0976311 7.68342 -0.0976311 7.29289 0.292893L0.928932 6.65685C0.538408 7.04738 0.538408 7.68054 0.928932 8.07107C1.31946 8.46159 1.95262 8.46159 2.34315 8.07107L8 2.41421L13.6569 8.07107C14.0474 8.46159 14.6805 8.46159 15.0711 8.07107C15.4616 7.68054 15.4616 7.04738 15.0711 6.65685L8.70711 0.292893ZM8 18H9L9 1H8H7L7 18H8Z", fill: "black" }) }), jsx("defs", { children: jsx("clipPath", { id: "clip0_520_6", children: jsx("rect", { width: "16", height: "18", fill: "white" }) }) })] }), allowOrder && order?.direction === 'desc' && jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", className: 'ms-25', width: "10", height: "10", viewBox: "0 0 16 18", fill: "none", children: [jsx("g", { "clip-path": "url(#clip0_520_2)", children: jsx("path", { d: "M7.29289 17.7071C7.68342 18.0976 8.31658 18.0976 8.70711 17.7071L15.0711 11.3431C15.4616 10.9526 15.4616 10.3195 15.0711 9.92893C14.6805 9.53841 14.0474 9.53841 13.6569 9.92893L8 15.5858L2.34315 9.92893C1.95262 9.53841 1.31946 9.53841 0.928932 9.92893C0.538408 10.3195 0.538408 10.9526 0.928932 11.3431L7.29289 17.7071ZM8 0L7 0L7 17H8H9L9 0L8 0Z", fill: "black" }) }), jsx("defs", { children: jsx("clipPath", { id: "clip0_520_2", children: jsx("rect", { width: "16", height: "18", fill: "white" }) }) })] }), allowFilter && (col.columns?.length ?? 0) === 0 && col.allowFilter !== false && jsxs(Dropdown$1, { isOpen: openFilter, toggle: (e) => {
41856
+ setOpenFilter(!openFilter);
41857
+ e.stopPropagation();
41858
+ }, onClick: (e) => {
41859
+ e.stopPropagation();
41860
+ }, children: [jsx(DropdownToggle$1, { tag: 'div', className: 'p-0 r-filter', children: jsxs("svg", { className: classNames$1('cursor-pointer ms-25', { 'active': filter }), width: "10", height: "10", viewBox: "0 0 24 24", fill: "none", xmlns: "http://www.w3.org/2000/svg", "stroke-width": "1.5", "font-size": "12", children: [jsx("path", { d: "M14.7 11.998v10.506c.052.4-.08.826-.381 1.106a1.306 1.306 0 0 1-.925.39 1.289 1.289 0 0 1-.926-.39l-2.637-2.68a1.323 1.323 0 0 1-.38-1.106v-7.826h-.04L1.85 2.16A1.348 1.348 0 0 1 2.076.293C2.325.107 2.6 0 2.888 0h18.373c.289 0 .564.107.814.293a1.348 1.348 0 0 1 .223 1.866L14.738 12H14.7Z", fill: "currentColor" }), " "] }) }), jsx(DropdownMenu$1, { container: container, className: 'formula-dropdown icon-dropdown p-0', style: {
41861
+ borderRadius: 8,
41862
+ zIndex: 1056
41863
+ }, children: jsx(DropdownItem$1, { className: 'p-1', style: { borderRadius: '6px' }, tag: 'div', header: true, children: jsx(RenderFilterElement$1, { setOpenFilter: setOpenFilter, filter: filter, filterBy: filterBy, optionsFilter: optionsFilter, formatSetting: formatSetting, changeFilter: changeFilter, column: col }) }) })] })] })] })] }) }) })) }, `header-${indexCol}`));
41864
+ };
41865
+ const RenderFilterElement$1 = ({ filter, optionsFilter, formatSetting, filterBy, setOpenFilter, changeFilter, column }) => {
41866
+ const { t } = useTranslation();
41867
+ const [operator, setOperator] = useState(filter?.ope ?? ((!column.filterType && column.editType === 'numeric') || column.filterType === 'select' ? 'equal' : 'contains'));
41868
+ const [valueFilter, setValueFilter] = useState(filter?.value ?? '');
41869
+ const RenderStringFilter = () => {
41870
+ const options = [
41871
+ { label: 'Bắt đầu bởi', value: 'startswith' },
41872
+ { label: 'Kết thúc bởi', value: 'endswith' },
41873
+ { label: 'Chứa', value: 'contains' },
41874
+ { label: 'Bằng', value: 'equal' },
41875
+ { label: 'Không bằng', value: 'notequal' }
41876
+ ];
41877
+ return (jsxs(Fragment$1, { children: [jsx(SelectTable, { value: options.find((x) => x.value === (operator)), options: options, onChange: (val) => {
41878
+ setOperator(val.value);
41879
+ }, placeholder: 'Select' }), jsx(Input$1, { className: 'my-1', value: valueFilter, onChange: (val) => {
41880
+ setValueFilter(val.target.value);
41881
+ } })] }));
41882
+ };
41883
+ const RenderNumberFilter = () => {
41884
+ const options = [
41885
+ { label: 'Lớn hơn', value: 'greaterthan' },
41886
+ { label: 'Lớn hơn hoặc bằng', value: 'greaterthanorequal' },
41887
+ { label: 'Bằng', value: 'equal' },
41888
+ { label: 'Bé hơn', value: 'lessthan' },
41889
+ { label: 'Bé hơn hoặc bằng', value: 'lessthanorequal' }
41890
+ ];
41891
+ const numericFormatProps = {
41892
+ value: !isNullOrUndefined$1(valueFilter) ? valueFilter.toString() : '',
41893
+ thousandSeparator: checkThousandSeparator(formatSetting?.thousandSeparator, formatSetting?.decimalSeparator),
41894
+ decimalSeparator: checkDecimalSeparator(formatSetting?.thousandSeparator, formatSetting?.decimalSeparator),
41895
+ allowNegative: column.numericSettings?.allowNegative ?? false,
41896
+ decimalScale: column.numericSettings?.fraction ?? 0
41897
+ };
41898
+ let floatValue = parseFloat(valueFilter ?? '0');
41899
+ return (jsxs(Fragment$1, { children: [jsx(SelectTable, { value: options.find((x) => x.value === (operator)), options: options, onChange: (val) => {
41900
+ setOperator(val.value);
41901
+ }, placeholder: t('Select') }), jsx(NumericFormat, { style: { textAlign: column.textAlign, height: 29 }, ...numericFormatProps, defaultValue: formartNumberic(valueFilter, formatSetting?.decimalSeparator ?? ',', formatSetting?.thousandSeparator ?? '.', column.numericSettings?.fraction), className: classNames$1('form-control my-1 input-numeric'), onValueChange: (values) => {
41902
+ floatValue = values?.floatValue;
41903
+ }, onFocus: (e) => {
41904
+ e.target.setSelectionRange(0, e.target.innerText.length - 1);
41905
+ }, onBlur: () => {
41906
+ if (floatValue !== valueFilter) {
41907
+ setValueFilter(!isNaN(floatValue) ? floatValue : 0);
41908
+ }
41909
+ } })] }));
41910
+ };
41911
+ const RenderSelectFilter = () => {
41912
+ return (jsx("div", { className: 'mb-1', children: jsx(SelectTable, { value: optionsFilter ? optionsFilter[column.field]?.find((x) => x.value === valueFilter) : undefined, options: (optionsFilter && optionsFilter[column.field]) ?? [], isClearable: true, onChange: (val) => {
41913
+ setValueFilter(val?.value);
41914
+ }, placeholder: t('Select') }) }));
41915
+ };
41916
+ const handleSave = () => {
41917
+ if (filter) {
41918
+ filter.ope = operator;
41919
+ filter.value = valueFilter ?? '';
41920
+ }
41921
+ else {
41922
+ filterBy.push({ key: column.field, ope: operator, value: valueFilter ?? '' });
41923
+ }
41924
+ changeFilter([...filterBy]);
41925
+ setOpenFilter(false);
41926
+ };
41927
+ return (jsxs("div", { className: 'r-filter-popup', onKeyDown: (e) => {
41928
+ if (e.code === 'Enter' || e.code === 'NumpadEnter') {
41929
+ handleSave();
41930
+ e.stopPropagation();
41931
+ }
41932
+ }, children: [((!column.filterType && column.editType === 'numeric') || column.filterType === 'numeric') ? jsxs(Fragment$1, { children: [RenderNumberFilter(), " "] }) : (column.filterType === 'select' ? jsxs(Fragment$1, { children: [RenderSelectFilter(), " "] }) : RenderStringFilter()), jsxs("div", { className: 'd-flex justify-content-end', children: [jsx(Button$1, { color: 'primary', style: { borderRadius: 3 }, className: 'me-50 py-25 px-50 fw-bold', onClick: handleSave, children: t('Filter') }), jsx(Button$1, { className: 'py-25 px-50 fw-bold', color: 'white', style: { borderRadius: 3, borderWidth: 0 }, onClick: () => {
41933
+ if (filterBy) {
41934
+ changeFilter(filterBy.filter((x) => x.key !== column.field));
41935
+ }
41936
+ setOpenFilter(false);
41937
+ }, children: t('Clear') })] })] }));
41820
41938
  };
41821
41939
 
41822
41940
  const defaultMaxHeight = 250;
@@ -42588,9 +42706,15 @@ const EditFormInline = forwardRef((props, ref) => {
42588
42706
  }) })] }));
42589
42707
  });
42590
42708
 
42709
+ const RenderColGroup = ({ contentColumns }) => (jsx("colgroup", { children: contentColumns.map((col, index) => (jsx("col", { style: {
42710
+ width: typeof col.width === 'number' ? `${col.width}px` : col.width || undefined,
42711
+ minWidth: typeof col.minWidth === 'number' ? `${col.minWidth}px` : col.minWidth || undefined,
42712
+ maxWidth: typeof col.maxWidth === 'number' ? `${col.maxWidth}px` : col.maxWidth || undefined
42713
+ } }, index))) }));
42714
+
42591
42715
  const TableEdit = forwardRef((props, ref) => {
42592
42716
  const { t } = useTranslation();
42593
- const { idTable, dataSource, columns, commandClick, dataSourceChange, rowChange, pagingSetting, setDataSource, height, maxHeight, minHeight, defaultValue, toolbarSetting, searchSetting, setSelectedItem, selectedItem, selectEnable, editDisable, addDisable, buttonSetting, formatSetting, handleSelect, haveSum, isMulti, disableAutoKey, onDuplicate } = props;
42717
+ const { idTable, dataSource, columns, commandClick, dataSourceChange, rowChange, pagingSetting, setDataSource, height, maxHeight, minHeight, defaultValue, toolbarSetting, searchSetting, setSelectedItem, selectedItem, selectEnable, editDisable, addDisable, buttonSetting, formatSetting, handleSelect, haveSum, isMulti, disableAutoKey, onDuplicate, allowFilter = true, allowOrder, optionsFilter } = props;
42594
42718
  useImperativeHandle(ref, () => {
42595
42719
  return {
42596
42720
  refeshFocusRow: handleRefeshRow
@@ -42599,17 +42723,11 @@ const TableEdit = forwardRef((props, ref) => {
42599
42723
  const [refreshRow, setRefreshRow] = useState(false);
42600
42724
  const [indexFocus, setIndexFocus] = useState(-1);
42601
42725
  const [selectedRows, setSelectedRows] = useState([]);
42602
- const [headerColumns, setHeaderColumns] = useState([[]]);
42603
42726
  const [contentColumns, setContentColumns] = useState([]);
42604
- const [levelCol, setLevelCol] = useState(0);
42605
- const [columnFistEdit, setColumnFistEdit] = useState(0);
42606
- const [columnLastEdit, setColumnlastEdit] = useState(0);
42607
- const [objWidthFixRight, setObjWidthFixRight] = useState({});
42608
- const [objWidthFixLeft, setObjWidthFixLeft] = useState({});
42609
- const [lastObjWidthFixLeft, setLastObjWidthFixLeft] = useState(0);
42610
- const [fisrtObjWidthFixRight, setFisrtObjWidthFixRight] = useState(0);
42611
42727
  const [openPopupSetupColumn, setOpenPopupSetupColumn] = useState(false);
42612
42728
  const [searchTerm, setSearchTerm] = useState('');
42729
+ const [orderBy, setOrderBy] = useState([]);
42730
+ const [filterBy, setFilterBy] = useState([]);
42613
42731
  const tableElement = useRef(null);
42614
42732
  const gridRef = useRef(null);
42615
42733
  const totalCount = dataSource.length;
@@ -42622,95 +42740,11 @@ const TableEdit = forwardRef((props, ref) => {
42622
42740
  pagingSetting.setCurrentPage(1);
42623
42741
  }
42624
42742
  }, [dataSource]);
42625
- useEffect(() => {
42626
- let indexFirst = -1;
42627
- let indexlast = -1;
42628
- let letfWidthFix = 0;
42629
- let rightWidthFix = 0;
42630
- contentColumns.forEach((item, index) => {
42631
- if (levelCol === 1) {
42632
- headerColumns[0][index].width = item.width;
42633
- headerColumns[0][index].visible = item.visible;
42634
- headerColumns[0][index].fixedType = item.fixedType;
42635
- }
42636
- if (item.fixedType === 'left' && item.visible !== false) {
42637
- setLastObjWidthFixLeft(index);
42638
- objWidthFixLeft[index] = letfWidthFix;
42639
- letfWidthFix += Number(item.width ?? 40);
42640
- }
42641
- const lasColumn = contentColumns[contentColumns.length - 1 - index];
42642
- if (lasColumn.fixedType === 'right' && lasColumn.visible !== false) {
42643
- setFisrtObjWidthFixRight(contentColumns.length - 1 - index);
42644
- objWidthFixRight[contentColumns.length - 1 - index] = rightWidthFix;
42645
- rightWidthFix += Number(lasColumn.width ?? 40);
42646
- }
42647
- if (item.editEnable && (item.visible !== false) && (!item.disabledCondition)) {
42648
- if (indexFirst === -1) {
42649
- indexFirst = index;
42650
- }
42651
- indexlast = index;
42652
- }
42653
- });
42654
- if (levelCol === 1) {
42655
- setHeaderColumns([...headerColumns]);
42656
- }
42657
- setObjWidthFixLeft(objWidthFixLeft);
42658
- setObjWidthFixRight(objWidthFixRight);
42659
- setColumnFistEdit(indexFirst + 1);
42660
- setColumnlastEdit(indexlast + 1);
42661
- }, [contentColumns]);
42662
- useEffect(() => {
42663
- const arrHeaderColumns = [];
42664
- const arrContentColumns = [];
42665
- let headerLevelRow = 0;
42666
- if (levelCol) {
42667
- headerLevelRow = levelCol;
42668
- }
42669
- else {
42670
- headerLevelRow = stretchColumn(columns, 0);
42671
- setLevelCol(headerLevelRow);
42672
- }
42673
- for (let i = 0; i < headerLevelRow; i++) {
42674
- arrHeaderColumns.push([]);
42675
- }
42676
- getNestedChildren(columns, arrHeaderColumns, arrContentColumns, 0, headerLevelRow);
42677
- setHeaderColumns(arrHeaderColumns);
42678
- setContentColumns(arrContentColumns);
42743
+ const { levels: headerColumns, flatVisble, objWidthFixLeft, objWidthFixRight, lastObjWidthFixLeft, fisrtObjWidthFixRight, objHeaderWidthFixLeft, objHeaderWidthFixRight, firstEdit: columnFirstEdit, lastEdit: columnLastEdit } = useMemo(() => {
42744
+ const obj = calculateTableStructure(columns);
42745
+ setContentColumns(obj.flat);
42746
+ return obj;
42679
42747
  }, [columns]);
42680
- const getNestedChildren = (array, arrHeaderColumns, arrContentColumns, level, maxLevelRow) => {
42681
- array.forEach((item) => {
42682
- const ele = { ...item, visible: item.visible, rowspan: 1, index: 0 };
42683
- if (item.columns && item.columns?.length > 0) {
42684
- const countLevel = getNestedChildren(item.columns, arrHeaderColumns, arrContentColumns, level + 1, maxLevelRow);
42685
- arrHeaderColumns[(maxLevelRow - 1) - countLevel].push(ele);
42686
- }
42687
- else {
42688
- ele.rowspan = maxLevelRow - level;
42689
- ele.index = arrContentColumns.length;
42690
- if (maxLevelRow === 1) {
42691
- ele.visible = (item.invisibleDisable ? item.visible : (contentColumns[arrContentColumns.length]?.visible ?? item.visible));
42692
- ele.width = (contentColumns[arrContentColumns.length]?.width ?? item.width);
42693
- ele.maxWidth = (contentColumns[arrContentColumns.length]?.maxWidth ?? item.maxWidth);
42694
- ele.minWidth = (contentColumns[arrContentColumns.length]?.minWidth ?? item.minWidth);
42695
- }
42696
- arrHeaderColumns[level].push(ele);
42697
- arrContentColumns.push(ele);
42698
- }
42699
- });
42700
- return level;
42701
- };
42702
- const stretchColumn = (subColumns, headerLevelRow) => {
42703
- let count = headerLevelRow + 1;
42704
- subColumns.map((item) => {
42705
- if (item.columns && item.columns.length > 0) {
42706
- const newCount = stretchColumn(item.columns, headerLevelRow + 1);
42707
- if (newCount > count) {
42708
- count = newCount;
42709
- }
42710
- }
42711
- });
42712
- return count;
42713
- };
42714
42748
  const handleRefeshRow = () => {
42715
42749
  setRefreshRow(true);
42716
42750
  setTimeout(() => {
@@ -43040,7 +43074,7 @@ const TableEdit = forwardRef((props, ref) => {
43040
43074
  }
43041
43075
  if (tableElement) {
43042
43076
  setIndexFocus(totalCount);
43043
- focusNewElement(columnFistEdit, totalCount + 1, true);
43077
+ focusNewElement(columnFirstEdit, totalCount + 1, true);
43044
43078
  }
43045
43079
  };
43046
43080
  const checkKeyDown = (e, row, col, indexRow, indexCol) => {
@@ -43276,14 +43310,6 @@ const TableEdit = forwardRef((props, ref) => {
43276
43310
  };
43277
43311
  const changeDataSource = (data, numberOfRows) => {
43278
43312
  if (!editDisable && setDataSource) {
43279
- if ((searchSetting?.searchTerm !== undefined ? searchSetting?.searchTerm : searchTerm)) {
43280
- if (searchSetting?.setSearchTerm) {
43281
- searchSetting?.setSearchTerm('');
43282
- }
43283
- else {
43284
- setSearchTerm('');
43285
- }
43286
- }
43287
43313
  if (numberOfRows && !addDisable) {
43288
43314
  for (let index = 0; index < numberOfRows; index++) {
43289
43315
  data.push(defaultValue ? { ...defaultValue, [fieldKey]: disableAutoKey ? undefined : generateUUID() } : {});
@@ -43484,22 +43510,52 @@ const TableEdit = forwardRef((props, ref) => {
43484
43510
  textAlign: col.textAlign ? col.textAlign : 'left'
43485
43511
  }, children: jsxs("div", { className: "r-footer-div", children: [col.haveSum === true && col.editType === "numeric" && (Number(sumValue) >= 0) && jsx(Fragment$1, { children: formartNumberic(sumValue, formatSetting?.decimalSeparator ?? ',', formatSetting?.thousandSeparator ?? '.', col.numericSettings?.fraction, true, false) }), col.haveSum === true && col.editType === "numeric" && (Number(sumValue) < 0) && jsxs("div", { style: { color: formatSetting?.colorNegative ?? 'red' }, children: [" ", `${formatSetting?.prefixNegative ?? '-'}${formartNumberic(sumValue, formatSetting?.decimalSeparator ?? ',', formatSetting?.thousandSeparator ?? '.', col.numericSettings?.fraction, true, false)}${formatSetting?.suffixNegative ?? ''}`] })] }) }) }, `summarycell-${indexCol}`));
43486
43512
  };
43487
- const checkSearch = (keyword, data, fieldKey) => {
43488
- if (!keyword || fieldKey.length === 0) {
43489
- return true;
43490
- }
43491
- for (let index = 0; index < fieldKey.length; index++) {
43492
- const key = fieldKey[index].trim();
43493
- if (data[key] && data[key].toString().trim().toLowerCase().includes(keyword.trim().toLowerCase())) {
43494
- return true;
43513
+ /**
43514
+ * Kiểm tra row thỏa mãn tất cả filter và chứa từ khóa tìm kiếm hay không
43515
+ */
43516
+ function checkRowMatch(row, filters, keyword, searchKeys) {
43517
+ if ((!filters || filters.length === 0) && (!keyword || !searchClient))
43518
+ return true; // Không có filter thì mặc định là match
43519
+ const isFilterMatch = filters.every(filter => {
43520
+ const { key, value, ope } = filter;
43521
+ const rowValue = row[key];
43522
+ if (rowValue === undefined || rowValue === null || value === undefined || value === null)
43523
+ return false;
43524
+ const valStr = String(rowValue).toLowerCase();
43525
+ const filterStr = String(value).toLowerCase();
43526
+ switch (ope) {
43527
+ case 'startswith':
43528
+ return valStr.startsWith(filterStr);
43529
+ case 'endswith':
43530
+ return valStr.endsWith(filterStr);
43531
+ case 'contains':
43532
+ return valStr.includes(filterStr);
43533
+ case 'equal':
43534
+ return rowValue == value;
43535
+ case 'notequal':
43536
+ return rowValue != value;
43537
+ case 'greaterthan':
43538
+ return rowValue > value;
43539
+ case 'greaterthanorequal':
43540
+ return rowValue >= value;
43541
+ case 'lessthan':
43542
+ return rowValue < value;
43543
+ case 'lessthanorequal':
43544
+ return rowValue <= value;
43545
+ default:
43546
+ return false;
43495
43547
  }
43496
- }
43497
- return false;
43498
- };
43548
+ });
43549
+ const isSearchMatch = !keyword || searchKeys.some(key => {
43550
+ const val = row[key];
43551
+ return val?.toString().toLowerCase().includes(keyword.trim().toLowerCase());
43552
+ });
43553
+ return isFilterMatch && isSearchMatch;
43554
+ }
43499
43555
  const renderData = () => {
43500
43556
  return (dataSource.map((row, indexRow) => {
43501
43557
  const isSelected = selectedRows?.some((x) => x[fieldKey] === row[fieldKey]);
43502
- const flagSearch = !searchClient || checkSearch(searchSetting?.searchTerm !== undefined ? searchSetting?.searchTerm : searchTerm, row, searchSetting?.keyField ?? []);
43558
+ const flagSearch = checkRowMatch(row, filterBy, searchSetting?.searchTerm !== undefined ? searchSetting?.searchTerm : searchTerm, searchSetting?.keyField ?? []);
43503
43559
  if (flagSearch) {
43504
43560
  const flagDisplay = !pagingClient || ((indexRow + 1) > ((pagingSetting.pageSize ?? 0) * ((pagingSetting.currentPage ?? 0) - 1)) && (indexRow + 1) <= ((pagingSetting.pageSize ?? 0) * ((pagingSetting.currentPage ?? 0))));
43505
43561
  return (flagDisplay && jsx(Fragment$1, { children: jsx("tr", { className: classNames$1('r-row'), children: contentColumns.map((col, indexCol) => renderContentCol(col, row, indexRow, indexCol, isSelected)) }, `row-${indexRow}`) }));
@@ -43511,14 +43567,18 @@ const TableEdit = forwardRef((props, ref) => {
43511
43567
  pagingSetting?.setCurrentPage(1);
43512
43568
  }
43513
43569
  }, [searchTerm, searchSetting?.searchTerm]);
43514
- return (jsxs(Fragment, { children: [jsxs("div", { className: "react-table-edit", children: [jsxs("div", { className: 'r-grid', ref: gridRef, children: [toolbarSetting?.showTopToolbar && jsx(RenderToolbarTop, { toolbarTopOption: toolbarTopOption }), jsx("div", { ref: tableElement, className: "r-gridtable", style: { height: `${height ? `${height}px` : 'auto'}`, minHeight: `${minHeight ? `${minHeight}px` : ''}`, maxHeight: `${maxHeight ? `${maxHeight}px` : '400px'}` }, children: jsxs("table", { style: { width: '100%' }, children: [jsx("thead", { className: 'r-gridheader', children: headerColumns.map((element, indexParent) => {
43570
+ return (jsxs(Fragment, { children: [jsxs("div", { className: "react-table-edit", children: [jsxs("div", { className: 'r-grid', ref: gridRef, children: [toolbarSetting?.showTopToolbar && jsx(RenderToolbarTop, { toolbarTopOption: toolbarTopOption }), jsx("div", { ref: tableElement, className: "r-gridtable", style: { height: `${height ? `${height}px` : 'auto'}`, minHeight: `${minHeight ? `${minHeight}px` : ''}`, maxHeight: `${maxHeight ? `${maxHeight}px` : '400px'}` }, children: jsxs("table", { style: { width: '100%' }, children: [jsx(RenderColGroup, { contentColumns: flatVisble }), jsx("thead", { className: 'r-gridheader', children: headerColumns.map((element, indexParent) => {
43515
43571
  return (jsx("tr", { className: "r-row", role: "row", children: element?.map((col, index) => {
43516
- return (jsx(HeaderTableCol$1, { col: col, dataSource: dataSource, indexCol: index, indexParent: indexParent, isMulti: isMulti ?? false, objWidthFixLeft: objWidthFixLeft, objWidthFixRight: objWidthFixRight, selectEnable: selectEnable ?? false, selectedRows: selectedRows, setSelectedRows: setSelectedRows, column: contentColumns, setColumn: setContentColumns, fisrtObjWidthFixRight: fisrtObjWidthFixRight, lastObjWidthFixLeft: lastObjWidthFixLeft, totalCount: totalCount }, `header-${indexParent}-${index}`));
43572
+ return (jsx(HeaderTableCol$1, { col: col, idTable: idTable ?? '', dataSource: dataSource, indexCol: index, indexParent: indexParent, isMulti: isMulti ?? false, objHeaderWidthFixLeft: objHeaderWidthFixLeft, objHeaderWidthFixRight: objHeaderWidthFixRight, selectEnable: selectEnable ?? false, selectedRows: selectedRows, setSelectedRows: setSelectedRows, container: tableElement, filterBy: filterBy, orderBy: orderBy, optionsFilter: optionsFilter, allowFilter: allowFilter, allowOrder: allowOrder, formatSetting: formatSetting, changeFilter: (val) => {
43573
+ setFilterBy([...val]);
43574
+ }, changeOrder: (val) => {
43575
+ setOrderBy([...val]);
43576
+ }, columns: contentColumns, setColumns: setContentColumns, fisrtObjWidthFixRight: fisrtObjWidthFixRight, lastObjWidthFixLeft: lastObjWidthFixLeft, totalCount: totalCount }, `header-${indexParent}-${index}`));
43517
43577
  }) }, `header-${-indexParent}`));
43518
43578
  }) }), jsx("tbody", { className: 'r-gridcontent', children: renderData() }), jsx("tfoot", { className: "r-gridfoot", children: haveSum == true ? jsx("tr", { className: 'r-row', children: contentColumns.map((col, index) => {
43519
43579
  return (renderFooterCol(col, index));
43520
43580
  }) }) : jsx(Fragment$1, {}) })] }) }), toolbarSetting?.showBottomToolbar && jsx(ToolbarBottom, { handleAdd: (numberOfRows) => {
43521
- handleAdd(dataSource, tableElement.current, columnFistEdit, changeDataSource, pagingSetting, setIndexFocus, focusNewElement, numberOfRows);
43581
+ handleAdd(dataSource, tableElement.current, columnFirstEdit, changeDataSource, pagingSetting, setIndexFocus, focusNewElement, numberOfRows);
43522
43582
  }, handleDuplicate: () => {
43523
43583
  handleDuplicate(dataSource, indexFocus, fieldKey, defaultValue, fieldUniKey, changeDataSource, tableElement, totalCount, toolbarSetting, buttonSetting, editDisable, addDisable, onDuplicate);
43524
43584
  }, handleInsertAfter: () => {
@@ -65634,12 +65694,6 @@ const RenderContentCol = (props) => {
65634
65694
  }, children: RenderElement() }, `col-${indexRow}-${indexCol}`));
65635
65695
  };
65636
65696
 
65637
- const RenderColGroup = ({ contentColumns }) => (jsx("colgroup", { children: contentColumns.map((col, index) => (jsx("col", { style: {
65638
- width: typeof col.width === 'number' ? `${col.width}px` : col.width || undefined,
65639
- minWidth: typeof col.minWidth === 'number' ? `${col.minWidth}px` : col.minWidth || undefined,
65640
- maxWidth: typeof col.maxWidth === 'number' ? `${col.maxWidth}px` : col.maxWidth || undefined
65641
- } }, index))) }));
65642
-
65643
65697
  const VirtualTable = ({ idTable, dataSource, rowHeight = 33, height = 400, columns, isMutil, isLoading, selectEnable, formatSetting, commandClick, allowFilter, allowOrder, setColumns, pagingSetting, changeFilter, changeOrder, searchSetting, columnsAggregate, toolbarSetting, optionsFilter }) => {
65644
65698
  const gridRef = useRef(null);
65645
65699
  const [startIndex, setStartIndex] = useState(0);