react-table-edit 1.4.22 → 1.4.24

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
@@ -19330,6 +19330,9 @@ const calculateTableStructure = (columns) => {
19330
19330
  const flatVisble = flat.filter((e) => e.visible !== false);
19331
19331
  const lastObjWidthFixLeft = Math.max(...Object.keys(objWidthFixLeft).map(Number), 0);
19332
19332
  const fisrtObjWidthFixRight = Math.min(...Object.keys(objWidthFixRight).map(Number), flat.length);
19333
+ const editableColumns = flat.filter(item => item.editEnable && item.visible !== false && !item.disabledCondition);
19334
+ const firstEdit = editableColumns[0];
19335
+ const lastEdit = editableColumns[editableColumns.length - 1];
19333
19336
  return {
19334
19337
  levels,
19335
19338
  flat,
@@ -19337,7 +19340,9 @@ const calculateTableStructure = (columns) => {
19337
19340
  objWidthFixLeft,
19338
19341
  objWidthFixRight,
19339
19342
  lastObjWidthFixLeft,
19340
- fisrtObjWidthFixRight
19343
+ fisrtObjWidthFixRight,
19344
+ firstEdit,
19345
+ lastEdit
19341
19346
  };
19342
19347
  };
19343
19348
 
@@ -39883,13 +39888,18 @@ if (process.env.NODE_ENV === 'production') {
39883
39888
  var InputMask = reactInputMask.exports;
39884
39889
 
39885
39890
  const DateInput = (props) => {
39886
- const { id, onKeyDown, dateFormat, className, onChange, value } = props;
39891
+ const { id, onKeyDown, dateFormat, className, onChange, value, onPaste } = props;
39887
39892
  const [open, setOpen] = useState(false);
39888
39893
  return (jsx(DatePicker, { id: id, open: open, className: className, selected: value, onChange: (date) => {
39889
39894
  if (onChange) {
39890
39895
  onChange(date);
39891
39896
  }
39892
- }, dateFormat: dateFormat, locale: "vi", showMonthDropdown: true, showYearDropdown: true, dropdownMode: "select", isClearable: true, onCalendarClose: () => setOpen(false), onCalendarOpen: () => setOpen(true), customInput: jsx(InputMask, { mask: "99/99/9999", placeholder: dateFormat }), onKeyDown: (e) => {
39897
+ }, dateFormat: dateFormat, locale: "vi", showMonthDropdown: true, showYearDropdown: true, dropdownMode: "select", isClearable: true, onCalendarClose: () => setOpen(false), onCalendarOpen: () => setOpen(true), customInput: jsx(InputMask, { mask: "99/99/9999", placeholder: dateFormat, onPaste: (e) => {
39898
+ if (onPaste) {
39899
+ onPaste(e);
39900
+ setOpen(false);
39901
+ }
39902
+ } }), onKeyDown: (e) => {
39893
39903
  if (e.code === 'Space') {
39894
39904
  setOpen(!open);
39895
39905
  setTimeout(() => {
@@ -39899,12 +39909,10 @@ const DateInput = (props) => {
39899
39909
  }
39900
39910
  }, 100);
39901
39911
  }
39902
- else {
39903
- if (onKeyDown && !open) {
39904
- const rs = onKeyDown(e);
39905
- if (rs) {
39906
- setOpen(false);
39907
- }
39912
+ else if (onKeyDown && (!open || ((e.ctrlKey || e.metaKey || e.altKey) && e.shiftKey))) {
39913
+ const rs = onKeyDown(e);
39914
+ if (rs) {
39915
+ setOpen(false);
39908
39916
  }
39909
39917
  }
39910
39918
  } }));
@@ -41780,31 +41788,51 @@ var css_248z$1 = ".react-resizable {\n position: relative;\n}\n.react-resizable
41780
41788
  styleInject(css_248z$1);
41781
41789
 
41782
41790
  const HeaderTableCol$1 = (props) => {
41783
- const { selectEnable, dataSource, setSelectedRows, col, indexCol, indexParent, objWidthFixLeft, objWidthFixRight, totalCount, selectedRows, column, setColumn, fisrtObjWidthFixRight, lastObjWidthFixLeft, isMulti } = props;
41791
+ const { selectEnable, dataSource, setSelectedRows, col, indexCol, indexParent, objWidthFixLeft, objWidthFixRight, totalCount, selectedRows, columns, setColumns, orderBy, changeFilter, filterBy, changeOrder, allowFilter, allowOrder, container, fisrtObjWidthFixRight, lastObjWidthFixLeft, formatSetting, optionsFilter, idTable, isMulti } = props;
41784
41792
  const { t } = useTranslation();
41793
+ const headerRef = useRef(null);
41794
+ const order = orderBy.find((item) => item.key === col.field);
41795
+ const [openFilter, setOpenFilter] = useState(false);
41796
+ const filter = filterBy.find((item) => item.key === col.field);
41785
41797
  const handleResize = (e, { size }) => {
41786
41798
  // Update the column width here
41787
41799
  // You might need to update the state or call a callback to update the width
41788
41800
  if (size.width > 50) {
41789
- const newColumns = [...column];
41801
+ const newColumns = [...columns];
41790
41802
  newColumns[indexCol].width = size.width;
41791
- if ((column[indexCol]?.maxWidth ?? 0) < size.width) {
41803
+ if ((columns[indexCol]?.maxWidth ?? 0) < size.width) {
41792
41804
  newColumns[indexCol].maxWidth = size.width;
41793
41805
  }
41794
- if ((column[indexCol]?.minWidth ?? 0) > size.width) {
41806
+ if ((columns[indexCol]?.minWidth ?? 0) > size.width) {
41795
41807
  newColumns[indexCol].minWidth = size.width;
41796
41808
  }
41797
- setColumn(newColumns);
41809
+ if (setColumns) {
41810
+ setColumns(newColumns);
41811
+ }
41798
41812
  }
41799
41813
  };
41800
- 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: {
41814
+ const checkOverflow = () => {
41815
+ return headerRef.current && headerRef.current.scrollHeight > headerRef.current.clientHeight;
41816
+ };
41817
+ 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: {
41801
41818
  top: `${indexParent * 42}px`,
41802
- left: col.fixedType === 'left' ? objWidthFixLeft[col.index ?? 0] : undefined,
41803
- right: col.fixedType === 'right' ? objWidthFixRight[col.index ?? 0] : undefined,
41804
- width: col.width ? typeof col.width === 'number' ? col.width : col.width?.includes('px') || col.width?.includes('%') ? col.width : `${col.width}px` : 'auto',
41805
- 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',
41806
- 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'
41807
- }, 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) => {
41819
+ left: col.fixedType === 'left' ? objWidthFixLeft[indexCol ?? 0] : undefined,
41820
+ right: col.fixedType === 'right' ? objWidthFixRight[indexCol ?? 0] : undefined
41821
+ }, children: jsxs("div", { style: { justifyContent: 'space-between' }, onClick: () => {
41822
+ if (order) {
41823
+ if (order.direction === 'asc') {
41824
+ order.direction = 'desc';
41825
+ changeOrder(orderBy);
41826
+ }
41827
+ else {
41828
+ changeOrder(orderBy.filter((x) => x.key !== col.field));
41829
+ }
41830
+ }
41831
+ else {
41832
+ orderBy.push({ direction: 'asc', key: col.field });
41833
+ changeOrder(orderBy);
41834
+ }
41835
+ }, 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) => {
41808
41836
  if (selectEnable) {
41809
41837
  if (e.target.checked) {
41810
41838
  setSelectedRows(dataSource.map((item) => { return item; }));
@@ -41813,7 +41841,89 @@ const HeaderTableCol$1 = (props) => {
41813
41841
  setSelectedRows([]);
41814
41842
  }
41815
41843
  }
41816
- } })), col.field !== 'checkbox' && jsx(Fragment$1, { children: jsx("span", { className: 'header-content', children: t(col.headerText ?? '') }) })] }) }) })) }, `header-${indexCol}`));
41844
+ } })), 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 && jsxs(Dropdown$1, { isOpen: openFilter, toggle: (e) => {
41845
+ setOpenFilter(!openFilter);
41846
+ e.stopPropagation();
41847
+ }, onClick: (e) => {
41848
+ e.stopPropagation();
41849
+ }, 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: {
41850
+ borderRadius: 8,
41851
+ zIndex: 1056
41852
+ }, 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}`));
41853
+ };
41854
+ const RenderFilterElement$1 = ({ filter, optionsFilter, formatSetting, filterBy, setOpenFilter, changeFilter, column }) => {
41855
+ const { t } = useTranslation();
41856
+ const [operator, setOperator] = useState(filter?.ope ?? ((!column.filterType && column.editType === 'numeric') || column.filterType === 'select' ? 'equal' : 'contains'));
41857
+ const [valueFilter, setValueFilter] = useState(filter?.value ?? '');
41858
+ const RenderStringFilter = () => {
41859
+ const options = [
41860
+ { label: 'Bắt đầu bởi', value: 'startswith' },
41861
+ { label: 'Kết thúc bởi', value: 'endswith' },
41862
+ { label: 'Chứa', value: 'contains' },
41863
+ { label: 'Bằng', value: 'equal' },
41864
+ { label: 'Không bằng', value: 'notequal' }
41865
+ ];
41866
+ return (jsxs(Fragment$1, { children: [jsx(SelectTable, { value: options.find((x) => x.value === (operator)), options: options, onChange: (val) => {
41867
+ setOperator(val.value);
41868
+ }, placeholder: 'Select' }), jsx(Input$1, { className: 'my-1', value: valueFilter, onChange: (val) => {
41869
+ setValueFilter(val.target.value);
41870
+ } })] }));
41871
+ };
41872
+ const RenderNumberFilter = () => {
41873
+ const options = [
41874
+ { label: 'Lớn hơn', value: 'greaterthan' },
41875
+ { label: 'Lớn hơn hoặc bằng', value: 'greaterthanorequal' },
41876
+ { label: 'Bằng', value: 'equal' },
41877
+ { label: 'Bé hơn', value: 'lessthan' },
41878
+ { label: 'Bé hơn hoặc bằng', value: 'lessthanorequal' }
41879
+ ];
41880
+ const numericFormatProps = {
41881
+ value: !isNullOrUndefined$1(valueFilter) ? valueFilter.toString() : '',
41882
+ thousandSeparator: checkThousandSeparator(formatSetting?.thousandSeparator, formatSetting?.decimalSeparator),
41883
+ decimalSeparator: checkDecimalSeparator(formatSetting?.thousandSeparator, formatSetting?.decimalSeparator),
41884
+ allowNegative: column.numericSettings?.allowNegative ?? false,
41885
+ decimalScale: column.numericSettings?.fraction ?? 0
41886
+ };
41887
+ let floatValue = parseFloat(valueFilter ?? '0');
41888
+ return (jsxs(Fragment$1, { children: [jsx(SelectTable, { value: options.find((x) => x.value === (operator)), options: options, onChange: (val) => {
41889
+ setOperator(val.value);
41890
+ }, 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) => {
41891
+ floatValue = values?.floatValue;
41892
+ }, onFocus: (e) => {
41893
+ e.target.setSelectionRange(0, e.target.innerText.length - 1);
41894
+ }, onBlur: () => {
41895
+ if (floatValue !== valueFilter) {
41896
+ setValueFilter(!isNaN(floatValue) ? floatValue : 0);
41897
+ }
41898
+ } })] }));
41899
+ };
41900
+ const RenderSelectFilter = () => {
41901
+ 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) => {
41902
+ setValueFilter(val?.value);
41903
+ }, placeholder: t('Select') }) }));
41904
+ };
41905
+ const handleSave = () => {
41906
+ if (filter) {
41907
+ filter.ope = operator;
41908
+ filter.value = valueFilter ?? '';
41909
+ }
41910
+ else {
41911
+ filterBy.push({ key: column.field, ope: operator, value: valueFilter ?? '' });
41912
+ }
41913
+ changeFilter([...filterBy]);
41914
+ setOpenFilter(false);
41915
+ };
41916
+ return (jsxs("div", { className: 'r-filter-popup', onKeyDown: (e) => {
41917
+ if (e.code === 'Enter' || e.code === 'NumpadEnter') {
41918
+ handleSave();
41919
+ e.stopPropagation();
41920
+ }
41921
+ }, 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', outline: true, style: { borderRadius: 3 }, onClick: () => {
41922
+ if (filterBy) {
41923
+ changeFilter(filterBy.filter((x) => x.key !== column.field));
41924
+ }
41925
+ setOpenFilter(false);
41926
+ }, children: t('Clear') })] })] }));
41817
41927
  };
41818
41928
 
41819
41929
  const defaultMaxHeight = 250;
@@ -42585,9 +42695,15 @@ const EditFormInline = forwardRef((props, ref) => {
42585
42695
  }) })] }));
42586
42696
  });
42587
42697
 
42698
+ const RenderColGroup = ({ contentColumns }) => (jsx("colgroup", { children: contentColumns.map((col, index) => (jsx("col", { style: {
42699
+ width: typeof col.width === 'number' ? `${col.width}px` : col.width || undefined,
42700
+ minWidth: typeof col.minWidth === 'number' ? `${col.minWidth}px` : col.minWidth || undefined,
42701
+ maxWidth: typeof col.maxWidth === 'number' ? `${col.maxWidth}px` : col.maxWidth || undefined
42702
+ } }, index))) }));
42703
+
42588
42704
  const TableEdit = forwardRef((props, ref) => {
42589
42705
  const { t } = useTranslation();
42590
- 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;
42706
+ 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;
42591
42707
  useImperativeHandle(ref, () => {
42592
42708
  return {
42593
42709
  refeshFocusRow: handleRefeshRow
@@ -42596,17 +42712,11 @@ const TableEdit = forwardRef((props, ref) => {
42596
42712
  const [refreshRow, setRefreshRow] = useState(false);
42597
42713
  const [indexFocus, setIndexFocus] = useState(-1);
42598
42714
  const [selectedRows, setSelectedRows] = useState([]);
42599
- const [headerColumns, setHeaderColumns] = useState([[]]);
42600
42715
  const [contentColumns, setContentColumns] = useState([]);
42601
- const [levelCol, setLevelCol] = useState(0);
42602
- const [columnFistEdit, setColumnFistEdit] = useState(0);
42603
- const [columnLastEdit, setColumnlastEdit] = useState(0);
42604
- const [objWidthFixRight, setObjWidthFixRight] = useState({});
42605
- const [objWidthFixLeft, setObjWidthFixLeft] = useState({});
42606
- const [lastObjWidthFixLeft, setLastObjWidthFixLeft] = useState(0);
42607
- const [fisrtObjWidthFixRight, setFisrtObjWidthFixRight] = useState(0);
42608
42716
  const [openPopupSetupColumn, setOpenPopupSetupColumn] = useState(false);
42609
42717
  const [searchTerm, setSearchTerm] = useState('');
42718
+ const [orderBy, setOrderBy] = useState([]);
42719
+ const [filterBy, setFilterBy] = useState([]);
42610
42720
  const tableElement = useRef(null);
42611
42721
  const gridRef = useRef(null);
42612
42722
  const totalCount = dataSource.length;
@@ -42619,95 +42729,11 @@ const TableEdit = forwardRef((props, ref) => {
42619
42729
  pagingSetting.setCurrentPage(1);
42620
42730
  }
42621
42731
  }, [dataSource]);
42622
- useEffect(() => {
42623
- let indexFirst = -1;
42624
- let indexlast = -1;
42625
- let letfWidthFix = 0;
42626
- let rightWidthFix = 0;
42627
- contentColumns.forEach((item, index) => {
42628
- if (levelCol === 1) {
42629
- headerColumns[0][index].width = item.width;
42630
- headerColumns[0][index].visible = item.visible;
42631
- headerColumns[0][index].fixedType = item.fixedType;
42632
- }
42633
- if (item.fixedType === 'left' && item.visible !== false) {
42634
- setLastObjWidthFixLeft(index);
42635
- objWidthFixLeft[index] = letfWidthFix;
42636
- letfWidthFix += Number(item.width ?? 40);
42637
- }
42638
- const lasColumn = contentColumns[contentColumns.length - 1 - index];
42639
- if (lasColumn.fixedType === 'right' && lasColumn.visible !== false) {
42640
- setFisrtObjWidthFixRight(contentColumns.length - 1 - index);
42641
- objWidthFixRight[contentColumns.length - 1 - index] = rightWidthFix;
42642
- rightWidthFix += Number(lasColumn.width ?? 40);
42643
- }
42644
- if (item.editEnable && (item.visible !== false) && (!item.disabledCondition)) {
42645
- if (indexFirst === -1) {
42646
- indexFirst = index;
42647
- }
42648
- indexlast = index;
42649
- }
42650
- });
42651
- if (levelCol === 1) {
42652
- setHeaderColumns([...headerColumns]);
42653
- }
42654
- setObjWidthFixLeft(objWidthFixLeft);
42655
- setObjWidthFixRight(objWidthFixRight);
42656
- setColumnFistEdit(indexFirst + 1);
42657
- setColumnlastEdit(indexlast + 1);
42658
- }, [contentColumns]);
42659
- useEffect(() => {
42660
- const arrHeaderColumns = [];
42661
- const arrContentColumns = [];
42662
- let headerLevelRow = 0;
42663
- if (levelCol) {
42664
- headerLevelRow = levelCol;
42665
- }
42666
- else {
42667
- headerLevelRow = stretchColumn(columns, 0);
42668
- setLevelCol(headerLevelRow);
42669
- }
42670
- for (let i = 0; i < headerLevelRow; i++) {
42671
- arrHeaderColumns.push([]);
42672
- }
42673
- getNestedChildren(columns, arrHeaderColumns, arrContentColumns, 0, headerLevelRow);
42674
- setHeaderColumns(arrHeaderColumns);
42675
- setContentColumns(arrContentColumns);
42732
+ const { levels: headerColumns, flatVisble, objWidthFixLeft, objWidthFixRight, lastObjWidthFixLeft, fisrtObjWidthFixRight, firstEdit: columnFirstEdit, lastEdit: columnLastEdit } = useMemo(() => {
42733
+ const obj = calculateTableStructure(columns);
42734
+ setContentColumns(obj.flat);
42735
+ return obj;
42676
42736
  }, [columns]);
42677
- const getNestedChildren = (array, arrHeaderColumns, arrContentColumns, level, maxLevelRow) => {
42678
- array.forEach((item) => {
42679
- const ele = { ...item, visible: item.visible, rowspan: 1, index: 0 };
42680
- if (item.columns && item.columns?.length > 0) {
42681
- const countLevel = getNestedChildren(item.columns, arrHeaderColumns, arrContentColumns, level + 1, maxLevelRow);
42682
- arrHeaderColumns[(maxLevelRow - 1) - countLevel].push(ele);
42683
- }
42684
- else {
42685
- ele.rowspan = maxLevelRow - level;
42686
- ele.index = arrContentColumns.length;
42687
- if (maxLevelRow === 1) {
42688
- ele.visible = (item.invisibleDisable ? item.visible : (contentColumns[arrContentColumns.length]?.visible ?? item.visible));
42689
- ele.width = (contentColumns[arrContentColumns.length]?.width ?? item.width);
42690
- ele.maxWidth = (contentColumns[arrContentColumns.length]?.maxWidth ?? item.maxWidth);
42691
- ele.minWidth = (contentColumns[arrContentColumns.length]?.minWidth ?? item.minWidth);
42692
- }
42693
- arrHeaderColumns[level].push(ele);
42694
- arrContentColumns.push(ele);
42695
- }
42696
- });
42697
- return level;
42698
- };
42699
- const stretchColumn = (subColumns, headerLevelRow) => {
42700
- let count = headerLevelRow + 1;
42701
- subColumns.map((item) => {
42702
- if (item.columns && item.columns.length > 0) {
42703
- const newCount = stretchColumn(item.columns, headerLevelRow + 1);
42704
- if (newCount > count) {
42705
- count = newCount;
42706
- }
42707
- }
42708
- });
42709
- return count;
42710
- };
42711
42737
  const handleRefeshRow = () => {
42712
42738
  setRefreshRow(true);
42713
42739
  setTimeout(() => {
@@ -42763,6 +42789,11 @@ const TableEdit = forwardRef((props, ref) => {
42763
42789
  if (checkKeyDown(e, row, col, indexRow + 1, indexCol + 1)) {
42764
42790
  return true;
42765
42791
  }
42792
+ }, onPaste: (e) => {
42793
+ if (toolbarSetting?.showBottomToolbar && !editDisable && !addDisable) {
42794
+ pasteDataFromExcel(indexRow, indexCol, e);
42795
+ e.preventDefault();
42796
+ }
42766
42797
  } }));
42767
42798
  case 'datetime':
42768
42799
  return (jsx(DateInput, { id: `${idTable}-col${indexCol + 1}-row${indexRow + 1}`, className: classNames$1('form-control border-0 rounded-0 input-numeric', { 'is-invalid': col.validate && col.validate(row[col.field], row) }), value: row[col.field], onChange: (date) => {
@@ -42773,6 +42804,11 @@ const TableEdit = forwardRef((props, ref) => {
42773
42804
  handleDataChange(row, col, indexRow);
42774
42805
  }, dateFormat: "dd/MM/yyyy HH:mm", onKeyDown: (e) => {
42775
42806
  checkKeyDown(e, row, col, indexRow + 1, indexCol + 1);
42807
+ }, onPaste: (e) => {
42808
+ if (toolbarSetting?.showBottomToolbar && !editDisable && !addDisable) {
42809
+ pasteDataFromExcel(indexRow, indexCol, e);
42810
+ e.preventDefault();
42811
+ }
42776
42812
  } }));
42777
42813
  case 'select':
42778
42814
  let valueSelect;
@@ -43027,7 +43063,7 @@ const TableEdit = forwardRef((props, ref) => {
43027
43063
  }
43028
43064
  if (tableElement) {
43029
43065
  setIndexFocus(totalCount);
43030
- focusNewElement(columnFistEdit, totalCount + 1, true);
43066
+ focusNewElement(columnFirstEdit, totalCount + 1, true);
43031
43067
  }
43032
43068
  };
43033
43069
  const checkKeyDown = (e, row, col, indexRow, indexCol) => {
@@ -43155,7 +43191,28 @@ const TableEdit = forwardRef((props, ref) => {
43155
43191
  }
43156
43192
  else {
43157
43193
  if (column.editType === 'date') {
43158
- const date = new Date(stringData);
43194
+ const [day, month, year] = stringData.split('/');
43195
+ const date = new Date(`${year}-${month}-${day}`);
43196
+ if (!isNaN(date.getTime())) {
43197
+ if (column.onPaste) {
43198
+ dataRow[column.field] = column.onPaste(dataRow, date);
43199
+ }
43200
+ else {
43201
+ dataRow[column.field] = date;
43202
+ }
43203
+ if (column.callback) {
43204
+ column.callback(date, currenRowIndex + indexRow, dataRow);
43205
+ }
43206
+ }
43207
+ else {
43208
+ notificationError(t('PasteExcelIncorrectFormat', { index: (currenRowIndex + indexRow + 1), field: t(column.headerText ?? ''), value: stringData }));
43209
+ }
43210
+ }
43211
+ else if (column.editType === 'datetime') {
43212
+ const [datePart, timePart] = stringData.split(' ');
43213
+ const [day, month, year] = datePart.split('/');
43214
+ const [hour, minute] = timePart.split(':');
43215
+ const date = new Date(year, month - 1, day, hour, minute);
43159
43216
  if (!isNaN(date.getTime())) {
43160
43217
  if (column.onPaste) {
43161
43218
  dataRow[column.field] = column.onPaste(dataRow, date);
@@ -43242,14 +43299,6 @@ const TableEdit = forwardRef((props, ref) => {
43242
43299
  };
43243
43300
  const changeDataSource = (data, numberOfRows) => {
43244
43301
  if (!editDisable && setDataSource) {
43245
- if ((searchSetting?.searchTerm !== undefined ? searchSetting?.searchTerm : searchTerm)) {
43246
- if (searchSetting?.setSearchTerm) {
43247
- searchSetting?.setSearchTerm('');
43248
- }
43249
- else {
43250
- setSearchTerm('');
43251
- }
43252
- }
43253
43302
  if (numberOfRows && !addDisable) {
43254
43303
  for (let index = 0; index < numberOfRows; index++) {
43255
43304
  data.push(defaultValue ? { ...defaultValue, [fieldKey]: disableAutoKey ? undefined : generateUUID() } : {});
@@ -43450,22 +43499,52 @@ const TableEdit = forwardRef((props, ref) => {
43450
43499
  textAlign: col.textAlign ? col.textAlign : 'left'
43451
43500
  }, 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}`));
43452
43501
  };
43453
- const checkSearch = (keyword, data, fieldKey) => {
43454
- if (!keyword || fieldKey.length === 0) {
43455
- return true;
43456
- }
43457
- for (let index = 0; index < fieldKey.length; index++) {
43458
- const key = fieldKey[index].trim();
43459
- if (data[key] && data[key].toString().trim().toLowerCase().includes(keyword.trim().toLowerCase())) {
43460
- return true;
43502
+ /**
43503
+ * 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
43504
+ */
43505
+ function checkRowMatch(row, filters, keyword, searchKeys) {
43506
+ if ((!filters || filters.length === 0) && (!keyword || !searchClient))
43507
+ return true; // Không có filter thì mặc định là match
43508
+ const isFilterMatch = filters.every(filter => {
43509
+ const { key, value, ope } = filter;
43510
+ const rowValue = row[key];
43511
+ if (rowValue === undefined || rowValue === null || value === undefined || value === null)
43512
+ return false;
43513
+ const valStr = String(rowValue).toLowerCase();
43514
+ const filterStr = String(value).toLowerCase();
43515
+ switch (ope) {
43516
+ case 'startswith':
43517
+ return valStr.startsWith(filterStr);
43518
+ case 'endswith':
43519
+ return valStr.endsWith(filterStr);
43520
+ case 'contains':
43521
+ return valStr.includes(filterStr);
43522
+ case 'equal':
43523
+ return rowValue == value;
43524
+ case 'notequal':
43525
+ return rowValue != value;
43526
+ case 'greaterthan':
43527
+ return rowValue > value;
43528
+ case 'greaterthanorequal':
43529
+ return rowValue >= value;
43530
+ case 'lessthan':
43531
+ return rowValue < value;
43532
+ case 'lessthanorequal':
43533
+ return rowValue <= value;
43534
+ default:
43535
+ return false;
43461
43536
  }
43462
- }
43463
- return false;
43464
- };
43537
+ });
43538
+ const isSearchMatch = !keyword || searchKeys.some(key => {
43539
+ const val = row[key];
43540
+ return val?.toString().toLowerCase().includes(keyword.trim().toLowerCase());
43541
+ });
43542
+ return isFilterMatch && isSearchMatch;
43543
+ }
43465
43544
  const renderData = () => {
43466
43545
  return (dataSource.map((row, indexRow) => {
43467
43546
  const isSelected = selectedRows?.some((x) => x[fieldKey] === row[fieldKey]);
43468
- const flagSearch = !searchClient || checkSearch(searchSetting?.searchTerm !== undefined ? searchSetting?.searchTerm : searchTerm, row, searchSetting?.keyField ?? []);
43547
+ const flagSearch = checkRowMatch(row, filterBy, searchSetting?.searchTerm !== undefined ? searchSetting?.searchTerm : searchTerm, searchSetting?.keyField ?? []);
43469
43548
  if (flagSearch) {
43470
43549
  const flagDisplay = !pagingClient || ((indexRow + 1) > ((pagingSetting.pageSize ?? 0) * ((pagingSetting.currentPage ?? 0) - 1)) && (indexRow + 1) <= ((pagingSetting.pageSize ?? 0) * ((pagingSetting.currentPage ?? 0))));
43471
43550
  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}`) }));
@@ -43477,14 +43556,18 @@ const TableEdit = forwardRef((props, ref) => {
43477
43556
  pagingSetting?.setCurrentPage(1);
43478
43557
  }
43479
43558
  }, [searchTerm, searchSetting?.searchTerm]);
43480
- 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) => {
43559
+ 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) => {
43481
43560
  return (jsx("tr", { className: "r-row", role: "row", children: element?.map((col, index) => {
43482
- 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}`));
43561
+ return (jsx(HeaderTableCol$1, { col: col, idTable: idTable ?? '', dataSource: dataSource, indexCol: index, indexParent: indexParent, isMulti: isMulti ?? false, objWidthFixLeft: objWidthFixLeft, objWidthFixRight: objWidthFixRight, selectEnable: selectEnable ?? false, selectedRows: selectedRows, setSelectedRows: setSelectedRows, container: tableElement, filterBy: filterBy, orderBy: orderBy, optionsFilter: optionsFilter, allowFilter: allowFilter, allowOrder: allowOrder, formatSetting: formatSetting, changeFilter: (val) => {
43562
+ setFilterBy([...val]);
43563
+ }, changeOrder: (val) => {
43564
+ setOrderBy([...val]);
43565
+ }, columns: contentColumns, setColumns: setContentColumns, fisrtObjWidthFixRight: fisrtObjWidthFixRight, lastObjWidthFixLeft: lastObjWidthFixLeft, totalCount: totalCount }, `header-${indexParent}-${index}`));
43483
43566
  }) }, `header-${-indexParent}`));
43484
43567
  }) }), 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) => {
43485
43568
  return (renderFooterCol(col, index));
43486
43569
  }) }) : jsx(Fragment$1, {}) })] }) }), toolbarSetting?.showBottomToolbar && jsx(ToolbarBottom, { handleAdd: (numberOfRows) => {
43487
- handleAdd(dataSource, tableElement.current, columnFistEdit, changeDataSource, pagingSetting, setIndexFocus, focusNewElement, numberOfRows);
43570
+ handleAdd(dataSource, tableElement.current, columnFirstEdit, changeDataSource, pagingSetting, setIndexFocus, focusNewElement, numberOfRows);
43488
43571
  }, handleDuplicate: () => {
43489
43572
  handleDuplicate(dataSource, indexFocus, fieldKey, defaultValue, fieldUniKey, changeDataSource, tableElement, totalCount, toolbarSetting, buttonSetting, editDisable, addDisable, onDuplicate);
43490
43573
  }, handleInsertAfter: () => {
@@ -65600,12 +65683,6 @@ const RenderContentCol = (props) => {
65600
65683
  }, children: RenderElement() }, `col-${indexRow}-${indexCol}`));
65601
65684
  };
65602
65685
 
65603
- const RenderColGroup = ({ contentColumns }) => (jsx("colgroup", { children: contentColumns.map((col, index) => (jsx("col", { style: {
65604
- width: typeof col.width === 'number' ? `${col.width}px` : col.width || undefined,
65605
- minWidth: typeof col.minWidth === 'number' ? `${col.minWidth}px` : col.minWidth || undefined,
65606
- maxWidth: typeof col.maxWidth === 'number' ? `${col.maxWidth}px` : col.maxWidth || undefined
65607
- } }, index))) }));
65608
-
65609
65686
  const VirtualTable = ({ idTable, dataSource, rowHeight = 33, height = 400, columns, isMutil, isLoading, selectEnable, formatSetting, commandClick, allowFilter, allowOrder, setColumns, pagingSetting, changeFilter, changeOrder, searchSetting, columnsAggregate, toolbarSetting, optionsFilter }) => {
65610
65687
  const gridRef = useRef(null);
65611
65688
  const [startIndex, setStartIndex] = useState(0);