rez-table-listing-mui 0.0.24 → 0.0.26

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 (50) hide show
  1. package/.env.uat +1 -0
  2. package/.eslintrc.cjs +11 -9
  3. package/dist/index.d.ts +104 -11
  4. package/dist/index.js +1 -1
  5. package/dist/index.mjs +1 -1
  6. package/package.json +6 -10
  7. package/src/App.tsx +185 -142
  8. package/src/assets/svg.tsx +33 -2
  9. package/src/components/common/confirm-modal/index.tsx +200 -0
  10. package/src/components/filter/components/attributes-filter.tsx +26 -0
  11. package/src/components/filter/components/forms/components/Attributes-select.tsx +180 -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 +424 -0
  20. package/src/components/filter/components/main-filter.tsx +53 -0
  21. package/src/components/filter/components/saved-edit-filter.tsx +101 -0
  22. package/src/components/filter/components/saved-filter.tsx +148 -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 +52 -0
  26. package/src/components/filter/index.tsx +258 -0
  27. package/src/components/index-table.tsx +20 -14
  28. package/src/components/index.scss +4 -0
  29. package/src/components/login/index.tsx +49 -0
  30. package/src/components/search/index.tsx +0 -1
  31. package/src/components/table-body-dnd-cell.tsx +3 -3
  32. package/src/components/table-body.tsx +8 -5
  33. package/src/components/table-head-popover.tsx +2 -1
  34. package/src/components/table-head.tsx +0 -10
  35. package/src/components/topbar/index.scss +6 -1
  36. package/src/components/topbar/index.tsx +59 -33
  37. package/src/components/viewmore/index.tsx +33 -17
  38. package/src/libs/hooks/useCraftTable.tsx +32 -6
  39. package/src/libs/hooks/useDefaultColumns.tsx +6 -5
  40. package/src/libs/hooks/useEntityTableAPI.tsx +183 -0
  41. package/src/libs/hooks/useEntityTableHooks.ts +25 -0
  42. package/src/libs/utils/apiColumn.ts +123 -0
  43. package/src/libs/utils/common.ts +42 -0
  44. package/src/main.tsx +6 -3
  45. package/src/types/common.ts +67 -0
  46. package/src/types/filter.ts +211 -0
  47. package/src/types/table-options.ts +15 -2
  48. package/src/types/table.ts +7 -6
  49. package/tsconfig.json +1 -1
  50. package/vite.config.ts +3 -3
@@ -0,0 +1,424 @@
1
+ import {
2
+ Box,
3
+ Button,
4
+ FormControl,
5
+ IconButton,
6
+ TextField,
7
+ Typography,
8
+ } from "@mui/material";
9
+ import { CloseIcon, DeleteIcon } from "../../../../assets/svg";
10
+ import {
11
+ FilterColumnsDataProps,
12
+ FilterDropdownDataProps,
13
+ FilterMasterStateProps,
14
+ UpdatedFilterStateProps,
15
+ } from "../../../../types/filter";
16
+ import { Controller, useForm } from "react-hook-form";
17
+ import FormTextfield from "./components/Textfield";
18
+ import React, { useEffect, useMemo } from "react";
19
+ import FormSelect from "./components/Select";
20
+ import FormDatePicker from "./components/Date";
21
+ import FormDropdown from "./components/Dropdown";
22
+ import FormMultiSelect from "./components/Multi-Select";
23
+ import { CraftTableOptionsProps } from "../../../../types/table-options";
24
+ import FilterCriteria from "./components/Filter-criteria";
25
+ import CustomSearch from "../search";
26
+
27
+ interface FormValues {
28
+ filterName: string;
29
+ [key: string]:
30
+ | {
31
+ value: string | string[];
32
+ operator: string;
33
+ }
34
+ | string;
35
+ }
36
+
37
+ const FilterForm = ({
38
+ columnsData,
39
+ dropdownData,
40
+ searchTerm = "",
41
+ setSearchTerm,
42
+ selectedFilters,
43
+ setSelectedFilters,
44
+ handleRemoveFilter,
45
+ handleClearAllFilters,
46
+ editMode = false,
47
+ tableStates,
48
+ setSavedFilterModalOpen,
49
+ setDeleteFilterModalOpen,
50
+ }: {
51
+ columnsData: FilterColumnsDataProps;
52
+ dropdownData: FilterDropdownDataProps;
53
+ searchTerm?: string;
54
+ setSearchTerm: React.Dispatch<React.SetStateAction<string>>;
55
+ selectedFilters: UpdatedFilterStateProps[];
56
+ setSelectedFilters: React.Dispatch<
57
+ React.SetStateAction<UpdatedFilterStateProps[]>
58
+ >;
59
+ handleRemoveFilter: (filter_attribute: string) => void;
60
+ handleClearAllFilters: () => void;
61
+ editMode?: boolean;
62
+ tableStates: CraftTableOptionsProps;
63
+ setSavedFilterModalOpen?: React.Dispatch<React.SetStateAction<boolean>>;
64
+ setDeleteFilterModalOpen?: React.Dispatch<React.SetStateAction<boolean>>;
65
+ }) => {
66
+ const { filterMaster, setFilters, setFilterMaster } = tableStates;
67
+
68
+ const filterName = filterMaster?.saved_filters?.selectedName || "";
69
+
70
+ const defaultValues = useMemo(() => {
71
+ const filterValues = selectedFilters.reduce((acc, curr) => {
72
+ if (curr.name) {
73
+ acc[curr.name] = {
74
+ value: curr.filter_value ?? "",
75
+ operator:
76
+ curr.filter_operator ?? curr.dropdown_list?.[0]?.value ?? "",
77
+ };
78
+ }
79
+ return acc;
80
+ }, {} as Record<string, { value: string | string[]; operator: string }>);
81
+
82
+ return {
83
+ filterName: filterName ?? "",
84
+ ...filterValues,
85
+ };
86
+ }, [selectedFilters, filterName]);
87
+
88
+ const {
89
+ control,
90
+ watch,
91
+ reset,
92
+ formState: { isDirty },
93
+ } = useForm<FormValues>({
94
+ mode: "onChange",
95
+ defaultValues,
96
+ });
97
+
98
+ // Watch for form changes
99
+ const formValues = watch();
100
+
101
+ // Effect to update filters when form values change
102
+ useEffect(() => {
103
+ if (isDirty) {
104
+ const updatedFilters = selectedFilters.map((filter) => {
105
+ if (filter.name && typeof formValues[filter.name] === "object") {
106
+ const filterValue = formValues[filter.name] as {
107
+ value: string | string[];
108
+ operator: string;
109
+ };
110
+ // Only update if the value or operator has actually changed
111
+ if (
112
+ filterValue.value !== filter.filter_value ||
113
+ filterValue.operator !== filter.filter_operator
114
+ ) {
115
+ return {
116
+ ...filter,
117
+ filter_value: filterValue.value,
118
+ filter_operator: filterValue.operator,
119
+ };
120
+ }
121
+ }
122
+ return filter;
123
+ });
124
+
125
+ // Only update if there are actual changes
126
+ const hasChanges = updatedFilters.some(
127
+ (filter, index) =>
128
+ filter.filter_value !== selectedFilters[index].filter_value ||
129
+ filter.filter_operator !== selectedFilters[index].filter_operator
130
+ );
131
+
132
+ if (hasChanges) {
133
+ setSelectedFilters(updatedFilters);
134
+ setFilters(updatedFilters);
135
+ }
136
+ }
137
+ }, [formValues, selectedFilters]);
138
+
139
+ const editModeStylingBorder = {
140
+ border: "1px solid #c5c5c5",
141
+ borderRadius: "6px",
142
+ padding: "5px 10px 10px 10px",
143
+ };
144
+
145
+ return (
146
+ <form>
147
+ <Box sx={editMode ? editModeStylingBorder : {}}>
148
+ {editMode && (
149
+ <Box
150
+ sx={{
151
+ "& .MuiOutlinedInput-root": {
152
+ borderRadius: "6px",
153
+ fontSize: "14px",
154
+ bgcolor: "#fafafa",
155
+ "& fieldset": { borderColor: "#c1c1c1" },
156
+ "&.Mui-focused fieldset": { borderColor: "#7A5AF8" },
157
+ },
158
+ display: "flex",
159
+ alignItems: "center", // vertical alignment
160
+ justifyContent: "center", // horizontal alignment
161
+ paddingY: 2,
162
+ gap: 1,
163
+ }}
164
+ >
165
+ <Controller
166
+ name="filterName"
167
+ control={control}
168
+ render={({ field }) => (
169
+ <TextField
170
+ fullWidth
171
+ size="small"
172
+ placeholder="Filter Name"
173
+ value={field.value}
174
+ onChange={(e) => {
175
+ field.onChange(e);
176
+
177
+ if (editMode) {
178
+ setFilterMaster(
179
+ (prev) =>
180
+ ({
181
+ ...prev,
182
+ saved_filters: {
183
+ ...prev?.saved_filters,
184
+ selectedName: e.target.value,
185
+ },
186
+ } as FilterMasterStateProps)
187
+ );
188
+ }
189
+ }}
190
+ inputRef={field.ref}
191
+ sx={{
192
+ maxWidth: 400,
193
+
194
+ "& .MuiOutlinedInput-root": {
195
+ bgcolor: "white",
196
+ borderRadius: "0px",
197
+ fontSize: "14px",
198
+ color: "#272524",
199
+ fontWeight: "500",
200
+ "& fieldset": { borderColor: "#c5c5c5" },
201
+ "&.Mui-focused fieldset": { borderColor: "#7A5AF8" },
202
+ },
203
+ }}
204
+ />
205
+ )}
206
+ />
207
+ <Box onClick={(e) => e.stopPropagation()}>
208
+ <IconButton
209
+ size="small"
210
+ onClick={() => {
211
+ setDeleteFilterModalOpen && setDeleteFilterModalOpen(true);
212
+ }}
213
+ >
214
+ <DeleteIcon />
215
+ </IconButton>
216
+ </Box>
217
+ </Box>
218
+ )}
219
+
220
+ <FilterCriteria
221
+ columnsData={columnsData}
222
+ tableStates={tableStates}
223
+ setSelectedFilters={setSelectedFilters}
224
+ />
225
+
226
+ {/* Render search input */}
227
+ {!editMode && (
228
+ <CustomSearch value={searchTerm} onChange={setSearchTerm} />
229
+ )}
230
+
231
+ {selectedFilters
232
+ ?.filter(
233
+ (filter) =>
234
+ filter.name?.toLowerCase().includes(searchTerm.toLowerCase()) ||
235
+ filter.filter_value
236
+ ?.toString()
237
+ .toLowerCase()
238
+ .includes(searchTerm.toLowerCase())
239
+ )
240
+ .map((filter) => {
241
+ const { dropdown_list = [] } = filter;
242
+
243
+ return (
244
+ <Box
245
+ key={filter.filter_attribute}
246
+ sx={{
247
+ mt: 2,
248
+ p: 1,
249
+ borderRadius: 2,
250
+ backgroundColor: "#FAFAFA",
251
+ display: "flex",
252
+ flexDirection: "column",
253
+ gap: 0.5,
254
+ // border: "1px solid #E0E0E0",
255
+ }}
256
+ >
257
+ <Box
258
+ sx={{
259
+ display: "flex",
260
+ justifyContent: "flex-start",
261
+ alignItems: "center",
262
+ gap: 2,
263
+ }}
264
+ >
265
+ <Typography
266
+ sx={{
267
+ fontWeight: 500,
268
+ fontSize: "13px",
269
+ color: "#797877",
270
+ }}
271
+ >
272
+ {filter.name}
273
+ </Typography>
274
+ <FormDropdown
275
+ filter={filter}
276
+ control={control}
277
+ dropdownList={dropdown_list}
278
+ sx={{
279
+ fontSize: "13px",
280
+ minWidth: 50,
281
+ border: "none",
282
+ boxShadow: "none",
283
+ }}
284
+ />
285
+ <IconButton
286
+ sx={{ marginLeft: "auto" }}
287
+ onClick={() => handleRemoveFilter(filter.filter_attribute)}
288
+ size="small"
289
+ >
290
+ <CloseIcon />
291
+ </IconButton>
292
+ </Box>
293
+
294
+ <Box>
295
+ {filter.data_type === "text" ? (
296
+ <FormTextfield filter={filter} control={control} />
297
+ ) : filter.data_type === "number" ? (
298
+ <FormTextfield filter={filter} control={control} />
299
+ ) : filter.data_type === "date" ? (
300
+ <FormDatePicker
301
+ filter={filter}
302
+ control={control}
303
+ sx={{
304
+ "& .MuiOutlinedInput-root": {
305
+ borderRadius: "6px",
306
+ fontSize: "14px",
307
+ bgcolor: "#ffffff",
308
+ "& fieldset": { borderColor: "#c1c1c1" },
309
+ "&.Mui-focused fieldset": {
310
+ borderColor: "#7A5AF8",
311
+ },
312
+ },
313
+ }}
314
+ />
315
+ ) : filter.data_type === "select" ? (
316
+ <FormSelect
317
+ filter={filter}
318
+ control={control}
319
+ dropdownData={dropdownData}
320
+ sx={{
321
+ "& .MuiOutlinedInput-root": {
322
+ borderRadius: "6px",
323
+ fontSize: "14px",
324
+ bgcolor: "#ffffff",
325
+ "& fieldset": { borderColor: "#c1c1c1" },
326
+ "&.Mui-focused fieldset": {
327
+ borderColor: "#7A5AF8",
328
+ },
329
+ },
330
+ }}
331
+ />
332
+ ) : filter.data_type === "multiselect" ? (
333
+ <FormMultiSelect
334
+ filter={filter}
335
+ control={control}
336
+ dropdownData={dropdownData}
337
+ sx={{
338
+ "& .MuiOutlinedInput-root": {
339
+ borderRadius: "6px",
340
+ fontSize: "14px",
341
+ bgcolor: "#ffffff",
342
+ "& fieldset": { borderColor: "#c1c1c1" },
343
+ "&.Mui-focused fieldset": {
344
+ borderColor: "#7A5AF8",
345
+ },
346
+ },
347
+ }}
348
+ />
349
+ ) : (
350
+ <FormControl
351
+ fullWidth
352
+ size="small"
353
+ sx={{
354
+ "& .MuiOutlinedInput-root": {
355
+ borderRadius: "6px",
356
+ fontSize: "14px",
357
+ bgcolor: "#ffffff",
358
+ "& fieldset": { borderColor: "#c1c1c1" },
359
+ "&.Mui-focused fieldset": {
360
+ borderColor: "#7A5AF8",
361
+ },
362
+ },
363
+ }}
364
+ ></FormControl>
365
+ )}
366
+ </Box>
367
+ </Box>
368
+ );
369
+ })}
370
+ </Box>
371
+
372
+ {selectedFilters.length > 0 && (
373
+ <Box
374
+ sx={{
375
+ display: "flex",
376
+ justifyContent: "center",
377
+ gap: 1,
378
+ mt: 3,
379
+ }}
380
+ >
381
+ <Button
382
+ variant="outlined"
383
+ sx={{
384
+ color: "#7A5AF8",
385
+ border: `1px solid #7A5AF8`,
386
+ borderRadius: "6px",
387
+ textTransform: "none",
388
+ fontSize: "14px",
389
+ }}
390
+ fullWidth
391
+ onClick={() => {
392
+ reset();
393
+ handleClearAllFilters();
394
+ }}
395
+ >
396
+ Clear All
397
+ </Button>
398
+
399
+ <Button
400
+ variant="contained"
401
+ fullWidth
402
+ sx={{
403
+ color: "white",
404
+ backgroundColor: "#7A5AF8",
405
+ "&.Mui-disabled": {
406
+ backgroundColor: "#d7cefd", // Change background color when disabled
407
+ color: "rgba(255, 255, 255, 0.7)",
408
+ },
409
+ }}
410
+ // onClick={() => setSaveFilterModalOpen(true)}
411
+ disabled={editMode && !isDirty}
412
+ onClick={() => {
413
+ setSavedFilterModalOpen && setSavedFilterModalOpen(true);
414
+ }}
415
+ >
416
+ Save Filter
417
+ </Button>
418
+ </Box>
419
+ )}
420
+ </form>
421
+ );
422
+ };
423
+
424
+ export default FilterForm;
@@ -0,0 +1,53 @@
1
+ import { Box } from "@mui/material";
2
+ import { useState } from "react";
3
+ import FilterForm from "./forms";
4
+ import { FilterFormComponentProps } from "../../../types/filter";
5
+
6
+ const MainFilter = ({
7
+ columnsData,
8
+ dropdownData,
9
+ tableStates,
10
+ selectedFilters,
11
+ setSelectedFilters,
12
+ setSavedFilterModalOpen,
13
+ }: FilterFormComponentProps) => {
14
+ const [searchTerm, setSearchTerm] = useState<string>("");
15
+
16
+ const { setFilters } = tableStates;
17
+
18
+ const handleRemoveFilter = (filter_attribute: string) => {
19
+ setFilters((prev) =>
20
+ prev.filter((filter) => filter.filter_attribute !== filter_attribute)
21
+ );
22
+ setSelectedFilters((prev) =>
23
+ prev.filter((filter) => filter.filter_attribute !== filter_attribute)
24
+ );
25
+ };
26
+
27
+ const handleClearAllFilters = () => {
28
+ setFilters([]);
29
+ setSelectedFilters([]);
30
+ };
31
+
32
+ return (
33
+ <Box>
34
+ {/* Set selectedFilters state */}
35
+
36
+ {/* Render selectedFilters state */}
37
+ <FilterForm
38
+ columnsData={columnsData}
39
+ searchTerm={searchTerm}
40
+ setSearchTerm={setSearchTerm}
41
+ selectedFilters={selectedFilters}
42
+ setSelectedFilters={setSelectedFilters}
43
+ handleRemoveFilter={handleRemoveFilter}
44
+ handleClearAllFilters={handleClearAllFilters}
45
+ tableStates={tableStates}
46
+ setSavedFilterModalOpen={setSavedFilterModalOpen}
47
+ dropdownData={dropdownData}
48
+ />
49
+ </Box>
50
+ );
51
+ };
52
+
53
+ export default MainFilter;
@@ -0,0 +1,101 @@
1
+ import { Box, Typography } from "@mui/material";
2
+ import FilterForm from "./forms";
3
+ import BackArrow from "@mui/icons-material/ArrowBackIosNew";
4
+ import {
5
+ FilterColumnsDataProps,
6
+ FilterDropdownDataProps,
7
+ UpdatedFilterStateProps,
8
+ } from "../../../types/filter";
9
+ import { CraftTableOptionsProps } from "../../../types/table-options";
10
+
11
+ const SavedFilterEditComponent = ({
12
+ columnsData,
13
+ dropdownData,
14
+ tableStates,
15
+ selectedFilters,
16
+ setSelectedFilters,
17
+ editMode,
18
+ setEditMode,
19
+ searchTerm,
20
+ setSearchTerm,
21
+ setSavedFilterModalOpen,
22
+ setDeleteFilterModalOpen,
23
+ }: {
24
+ columnsData: FilterColumnsDataProps;
25
+ dropdownData: FilterDropdownDataProps;
26
+ tableStates: CraftTableOptionsProps;
27
+ selectedFilters: UpdatedFilterStateProps[];
28
+ setSelectedFilters: React.Dispatch<
29
+ React.SetStateAction<UpdatedFilterStateProps[]>
30
+ >;
31
+ editMode?: boolean;
32
+ setEditMode?: React.Dispatch<React.SetStateAction<boolean>>;
33
+ searchTerm?: string;
34
+ setSearchTerm: React.Dispatch<React.SetStateAction<string>>;
35
+ setSavedFilterModalOpen?: React.Dispatch<React.SetStateAction<boolean>>;
36
+ setDeleteFilterModalOpen?: React.Dispatch<React.SetStateAction<boolean>>;
37
+ }) => {
38
+ const { setFilters } = tableStates;
39
+
40
+ const handleRemoveFilter = (filter_attribute: string) => {
41
+ setFilters((prev) =>
42
+ prev.filter((filter) => filter.filter_attribute !== filter_attribute)
43
+ );
44
+ setSelectedFilters((prev) =>
45
+ prev.filter((filter) => filter.filter_attribute !== filter_attribute)
46
+ );
47
+ };
48
+
49
+ const handleClearAllFilters = () => {
50
+ setFilters([]);
51
+ setSelectedFilters([]);
52
+ };
53
+
54
+ return (
55
+ <>
56
+ <Box>
57
+ <Box
58
+ sx={{
59
+ display: "flex",
60
+ alignItems: "center",
61
+ gap: 1,
62
+ cursor: "pointer",
63
+ mb: 2,
64
+ }}
65
+ onClick={() => {
66
+ setEditMode && setEditMode(false);
67
+ }}
68
+ >
69
+ <BackArrow sx={{ width: "13px", height: "13px" }} />
70
+ <Typography variant="body2" sx={{ color: "#8592A3" }}>
71
+ Back To Saved Filters
72
+ </Typography>
73
+ </Box>
74
+ </Box>
75
+
76
+ {/* <FilterCriteria
77
+ columnsData={columnsData}
78
+ tableStates={tableStates}
79
+ setSelectedFilters={setSelectedFilters}
80
+ /> */}
81
+
82
+ {/* Render selectedFilters state */}
83
+ <FilterForm
84
+ selectedFilters={selectedFilters}
85
+ setSelectedFilters={setSelectedFilters}
86
+ handleRemoveFilter={handleRemoveFilter}
87
+ handleClearAllFilters={handleClearAllFilters}
88
+ editMode={editMode}
89
+ tableStates={tableStates}
90
+ columnsData={columnsData}
91
+ dropdownData={dropdownData}
92
+ searchTerm={searchTerm}
93
+ setSearchTerm={setSearchTerm}
94
+ setSavedFilterModalOpen={setSavedFilterModalOpen}
95
+ setDeleteFilterModalOpen={setDeleteFilterModalOpen}
96
+ />
97
+ </>
98
+ );
99
+ };
100
+
101
+ export default SavedFilterEditComponent;