rez-table-listing-mui 2.0.13 → 2.0.14

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.
@@ -0,0 +1,240 @@
1
+ import React, { useEffect, useState } from "react";
2
+ import {
3
+ Box,
4
+ Select,
5
+ MenuItem,
6
+ FormControl,
7
+ Typography,
8
+ Grid,
9
+ } from "@mui/material";
10
+
11
+ import ListingValues from "../common/listing-values";
12
+ import {
13
+ DndContext,
14
+ closestCenter,
15
+ KeyboardSensor,
16
+ MouseSensor,
17
+ TouchSensor,
18
+ useSensor,
19
+ useSensors,
20
+ DragEndEvent,
21
+ } from "@dnd-kit/core";
22
+ import { TabsStyles } from "../style";
23
+ import { craftTableFilterSettingsOptionsProps } from "../../../types/table-options";
24
+ import { LANE_SELECTS } from "../constants";
25
+
26
+ const GroupBy = ({
27
+ filterSettingStates,
28
+ columnsData,
29
+ tabsApiData,
30
+ tabsApiDataLoading,
31
+ }: {
32
+ filterSettingStates: craftTableFilterSettingsOptionsProps;
33
+ columnsData: any;
34
+ tabsApiData?: any[];
35
+ tabsApiDataLoading?: boolean;
36
+ }) => {
37
+ const { settingsData, setSettingsData } = filterSettingStates;
38
+
39
+ const quickTabStates = settingsData?.quick_tab as any;
40
+ const [searchTerm, setSearchTerm] = useState("");
41
+
42
+ const isStatus = quickTabStates?.attribute === "Status";
43
+ const enableDND =
44
+ quickTabStates?.attribute === "Source" &&
45
+ quickTabStates?.sorting === "custom";
46
+
47
+ const sensors = useSensors(
48
+ useSensor(MouseSensor),
49
+ useSensor(TouchSensor),
50
+ useSensor(KeyboardSensor)
51
+ );
52
+
53
+ useEffect(() => {
54
+ if (!quickTabStates || !quickTabStates.attribute) {
55
+ setSettingsData((prev) => ({
56
+ ...prev,
57
+ quick_tab: {
58
+ attribute: "Status",
59
+ sorting: "asc",
60
+ show_list: [],
61
+ hide_list: [],
62
+ },
63
+ }));
64
+ }
65
+ }, []);
66
+
67
+ useEffect(() => {
68
+ if (!tabsApiData) return;
69
+
70
+ setSettingsData((prev) => ({
71
+ ...prev,
72
+ quick_tab: {
73
+ ...prev.quick_tab,
74
+ hide_list: tabsApiData,
75
+ show_list: [],
76
+ sorting: quickTabStates?.attribute === "Source" ? "count_dsc" : "asc",
77
+ },
78
+ }));
79
+ }, [quickTabStates?.attribute]);
80
+
81
+ /* Drag logic unchanged */
82
+ const handleDragEnd = (event: DragEndEvent) => {
83
+ const { active, over } = event;
84
+ if (!over) return;
85
+
86
+ const from = active.data.current?.containerId;
87
+ const to = over.data.current?.containerId;
88
+ if (!from || !to) return;
89
+
90
+ const showList = [...(quickTabStates.show_list ?? [])];
91
+ const hideList = [...(quickTabStates.hide_list ?? [])];
92
+
93
+ if (from === to) {
94
+ const list = from === "lanes" ? showList : hideList;
95
+ const oldIndex = list.indexOf(String(active.id));
96
+ const newIndex = list.indexOf(String(over.id));
97
+ if (oldIndex !== -1 && newIndex !== -1) {
98
+ const [moved] = list.splice(oldIndex, 1);
99
+ list.splice(newIndex, 0, moved);
100
+ }
101
+ } else {
102
+ if (from === "list" && to === "lanes") {
103
+ hideList.splice(hideList.indexOf(String(active.id)), 1);
104
+ showList.push(String(active.id));
105
+ }
106
+ if (from === "lanes" && to === "list") {
107
+ showList.splice(showList.indexOf(String(active.id)), 1);
108
+ hideList.push(String(active.id));
109
+ }
110
+ }
111
+
112
+ setSettingsData((prev) => ({
113
+ ...prev,
114
+ quick_tab: {
115
+ ...prev.quick_tab,
116
+ show_list: showList,
117
+ hide_list: hideList,
118
+ },
119
+ }));
120
+ };
121
+
122
+ const handleItemToggle = (itemId: string, fromContainerId: string) => {
123
+ const showList = [...(quickTabStates.show_list ?? [])];
124
+ const hideList = [...(quickTabStates.hide_list ?? [])];
125
+
126
+ if (fromContainerId === "list") {
127
+ hideList.splice(hideList.indexOf(itemId), 1);
128
+ showList.push(itemId);
129
+ } else {
130
+ showList.splice(showList.indexOf(itemId), 1);
131
+ hideList.push(itemId);
132
+ }
133
+
134
+ setSettingsData((prev) => ({
135
+ ...prev,
136
+ quick_tab: {
137
+ ...prev.quick_tab,
138
+ show_list: showList,
139
+ hide_list: hideList,
140
+ },
141
+ }));
142
+ };
143
+
144
+ const sortingOptions = [
145
+ { label: "A-Z", value: "asc" },
146
+ { label: "Z-A", value: "dsc" },
147
+ { label: "Count (Ascending)", value: "count_asc" },
148
+ { label: "Count (Descending)", value: "count_dsc" },
149
+ { label: "Custom", value: "custom" },
150
+ ];
151
+
152
+ return (
153
+ <Box sx={{ display: "flex", flexDirection: "column", height: "100%" }}>
154
+ <Typography variant="caption" sx={TabsStyles.mainTabsHeader}>
155
+ **Swim Lane settings will be reflected in vertical lanes
156
+ </Typography>
157
+
158
+ <Grid sx={{ position: "relative" }} container>
159
+ <Grid size={12}>
160
+ <Grid sx={TabsStyles.mainTabDropdown} size={6}>
161
+ <FormControl sx={TabsStyles.mainTabSelect} size="small">
162
+ <Select
163
+ value={quickTabStates?.attribute || ""}
164
+ onChange={(e) =>
165
+ setSettingsData((prev) => ({
166
+ ...prev,
167
+ quick_tab: {
168
+ ...prev.quick_tab,
169
+ attribute: e.target.value,
170
+ },
171
+ }))
172
+ }
173
+ >
174
+ {LANE_SELECTS?.map((lane: any) => (
175
+ <MenuItem key={lane?.key} value={lane?.value}>
176
+ {lane?.value}
177
+ </MenuItem>
178
+ ))}
179
+ </Select>
180
+ </FormControl>
181
+
182
+ <FormControl sx={TabsStyles.selectDropdownSeparator} size="small">
183
+ <Select
184
+ disabled={isStatus}
185
+ value={quickTabStates?.sorting}
186
+ onChange={(e) =>
187
+ setSettingsData((prev) => ({
188
+ ...prev,
189
+ quick_tab: {
190
+ ...prev.quick_tab,
191
+ sorting: e.target.value,
192
+ },
193
+ }))
194
+ }
195
+ >
196
+ {!isStatus &&
197
+ sortingOptions.map((opt) => (
198
+ <MenuItem key={opt.value} value={opt.value}>
199
+ {opt.label}
200
+ </MenuItem>
201
+ ))}
202
+ </Select>
203
+ </FormControl>
204
+ </Grid>
205
+ </Grid>
206
+
207
+ <DndContext
208
+ sensors={sensors}
209
+ collisionDetection={closestCenter}
210
+ onDragEnd={handleDragEnd}
211
+ >
212
+ <Grid sx={{ mt: 2 }} container spacing={2} size={12}>
213
+ <ListingValues
214
+ buttonText="Show All"
215
+ headerText="List of Values"
216
+ filteredValues={quickTabStates?.hide_list || []}
217
+ searchTerm={searchTerm}
218
+ setSearchTerm={setSearchTerm}
219
+ containerId="list"
220
+ tabsApiDataLoading={tabsApiDataLoading}
221
+ onItemToggle={handleItemToggle}
222
+ enableDragAndDrop={enableDND}
223
+ />
224
+
225
+ <ListingValues
226
+ buttonText="Hide All"
227
+ headerText="View as Lanes"
228
+ filteredValues={quickTabStates?.show_list || []}
229
+ containerId="lanes"
230
+ onItemToggle={handleItemToggle}
231
+ enableDragAndDrop={enableDND}
232
+ />
233
+ </Grid>
234
+ </DndContext>
235
+ </Grid>
236
+ </Box>
237
+ );
238
+ };
239
+
240
+ export default GroupBy;
@@ -8,7 +8,7 @@ export const SETTINGS_TABS: { label: string }[] = [
8
8
 
9
9
  export const KANBAN_SETTINGS_TABS: { label: string }[] = [
10
10
  { label: "Lane" },
11
- { label: "Group By" },
11
+ { label: "Swim Lane" },
12
12
  ];
13
13
 
14
14
  export const LANE_SELECTS = [
@@ -22,3 +22,4 @@ export const TOGGLE_BUTTON_TABS: ToggleButtonTabsProps[] = [
22
22
  { label: "Default", value: true, isDisabled: false },
23
23
  { label: "Tab Wise", value: false, isDisabled: false },
24
24
  ];
25
+
@@ -20,7 +20,7 @@ import CustomButton from "./components/custom-button";
20
20
  import { KANBAN_SETTINGS_TABS, SETTINGS_TABS } from "./constants";
21
21
  import Loader from "../common/loader/loader";
22
22
  import Lane from "./components/lane";
23
- import GroupBy from "./components/group-by";
23
+ import GroupBy from "./components/swim-lane";
24
24
  import { useFullscreenPopoverContainer } from "../../libs/hooks/useFullScreen";
25
25
 
26
26
  export function QuickFilterSettings({
@@ -41,6 +41,8 @@ export function QuickFilterSettings({
41
41
  tabsApiDataLoading,
42
42
  onSaveSettingsData,
43
43
  activeTab,
44
+ selectAttributeData,
45
+ selectSwinLandData,
44
46
  }: QuickFilterModalProps) {
45
47
  const [tabValue, setTabValue] = useState(0);
46
48
  const { container: fullscreenContainer } = useFullscreenPopoverContainer();
@@ -66,27 +68,27 @@ export function QuickFilterSettings({
66
68
  };
67
69
 
68
70
  const handleSaveSetSettingsData = () => {
69
- const copyColumnTabState = columnTabState?.isDefault
70
- ? {
71
- isDefault: true,
72
- show_list: columnTabState?.show_list || [],
73
- hide_list: columnTabState?.hide_list || [],
74
- }
75
- : {
76
- isDefault: false,
77
- tabs: columnTabState?.tabs || [],
78
- };
79
-
80
- const copySortingTabState = sortingTabState?.isDefault
81
- ? {
82
- isDefault: true,
83
- sortby:
84
- sortingTabState?.sortby?.filter((item) => item.column !== "") || [],
85
- }
86
- : {
87
- isDefault: false,
88
- tabs: sortingTabState?.tabs || [],
89
- };
71
+ const copyColumnTabState = {
72
+ isDefault: columnTabState?.isDefault,
73
+ show_list: columnTabState?.show_list || [],
74
+ hide_list: columnTabState?.hide_list || [],
75
+ tabs: columnTabState?.tabs || [],
76
+ };
77
+ // : {
78
+ // isDefault: false,
79
+ // tabs: columnTabState?.tabs || [],
80
+ // };
81
+ // commented as per the requirement
82
+ const copySortingTabState = {
83
+ isDefault: sortingTabState?.isDefault,
84
+ sortby:
85
+ sortingTabState?.sortby?.filter((item) => item.column !== "") || [],
86
+ tabs: sortingTabState?.tabs || [],
87
+ };
88
+ // : {
89
+ // isDefault: false,
90
+ // tabs: sortingTabState?.tabs || [],
91
+ // };
90
92
 
91
93
  const modifiedSettingsData = {
92
94
  quick_tab: quickTabStates,
@@ -109,7 +111,12 @@ export function QuickFilterSettings({
109
111
  container={fullscreenContainer}
110
112
  >
111
113
  <DialogTitle sx={dialogStyles.dialogTitle}>
112
- <Typography sx={{ fontSize: "1.125rem" }}>List View Setting</Typography>
114
+ <Typography sx={{ fontSize: "1.125rem" }}>
115
+ {view === "listing"
116
+ ? "Quick Filter Settings"
117
+ : "Kanban View Settings"}
118
+ </Typography>
119
+
113
120
  <IconButton
114
121
  size="small"
115
122
  color="inherit"
@@ -182,6 +189,7 @@ export function QuickFilterSettings({
182
189
  <Lane
183
190
  filterSettingStates={filterSettingStates}
184
191
  columnsData={columnsData}
192
+ selectAttributeData={selectAttributeData}
185
193
  />
186
194
  )}
187
195
  </CustomTabPanel>
@@ -193,6 +201,7 @@ export function QuickFilterSettings({
193
201
  <GroupBy
194
202
  filterSettingStates={filterSettingStates}
195
203
  columnsData={columnsData}
204
+ selectSwinLandData={selectSwinLandData}
196
205
  />
197
206
  )}
198
207
  </CustomTabPanel>
@@ -203,15 +212,33 @@ export function QuickFilterSettings({
203
212
  </DialogContent>
204
213
 
205
214
  {!columnsDataLoading && hasAPIData && (
215
+ // <DialogActions>
216
+ // <CustomButton
217
+ // // disabled={saveButtonError?.hasError}
218
+ // // disabled={saveButtonError?.hasError}
219
+ // disabled={disbaledCondition}
220
+ // onClick={handleSaveSetSettingsData}
221
+ // >
222
+ // {view === "listing" ? "Save Quick Filter" : "Save Kanban Layout"}
223
+ // </CustomButton>
224
+ // </DialogActions>
206
225
  <DialogActions>
207
- <CustomButton
208
- // disabled={saveButtonError?.hasError}
209
- // disabled={saveButtonError?.hasError}
210
- disabled={disbaledCondition}
211
- onClick={handleSaveSetSettingsData}
212
- >
213
- {view === "listing" ? "Save Quick Filter" : "Save Kanban Layout"}
214
- </CustomButton>
226
+ {view === "kanban" && tabValue === 0 && (
227
+ <>
228
+ <CustomButton onClick={handleSaveSetSettingsData}>
229
+ Save & Close
230
+ </CustomButton>
231
+ <CustomButton onClick={() => setTabValue(1)} variant="contained">
232
+ Next
233
+ </CustomButton>
234
+ </>
235
+ )}
236
+
237
+ {view === "kanban" && tabValue === 1 && (
238
+ <CustomButton onClick={handleSaveSetSettingsData}>
239
+ Save
240
+ </CustomButton>
241
+ )}
215
242
  </DialogActions>
216
243
  )}
217
244
  </CustomDialog>
@@ -4,7 +4,12 @@ import {
4
4
  useQuery,
5
5
  useQueryClient,
6
6
  } from "@tanstack/react-query";
7
- import { api, ENTITY_TYPE, MAPPED_ENTITY_TYPE } from "../utils/common";
7
+ import {
8
+ api,
9
+ APP_CODE,
10
+ ENTITY_TYPE,
11
+ MAPPED_ENTITY_TYPE,
12
+ } from "../utils/common";
8
13
  import {
9
14
  APIParamsProps,
10
15
  EntityListingResponse,
@@ -62,7 +67,7 @@ const entityListingCall = async ({
62
67
  responseStatus: number;
63
68
  data: EntityListingResponse;
64
69
  }> => {
65
- const url = `filter/adm`;
70
+ const url = `filter/${APP_CODE}`;
66
71
 
67
72
  const body = {
68
73
  entity_type,
@@ -102,6 +107,7 @@ export const useEntityTableAPI = ({
102
107
  ],
103
108
  attributeFilter = [],
104
109
  flatJson,
110
+ module_code,
105
111
  }: EntityTableAPIProps) => {
106
112
  const { data, isPending: isTableDataPending } = useQuery({
107
113
  queryKey: ["entityTable", page, size, tabs, quickFilter],
@@ -1,4 +1,4 @@
1
- import { api, MAPPED_ENTITY_TYPE } from "./common";
1
+ import { api, APP_CODE, MAPPED_ENTITY_TYPE } from "./common";
2
2
  import {
3
3
  createSavedFilterPayload,
4
4
  deleteSavedFilterPayload,
@@ -225,7 +225,7 @@ export const getAttributes = async (
225
225
  };
226
226
 
227
227
  export const getTableTabs = async (payload: any) => {
228
- const response = await api.post(`filter/adm/tabs`, payload);
228
+ const response = await api.post(`filter/${APP_CODE}/tabs`, payload);
229
229
  return response.data;
230
230
  };
231
231
 
@@ -263,3 +263,49 @@ export const newCommonGetDropdownDataAPI = async ({
263
263
  .post(`entity/getAttributeDropdown${queryString}`, requestBody)
264
264
  .then((response) => response.data);
265
265
  };
266
+
267
+ export const commonFetchDropdownDataAPI = async ({
268
+ entity_type,
269
+ enterprise_id,
270
+ data,
271
+ inactiveIds,
272
+ parentId,
273
+ }: {
274
+ entity_type: string | undefined;
275
+ enterprise_id?: string | null;
276
+ data?: any;
277
+ inactiveIds?: string | null;
278
+ parentId?: number | string;
279
+ }) => {
280
+ const requestBody = {
281
+ // status: "ACTIVE",
282
+ enterprise_id,
283
+ ...data,
284
+ };
285
+
286
+ let params = "";
287
+
288
+ const queryParams: string[] = [];
289
+
290
+ if (!Number.isNaN(Number(inactiveIds)) && inactiveIds) {
291
+ queryParams.push(`inactiveIds=${inactiveIds}`);
292
+ }
293
+
294
+ if (parentId !== undefined && parentId !== null) {
295
+ queryParams.push(`parent=${parentId}`);
296
+ }
297
+
298
+ if (queryParams.length > 0) {
299
+ params = `?${queryParams.join("&")}`;
300
+ }
301
+ // if (entity_type === "ORGP") {
302
+ // return await api.get(`organization/sso/getdropdown`).then((response) => {
303
+ // return response.data;
304
+ // });
305
+ // }
306
+ return await api
307
+ .post(`entity/getListMasterDropdown/${entity_type}${params}`, requestBody)
308
+ .then((response) => {
309
+ return response.data;
310
+ });
311
+ };
@@ -77,14 +77,16 @@ export function customDebounce<T extends (...args: any[]) => any>(
77
77
  }
78
78
 
79
79
  //ENTITY TYPE
80
- const ENVIRONMENT = "adm_dev";
81
- export const ENTITY_TYPE = "SCH";
80
+ const ENVIRONMENT = "crm_dev";
81
+ export const ENTITY_TYPE = "LEAD";
82
+ export const MODULE_CODE = "school_adm_org";
82
83
  export const MAPPED_ENTITY_TYPE = "LYPR"; // LAP OR LYPR
83
84
  export const USER_ID = 226;
85
+ export const APP_CODE = "crm";
84
86
 
85
87
  const environments = {
86
88
  adm_dev: "http://localhost:6010/api",
87
- crm_dev: "http://localhost:4011/api",
89
+ crm_dev: "http://localhost:6011/api",
88
90
  uat: "https://api.eth-qa.rezolut.in/api/enrol",
89
91
  };
90
92
 
@@ -65,6 +65,7 @@ export interface EntityTableAPIProps {
65
65
  filter_value: string[] | string;
66
66
  }[];
67
67
  flatJson: boolean;
68
+ module_code?: string;
68
69
  }
69
70
 
70
71
  export interface viewSettingsDropDownAPIProps {
@@ -19,6 +19,8 @@ export interface QuickFilterModalProps {
19
19
  tabsApiDataLoading?: boolean;
20
20
  onSaveSettingsData?: (data: any) => void;
21
21
  activeTab?: string;
22
+ selectAttributeData?: { label: string; value: string }[];
23
+ selectSwinLandData?: { label: string; value: string }[];
22
24
  }
23
25
 
24
26
  type TabName = string;
@@ -55,7 +55,8 @@ export type FilterInputDataTypes =
55
55
  | "multiselect"
56
56
  | "date"
57
57
  | "year"
58
- | "number";
58
+ | "number"
59
+ | "label";
59
60
 
60
61
  export interface FilterColumnsListProps {
61
62
  created_date: string | null;
@@ -1,7 +1,7 @@
1
1
  import { useState } from "react";
2
2
  import Kanban from "../kanban";
3
3
  import LeadCard from "../kanban/components/LeadCard";
4
- import { useGetKanbanData } from "../kanban/hooks/hooks";
4
+ import { kanbanDropdownResults, useGetKanbanData } from "../kanban/hooks/hooks";
5
5
  import { useCraftTable } from "../listing/libs/hooks/useCraftTable";
6
6
  import {
7
7
  useEntityTableAPI,
@@ -16,6 +16,9 @@ const KanbanView = () => {
16
16
  const { getSettingsAPIData } = useGetSettingsDataAPI(ENTITY_TYPE);
17
17
  const [selectedTab, setSelectedTab] = useState("All");
18
18
  const tableStates = useCraftTable();
19
+ const [selectAttributeData] = kanbanDropdownResults("ATT", "1001");
20
+ const [selectSwinLandData] = kanbanDropdownResults("SWM", "1001");
21
+
19
22
  const { tableData } = useEntityTableAPI({
20
23
  page: 0,
21
24
  size: 20,
@@ -57,6 +60,8 @@ const KanbanView = () => {
57
60
  onClose={() => setShowListViewSettings(false)}
58
61
  columnsData={metaData || {}}
59
62
  columnsDataLoading={isLoading}
63
+ selectAttributeData={selectAttributeData?.data}
64
+ selectSwinLandData={selectSwinLandData?.data}
60
65
  // tabsApiData={settingsTabDropdownData || []}
61
66
  // tabsApiDataLoading={settingsTabDropdownPending}
62
67
  // onSaveSettingsData={handleSaveSettingsData}
@@ -10,6 +10,7 @@ import {
10
10
  ENTITY_TYPE,
11
11
  formatTableHeaders,
12
12
  MAPPED_ENTITY_TYPE,
13
+ MODULE_CODE,
13
14
  } from "../listing/libs/utils/common";
14
15
  import {
15
16
  useCommonFilterDropdownAPI,
@@ -135,7 +136,7 @@ function ListingView() {
135
136
  // }, 1000);
136
137
 
137
138
  fetchMeta();
138
- }, [selectedTab]);
139
+ }, [selectedTab, metaQuery?.data]);
139
140
 
140
141
  // useEffect(() => {
141
142
  // setFilters(detailsQuery.data ?? []);
@@ -187,6 +188,7 @@ function ListingView() {
187
188
  ],
188
189
  attributeFilter: [],
189
190
  flatJson: metaQuery.data?.is_flat_json || false,
191
+ // module_code: MODULE_CODE,
190
192
  });
191
193
 
192
194
  const newData = useMemo(
@@ -381,24 +383,7 @@ function ListingView() {
381
383
  );
382
384
  };
383
385
 
384
- return isTableDataPending ? (
385
- <Box
386
- sx={{
387
- // full viewport height
388
- display: "flex",
389
- flexDirection: "column",
390
- alignItems: "center",
391
- justifyContent: "center",
392
- gap: 2,
393
- bgcolor: "background.default",
394
- }}
395
- >
396
- <CircularProgress size={60} thickness={5} color="primary" />
397
- <Typography variant="body1" color="text.secondary">
398
- Loading, please wait...
399
- </Typography>
400
- </Box>
401
- ) : (
386
+ return (
402
387
  <TableWrapper
403
388
  data={filteredData}
404
389
  activeTab={selectedTab}
@@ -528,7 +513,7 @@ function ListingView() {
528
513
  ),
529
514
  searchValue: searchTerm,
530
515
  onSearchChange: (val) => setSearchTerm(val),
531
- showFilterToggle: false,
516
+ showFilterToggle: true,
532
517
  onFilterButtonClick: () =>
533
518
  tableStates.setShowTableFilter(!tableStates.showTableFilter),
534
519
  showColumnToggle: false,