rez-table-listing-mui 1.0.48 → 1.0.50

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 (36) hide show
  1. package/dist/index.d.ts +7 -1
  2. package/dist/index.js +1 -1
  3. package/dist/index.mjs +1 -1
  4. package/package.json +1 -1
  5. package/src/App.tsx +81 -24
  6. package/src/assets/svg.tsx +5 -5
  7. package/src/components/filter/components/attributes-filter.tsx +78 -52
  8. package/src/components/filter/components/forms/components/Date.tsx +178 -109
  9. package/src/components/filter/components/forms/components/Dropdown.tsx +36 -3
  10. package/src/components/filter/components/forms/components/Filter-criteria.tsx +3 -3
  11. package/src/components/filter/components/forms/components/Multi-Select.tsx +62 -34
  12. package/src/components/filter/components/forms/index.tsx +29 -7
  13. package/src/components/filter/components/main-filter.tsx +3 -0
  14. package/src/components/filter/components/saved-edit-filter.tsx +6 -0
  15. package/src/components/filter/components/saved-filter.tsx +66 -9
  16. package/src/components/filter/components/search/index.tsx +18 -1
  17. package/src/components/filter/index.tsx +21 -6
  18. package/src/components/filter/style.ts +1 -1
  19. package/src/components/index.scss +1 -1
  20. package/src/components/table-settings/common/info-alert.tsx +37 -0
  21. package/src/components/table-settings/common/listing-values.tsx +102 -54
  22. package/src/components/table-settings/components/column.tsx +206 -173
  23. package/src/components/table-settings/components/quick-tab.tsx +281 -153
  24. package/src/components/table-settings/components/sorting.tsx +135 -120
  25. package/src/components/table-settings/components/toggle-button-switch.tsx +2 -2
  26. package/src/components/table-settings/index.tsx +3 -5
  27. package/src/components/table-settings/style.ts +1 -0
  28. package/src/components/topbar/index.tsx +3 -1
  29. package/src/libs/hooks/useCraftTable.tsx +5 -0
  30. package/src/libs/hooks/useElementWidth.tsx +2 -2
  31. package/src/libs/hooks/useEntityTableAPI.tsx +1 -16
  32. package/src/libs/utils/apiColumn.ts +1 -11
  33. package/src/libs/utils/common.ts +4 -3
  34. package/src/types/filter-settings.ts +11 -0
  35. package/src/types/filter.ts +1 -2
  36. package/src/types/table-options.ts +2 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rez-table-listing-mui",
3
- "version": "1.0.48",
3
+ "version": "1.0.50",
4
4
  "type": "module",
5
5
  "description": "A rez table listing component built on TanStack Table",
6
6
  "main": "dist/index.js",
package/src/App.tsx CHANGED
@@ -23,7 +23,9 @@ import { CraftTableFilter } from ".";
23
23
  import { useCraftTableFilterSettings } from "./libs/hooks/useCraftTableFilterSettings";
24
24
  import { QuickFilterSettings } from "./components/table-settings";
25
25
  import { SettingsDataProps } from "./types/filter-settings";
26
- // import { ENTITY_TYPE } from "./libs/utils/common";
26
+ import { FilterMasterStateProps } from "./types/filter";
27
+ import { ColumnDef } from "@tanstack/react-table";
28
+ import { ENTITY_TYPE } from "./libs/utils/common";
27
29
 
28
30
  function App() {
29
31
  // const [mockLoading, setMockLoading] = useState<boolean>(true);
@@ -31,21 +33,21 @@ function App() {
31
33
  const [columns, setColumns] = useState<any[]>([]);
32
34
  const [searchTerm, setSearchTerm] = useState("");
33
35
  // const [data, setData] = useState<Person[]>(() => makeData(50, 3, 2));
34
- // const [entity_type] = useState(ENTITY_TYPE); //OR UPR BRD
35
36
 
36
37
  const [selectedTab, setSelectedTab] = useState("ALL");
37
38
 
38
39
  const tableStates = useCraftTable();
39
40
  const filterSettingStates = useCraftTableFilterSettings();
40
41
 
41
- const { filters, setFilters, filterMaster, filterToDelete } = tableStates;
42
+ const { filters, setFilters, filterMaster, setFilterMaster, filterToDelete } =
43
+ tableStates;
42
44
 
43
45
  const { showListViewSettings, setShowListViewSettings, setSettingsData } =
44
46
  filterSettingStates;
45
47
 
46
48
  const { defaultColumns } = useDefaultColumns();
47
49
 
48
- const { metaQuery } = useFetchData("BRD");
50
+ const { metaQuery } = useFetchData(ENTITY_TYPE);
49
51
  const { detailsQuery } = useDetailsQueryAPI(
50
52
  filterMaster?.saved_filters?.selectedId
51
53
  ? filterMaster?.saved_filters?.selectedId
@@ -55,16 +57,16 @@ function App() {
55
57
  const { savedMutation } = useSavedFilterAPI(); //API CALL FOR SAVED FILTER
56
58
  const { deleteMutation } = useDeleteFilterAPI(); //API FOR DELETING FILTER
57
59
  const { updateMutation } = useUpdateFilterAPI(); //API FOR UPDATE FILTER
58
- const { saveSettingsDataMutation } = useSaveSettingsDataAPI("BRD");
60
+ const { saveSettingsDataMutation } = useSaveSettingsDataAPI(ENTITY_TYPE);
59
61
  const { dropdownData } = useCommonDropdownAPI(metaQuery.data);
60
62
  const { settingsTabDropdownData, settingsTabDropdownPending } =
61
63
  useSettingsDropDownAPI({
62
- entity_type: "BRD",
64
+ entity_type: ENTITY_TYPE,
63
65
  column: filterSettingStates?.quickTabStates?.attribute,
64
66
  sort_by: filterSettingStates?.quickTabStates?.sorting,
65
67
  });
66
68
 
67
- const { getSettingsAPIData } = useGetSettingsDataAPI("BRD");
69
+ const { getSettingsAPIData } = useGetSettingsDataAPI(ENTITY_TYPE);
68
70
 
69
71
  useEffect(() => {
70
72
  // setTimeout(() => {
@@ -73,10 +75,24 @@ function App() {
73
75
 
74
76
  const fetchMeta = async () => {
75
77
  try {
76
- const { res: allColumns } = await entityTableMetaMaster("BRD");
78
+ const { res: allColumns } = await entityTableMetaMaster(ENTITY_TYPE);
77
79
 
78
80
  const savedColumnSettings = filterSettingStates.settingsData?.column;
79
81
 
82
+ const getOrderedColumns = (
83
+ showList: { value: string }[],
84
+ filteredColumns: any[]
85
+ ) => {
86
+ // Build ordered columns using showList and filteredColumns
87
+ return showList
88
+ .map((showItem) => {
89
+ return filteredColumns.find(
90
+ (col) => col.accessorKey === showItem.value
91
+ );
92
+ })
93
+ .filter((col): col is ColumnDef<any> => col !== undefined); // Ensure non-undefined columns are returned
94
+ };
95
+
80
96
  if (
81
97
  savedColumnSettings &&
82
98
  !savedColumnSettings.isDefault &&
@@ -91,10 +107,14 @@ function App() {
91
107
  const visibleColumns = new Set(
92
108
  activeTabSettings.show_list.map((c) => c.value)
93
109
  );
94
- const filtered = allColumns.filter((col: any) =>
110
+
111
+ // First, filter columns based on visibleColumns
112
+ const filteredColumns = allColumns.filter((col: any) =>
95
113
  visibleColumns.has(col.accessorKey)
96
114
  );
97
- setColumns(filtered);
115
+ setColumns(
116
+ getOrderedColumns(activeTabSettings.show_list, filteredColumns)
117
+ );
98
118
  } else {
99
119
  // Fallback if no specific settings for the active tab are found
100
120
  setColumns(allColumns);
@@ -107,7 +127,10 @@ function App() {
107
127
  const filtered = allColumns.filter((col: any) =>
108
128
  visibleColumns.has(col.accessorKey)
109
129
  );
110
- setColumns(filtered);
130
+
131
+ setColumns(
132
+ getOrderedColumns(savedColumnSettings.show_list, filtered)
133
+ );
111
134
  } else {
112
135
  // No settings found, use all columns
113
136
  setColumns(allColumns);
@@ -118,7 +141,7 @@ function App() {
118
141
  };
119
142
 
120
143
  fetchMeta();
121
- }, [filterSettingStates.settingsData, selectedTab]);
144
+ }, [selectedTab]);
122
145
 
123
146
  useEffect(() => {
124
147
  setFilters(detailsQuery.data ?? []);
@@ -134,10 +157,11 @@ function App() {
134
157
  const { tableData } = useEntityTableAPI({
135
158
  page: 0,
136
159
  size: 50,
137
- entity_type: "BRD",
160
+ entity_type: ENTITY_TYPE,
138
161
  tabs: {
139
- columnName: "status",
140
- sortBy: "ASC",
162
+ columnName:
163
+ getSettingsAPIData?.layout_json?.quick_tab?.attribute || "status",
164
+ sortBy: getSettingsAPIData?.layout_json?.quick_tab?.sorting || "ASC",
141
165
  value:
142
166
  selectedTab.toLowerCase() === "all" ? "" : selectedTab.toLowerCase(),
143
167
  },
@@ -157,6 +181,27 @@ function App() {
157
181
  );
158
182
  const tabsData = tableData?.entity_tabs;
159
183
 
184
+ // Auto-switch tab if the selected tab is removed
185
+ useEffect(() => {
186
+ if (
187
+ tabsData &&
188
+ tabsData.length > 0 &&
189
+ !tabsData.some(
190
+ (tab) => tab.tab_value?.toLowerCase() === selectedTab.toLowerCase()
191
+ )
192
+ ) {
193
+ // Try to select 'ALL' if it exists
194
+ const allTab = tabsData.find(
195
+ (tab) => tab.tab_value?.toLowerCase() === "all"
196
+ );
197
+ if (allTab) {
198
+ setSelectedTab(allTab.tab_value || "ALL");
199
+ } else {
200
+ setSelectedTab(tabsData[0].tab_value || "ALL");
201
+ }
202
+ }
203
+ }, [tabsData, selectedTab]);
204
+
160
205
  const totalCount = useMemo(() => {
161
206
  return Number(
162
207
  tableData?.entity_tabs?.find((tab) => {
@@ -213,7 +258,7 @@ function App() {
213
258
  const payload = {
214
259
  name,
215
260
  is_default: false,
216
- mapped_entity_type: "BRD", // For that entity type
261
+ mapped_entity_type: ENTITY_TYPE, // For that entity type
217
262
  status: "ACTIVE",
218
263
  entity_type: "SFM", // FIXED entity type
219
264
  filterDetails: quickFilter,
@@ -222,10 +267,22 @@ function App() {
222
267
  savedMutation.mutate(
223
268
  { entity_type, payload },
224
269
  {
225
- onSuccess: () => {},
226
- onError: (error: any) => {
227
- const msg = error?.response?.data?.message;
228
- console.log("Error in saving filter", msg, error);
270
+ onSuccess: (response) => {
271
+ const newFilterId = response?.id;
272
+ if (newFilterId) {
273
+ setFilterMaster(
274
+ (prev) =>
275
+ ({
276
+ ...prev,
277
+ saved_filters: {
278
+ ...prev?.saved_filters,
279
+ selectedId: newFilterId.toString(),
280
+ selectedName: name,
281
+ },
282
+ activeFilterTabIndex: 1,
283
+ } as FilterMasterStateProps)
284
+ );
285
+ }
229
286
  },
230
287
  }
231
288
  );
@@ -237,7 +294,7 @@ function App() {
237
294
  name: filterToDelete?.label,
238
295
  id: filterToDelete?.value,
239
296
  is_default: false,
240
- mapped_entity_type: "BRD",
297
+ mapped_entity_type: ENTITY_TYPE,
241
298
  status: "INACTIVE",
242
299
  entity_type: "SFM",
243
300
  };
@@ -257,7 +314,7 @@ function App() {
257
314
  name: filterMaster?.saved_filters?.selectedName, // Name of the filter
258
315
  is_default: false,
259
316
  id: filterMaster?.saved_filters?.selectedId,
260
- mapped_entity_type: "BRD",
317
+ mapped_entity_type: ENTITY_TYPE,
261
318
  status: "ACTIVE",
262
319
  entity_type: "SFM",
263
320
  filterDetails: quickFilter,
@@ -269,7 +326,7 @@ function App() {
269
326
  const handleSaveSettingsData = (settingsData: SettingsDataProps) => {
270
327
  const payload = {
271
328
  entity_type: "LAP",
272
- mapped_entity_type: "BRD",
329
+ mapped_entity_type: ENTITY_TYPE,
273
330
  layout_json: settingsData,
274
331
  };
275
332
 
@@ -332,7 +389,7 @@ function App() {
332
389
  showIcon: true,
333
390
  onClick: () => setShowListViewSettings(!showListViewSettings),
334
391
  }}
335
- activeTab={selectedTab}
392
+ activeTab={selectedTab?.toUpperCase()}
336
393
  tableStates={tableStates}
337
394
  tabsData={tabsData}
338
395
  onClick={(state) => {
@@ -172,7 +172,7 @@ export const ArrowDownUp = () => (
172
172
  );
173
173
  export const EditIcon = () => (
174
174
  <svg
175
- width="12"
175
+ width="18"
176
176
  height="12"
177
177
  viewBox="0 0 12 12"
178
178
  fill="none"
@@ -181,14 +181,14 @@ export const EditIcon = () => (
181
181
  <path
182
182
  d="M1.33331 10.6663H2.17431L8.99865 3.84201L8.15765 3.00101L1.33331 9.82534V10.6663ZM0.93598 11.6663C0.765202 11.6663 0.622091 11.6086 0.506646 11.493C0.391091 11.3776 0.333313 11.2345 0.333313 11.0637V9.90867C0.333313 9.74612 0.364535 9.59118 0.42698 9.44384C0.489313 9.29651 0.575202 9.16812 0.684646 9.05868L9.12698 0.620174C9.22776 0.528619 9.33904 0.457897 9.46081 0.408008C9.5827 0.358008 9.71048 0.333008 9.84415 0.333008C9.97781 0.333008 10.1073 0.35673 10.2325 0.404175C10.3578 0.451619 10.4688 0.527063 10.5653 0.630507L11.3795 1.45484C11.4829 1.5514 11.5566 1.66251 11.6006 1.78817C11.6446 1.91384 11.6666 2.03951 11.6666 2.16517C11.6666 2.29929 11.6438 2.42723 11.598 2.54901C11.5522 2.6709 11.4794 2.78223 11.3795 2.88301L2.94098 11.315C2.83154 11.4245 2.70315 11.5103 2.55581 11.5727C2.40848 11.6351 2.25354 11.6663 2.09098 11.6663H0.93598ZM8.57081 3.42884L8.15765 3.00101L8.99865 3.84201L8.57081 3.42884Z"
183
183
  fill="#0E0C0B"
184
- fill-opacity="0.4"
184
+ fillOpacity={0.4}
185
185
  />
186
186
  </svg>
187
187
  );
188
188
 
189
189
  export const DeleteIcon = () => (
190
190
  <svg
191
- width="20"
191
+ width="18"
192
192
  height="20"
193
193
  viewBox="0 0 10 12"
194
194
  fill="none"
@@ -664,7 +664,7 @@ export const SortingIcon = () => {
664
664
  );
665
665
  };
666
666
 
667
- export const FilterationIcon = () => {
667
+ export const FilterationIcon = ({ color = "#1C1B1F" }) => {
668
668
  return (
669
669
  <svg
670
670
  width="20"
@@ -687,7 +687,7 @@ export const FilterationIcon = () => {
687
687
  <g mask="url(#mask0_811_12698)">
688
688
  <path
689
689
  d="M8.33333 15V13.3333H11.6667V15H8.33333ZM5 10.8333V9.16667H15V10.8333H5ZM2.5 6.66667V5H17.5V6.66667H2.5Z"
690
- fill="#1C1B1F"
690
+ fill={color}
691
691
  />
692
692
  </g>
693
693
  </svg>
@@ -4,7 +4,6 @@ import {
4
4
  FormControlLabel,
5
5
  MenuItem,
6
6
  Radio,
7
- RadioGroup,
8
7
  Select,
9
8
  SelectChangeEvent,
10
9
  } from "@mui/material";
@@ -27,21 +26,23 @@ const AttributesFilter = ({
27
26
 
28
27
  const selectedAttribute = filterMaster?.attributes?.selected;
29
28
 
30
- // Get the current filter value to set radio button state
29
+ // Get the current filter value(s) to determine selected options
31
30
  const currentFilterValue = useMemo(() => {
32
- if (!selectedAttribute) return "";
31
+ if (!selectedAttribute) return [];
33
32
 
34
33
  const matchingColumn = columnsData.column_list.find(
35
34
  (column) => column.datasource_list === selectedAttribute
36
35
  );
37
36
 
38
- if (!matchingColumn) return "";
37
+ if (!matchingColumn) return [];
39
38
 
40
39
  const existingFilter = filters.find(
41
40
  (filter) => filter.filter_attribute === matchingColumn.attribute_key
42
41
  );
43
42
 
44
- return existingFilter?.filter_value || "";
43
+ return Array.isArray(existingFilter?.filter_value)
44
+ ? existingFilter?.filter_value
45
+ : [];
45
46
  }, [selectedAttribute, filters, columnsData]);
46
47
 
47
48
  const handleSelectChange = (event: SelectChangeEvent) => {
@@ -54,47 +55,69 @@ const AttributesFilter = ({
54
55
  attributes: {
55
56
  ...prev?.attributes,
56
57
  selected: attributeKey,
57
- radio: "", // Reset radio selection when changing attribute
58
+ radio: [],
58
59
  },
59
60
  } as FilterMasterStateProps)
60
61
  );
61
62
  };
62
63
 
63
- const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
64
- event.preventDefault();
64
+ const handleMultiRadioToggle = (value: string) => {
65
+ const selectedAttr = filterMaster?.attributes.selected;
66
+ if (!selectedAttr) return;
65
67
 
66
- const selectedValue = event.target.value;
68
+ const matchingColumn = columnsData.column_list.find(
69
+ (column) => column.datasource_list === selectedAttr
70
+ );
71
+ if (!matchingColumn) return;
67
72
 
68
- setFilterMaster(
69
- (prev) =>
70
- ({
71
- ...prev,
72
- attributes: {
73
- ...prev?.attributes,
74
- radio: selectedValue,
75
- },
76
- activeFilterTabIndex: tabValue,
77
- } as FilterMasterStateProps)
73
+ const existingFilter = filters.find(
74
+ (f) => f.filter_attribute === matchingColumn.attribute_key
78
75
  );
79
76
 
80
- const selectedAttribute = filterMaster?.attributes.selected;
81
- if (selectedAttribute) {
82
- const matchingColumn = columnsData.column_list.find(
83
- (column) => column.datasource_list === selectedAttribute
77
+ const currentValues: string[] = Array.isArray(existingFilter?.filter_value)
78
+ ? existingFilter.filter_value
79
+ : [];
80
+
81
+ const isAlreadySelected = currentValues.includes(value);
82
+
83
+ const updatedValues = isAlreadySelected
84
+ ? currentValues.filter((v) => v !== value)
85
+ : [...currentValues, value];
86
+
87
+ const defaultOperator =
88
+ columnsData.operation_list[matchingColumn.data_type]?.[0]?.value || "in";
89
+
90
+ const newFilter = {
91
+ filter_attribute: matchingColumn.attribute_key,
92
+ filter_operator: defaultOperator,
93
+ filter_value: updatedValues,
94
+ };
95
+
96
+ setFilters((prevFilters) => {
97
+ const exists = prevFilters.some(
98
+ (f) => f.filter_attribute === matchingColumn.attribute_key
84
99
  );
85
- if (matchingColumn) {
86
- const defaultOperator =
87
- columnsData.operation_list[matchingColumn.data_type]?.[0]?.value ||
88
- "equals";
89
- const newFilter = {
90
- filter_attribute: matchingColumn.attribute_key,
91
- filter_operator: defaultOperator,
92
- filter_value: selectedValue,
93
- };
94
-
95
- setFilters([newFilter]);
100
+ if (exists) {
101
+ return prevFilters.map((f) =>
102
+ f.filter_attribute === matchingColumn.attribute_key ? newFilter : f
103
+ );
104
+ } else {
105
+ return [...prevFilters, newFilter];
96
106
  }
97
- }
107
+ });
108
+
109
+ setFilterMaster((prev) => {
110
+ if (!prev || !prev.attributes.selected) return prev;
111
+
112
+ return {
113
+ ...prev,
114
+ attributes: {
115
+ ...prev.attributes,
116
+ radio: updatedValues,
117
+ },
118
+ activeFilterTabIndex: tabValue as number,
119
+ };
120
+ });
98
121
  };
99
122
 
100
123
  const selectedAttributeOptions = useMemo(() => {
@@ -170,27 +193,30 @@ const AttributesFilter = ({
170
193
  {dropdownData && (
171
194
  <Box sx={{ mt: 2 }}>
172
195
  <FormControl>
173
- <RadioGroup
174
- onChange={handleRadioChange}
175
- value={currentFilterValue} // Set the value from current filter
176
- >
177
- {selectedAttributeOptions
178
- ?.filter((option) => {
179
- if (!searchTerm) return true;
180
-
181
- return option.label
182
- .toLowerCase()
183
- .includes(searchTerm.toLowerCase());
184
- })
185
- .map((option) => (
196
+ {selectedAttributeOptions
197
+ ?.filter((option) => {
198
+ if (!searchTerm) return true;
199
+
200
+ return option.label
201
+ .toLowerCase()
202
+ .includes(searchTerm.toLowerCase());
203
+ })
204
+ .map((option) => {
205
+ const isSelected = currentFilterValue.includes(option.value);
206
+
207
+ return (
186
208
  <FormControlLabel
187
209
  key={option.value}
188
- value={option.value}
189
- control={<Radio />}
210
+ control={
211
+ <Radio
212
+ checked={isSelected}
213
+ onClick={() => handleMultiRadioToggle(option.value)}
214
+ />
215
+ }
190
216
  label={option.label}
191
217
  />
192
- ))}
193
- </RadioGroup>
218
+ );
219
+ })}
194
220
  </FormControl>
195
221
  </Box>
196
222
  )}