es-grid-template 1.3.0 → 1.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/assets/index.css +16 -0
  2. package/assets/index.scss +37 -3
  3. package/es/grid-component/CheckboxFilter.js +4 -0
  4. package/es/grid-component/CheckboxFilter2.d.ts +20 -0
  5. package/es/grid-component/CheckboxFilter2.js +248 -0
  6. package/es/grid-component/ColumnsGroup/ColumnsGroup.js +4 -4
  7. package/es/grid-component/ContextMenu.js +1 -0
  8. package/es/grid-component/ConvertColumnTable.js +1 -0
  9. package/es/grid-component/EditableCell.js +11 -8
  10. package/es/grid-component/InternalTable.js +47 -11
  11. package/es/grid-component/TableGrid.d.ts +3 -0
  12. package/es/grid-component/TableGrid.js +71 -7
  13. package/es/grid-component/hooks/columns/index.js +14 -45
  14. package/es/grid-component/hooks/content/HeaderContent.js +54 -58
  15. package/es/grid-component/hooks/useColumns.d.ts +4 -2
  16. package/es/grid-component/hooks/useColumns.js +32 -13
  17. package/es/grid-component/hooks/utils.d.ts +9 -0
  18. package/es/grid-component/hooks/utils.js +278 -1
  19. package/es/grid-component/number-range/index.d.ts +10 -0
  20. package/es/grid-component/number-range/index.js +59 -0
  21. package/es/grid-component/styles.scss +24 -0
  22. package/es/grid-component/table/Grid.d.ts +3 -0
  23. package/es/grid-component/table/GridEdit.js +360 -106
  24. package/es/grid-component/table/Group.d.ts +1 -0
  25. package/es/grid-component/table/Group.js +1 -1
  26. package/es/grid-component/type.d.ts +2 -1
  27. package/lib/grid-component/CheckboxFilter.js +4 -0
  28. package/lib/grid-component/CheckboxFilter2.d.ts +20 -0
  29. package/lib/grid-component/CheckboxFilter2.js +257 -0
  30. package/lib/grid-component/ColumnsGroup/ColumnsGroup.js +4 -4
  31. package/lib/grid-component/ContextMenu.js +1 -0
  32. package/lib/grid-component/ConvertColumnTable.js +1 -0
  33. package/lib/grid-component/EditableCell.js +11 -8
  34. package/lib/grid-component/InternalTable.js +41 -10
  35. package/lib/grid-component/TableGrid.d.ts +3 -0
  36. package/lib/grid-component/TableGrid.js +68 -7
  37. package/lib/grid-component/hooks/columns/index.js +14 -45
  38. package/lib/grid-component/hooks/content/HeaderContent.js +53 -55
  39. package/lib/grid-component/hooks/useColumns.d.ts +4 -2
  40. package/lib/grid-component/hooks/useColumns.js +31 -12
  41. package/lib/grid-component/hooks/utils.d.ts +9 -0
  42. package/lib/grid-component/hooks/utils.js +293 -4
  43. package/lib/grid-component/number-range/index.d.ts +10 -0
  44. package/lib/grid-component/number-range/index.js +67 -0
  45. package/lib/grid-component/styles.scss +24 -0
  46. package/lib/grid-component/table/Grid.d.ts +3 -0
  47. package/lib/grid-component/table/GridEdit.js +358 -104
  48. package/lib/grid-component/table/Group.d.ts +1 -0
  49. package/lib/grid-component/table/Group.js +1 -1
  50. package/lib/grid-component/type.d.ts +2 -1
  51. package/package.json +109 -108
@@ -787,4 +787,281 @@ export const isArraysEqual = (arr1, arr2) => {
787
787
  };
788
788
  export const editAbleColumns = columns => {
789
789
  return columns.filter(col => col.field !== '#' && col.field !== 'index' && col.field !== 'command' && col.visible !== false);
790
- };
790
+ };
791
+ export const findItemPath = (tree, targetItem, rowKey) => {
792
+ let result = null;
793
+ function dfs(nodes, path = []) {
794
+ for (let i = 0; i < nodes.length; i++) {
795
+ const currentPath = [...path, i + 1];
796
+ const node = nodes[i];
797
+ if (node?.[rowKey] === targetItem?.[rowKey]) {
798
+ result = currentPath.join('.');
799
+ return true;
800
+ }
801
+ if (node?.children) {
802
+ if (dfs(node.children, currentPath)) {
803
+ return true;
804
+ }
805
+ }
806
+ }
807
+ return false;
808
+ }
809
+ dfs(tree);
810
+ return result;
811
+ };
812
+ export const filterDataByColumns = (data, queries) => {
813
+ if (!queries || queries.length === 0) {
814
+ return data;
815
+ }
816
+ return data.filter(item => {
817
+ let result = null;
818
+ for (const query of queries) {
819
+ const {
820
+ field,
821
+ value,
822
+ operator,
823
+ predicate
824
+ } = query;
825
+ const itemValue = item[field];
826
+ let condition = false;
827
+
828
+ // Normalize string values for comparison
829
+ const itemStr = itemValue?.toString().toLowerCase?.();
830
+ const queryStr = value?.toString().toLowerCase?.();
831
+ switch (operator.toLowerCase()) {
832
+ case "equal":
833
+ if (isDateString(value)) {
834
+ condition = compareDate(itemValue, value);
835
+ } else {
836
+ condition = itemValue == value;
837
+ }
838
+ break;
839
+ case "notequal":
840
+ if (isDateString(value)) {
841
+ condition = !compareDate(itemValue, value);
842
+ } else {
843
+ condition = itemValue != value;
844
+ }
845
+ break;
846
+ case "greaterthan":
847
+ condition = itemValue > value;
848
+ break;
849
+ case "greaterthanorequal":
850
+ condition = itemValue >= value;
851
+ break;
852
+ case "lessthan":
853
+ condition = itemValue < value;
854
+ break;
855
+ case "lessthanorequal":
856
+ condition = itemValue <= value;
857
+ break;
858
+ case "contains":
859
+ condition = itemStr?.includes(queryStr);
860
+ break;
861
+ case "startswith":
862
+ condition = itemStr?.startsWith(queryStr);
863
+ break;
864
+ case "endswith":
865
+ condition = itemStr?.endsWith(queryStr);
866
+ break;
867
+ default:
868
+ console.warn(`Unknown operator: ${operator}`);
869
+ break;
870
+ }
871
+ if (predicate === "and") {
872
+ result = result === null ? condition : result && condition;
873
+ } else if (predicate === "or") {
874
+ result = result === null ? condition : result || condition;
875
+ }
876
+ }
877
+ return result;
878
+ });
879
+ };
880
+ export const filterDataByColumns2 = (data, queries) => {
881
+ if (!queries || queries.length === 0) {
882
+ return data;
883
+ }
884
+ return data.filter(item => {
885
+ // Nếu isFilterState = true thì giữ lại dòng này, không cần kiểm tra filter
886
+ if (item.isFilterState) {
887
+ return true;
888
+ }
889
+ let result = null;
890
+ for (const query of queries) {
891
+ const {
892
+ field,
893
+ value,
894
+ operator,
895
+ predicate
896
+ } = query;
897
+ const itemValue = item[field];
898
+ let condition = false;
899
+
900
+ // Normalize string values for comparison
901
+ const itemStr = itemValue?.toString().toLowerCase?.();
902
+ const queryStr = value?.toString().toLowerCase?.();
903
+ switch (operator.toLowerCase()) {
904
+ case "equal":
905
+ condition = isDateString(value) ? compareDate(itemValue, value) : itemValue == value;
906
+ break;
907
+ case "notequal":
908
+ condition = isDateString(value) ? !compareDate(itemValue, value) : itemValue != value;
909
+ break;
910
+ case "greaterthan":
911
+ condition = itemValue > value;
912
+ break;
913
+ case "greaterthanorequal":
914
+ condition = itemValue >= value;
915
+ break;
916
+ case "lessthan":
917
+ condition = itemValue < value;
918
+ break;
919
+ case "lessthanorequal":
920
+ condition = itemValue <= value;
921
+ break;
922
+ case "contains":
923
+ condition = itemStr?.includes(queryStr);
924
+ break;
925
+ case "startswith":
926
+ condition = itemStr?.startsWith(queryStr);
927
+ break;
928
+ case "endswith":
929
+ condition = itemStr?.endsWith(queryStr);
930
+ break;
931
+ default:
932
+ console.warn(`Unknown operator: ${operator}`);
933
+ break;
934
+ }
935
+
936
+ // Áp dụng toán tử logic (and/or)
937
+ if (predicate === "and") {
938
+ result = result === null ? condition : result && condition;
939
+ } else if (predicate === "or") {
940
+ result = result === null ? condition : result || condition;
941
+ }
942
+ }
943
+ return result;
944
+ });
945
+ };
946
+ export const removeFieldRecursive = (data, field) => {
947
+ return data.map(item => {
948
+ const {
949
+ [field]: _,
950
+ ...rest
951
+ } = item;
952
+ if (rest.children && Array.isArray(rest.children)) {
953
+ rest.children = removeFieldRecursive(rest.children, field);
954
+ }
955
+ return rest;
956
+ });
957
+ };
958
+ export const filterDataByColumns3 = (data, queries) => {
959
+ if (!queries || queries.length === 0) {
960
+ return data;
961
+ }
962
+ return data.filter(item => {
963
+ if (item.isFilterState === true) {
964
+ return true;
965
+ }
966
+ let result = null;
967
+ for (const query of queries) {
968
+ const {
969
+ field,
970
+ value,
971
+ operator,
972
+ predicate
973
+ } = query;
974
+ const itemValue = item[field];
975
+ let condition = false;
976
+ const isDateComparison = isDate(itemValue) || isDateString(value);
977
+ const itemDate = isDateComparison ? new Date(itemValue) : null;
978
+ const queryDate = isDateComparison ? parseToDate(value) : null;
979
+ const itemStr = itemValue?.toString().toLowerCase?.();
980
+ const queryStr = value?.toString().toLowerCase?.();
981
+ switch (operator.toLowerCase()) {
982
+ case "equal":
983
+ condition = isDateComparison ? compareDates(itemDate, queryDate) : itemValue == value;
984
+ break;
985
+ case "notequal":
986
+ condition = isDateComparison ? !compareDates(itemDate, queryDate) : itemValue != value;
987
+ break;
988
+ case "greaterthan":
989
+ // @ts-ignore
990
+ condition = isDateComparison ? itemDate > queryDate : itemValue > value;
991
+
992
+ // condition = isDateComparison ? invalidDate(itemDate) && invalidDate(queryDate) && itemDate > queryDate : itemValue > value;
993
+ break;
994
+ case "greaterthanorequal":
995
+ // @ts-ignore
996
+ condition = isDateComparison ? itemDate >= queryDate : itemValue >= value;
997
+ break;
998
+ case "lessthan":
999
+ // @ts-ignore
1000
+ condition = isDateComparison ? itemDate < queryDate : itemValue < value;
1001
+ break;
1002
+ case "lessthanorequal":
1003
+ // @ts-ignore
1004
+ condition = isDateComparison ? itemDate <= queryDate : itemValue <= value;
1005
+ break;
1006
+ case "contains":
1007
+ condition = itemStr?.includes(queryStr);
1008
+ break;
1009
+ case "startswith":
1010
+ condition = itemStr?.startsWith(queryStr);
1011
+ break;
1012
+ case "endswith":
1013
+ condition = itemStr?.endsWith(queryStr);
1014
+ break;
1015
+ default:
1016
+ console.warn(`Unknown operator: ${operator}`);
1017
+ break;
1018
+ }
1019
+ if (predicate === "and") {
1020
+ result = result === null ? condition : result && condition;
1021
+ } else if (predicate === "or") {
1022
+ result = result === null ? condition : result || condition;
1023
+ }
1024
+ }
1025
+ return result;
1026
+ });
1027
+ };
1028
+
1029
+ // ======= Helper functions ========
1030
+
1031
+ // Kiểm tra có phải Date object không
1032
+ function isDate(value) {
1033
+ return value instanceof Date || !isNaN(Date.parse(value));
1034
+ }
1035
+
1036
+ // Chuỗi MM/YYYY → Date
1037
+ export function isDateString(str) {
1038
+ return typeof str === "string" && (/^\d{2}\/\d{4}$/.test(str) || /^\d{4}-\d{2}-\d{2}$/.test(str));
1039
+ }
1040
+
1041
+ // // Helper: check if a string is in MM/YYYY format
1042
+ // export function isDateString(str: any) {
1043
+ // return typeof str === "string" && /^\d{2}\/\d{4}$/.test(str);
1044
+ // }
1045
+
1046
+ function parseToDate(str) {
1047
+ if (/^\d{2}\/\d{4}$/.test(str)) {
1048
+ const [month, year] = str.split('/');
1049
+ return new Date(parseInt(year), parseInt(month) - 1, 1);
1050
+ }
1051
+ return new Date(str);
1052
+ }
1053
+
1054
+ // So sánh ngày (cùng ngày/tháng/năm)
1055
+ export function compareDates(date1, date2) {
1056
+ return date1.getDate() === date2.getDate() && date1.getMonth() === date2.getMonth() && date1.getFullYear() === date2.getFullYear();
1057
+ }
1058
+
1059
+ // Helper: compare MM/YYYY date string with itemValue
1060
+ export function compareDate(itemValue, value) {
1061
+ const [month, year] = value.split('/').map(Number);
1062
+ const date = new Date(itemValue);
1063
+ return date.getMonth() + 1 === month && date.getFullYear() === year;
1064
+ }
1065
+ export function invalidDate(date) {
1066
+ return date instanceof Date && !isNaN(date.getTime());
1067
+ }
@@ -0,0 +1,10 @@
1
+ import React from "react";
2
+ type Props = {
3
+ t?: any;
4
+ format?: any;
5
+ min: number | string | undefined;
6
+ max: number | string | undefined;
7
+ onChange?: (values: any[]) => void;
8
+ };
9
+ declare const NumberRange: (props: Props) => React.JSX.Element;
10
+ export default NumberRange;
@@ -0,0 +1,59 @@
1
+ import React, { Fragment } from "react";
2
+ import { NumericFormat } from "react-numeric-component";
3
+ import { Input } from "rc-master-ui";
4
+ const NumberRange = props => {
5
+ const {
6
+ t,
7
+ max,
8
+ min,
9
+ onChange
10
+ } = props;
11
+ const values = React.useMemo(() => [min, max], [min, max]);
12
+
13
+ // const [values, setValues] = React.useState<any[]>(() =>
14
+ // mergedValues,
15
+ // );
16
+
17
+ return /*#__PURE__*/React.createElement(Fragment, null, /*#__PURE__*/React.createElement("div", {
18
+ className: '',
19
+ style: {
20
+ display: 'flex'
21
+ }
22
+ }, /*#__PURE__*/React.createElement("div", {
23
+ style: {
24
+ marginBottom: 8
25
+ }
26
+ }, /*#__PURE__*/React.createElement(NumericFormat, {
27
+ value: values[0] ?? ''
28
+ // value={min}
29
+ // thousandSeparator={checkThousandSeparator(thousandSeparator, decimalSeparator)}
30
+ // decimalSeparator={checkDecimalSeparator(thousandSeparator, decimalSeparator)}
31
+ ,
32
+ allowNegative: true,
33
+ customInput: Input,
34
+ className: ' rounded-0 input-element form-control',
35
+ onValueChange: vals => {
36
+ // onChangeValueFilter(type, values.floatValue, 'min')
37
+
38
+ // setValues([vals.floatValue, values[1]])
39
+ onChange?.([vals.floatValue, max]);
40
+ },
41
+ placeholder: t ? t('Min') : 'Min',
42
+ autoFocus: true
43
+ })), /*#__PURE__*/React.createElement("span", null, "-"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement(NumericFormat, {
44
+ value: values[1] ?? ''
45
+ // value={max}
46
+ // thousandSeparator={checkThousandSeparator(thousandSeparator, decimalSeparator)}
47
+ // decimalSeparator={checkDecimalSeparator(thousandSeparator, decimalSeparator)}
48
+ ,
49
+ allowNegative: true,
50
+ customInput: Input,
51
+ className: ' rounded-0 input-element form-control',
52
+ onValueChange: vals => {
53
+ // setValues([values[0], vals.floatValue])
54
+ onChange?.([min, vals.floatValue]);
55
+ },
56
+ placeholder: t ? t('Max') : 'Max'
57
+ }))));
58
+ };
59
+ export default NumberRange;
@@ -133,6 +133,21 @@ $fontFamily: "Montserrat",Helvetica,Arial,serif !default;
133
133
 
134
134
  .#{$prefix}-table-tbody {
135
135
 
136
+
137
+ .#{$prefix}-table-cell {
138
+ line-height: 22px;
139
+
140
+ .ui-rc-table-cell-content {
141
+ line-height: 22px;
142
+ }
143
+
144
+ &.#{$prefix}-table-cell-fix-left-last {
145
+ .#{$prefix}-table-cell-content {
146
+ }
147
+ }
148
+
149
+ }
150
+
136
151
  .#{$prefix}-table-row {
137
152
 
138
153
  &.#{$prefix}-table-row-selected {
@@ -212,6 +227,10 @@ $fontFamily: "Montserrat",Helvetica,Arial,serif !default;
212
227
 
213
228
  .#{$prefix}-table-cell {
214
229
 
230
+ .ui-rc-table-cell-content {
231
+ line-height: 22px;
232
+ }
233
+
215
234
  &.#{$prefix}-table-cell-fix-left-last {
216
235
  .#{$prefix}-table-cell-content {
217
236
  //overflow: visible;
@@ -604,6 +623,10 @@ $fontFamily: "Montserrat",Helvetica,Arial,serif !default;
604
623
  background-color: $cell-selected-bg;
605
624
  }
606
625
 
626
+ .ui-rc_cell-content.disable {
627
+ background-color: #f0f0f0;
628
+ }
629
+
607
630
  .ui-rc_cell-content--index {
608
631
  &.focus {
609
632
  background-color: $cell-index-focus-bg;
@@ -688,6 +711,7 @@ $fontFamily: "Montserrat",Helvetica,Arial,serif !default;
688
711
  transition: 0.3s;
689
712
  white-space: nowrap;
690
713
  overflow: hidden;
714
+ line-height: 22px;
691
715
  }
692
716
  }
693
717
  }
@@ -3,11 +3,14 @@ import type { ColumnsTable, GridTableProps } from "../type";
3
3
  import type { GetRowKey } from "../type";
4
4
  type Props<T> = GridTableProps<T> & {
5
5
  tableRef: any;
6
+ triggerFilter?: (queries: any) => void;
6
7
  triggerChangeColumns?: (columns: ColumnsTable<T>, type: string) => void;
7
8
  triggerChangeData?: (newData: T[], type: string) => void;
8
9
  getRowKey: GetRowKey<T>;
9
10
  triggerGroupColumns?: (groupedColumns: string[]) => void;
10
11
  triggerPaste?: (pastedRows: T[], pastedColumnsArray: string[], newData: T[]) => void;
12
+ isFilter?: boolean;
13
+ setIsFilter?: React.Dispatch<React.SetStateAction<boolean>>;
11
14
  };
12
15
  declare const Grid: <RecordType extends object>(props: Props<RecordType>) => React.JSX.Element;
13
16
  export default Grid;