rez-table-listing-mui 0.0.25 → 0.0.27

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 (47) hide show
  1. package/.env.uat +1 -0
  2. package/.eslintrc.cjs +11 -9
  3. package/dist/index.d.ts +102 -8
  4. package/dist/index.js +1 -1
  5. package/dist/index.mjs +1 -1
  6. package/package.json +25 -11
  7. package/src/App.tsx +172 -129
  8. package/src/assets/svg.tsx +65 -2
  9. package/src/components/common/confirm-modal/index.tsx +200 -0
  10. package/src/components/filter/components/attributes-filter.tsx +28 -0
  11. package/src/components/filter/components/forms/components/Attributes-select.tsx +182 -0
  12. package/src/components/filter/components/forms/components/Date.tsx +58 -0
  13. package/src/components/filter/components/forms/components/Dropdown.tsx +62 -0
  14. package/src/components/filter/components/forms/components/Filter-criteria.tsx +164 -0
  15. package/src/components/filter/components/forms/components/Multi-Select.tsx +57 -0
  16. package/src/components/filter/components/forms/components/Select.tsx +53 -0
  17. package/src/components/filter/components/forms/components/Textfield.tsx +43 -0
  18. package/src/components/filter/components/forms/components/styles.tsx +11 -0
  19. package/src/components/filter/components/forms/index.tsx +444 -0
  20. package/src/components/filter/components/main-filter.tsx +66 -0
  21. package/src/components/filter/components/saved-edit-filter.tsx +107 -0
  22. package/src/components/filter/components/saved-filter.tsx +150 -0
  23. package/src/components/filter/components/search/index.tsx +56 -0
  24. package/src/components/filter/components/tabs/custom-tab-panel.tsx +29 -0
  25. package/src/components/filter/components/tabs/index.tsx +85 -0
  26. package/src/components/filter/index.tsx +261 -0
  27. package/src/components/index-table.tsx +3 -6
  28. package/src/components/index.scss +4 -0
  29. package/src/components/login/index.tsx +49 -0
  30. package/src/components/table-body.tsx +6 -4
  31. package/src/components/table-head.tsx +0 -10
  32. package/src/components/topbar/index.scss +5 -0
  33. package/src/components/topbar/index.tsx +54 -19
  34. package/src/components/viewmore/index.tsx +2 -2
  35. package/src/libs/hooks/useCraftTable.tsx +29 -5
  36. package/src/libs/hooks/useDefaultColumns.tsx +2 -2
  37. package/src/libs/hooks/useEntityTableAPI.tsx +183 -0
  38. package/src/libs/hooks/useEntityTableHooks.ts +25 -0
  39. package/src/libs/utils/apiColumn.ts +123 -0
  40. package/src/libs/utils/common.ts +42 -0
  41. package/src/main.tsx +6 -3
  42. package/src/types/common.ts +67 -0
  43. package/src/types/filter.ts +215 -0
  44. package/src/types/table-options.ts +15 -2
  45. package/src/types/table.ts +5 -5
  46. package/tsconfig.json +1 -1
  47. package/vite.config.ts +3 -3
@@ -17,7 +17,6 @@ import {
17
17
  import DraggableTableHeader from "./table-head-dnd-cell";
18
18
  import TableHeadPin from "./table-head-pin";
19
19
  import Checkbox from "./inputs/checkbox";
20
- import TableHeadPopover from "./table-head-popover";
21
20
 
22
21
  interface TableHeadProps<T> {
23
22
  table: Table<T>;
@@ -41,15 +40,6 @@ function TableHead<T>({
41
40
 
42
41
  // Popover
43
42
  const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);
44
- const [wrap, setWrap] = useState(false);
45
-
46
- const handleClose = () => {
47
- setAnchorEl(null);
48
- };
49
-
50
- const toggleWrap = () => {
51
- setWrap((prev) => !prev);
52
- };
53
43
 
54
44
  const handleHover = (event: React.MouseEvent<HTMLElement>) => {
55
45
  setAnchorEl((prev) => (prev ? null : event.currentTarget));
@@ -126,3 +126,8 @@
126
126
  }
127
127
  }
128
128
  }
129
+
130
+ .MuiDrawer-root {
131
+ display: block !important;
132
+ transform: none !important;
133
+ }
@@ -2,7 +2,7 @@ import React, { useState, useRef, useEffect } from "react";
2
2
  import {
3
3
  ChangeLayoutIcon,
4
4
  SortingIcon,
5
- CustomizationIcon,
5
+ FilterationIcon,
6
6
  HideColumnIcon,
7
7
  } from "../../assets/svg";
8
8
  import { Popover } from "@mui/material";
@@ -17,9 +17,11 @@ import SortPopover from "../sorting-modal.tsx";
17
17
  import ColumnToggle from "../column-visibility-modal/index.tsx";
18
18
  import { CraftTableOptionsProps } from "../../types/table-options.ts";
19
19
  import TableSearch from "../search/index.tsx";
20
+ import FilterDrawer from "../filter/index.tsx";
20
21
 
21
22
  interface TopbarProps<T> {
22
23
  table: Table<T>;
24
+ isFullscreen: boolean;
23
25
  fullscreenToggle: () => void;
24
26
  isCompactTable: boolean;
25
27
  setIsCompactTable: React.Dispatch<React.SetStateAction<boolean>>;
@@ -35,13 +37,14 @@ interface TopbarProps<T> {
35
37
  function Topbar<T>({
36
38
  table,
37
39
  isCompactTable,
40
+ isFullscreen,
38
41
  fullscreenToggle,
39
42
  setIsCompactTable,
40
43
  paginationComponent,
41
44
  topbarOptions,
42
45
  tableStates,
43
46
  }: TopbarProps<T>) {
44
- const [isFullscreen, setIsFullscreen] = useState(false);
47
+ const [isFullscreenState, setIsFullscreenState] = useState(isFullscreen);
45
48
  const [sortAnchorEl, setSortAnchorEl] = useState<HTMLElement | null>(null);
46
49
  const [groupBy, setGroupBy] = useState<string>("None");
47
50
 
@@ -57,7 +60,12 @@ function Topbar<T>({
57
60
  table.getAllLeafColumns().map((col) => col.id)
58
61
  );
59
62
 
60
- // console.log("showColumnHiding", showColumnHiding); //only for built purpose-> remove it later
63
+ //Filter
64
+ const [showFilterInput, setShowFilterInput] = useState(false);
65
+
66
+ // search
67
+ const [showSearchInput, setShowSearchInput] = useState(false);
68
+ const searchContainerRef = useRef<HTMLDivElement>(null);
61
69
 
62
70
  // sync column order with table instance
63
71
  useEffect(() => {
@@ -70,11 +78,22 @@ function Topbar<T>({
70
78
  showColumnToggle,
71
79
  showChangeLayoutToggle,
72
80
  viewMoreToggle,
81
+ showSortingToggle,
82
+ showFilterToggle,
73
83
  showSearch,
74
- showFilter,
75
- showCustomizationToggle,
76
84
  searchValue,
77
85
  onSearchChange,
86
+ filterOptions = {
87
+ columnsData: {
88
+ column_list: [],
89
+ operation_list: {},
90
+ saved_filter: [],
91
+ },
92
+ onDeleteFilter: () => {},
93
+ onSaveFilter: () => {},
94
+ dropdownData: [],
95
+ onUpdateFilter: () => {},
96
+ },
78
97
  } = topbarOptions ?? {};
79
98
 
80
99
  const { container: fullscreenContainer } = useFullscreenPopoverContainer();
@@ -94,15 +113,15 @@ function Topbar<T>({
94
113
  setLayoutAnchorEl(null);
95
114
  };
96
115
 
97
- // search
98
- const [showSearchInput, setShowSearchInput] = useState(false);
99
- const searchContainerRef = useRef<HTMLDivElement>(null);
100
-
101
116
  useOutsideClick({
102
117
  ref: searchContainerRef,
103
118
  handler: () => setShowSearchInput(false),
104
119
  });
105
120
 
121
+ const handleFilterDrawer = () => {
122
+ setShowFilterInput((prev) => !prev);
123
+ };
124
+
106
125
  return (
107
126
  <div className="ts-topbar">
108
127
  <div className="tabs-section">{leftSideComponent}</div>
@@ -112,10 +131,12 @@ function Topbar<T>({
112
131
  {paginationComponent}
113
132
 
114
133
  {showSearch && (
115
- <TableSearch
116
- value={searchValue ?? ""}
117
- onChange={onSearchChange ?? (() => {})}
118
- />
134
+ <div title="Search">
135
+ <TableSearch
136
+ value={searchValue ?? ""}
137
+ onChange={onSearchChange ?? (() => {})}
138
+ />
139
+ </div>
119
140
  )}
120
141
 
121
142
  {showChangeLayoutToggle && (
@@ -168,7 +189,7 @@ function Topbar<T>({
168
189
  </>
169
190
  )}
170
191
 
171
- {showFilter && (
192
+ {showSortingToggle && (
172
193
  <>
173
194
  <div
174
195
  className="filter ts--button"
@@ -189,9 +210,23 @@ function Topbar<T>({
189
210
  </>
190
211
  )}
191
212
 
192
- {showCustomizationToggle && (
193
- <div className="customization ts--button" title="Filter">
194
- <CustomizationIcon />
213
+ {showFilterToggle && (
214
+ <div
215
+ className="filter ts--button"
216
+ title="Filter"
217
+ onClick={() => setShowFilterInput(true)}
218
+ >
219
+ <FilterationIcon />
220
+ <FilterDrawer
221
+ tableStates={tableStates}
222
+ open={showFilterInput}
223
+ onClose={handleFilterDrawer}
224
+ onDeleteFilter={filterOptions?.onDeleteFilter}
225
+ columnsData={filterOptions.columnsData} // @ts-ignore
226
+ onSaveFilter={filterOptions?.onSaveFilter}
227
+ dropdownData={filterOptions.dropdownData}
228
+ onUpdateFilter={filterOptions?.onUpdateFilter}
229
+ />
195
230
  </div>
196
231
  )}
197
232
 
@@ -202,10 +237,10 @@ function Topbar<T>({
202
237
  onCompactToggle={(value: string) =>
203
238
  setIsCompactTable(value === "Compact")
204
239
  }
205
- isFullscreen={isFullscreen}
240
+ isFullscreen={isFullscreenState}
206
241
  onFullscreenToggle={() => {
207
242
  fullscreenToggle();
208
- setIsFullscreen((prev) => !prev);
243
+ setIsFullscreenState((prev) => !prev);
209
244
  }}
210
245
  groupBy={groupBy}
211
246
  onGroupByChange={(value: string) => setGroupBy(value)}
@@ -27,8 +27,8 @@ const ViewMore = ({
27
27
  onCompactToggle,
28
28
  isFullscreen,
29
29
  onFullscreenToggle,
30
- groupBy,
31
- onGroupByChange,
30
+ // groupBy,
31
+ // onGroupByChange,
32
32
  tableStates,
33
33
  }: ViewMorePopoverProps) => {
34
34
  const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
@@ -6,6 +6,11 @@ import {
6
6
  } from "@tanstack/react-table";
7
7
  import { useState } from "react";
8
8
  import { CraftTableOptionsProps } from "../../types/table-options";
9
+ import {
10
+ FilterMasterStateProps,
11
+ FilterOperationListProps,
12
+ FilterStateProps,
13
+ } from "../../types/filter";
9
14
 
10
15
  export function useCraftTable(paginationPageSize: number = 25) {
11
16
  const [pagination, setPagination] = useState<PaginationState>({
@@ -18,9 +23,20 @@ export function useCraftTable(paginationPageSize: number = 25) {
18
23
  const [wrapColumns, setWrapColumns] = useState<Record<string, boolean>>({
19
24
  all_wrap: true,
20
25
  });
21
- const [globalWrapColumns, setGlobalWrapColumns] = useState<boolean | null>(
22
- null
23
- );
26
+
27
+ // Filters to be rendered in form
28
+ const [filters, setFilters] = useState<FilterStateProps[]>([]);
29
+ // Saved filter Component - savedFilterEditValue is set on list click
30
+ const [savedFilterEditValue, setSavedFilterEditValue] = useState<
31
+ string | number
32
+ >("");
33
+ const [filterToDelete, setFilterToDelete] =
34
+ useState<FilterOperationListProps | null>(null);
35
+ const [filterSelectedAttributeValue, setFilterSelectedAttributeValue] =
36
+ useState<string>("");
37
+
38
+ const [filterMaster, setFilterMaster] =
39
+ useState<FilterMasterStateProps | null>(null);
24
40
 
25
41
  if (pagination.pageIndex < 0 || pagination.pageSize <= 0) {
26
42
  throw new Error(
@@ -39,8 +55,16 @@ export function useCraftTable(paginationPageSize: number = 25) {
39
55
  setExpanded: setExpanded,
40
56
  wrapColumns: wrapColumns,
41
57
  setWrapColumns: setWrapColumns,
42
- globalWrapColumns: globalWrapColumns,
43
- setGlobalWrapColumns: setGlobalWrapColumns,
58
+ filters: filters,
59
+ setFilters: setFilters,
60
+ savedFilterEditValue: savedFilterEditValue,
61
+ setSavedFilterEditValue: setSavedFilterEditValue,
62
+ filterToDelete: filterToDelete,
63
+ setFilterToDelete: setFilterToDelete,
64
+ filterSelectedAttributeValue: filterSelectedAttributeValue,
65
+ setFilterSelectedAttributeValue: setFilterSelectedAttributeValue,
66
+ filterMaster: filterMaster,
67
+ setFilterMaster: setFilterMaster,
44
68
  };
45
69
 
46
70
  return craftTableOptions;
@@ -11,7 +11,7 @@ export const useDefaultColumns = () => {
11
11
  header: "First Name",
12
12
  id: "firstName",
13
13
  accessorKey: "firstName",
14
- // meta: { label: "First Name" },
14
+ meta: { label: "First Name" },
15
15
  // header: ({ table }) => (
16
16
  // <>
17
17
  // <button
@@ -58,7 +58,7 @@ export const useDefaultColumns = () => {
58
58
  header: "Last Name",
59
59
  accessorKey: "lastName",
60
60
  size: 100,
61
- meta: { wrap: true },
61
+ meta: { label: "Last Name" },
62
62
  },
63
63
  {
64
64
  header: "Email Id",
@@ -0,0 +1,183 @@
1
+ import {
2
+ useMutation,
3
+ useQueries,
4
+ useQuery,
5
+ useQueryClient,
6
+ } from "@tanstack/react-query";
7
+ import { api, ENTITY_TYPE } from "../utils/common";
8
+ import {
9
+ APIParamsProps,
10
+ EntityListingResponse,
11
+ EntityTableAPIProps,
12
+ } from "../../types/common";
13
+ import {
14
+ commonGetDropdownDataAPI,
15
+ createSavedFilter,
16
+ deleteSavedFilter,
17
+ updateSavedFilter,
18
+ } from "../utils/apiColumn";
19
+ import { FilterColumnsDataProps } from "../../types/filter";
20
+
21
+ const entityListingCall = async ({
22
+ page,
23
+ size,
24
+ entity_type = ENTITY_TYPE,
25
+ tabs = {
26
+ columnName: "status",
27
+ sortBy: "ASC",
28
+ value: "",
29
+ },
30
+ sortby = [
31
+ {
32
+ sortColum: "name",
33
+ sortType: "ASC",
34
+ },
35
+ {
36
+ sortColum: "status",
37
+ sortType: "DSC",
38
+ },
39
+ ],
40
+ quickFilter = [],
41
+ attributeFilter = [],
42
+ }: EntityTableAPIProps): Promise<{
43
+ responseStatus: number;
44
+ data: EntityListingResponse;
45
+ }> => {
46
+ const url = `filter`;
47
+
48
+ const body = {
49
+ entity_type,
50
+ tabs,
51
+ sortby,
52
+ quickFilter,
53
+ attributeFilter,
54
+ };
55
+
56
+ const params: APIParamsProps = {
57
+ page,
58
+ size,
59
+ };
60
+
61
+ const response = await api.post(url, body, { params });
62
+
63
+ return { responseStatus: response.status, data: response.data };
64
+ };
65
+
66
+ export const useEntityTableAPI = ({
67
+ page = 0,
68
+ size = 50,
69
+ quickFilter = [],
70
+ }: EntityTableAPIProps) => {
71
+ const { data, isPending: isTableDataPending } = useQuery({
72
+ queryKey: [page, size, quickFilter],
73
+ queryFn: () =>
74
+ entityListingCall({
75
+ page,
76
+ size,
77
+ quickFilter,
78
+ }),
79
+ });
80
+
81
+ return {
82
+ tableData: data?.data.data,
83
+ status: data?.responseStatus,
84
+ isTableDataPending,
85
+ };
86
+ };
87
+
88
+ //for saved filter API
89
+ export const useSavedFilterAPI = () => {
90
+ const queryClient = useQueryClient();
91
+ const savedMutation = useMutation({
92
+ mutationKey: ["savedFilter"],
93
+ mutationFn: ({
94
+ entity_type,
95
+ payload,
96
+ }: {
97
+ entity_type: string;
98
+ payload: any;
99
+ }) => {
100
+ return createSavedFilter(entity_type, payload);
101
+ },
102
+ onSuccess: () => {
103
+ queryClient.invalidateQueries({ queryKey: ["meta"] });
104
+ },
105
+ });
106
+
107
+ return { savedMutation };
108
+ };
109
+
110
+ //for delete filter API
111
+ export const useDeleteFilterAPI = () => {
112
+ const queryClient = useQueryClient();
113
+ const deleteMutation = useMutation({
114
+ mutationKey: ["deleteFilter"],
115
+ mutationFn: ({
116
+ entity_type,
117
+ payload,
118
+ }: {
119
+ entity_type: string;
120
+ payload: any;
121
+ }) => {
122
+ return deleteSavedFilter(entity_type, payload);
123
+ },
124
+ onSuccess: () => {
125
+ queryClient.invalidateQueries({ queryKey: ["meta"] });
126
+ },
127
+ });
128
+
129
+ return { deleteMutation };
130
+ };
131
+
132
+ // for updating saved filter API
133
+ export const useUpdateFilterAPI = () => {
134
+ const queryClient = useQueryClient();
135
+
136
+ const updateMutation = useMutation({
137
+ mutationKey: ["updateFilter"],
138
+ mutationFn: ({
139
+ entity_type,
140
+ payload,
141
+ }: {
142
+ entity_type: string;
143
+ payload: any;
144
+ }) => {
145
+ return updateSavedFilter(entity_type, payload);
146
+ },
147
+ onSuccess: () => {
148
+ queryClient.invalidateQueries({ queryKey: ["meta"] });
149
+ },
150
+ });
151
+
152
+ return { updateMutation };
153
+ };
154
+
155
+ export const useCommonDropdownAPI = (
156
+ metaData?: FilterColumnsDataProps,
157
+ value?: string
158
+ ) => {
159
+ // Step 1: Extract all keys and query types
160
+ const dropdownConfigs = (metaData?.column_list || [])
161
+ .filter((col) => col?.datasource_list)
162
+ .map((col) => ({
163
+ key: col.attribute_key,
164
+ dataSourceType: value ?? col.datasource_list ?? "STS",
165
+ }));
166
+
167
+ // Step 2: Use useQueries to fetch them all in parallel
168
+ const dropdownResults = useQueries({
169
+ queries: dropdownConfigs.map((cfg) => ({
170
+ queryKey: ["commonDropdown", cfg.dataSourceType],
171
+ queryFn: () => commonGetDropdownDataAPI(cfg.dataSourceType, null),
172
+ enabled: !!cfg.dataSourceType,
173
+ })),
174
+ });
175
+
176
+ // Step 3: Map results to keys
177
+ const dropdownData: Record<string, any> = {};
178
+ dropdownConfigs.forEach((cfg, idx) => {
179
+ dropdownData[cfg.key] = dropdownResults[idx].data;
180
+ });
181
+
182
+ return { dropdownData };
183
+ };
@@ -0,0 +1,25 @@
1
+ import { useQuery } from "@tanstack/react-query";
2
+ import {
3
+ entityTableFilterMaster,
4
+ fetchDetailsByFilterId,
5
+ } from "../utils/apiColumn";
6
+
7
+ export const useDetailsQueryAPI = (value: string) => {
8
+ const detailsQuery = useQuery({
9
+ queryKey: ["details", value],
10
+ queryFn: () => fetchDetailsByFilterId(value),
11
+ enabled: !!value, // This ensures that the second query only runs if the first one has data
12
+ });
13
+
14
+ return { detailsQuery };
15
+ };
16
+
17
+ export const useFetchData = (entity_type: string) => {
18
+ // First query to get meta data
19
+ const metaQuery = useQuery({
20
+ queryKey: ["meta", entity_type],
21
+ queryFn: () => entityTableFilterMaster(entity_type),
22
+ });
23
+
24
+ return { metaQuery };
25
+ };
@@ -0,0 +1,123 @@
1
+ import { api } from "./common";
2
+ import {
3
+ createSavedFilterPaload,
4
+ deleteSavedFilterPayload,
5
+ updateSavedFilterPayload,
6
+ } from "../../types/filter";
7
+
8
+ export const entityTableMetaMaster = async (entity_type: string) => {
9
+ try {
10
+ const response = await api.post(
11
+ `/meta/get-table-data?entity_type=${entity_type}&list_type=${entity_type}`
12
+ );
13
+
14
+ const rawColumns = response.data?.data?.column_list || [];
15
+
16
+ const res = rawColumns.map((item: any) => ({
17
+ id: item.attribute_key,
18
+ accessorKey: item.attribute_key,
19
+ header: item.name,
20
+ }));
21
+ return { res };
22
+ } catch (error) {
23
+ console.error("Failed to fetch table meta:", error);
24
+ return { res: [] };
25
+ }
26
+ };
27
+
28
+ export const entityTableFilterMaster = async (entity_type: string) => {
29
+ try {
30
+ const response = await api.post(
31
+ `/meta/get-table-data?entity_type=${entity_type}&list_type=${entity_type}`
32
+ );
33
+
34
+ const filteredData = {
35
+ ...response.data.data,
36
+ column_list: response.data.data.column_list.filter(
37
+ (item: any) => item.attribute_key !== "action"
38
+ ),
39
+ };
40
+ // console.log("response", filteredData.column_list);
41
+ // return response.data.data;
42
+ return filteredData; // FOR ACTION COLUMN REMOVE
43
+ } catch (error) {
44
+ console.error("Failed to fetch filter operation list meta:", error);
45
+ }
46
+ };
47
+
48
+ export const fetchDetailsByFilterId = async (filterId: string) => {
49
+ const response = await api.get(`/filter/${filterId}`);
50
+ return response.data;
51
+ };
52
+
53
+ export const commonGetDropdownDataAPI = async (
54
+ entity_type: string,
55
+ organization_id?: string | null,
56
+ data?: any
57
+ ) => {
58
+ try {
59
+ const requestBody = {
60
+ status: "ACTIVE",
61
+ organization_id: organization_id,
62
+ ...data,
63
+ };
64
+
65
+ const response = await api.post(
66
+ `/list-master/getDropdownData/${entity_type}`,
67
+ requestBody
68
+ );
69
+
70
+ return response.data;
71
+ } catch (error) {
72
+ console.error("Failed to fetch dropdown data:", error);
73
+ throw error;
74
+ }
75
+ };
76
+
77
+ export const createSavedFilter = async (
78
+ entity_type: string,
79
+ payload: createSavedFilterPaload
80
+ ) => {
81
+ try {
82
+ const response = await api.post(
83
+ `/entity/create?entity_type=${entity_type}`,
84
+ payload
85
+ );
86
+ return response.data;
87
+ } catch (error) {
88
+ console.error("Failed to fetch saved filter list:", error);
89
+ throw error;
90
+ }
91
+ };
92
+
93
+ export const deleteSavedFilter = async (
94
+ entity_type: string,
95
+ payload: deleteSavedFilterPayload
96
+ ) => {
97
+ try {
98
+ const response = await api.post(
99
+ `/entity/update/17?entity_type=${entity_type}`,
100
+ payload
101
+ );
102
+ return response.data;
103
+ } catch (error) {
104
+ console.error("Failed to delete saved filter:", error);
105
+ throw error;
106
+ }
107
+ };
108
+
109
+ export const updateSavedFilter = async (
110
+ entity_type: string,
111
+ payload: updateSavedFilterPayload
112
+ ) => {
113
+ try {
114
+ const response = await api.post(
115
+ `/entity/update/17?entity_type=${entity_type}`,
116
+ payload
117
+ );
118
+ return response.data;
119
+ } catch (error) {
120
+ console.error("Failed to update saved filter:", error);
121
+ throw error;
122
+ }
123
+ };
@@ -1,6 +1,7 @@
1
1
  import { Column } from "@tanstack/react-table";
2
2
  import { alignProps } from "../../types/common";
3
3
  import { CSSProperties } from "react";
4
+ import axios from "axios";
4
5
 
5
6
  export const formatClassName = (className: string): string => {
6
7
  return className.replace(/\s+/g, " ").trim();
@@ -60,3 +61,44 @@ export const getColumnPinningStylesBody = <T>(
60
61
  width: column.getSize(),
61
62
  };
62
63
  };
64
+
65
+ export function customDebounce<T extends (...args: any[]) => any>(
66
+ func: T,
67
+ delay: number
68
+ ): (...args: Parameters<T>) => void {
69
+ let timerId: ReturnType<typeof setTimeout> | null = null;
70
+
71
+ return function (this: ThisParameterType<T>, ...args: Parameters<T>): void {
72
+ if (timerId) clearTimeout(timerId);
73
+ timerId = setTimeout(() => {
74
+ func.apply(this, args);
75
+ }, delay);
76
+ };
77
+ }
78
+
79
+ // uat http://13.200.182.92:9091/api
80
+ // local http://localhost:9091/api
81
+
82
+ // API INTEGRATION
83
+ export const api = axios.create({
84
+ baseURL: "http://13.200.182.92:9091/api",
85
+ timeout: 10000,
86
+ headers: {
87
+ "Content-Type": "application/json",
88
+ },
89
+ });
90
+
91
+ api.interceptors.request.use(
92
+ (config) => {
93
+ const token = localStorage.getItem("authToken");
94
+ if (token) {
95
+ config.headers.Authorization = `Bearer ${token}`;
96
+ }
97
+ return config;
98
+ },
99
+ (error) => {
100
+ return Promise.reject(error);
101
+ }
102
+ );
103
+
104
+ export const ENTITY_TYPE = "UPR";
package/src/main.tsx CHANGED
@@ -1,9 +1,12 @@
1
1
  import React from "react";
2
2
  import ReactDOM from "react-dom/client";
3
3
  import App from "./App.tsx";
4
+ import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
4
5
 
5
6
  ReactDOM.createRoot(document.getElementById("root")!).render(
6
- <React.StrictMode>
7
- <App />
8
- </React.StrictMode>
7
+ <QueryClientProvider client={new QueryClient()}>
8
+ <React.StrictMode>
9
+ <App />
10
+ </React.StrictMode>
11
+ </QueryClientProvider>
9
12
  );