rez-table-listing-mui 1.3.44 → 1.3.46

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 (41) hide show
  1. package/dist/index.d.ts +70 -9
  2. package/dist/index.js +1 -1
  3. package/dist/index.js.map +1 -1
  4. package/dist/index.mjs +1 -1
  5. package/dist/index.mjs.map +1 -1
  6. package/package.json +1 -1
  7. package/src/listing/components/common/saved-filter-modal/index.tsx +517 -0
  8. package/src/listing/components/filter/components/attributes-filter.tsx +2 -2
  9. package/src/listing/components/filter/components/forms/components/Dropdown.tsx +2 -2
  10. package/src/listing/components/filter/components/forms/components/Filter-criteria.tsx +9 -7
  11. package/src/listing/components/filter/components/forms/components/Textfield.tsx +2 -4
  12. package/src/listing/components/filter/components/forms/components/filter-criteria-list.tsx +1 -0
  13. package/src/listing/components/filter/components/forms/index.tsx +23 -14
  14. package/src/listing/components/filter/components/forms/utils/filter-date-input-resolver.tsx +3 -3
  15. package/src/listing/components/filter/components/main-filter.tsx +6 -6
  16. package/src/listing/components/filter/components/saved-edit-filter.tsx +5 -3
  17. package/src/listing/components/filter/components/saved-filter.tsx +300 -124
  18. package/src/listing/components/filter/components/search/index.tsx +1 -0
  19. package/src/listing/components/filter/components/single-filter-rendering.tsx +3 -3
  20. package/src/listing/components/filter/index.tsx +130 -5
  21. package/src/listing/components/index-table.tsx +9 -0
  22. package/src/listing/components/login/index.tsx +3 -6
  23. package/src/listing/components/table-dnd.tsx +6 -0
  24. package/src/listing/components/table-head-dnd-cell.tsx +7 -0
  25. package/src/listing/components/table-head-popover.tsx +24 -3
  26. package/src/listing/components/table-head.tsx +10 -0
  27. package/src/listing/components/table-settings/components/column.tsx +85 -26
  28. package/src/listing/components/table-settings/components/quick-tab.tsx +395 -77
  29. package/src/listing/components/table-settings/components/sorting.tsx +60 -20
  30. package/src/listing/components/table-settings/index.tsx +12 -2
  31. package/src/listing/components/table.tsx +6 -0
  32. package/src/listing/libs/hooks/useEntityTableAPI.tsx +20 -5
  33. package/src/listing/libs/utils/apiColumn.ts +8 -3
  34. package/src/listing/libs/utils/common.ts +2 -1
  35. package/src/listing/libs/utils/hydrate-saved-filters.ts +2 -2
  36. package/src/listing/types/common.ts +1 -0
  37. package/src/listing/types/filter-settings.ts +8 -2
  38. package/src/listing/types/filter.ts +51 -3
  39. package/src/listing/types/table.ts +9 -0
  40. package/src/view/FIlterWrapper.tsx +15 -0
  41. package/src/view/ListingView.tsx +179 -63
@@ -29,15 +29,24 @@ import {
29
29
  import { TabsStyles } from "../style";
30
30
  import InfoAlert from "../common/info-alert";
31
31
  import { useFullscreenPopoverContainer } from "../../../libs/hooks/useFullScreen";
32
+ import { ColumnItem } from "./column";
32
33
 
33
34
  const QuickTab = ({
34
35
  filterSettingStates,
35
36
  columnsData,
36
37
  tabsApiData,
37
38
  tabsApiDataLoading,
39
+ activeTab,
40
+ columnTabAttributes,
38
41
  }: SettingsQuickTabProps) => {
39
- const { settingsData, setSettingsData, saveButtonError, setSaveButtonError } =
40
- filterSettingStates;
42
+ const {
43
+ settingsData,
44
+ setSettingsData,
45
+ saveButtonError,
46
+ setSaveButtonError,
47
+ columnTabState,
48
+ sortingTabState,
49
+ } = filterSettingStates;
41
50
  const { container: fullscreenContainer } = useFullscreenPopoverContainer();
42
51
 
43
52
  const [searchTerm, setSearchTerm] = useState<string>("");
@@ -46,7 +55,15 @@ const QuickTab = ({
46
55
  );
47
56
 
48
57
  const quickTabStates = settingsData?.quick_tab as QuickTabConfigProps;
49
-
58
+ const mappedColumns: ColumnItem[] =
59
+ columnTabAttributes?.map((column) => ({
60
+ label: column?.name,
61
+ value: column?.attribute_key,
62
+ })) || [];
63
+ // const activeTabIndex = filterSettingStates?.columnTabState?.tabs?.findIndex(
64
+ // (tab) => tab?.tab_name?.value == activeTab
65
+ // // tab?.tab_name?.label?.toLowerCase() == activeTab?.toLowerCase()
66
+ // );
50
67
  // In case there is no quick tab state from API
51
68
  useEffect(() => {
52
69
  const stateToArray =
@@ -169,82 +186,240 @@ const QuickTab = ({
169
186
  // Drag and drop logic, update only local state
170
187
  const handleDragEnd = (event: DragEndEvent) => {
171
188
  const { active, over } = event;
172
- if (!over) {
173
- return;
174
- }
189
+ if (!over) return;
190
+
175
191
  const currentContainer = active.data.current?.containerId;
176
192
  const overContainer = over.data.current?.containerId;
193
+
177
194
  if (!currentContainer || !overContainer) return;
195
+
196
+ let newShowList = [...(quickTabStates.show_list ?? [])];
197
+ let newHideList = [...(quickTabStates.hide_list ?? [])];
198
+
199
+ // -------------------------------------
200
+ // CASE 1: REORDER INSIDE SAME LIST
201
+ // -------------------------------------
178
202
  if (currentContainer === overContainer) {
179
- // Reorder within the same list
180
- let newShowList = [...(quickTabStates.show_list ?? [])];
181
- let newHideList = [...(quickTabStates.hide_list ?? [])];
182
203
  if (currentContainer === "list") {
183
- // const oldIndex = newHideList.indexOf(String(active.id));
184
204
  const oldIndex = newHideList.findIndex((i) => i.value === active.id);
185
- const newIndex = newHideList.findIndex((i) => i.value === over.id); //newHideList.indexOf(String(over.id));
205
+ const newIndex = newHideList.findIndex((i) => i.value === over.id);
206
+
186
207
  if (oldIndex !== -1 && newIndex !== -1) {
187
208
  const [removed] = newHideList.splice(oldIndex, 1);
188
209
  newHideList.splice(newIndex, 0, removed);
189
210
  }
190
211
  } else {
191
- const oldIndex = newShowList.findIndex((i) => i.value === active.id); //newShowList.indexOf(String(active.id));
192
- const newIndex = newShowList.findIndex((i) => i.value === over.id); //newShowList.indexOf(String(over.id));
212
+ const oldIndex = newShowList.findIndex((i) => i.value === active.id);
213
+ const newIndex = newShowList.findIndex((i) => i.value === over.id);
214
+
193
215
  if (oldIndex !== -1 && newIndex !== -1) {
194
216
  const [removed] = newShowList.splice(oldIndex, 1);
195
217
  newShowList.splice(newIndex, 0, removed);
196
218
  }
197
219
  }
220
+ }
198
221
 
199
- setSettingsData((prev) => ({
200
- ...prev,
201
- quick_tab: {
202
- ...prev?.quick_tab,
203
- show_list: newShowList,
204
- hide_list: newHideList,
205
- },
206
- }));
207
- } else {
208
- // Move between lists
209
- let newShowList = [...(quickTabStates.show_list ?? [])];
210
- let newHideList = [...(quickTabStates.hide_list ?? [])];
222
+ // -------------------------------------
223
+ // CASE 2: MOVE BETWEEN LISTS
224
+ // -------------------------------------
225
+ if (currentContainer !== overContainer) {
211
226
  if (currentContainer === "list" && overContainer === "tabs") {
212
- if (newShowList.length >= 5) return; // prevent overflow
213
- // Move from hide to show
214
-
215
- const idx = newHideList.findIndex((i) => i.value === String(active.id)); //newHideList.indexOf(String(active.id));
216
- if (idx !== -1) {
217
- newHideList.splice(idx, 1);
218
- newShowList.push({
219
- value: String(active.id),
220
- label:
221
- tabsApiData?.find((i) => i.value === String(active.id))?.label ??
222
- "",
223
- });
227
+ if (newShowList.length < 5) {
228
+ const idx = newHideList.findIndex(
229
+ (i) => i.value === String(active.id)
230
+ );
231
+ if (idx !== -1) {
232
+ const item = newHideList.splice(idx, 1)[0];
233
+ newShowList.push(item);
234
+
235
+ // 🌟 ALSO create sorting tab entry if missing
236
+ // if (!settingsData?.sorting?.isDefault) {
237
+ // const exists = settingsData.sorting?.tabs?.some(
238
+ // (t) => t.tab_name.value === item.value
239
+ // );
240
+
241
+ // if (!exists) {
242
+ // settingsData?.sorting.tabs.push({
243
+ // tab_name: item,
244
+ // sortby: [{ column: "", order: "asc" }],
245
+ // });
246
+ // }
247
+ // }
248
+
249
+ setSettingsData((prev) => {
250
+ let updatedSorting = prev.sorting;
251
+ let updatedColumn = prev.column;
252
+
253
+ // ---------------------------------------------------
254
+ // ⭐ Add to sorting.tabs (if not default and not exist)
255
+ // ---------------------------------------------------
256
+ if (!prev?.sorting?.isDefault) {
257
+ const sortingExists = prev.sorting?.tabs?.some(
258
+ (t) => t.tab_name.value === item.value
259
+ );
260
+
261
+ if (!sortingExists) {
262
+ updatedSorting = {
263
+ ...prev.sorting,
264
+ tabs: [
265
+ ...prev.sorting.tabs,
266
+ {
267
+ tab_name: item,
268
+ sortby: [],
269
+ },
270
+ ],
271
+ };
272
+ }
273
+ }
274
+
275
+ // ---------------------------------------------------
276
+ // ⭐ Add to column.tabs (if not default and not exist)
277
+ // ---------------------------------------------------
278
+ if (!prev?.column?.isDefault) {
279
+ const columnExists = prev.column?.tabs?.some(
280
+ (t) => t.tab_name.value === item.value
281
+ );
282
+
283
+ if (!columnExists) {
284
+ updatedColumn = {
285
+ ...prev.column,
286
+ tabs: [
287
+ ...prev.column.tabs,
288
+ {
289
+ tab_name: item,
290
+ show_list: mappedColumns,
291
+ hide_list: [],
292
+ },
293
+ ],
294
+ };
295
+ }
296
+ }
297
+
298
+ // ---------------------------------------------------
299
+ // ⭐ FINAL RETURN
300
+ // ---------------------------------------------------
301
+ return {
302
+ ...prev,
303
+ sorting: updatedSorting,
304
+ column: updatedColumn,
305
+ };
306
+ });
307
+ }
224
308
  }
225
309
  } else if (currentContainer === "tabs" && overContainer === "list") {
226
- // Move from show to hide
227
- const idx = newShowList.findIndex((i) => i.value === String(active.id)); //newShowList.indexOf(String(active.id));
310
+ const idx = newShowList.findIndex((i) => i.value === String(active.id));
228
311
  if (idx !== -1) {
229
- newShowList.splice(idx, 1);
230
- newHideList.push({
231
- value: String(active.id),
232
- label:
233
- tabsApiData?.find((i) => i.value === String(active.id))?.label ??
234
- "",
312
+ const item = newShowList.splice(idx, 1)[0];
313
+ newHideList.push(item);
314
+ setSettingsData((prev) => {
315
+ let updatedSorting = prev.sorting;
316
+ let updatedColumn = prev.column;
317
+
318
+ // ---------------------------------------------------
319
+ // Remove from sorting.tabs (if not default)
320
+ // ---------------------------------------------------
321
+ if (!prev?.sorting?.isDefault) {
322
+ updatedSorting = {
323
+ ...prev.sorting,
324
+ tabs: prev?.sorting?.tabs?.filter(
325
+ (t) => t.tab_name?.value !== item?.value
326
+ ),
327
+ };
328
+ }
329
+
330
+ // ---------------------------------------------------
331
+ // Remove from column.tabs (if not default)
332
+ // ---------------------------------------------------
333
+ if (!prev?.column?.isDefault) {
334
+ updatedColumn = {
335
+ ...prev.column,
336
+ tabs: prev?.column?.tabs?.filter(
337
+ (t) => t.tab_name?.value !== item?.value
338
+ ),
339
+ };
340
+ }
341
+
342
+ // ---------------------------------------------------
343
+ // ⭐ FINAL RETURN
344
+ // ---------------------------------------------------
345
+ return {
346
+ ...prev,
347
+ sorting: updatedSorting,
348
+ column: updatedColumn,
349
+ };
235
350
  });
236
351
  }
237
352
  }
353
+ }
238
354
 
239
- setSettingsData((prev) => ({
355
+ // ----------------------------------------------------------
356
+ // ⭐ APPLY MASTER UPDATE (with isDefault CHECK for columns)
357
+ // ----------------------------------------------------------
358
+ setSettingsData((prev) => {
359
+ let updatedColumn = prev.column;
360
+
361
+ // -----------------------------------------
362
+ // ⭐ COLUMN REORDER (only if NOT default)
363
+ // -----------------------------------------
364
+ if (!prev?.column?.isDefault) {
365
+ updatedColumn = {
366
+ ...prev.column,
367
+ tabs: prev.column?.tabs
368
+ ? [...prev.column.tabs].sort((a, b) => {
369
+ const i1 = newShowList.findIndex(
370
+ (t) => t.value === a.tab_name.value
371
+ );
372
+ const i2 = newShowList.findIndex(
373
+ (t) => t.value === b.tab_name.value
374
+ );
375
+ return i1 - i2;
376
+ })
377
+ : [],
378
+ };
379
+ }
380
+
381
+ // -----------------------------------------
382
+ // ⭐ SORTING REORDER (same pattern as column)
383
+ // -----------------------------------------
384
+ const updatedSorting = (() => {
385
+ // If default → clear tabs
386
+ if (prev.sorting?.isDefault) {
387
+ return {
388
+ isDefault: true,
389
+ sort_by: prev.sorting?.sort_by || "asc",
390
+ };
391
+ }
392
+
393
+ // If custom → reorder tabs based on newShowList
394
+ const sorted = {
395
+ ...prev.sorting,
396
+ tabs: prev.sorting?.tabs
397
+ ? [...prev.sorting.tabs].sort((a, b) => {
398
+ const i1 = newShowList.findIndex(
399
+ (t) => t.value === a.tab_name.value
400
+ );
401
+ const i2 = newShowList.findIndex(
402
+ (t) => t.value === b.tab_name.value
403
+ );
404
+ return i1 - i2;
405
+ })
406
+ : [],
407
+ };
408
+ return sorted;
409
+ })();
410
+
411
+ // FINAL RETURN
412
+ return {
240
413
  ...prev,
241
414
  quick_tab: {
242
- ...prev?.quick_tab,
415
+ ...prev.quick_tab,
243
416
  show_list: newShowList,
244
417
  hide_list: newHideList,
245
418
  },
246
- }));
247
- }
419
+ column: updatedColumn,
420
+ sorting: updatedSorting,
421
+ };
422
+ });
248
423
  };
249
424
 
250
425
  const filteredListValues = hideListValues.filter((value) =>
@@ -275,17 +450,67 @@ const QuickTab = ({
275
450
  };
276
451
 
277
452
  const handleHideAll = () => {
278
- setSettingsData((prev) => ({
279
- ...prev,
280
- quick_tab: {
453
+ setSettingsData((prev) => {
454
+ const updatedQuickTab = {
281
455
  ...prev?.quick_tab,
282
456
  hide_list: [
283
457
  ...(prev?.quick_tab?.hide_list || []),
284
458
  ...(prev?.quick_tab?.show_list || []),
285
459
  ],
286
460
  show_list: [],
287
- },
288
- }));
461
+ };
462
+
463
+ // Reset only the lists, not the whole structure
464
+ const updatedColumn = (() => {
465
+ if (prev?.column?.isDefault) {
466
+ return {
467
+ ...prev.column,
468
+ show_list: [],
469
+ hide_list: [
470
+ ...(prev.column?.hide_list || []),
471
+ ...(prev.column?.show_list || []),
472
+ ],
473
+ };
474
+ }
475
+
476
+ // Tab mode → reset each tab's field lists
477
+ const updatedTabs = prev?.column?.tabs?.map((t) => ({
478
+ ...t,
479
+ show_list: [],
480
+ hide_list: [...(t.hide_list || []), ...(t.show_list || [])],
481
+ }));
482
+
483
+ return {
484
+ ...prev.column,
485
+ tabs: updatedTabs,
486
+ };
487
+ })();
488
+
489
+ const updatedSorting = (() => {
490
+ // DEFAULT MODE: sorting applies globally
491
+ if (prev.sorting?.isDefault) {
492
+ return {
493
+ ...prev.sorting,
494
+ sortby: [], // reset sort
495
+ };
496
+ }
497
+
498
+ // TAB MODE: need to clear sorting per tab
499
+ return {
500
+ ...prev.sorting,
501
+ tabs: prev.quick_tab?.show_list?.map(() => ({
502
+ sortby: [],
503
+ })),
504
+ };
505
+ })();
506
+
507
+ return {
508
+ ...prev,
509
+ quick_tab: updatedQuickTab,
510
+ column: updatedColumn,
511
+ sorting: updatedSorting,
512
+ };
513
+ });
289
514
  };
290
515
 
291
516
  // Checkbox logic (local only)
@@ -317,31 +542,104 @@ const QuickTab = ({
317
542
  const toShowList = [...(quickTabStates.show_list ?? [])];
318
543
  const toHideList = [...(quickTabStates.hide_list ?? [])];
319
544
 
320
- if (fromContainerId === "list") {
321
- if (toShowList.length >= 5) return; // prevent overflow
322
- // Move from hide_list to show_list
323
- const index = toHideList.findIndex((i) => i.value == item.value);
324
- if (index > -1) {
325
- toHideList.splice(index, 1);
326
- toShowList.push(item);
327
- }
328
- } else if (fromContainerId === "tabs") {
329
- // Move from show_list to hide_list
330
- const index = toShowList.indexOf(item);
331
- if (index > -1) {
332
- toShowList.splice(index, 1);
333
- toHideList.push(item);
545
+ setSettingsData((prev) => {
546
+ let updatedColumn = prev.column; // default (unchanged)
547
+ let updatedSorting = prev.sorting;
548
+
549
+ if (fromContainerId === "list") {
550
+ if (toShowList.length >= 5) return prev;
551
+
552
+ const index = toHideList.findIndex((i) => i.value == item.value);
553
+ if (index > -1) {
554
+ toHideList.splice(index, 1);
555
+ toShowList.push(item);
556
+ // 🌟 ALSO create sorting tab entry if missing
557
+ if (!sortingTabState?.isDefault) {
558
+ const exists = prev.sorting?.tabs?.some(
559
+ (t) => t.tab_name.value === item.value
560
+ );
561
+ if (!exists) {
562
+ updatedSorting = {
563
+ ...prev.sorting,
564
+ tabs: [
565
+ ...prev.sorting.tabs,
566
+ {
567
+ tab_name: {
568
+ label: item.label,
569
+ value: item.value,
570
+ },
571
+ sortby: [],
572
+ },
573
+ ],
574
+ };
575
+ }
576
+ }
577
+ if (!columnTabState?.isDefault) {
578
+ const exists = prev?.column?.tabs?.some(
579
+ (t) => t.tab_name.value === item.value
580
+ );
581
+ if (!exists) {
582
+ updatedColumn = {
583
+ ...prev.column,
584
+ tabs: [
585
+ ...prev.column.tabs,
586
+ {
587
+ tab_name: {
588
+ label: item.label,
589
+ value: item.value,
590
+ },
591
+ show_list: mappedColumns,
592
+ hide_list: [],
593
+ },
594
+ ],
595
+ };
596
+ }
597
+ }
598
+ }
599
+ } else if (fromContainerId === "tabs") {
600
+ const index = toShowList.findIndex((i) => i.value == item.value);
601
+ if (index > -1) {
602
+ toShowList.splice(index, 1);
603
+ toHideList.push(item);
604
+ // let itemIndex =
605
+ // filterSettingStates?.quickTabStates?.show_list?.findIndex(
606
+ // (i) => i.value == item.value
607
+ // );
608
+ // 🔥 REMOVE COLUMN WHEN TAB REMOVED (if not default)
609
+ if (!columnTabState?.isDefault) {
610
+ const updatedTabs = prev?.column?.tabs.filter(
611
+ (tab) => tab.tab_name?.value !== item.value
612
+ );
613
+
614
+ updatedColumn = {
615
+ ...prev.column,
616
+ tabs: updatedTabs,
617
+ };
618
+ }
619
+
620
+ if (!sortingTabState.isDefault) {
621
+ const updatedSortingTabs = prev?.sorting?.tabs?.filter(
622
+ (tab) => tab.tab_name?.value != item.value
623
+ );
624
+ updatedSorting = {
625
+ ...prev.sorting,
626
+ tabs: updatedSortingTabs,
627
+ };
628
+ }
629
+ }
334
630
  }
335
- }
336
631
 
337
- setSettingsData((prev) => ({
338
- ...prev,
339
- quick_tab: {
340
- ...prev?.quick_tab,
341
- show_list: toShowList,
342
- hide_list: toHideList,
343
- },
344
- }));
632
+ return {
633
+ ...prev,
634
+ quick_tab: {
635
+ ...prev?.quick_tab,
636
+ show_list: toShowList,
637
+ hide_list: toHideList,
638
+ },
639
+ column: updatedColumn,
640
+ sorting: updatedSorting,
641
+ };
642
+ });
345
643
  };
346
644
 
347
645
  const enableDND = quickTabStates?.sorting === "custom" ? true : false;
@@ -373,6 +671,26 @@ const QuickTab = ({
373
671
  ...prev?.quick_tab,
374
672
  attribute: e.target.value,
375
673
  },
674
+ // column: prev.column?.isDefault
675
+ // ? {
676
+ // ...prev.column,
677
+ // show_list: mappedColumns,
678
+ // hide_list: [],
679
+ // }
680
+ // : {
681
+ // ...prev.column,
682
+ // tabs: [],
683
+ // },
684
+
685
+ // sorting: prev.sorting?.isDefault
686
+ // ? {
687
+ // ...prev.sorting,
688
+ // sortby: [],
689
+ // }
690
+ // : {
691
+ // ...prev.sorting,
692
+ // tabs: [],
693
+ // },
376
694
  }))
377
695
  }
378
696
  MenuProps={{ container: fullscreenContainer }}