rez-table-listing-mui 0.0.25 → 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 (47) hide show
  1. package/.env.uat +1 -0
  2. package/.eslintrc.cjs +11 -9
  3. package/dist/index.d.ts +101 -8
  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 +172 -129
  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 +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 +211 -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
@@ -0,0 +1,180 @@
1
+ import {
2
+ Box,
3
+ FormControl,
4
+ MenuItem,
5
+ Select,
6
+ SelectChangeEvent,
7
+ Radio,
8
+ RadioGroup,
9
+ FormControlLabel,
10
+ } from "@mui/material";
11
+ import {
12
+ AttributesFilterSelectProps,
13
+ FilterMasterStateProps,
14
+ } from "../../../../../types/filter";
15
+ import { useMemo } from "react";
16
+ import CustomSearch from "../../search";
17
+
18
+ const SelectAttribute = ({
19
+ columnsData,
20
+ tableStates,
21
+ dropdownData,
22
+ searchTerm = "",
23
+ setSearchTerm,
24
+ }: AttributesFilterSelectProps) => {
25
+ const { filterMaster, setFilterMaster, filters, setFilters } = tableStates;
26
+
27
+ const selectedAttribute = filterMaster?.attributes?.selected;
28
+
29
+ const handleSelectChange = (event: SelectChangeEvent) => {
30
+ const attributeKey = event.target.value as string;
31
+
32
+ setFilterMaster(
33
+ (prev) =>
34
+ ({
35
+ ...prev,
36
+ attributes: {
37
+ ...prev?.attributes,
38
+ selected: attributeKey,
39
+ },
40
+ } as FilterMasterStateProps)
41
+ );
42
+ };
43
+
44
+ const handleRadioChange = (event: React.ChangeEvent<HTMLInputElement>) => {
45
+ event.preventDefault();
46
+
47
+ const selectedValue = event.target.value;
48
+ setFilterMaster(
49
+ (prev) =>
50
+ ({
51
+ ...prev,
52
+ attributes: {
53
+ ...prev?.attributes,
54
+ radio: selectedValue,
55
+ },
56
+ } as FilterMasterStateProps)
57
+ );
58
+
59
+ const selectedAttribute = filterMaster?.attributes.selected;
60
+ if (selectedAttribute) {
61
+ const matchingColumn = columnsData.column_list.find(
62
+ (column) => column.datasource_list === selectedAttribute
63
+ );
64
+ if (matchingColumn) {
65
+ const defaultOperator =
66
+ columnsData.operation_list[matchingColumn.data_type]?.[0]?.value ||
67
+ "equals";
68
+ const newFilter = {
69
+ filter_attribute: matchingColumn.attribute_key,
70
+ filter_operator: defaultOperator,
71
+ filter_value: selectedValue,
72
+ };
73
+
74
+ const existingFilterIndex = filters.findIndex(
75
+ (filter) => filter.filter_attribute === matchingColumn.attribute_key
76
+ );
77
+
78
+ let updatedFilters;
79
+ if (existingFilterIndex !== -1) {
80
+ updatedFilters = [...filters];
81
+ updatedFilters[existingFilterIndex] = newFilter;
82
+ } else {
83
+ updatedFilters = [...filters, newFilter];
84
+ }
85
+
86
+ setFilters(updatedFilters);
87
+ }
88
+ }
89
+ };
90
+
91
+ const selectedAttributeOptions = useMemo(() => {
92
+ const selected = columnsData.column_list.find(
93
+ (col) => col.datasource_list === selectedAttribute
94
+ )?.attribute_key;
95
+
96
+ return selected ? dropdownData[selected] : [];
97
+ }, [selectedAttribute, dropdownData]);
98
+
99
+ return (
100
+ <Box sx={{ mt: 2 }}>
101
+ <FormControl fullWidth size="small">
102
+ <Select
103
+ value={selectedAttribute || ""}
104
+ onChange={handleSelectChange}
105
+ displayEmpty // Ensures the placeholder is shown when no value is selected
106
+ renderValue={(selected) => {
107
+ if (!selected) {
108
+ return <span>Select Attribute</span>;
109
+ }
110
+ return columnsData?.column_list?.find(
111
+ (col) => col.datasource_list === selected
112
+ )?.name;
113
+ }}
114
+ sx={{
115
+ "& .MuiOutlinedInput-root": {
116
+ borderRadius: "6px",
117
+ fontSize: "14px",
118
+ bgcolor: "#fafafa",
119
+ "& fieldset": {
120
+ borderColor: "#7a5af8 !important",
121
+ },
122
+ "&:hover fieldset": {
123
+ borderColor: "#7a5af8 !important",
124
+ },
125
+ "&.Mui-focused fieldset": {
126
+ borderColor: "#7a5af8 !important",
127
+ boxShadow: "none",
128
+ },
129
+ },
130
+ "& .MuiSelect-select": {
131
+ padding: "8px 14px",
132
+ },
133
+ }}
134
+ >
135
+ {columnsData?.column_list
136
+ ?.filter((column) => column.data_type.includes("select"))
137
+ .map((column, index) => (
138
+ <MenuItem
139
+ key={index}
140
+ value={column.datasource_list}
141
+ disabled={column.datasource_list === selectedAttribute}
142
+ >
143
+ {column.name}
144
+ </MenuItem>
145
+ ))}
146
+ </Select>
147
+ {selectedAttribute && (
148
+ <CustomSearch value={searchTerm} onChange={setSearchTerm} />
149
+ )}
150
+ </FormControl>
151
+
152
+ {dropdownData && (
153
+ <Box sx={{ mt: 2 }}>
154
+ <FormControl>
155
+ <RadioGroup onChange={handleRadioChange}>
156
+ {selectedAttributeOptions
157
+ ?.filter((option) => {
158
+ if (!searchTerm) return true;
159
+
160
+ return option.label
161
+ .toLowerCase()
162
+ .includes(searchTerm.toLowerCase());
163
+ })
164
+ .map((option) => (
165
+ <FormControlLabel
166
+ key={option.value}
167
+ value={option.value}
168
+ control={<Radio />}
169
+ label={option.label}
170
+ />
171
+ ))}
172
+ </RadioGroup>
173
+ </FormControl>
174
+ </Box>
175
+ )}
176
+ </Box>
177
+ );
178
+ };
179
+
180
+ export default SelectAttribute;
@@ -0,0 +1,58 @@
1
+ import { Controller } from "react-hook-form";
2
+ import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
3
+ import { DatePicker } from "@mui/x-date-pickers/DatePicker";
4
+ import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
5
+ import moment from "moment";
6
+ import { UpdatedFilterStateProps } from "../../../../../types/filter";
7
+ import { SxProps, Theme } from "@mui/material";
8
+
9
+ const FormDatePicker = ({
10
+ filter,
11
+ control,
12
+ sx,
13
+ }: {
14
+ filter: UpdatedFilterStateProps;
15
+ control: any;
16
+ sx?: SxProps<Theme>;
17
+ }) => {
18
+ return (
19
+ <Controller
20
+ name={`${filter?.name}.value`} // or use a consistent structure like `filters.${index}.filter_value`
21
+ control={control}
22
+ defaultValue={
23
+ filter.filter_value
24
+ ? moment(filter.filter_value, "DD-MM-YYYY").toDate()
25
+ : null
26
+ }
27
+ render={({ field }) => (
28
+ <LocalizationProvider dateAdapter={AdapterDateFns}>
29
+ <DatePicker
30
+ sx={{
31
+ "& .MuiOutlinedInput-input": {
32
+ padding: "12px 20px",
33
+ },
34
+ }}
35
+ {...field}
36
+ value={
37
+ field.value ? moment(field.value, "DD-MM-YYYY").toDate() : null
38
+ }
39
+ onChange={(date) => {
40
+ const formatted = date ? moment(date).format("DD-MM-YYYY") : "";
41
+ field.onChange(formatted);
42
+ }}
43
+ format="dd-MM-yyyy"
44
+ slotProps={{
45
+ textField: {
46
+ size: "small",
47
+ fullWidth: true,
48
+ placeholder: "DD-MM-YYYY",
49
+ },
50
+ }}
51
+ />
52
+ </LocalizationProvider>
53
+ )}
54
+ />
55
+ );
56
+ };
57
+
58
+ export default FormDatePicker;
@@ -0,0 +1,62 @@
1
+ import { FormControl, MenuItem, Select, SxProps, Theme } from "@mui/material";
2
+ import { Controller } from "react-hook-form";
3
+ import { UpdatedFilterStateProps } from "../../../../../types/filter";
4
+
5
+ interface FormDropdownProps {
6
+ filter: UpdatedFilterStateProps;
7
+ control: any;
8
+ dropdownList: {
9
+ label?: string;
10
+ value?: string;
11
+ }[];
12
+ isLoading?: boolean;
13
+ sx?: SxProps<Theme>;
14
+ }
15
+
16
+ const FormDropdown = ({
17
+ filter,
18
+ control,
19
+ dropdownList,
20
+ isLoading = false,
21
+ sx,
22
+ }: FormDropdownProps) => {
23
+ return (
24
+ <Controller
25
+ name={`${filter?.name}.operator`}
26
+ control={control}
27
+ defaultValue={filter.filter_operator || dropdownList?.[0]?.value || ""}
28
+ render={({ field }) => (
29
+ <FormControl sx={sx} size="small">
30
+ <Select
31
+ {...field}
32
+ variant="standard"
33
+ sx={{
34
+ fontSize: "0.875rem",
35
+ minWidth: 50,
36
+ border: "none",
37
+ boxShadow: "none",
38
+ "& .MuiSelect-icon": {
39
+ top: "45%", // move up
40
+ transform: "translateY(-50%)",
41
+ "& .MuiOutlinedInput-input": {
42
+ padding: "12px 20px",
43
+ },
44
+ },
45
+ }}
46
+ disabled={isLoading}
47
+ disableUnderline
48
+ >
49
+ {dropdownList &&
50
+ dropdownList.map((item, idx) => (
51
+ <MenuItem key={idx} value={item.value}>
52
+ {item.label}
53
+ </MenuItem>
54
+ ))}
55
+ </Select>
56
+ </FormControl>
57
+ )}
58
+ />
59
+ );
60
+ };
61
+
62
+ export default FormDropdown;
@@ -0,0 +1,164 @@
1
+ import {
2
+ Box,
3
+ Button,
4
+ styled,
5
+ List,
6
+ ListItem,
7
+ Paper,
8
+ ListSubheader,
9
+ ListItemText,
10
+ } from "@mui/material";
11
+ import { useState, useRef } from "react";
12
+ import { AddIcon } from "../../../../../assets/svg";
13
+ import {
14
+ FilterColumnsDataProps,
15
+ FilterColumnsListProps,
16
+ UpdatedFilterStateProps,
17
+ } from "../../../../../types/filter";
18
+ import { CraftTableOptionsProps } from "../../../../../types/table-options";
19
+
20
+ const FilterCriteria = ({
21
+ columnsData,
22
+ tableStates,
23
+ setSelectedFilters,
24
+ }: {
25
+ columnsData: FilterColumnsDataProps;
26
+ tableStates: CraftTableOptionsProps;
27
+ setSelectedFilters: React.Dispatch<
28
+ React.SetStateAction<UpdatedFilterStateProps[]>
29
+ >;
30
+ }) => {
31
+ const FilterButton = styled(Button)(({ theme }) => ({
32
+ borderRadius: 20,
33
+ borderColor: theme.palette.primary.main,
34
+ color: theme.palette.primary.main,
35
+ textTransform: "none",
36
+ padding: "8px 16px",
37
+ "&:hover": {
38
+ borderColor: theme.palette.primary.dark,
39
+ },
40
+ }));
41
+
42
+ const [showFilterOptions, setShowFilterOption] = useState(false);
43
+ const { filters, setFilters } = tableStates;
44
+ const filterButtonRef = useRef<HTMLButtonElement>(null);
45
+
46
+ const handleAddFilter = (column: FilterColumnsListProps) => {
47
+ const dropdownOptions = columnsData.operation_list[column.data_type];
48
+ const defaultValue = column.data_type === "multiselect" ? [] : "";
49
+ const defaultOperator = dropdownOptions?.[0]?.value || "";
50
+ const matchingDropdownList =
51
+ columnsData.operation_list[column.data_type] || [];
52
+
53
+ const newFilter = {
54
+ filter_attribute: column.attribute_key,
55
+ filter_operator: defaultOperator,
56
+ filter_value: defaultValue,
57
+ };
58
+
59
+ const newSelectedFilter = {
60
+ ...newFilter,
61
+ id: column.id,
62
+ name: column.name,
63
+ data_type: column.data_type,
64
+ dropdown_list: matchingDropdownList,
65
+ };
66
+
67
+ setFilters((prev) => [...prev, newFilter]);
68
+ setSelectedFilters((prev) => [...prev, newSelectedFilter]);
69
+ // if (editMode) {
70
+ // setEditFilters((prev) => [...prev, newFilter]);
71
+ // setSelectedFilters((prev) => [...prev, newSelectedFilter]);
72
+ // } else {
73
+ // setFilters((prev) => [...prev, newFilter]);
74
+ // setSelectedFilters((prev) => [...prev, newSelectedFilter]);
75
+ // }
76
+
77
+ setShowFilterOption(false);
78
+ };
79
+
80
+ const toggleFilterOptions = () => {
81
+ setShowFilterOption((prev) => !prev);
82
+ };
83
+
84
+ return (
85
+ <Box>
86
+ <FilterButton
87
+ fullWidth
88
+ startIcon={<AddIcon />}
89
+ onClick={toggleFilterOptions}
90
+ sx={{
91
+ bgcolor: "#eae4fe",
92
+ borderRadius: "6px",
93
+ color: "#7a5af8",
94
+ fontSize: "13px",
95
+ fontWeight: 500,
96
+ }}
97
+ ref={filterButtonRef}
98
+ >
99
+ Filter Criteria
100
+ </FilterButton>
101
+
102
+ {showFilterOptions && (
103
+ <Paper
104
+ sx={{
105
+ mt: 2,
106
+ width: filterButtonRef.current?.offsetWidth || 360, // Dynamic width based on button
107
+ p: 1,
108
+ maxHeight: "300px",
109
+ overflowY: "auto",
110
+ cursor: "pointer",
111
+ position: "absolute",
112
+ zIndex: 1300,
113
+ }}
114
+ >
115
+ <Box
116
+ sx={{
117
+ maxHeight: "300px", // Adjust height as needed
118
+ overflowY: "auto", // Enable vertical scrolling
119
+ width: "100%", // Adjust width as needed
120
+ }}
121
+ >
122
+ <List
123
+ subheader={
124
+ <ListSubheader
125
+ component="div"
126
+ sx={{
127
+ fontWeight: "bold",
128
+ bgcolor: "#f5f5f9",
129
+ borderRadius: "6px",
130
+ }}
131
+ >
132
+ Filter by...
133
+ </ListSubheader>
134
+ }
135
+ >
136
+ {columnsData?.column_list?.map((column, index) => {
137
+ const isAlreadySelected = filters?.some(
138
+ (filter) => filter.filter_attribute === column.attribute_key
139
+ );
140
+
141
+ return (
142
+ <ListItem
143
+ key={index}
144
+ onClick={() =>
145
+ !isAlreadySelected && handleAddFilter(column)
146
+ } // Prevent click if already selected
147
+ sx={{
148
+ opacity: isAlreadySelected ? 0.5 : 1,
149
+ cursor: isAlreadySelected ? "not-allowed" : "pointer",
150
+ }}
151
+ >
152
+ <ListItemText primary={column.name} />
153
+ </ListItem>
154
+ );
155
+ })}
156
+ </List>
157
+ </Box>
158
+ </Paper>
159
+ )}
160
+ </Box>
161
+ );
162
+ };
163
+
164
+ export default FilterCriteria;
@@ -0,0 +1,57 @@
1
+ import { Controller } from "react-hook-form";
2
+ import { FormControl, Select, MenuItem, Theme, SxProps } from "@mui/material";
3
+ import { UpdatedFilterStateProps } from "../../../../../types/filter";
4
+ import { DropdownOption } from "../../../../../types/common";
5
+
6
+ const FormMultiSelect = ({
7
+ filter,
8
+ control,
9
+ dropdownData,
10
+ sx,
11
+ }: {
12
+ filter: UpdatedFilterStateProps;
13
+ control: any;
14
+ dropdownData: Record<string, DropdownOption[]>;
15
+ sx?: SxProps<Theme>;
16
+ }) => {
17
+ const options = dropdownData[filter.filter_attribute] || [];
18
+
19
+ return (
20
+ <Controller
21
+ name={`${filter?.name}.value`}
22
+ control={control}
23
+ defaultValue={filter.filter_value || []}
24
+ render={({ field }) => (
25
+ <FormControl sx={sx} fullWidth size="small">
26
+ <Select
27
+ {...field}
28
+ sx={{
29
+ "& .MuiOutlinedInput-input": {
30
+ padding: "12px 20px",
31
+ },
32
+ }}
33
+ multiple
34
+ value={field.value || []}
35
+ onChange={(e) => field.onChange(e.target.value)}
36
+ renderValue={(selected: string[]) =>
37
+ selected
38
+ .map(
39
+ (val) =>
40
+ options.find((item) => item.value === val)?.label || val
41
+ )
42
+ .join(", ")
43
+ }
44
+ >
45
+ {options.map((item, idx) => (
46
+ <MenuItem key={idx} value={item.value}>
47
+ {item.label}
48
+ </MenuItem>
49
+ ))}
50
+ </Select>
51
+ </FormControl>
52
+ )}
53
+ />
54
+ );
55
+ };
56
+
57
+ export default FormMultiSelect;
@@ -0,0 +1,53 @@
1
+ import { FormControl, MenuItem, Select, SxProps, Theme } from "@mui/material";
2
+ import { Controller } from "react-hook-form";
3
+ import { UpdatedFilterStateProps } from "../../../../../types/filter";
4
+ import { DropdownOption } from "../../../../../types/common";
5
+
6
+ interface FormSelectProps {
7
+ filter: UpdatedFilterStateProps;
8
+ control: any;
9
+ dropdownData: Record<string, DropdownOption[]>;
10
+ isLoading?: boolean;
11
+ sx?: SxProps<Theme>;
12
+ }
13
+
14
+ const FormSelect = ({
15
+ filter,
16
+ control,
17
+ dropdownData,
18
+ isLoading = false,
19
+ sx,
20
+ }: FormSelectProps) => {
21
+ // Use dropdownData if available, otherwise fallback to filter's dropdown_list
22
+ const dropdownOptions =
23
+ dropdownData[filter.filter_attribute] || filter.dropdown_list || [];
24
+
25
+ return (
26
+ <Controller
27
+ name={`${filter?.name}.value`}
28
+ control={control}
29
+ defaultValue={filter.filter_value || ""}
30
+ render={({ field }) => (
31
+ <FormControl sx={sx} fullWidth size="small">
32
+ <Select
33
+ {...field}
34
+ disabled={isLoading}
35
+ sx={{
36
+ "& .MuiOutlinedInput-input": {
37
+ padding: "12px 20px",
38
+ },
39
+ }}
40
+ >
41
+ {dropdownOptions.map((item, idx) => (
42
+ <MenuItem key={idx} value={item.value}>
43
+ {item.label}
44
+ </MenuItem>
45
+ ))}
46
+ </Select>
47
+ </FormControl>
48
+ )}
49
+ />
50
+ );
51
+ };
52
+
53
+ export default FormSelect;
@@ -0,0 +1,43 @@
1
+ import { TextField } from "@mui/material";
2
+ import { Controller } from "react-hook-form";
3
+ import { TextFieldStyles } from "./styles";
4
+ import { UpdatedFilterStateProps } from "../../../../../types/filter";
5
+
6
+ interface FormTextfieldProps {
7
+ filter: UpdatedFilterStateProps;
8
+ control: any;
9
+ isLoading?: boolean;
10
+ }
11
+
12
+ const FormTextfield = ({
13
+ filter,
14
+ control,
15
+ isLoading = false,
16
+ }: FormTextfieldProps) => {
17
+ return (
18
+ <Controller
19
+ name={`${filter?.name}.value`}
20
+ control={control}
21
+ defaultValue={filter.filter_value || ""}
22
+ render={({ field }) => (
23
+ <TextField
24
+ {...field}
25
+ fullWidth
26
+ variant="outlined"
27
+ size="small"
28
+ sx={{
29
+ ...TextFieldStyles,
30
+ "& .MuiOutlinedInput-input": {
31
+ padding: "12px 20px",
32
+ },
33
+ }}
34
+ type={filter.data_type || "text"}
35
+ placeholder={"Enter value"}
36
+ disabled={isLoading}
37
+ />
38
+ )}
39
+ />
40
+ );
41
+ };
42
+
43
+ export default FormTextfield;
@@ -0,0 +1,11 @@
1
+ export const TextFieldStyles = {
2
+ "& .MuiOutlinedInput-root": {
3
+ borderRadius: "6px",
4
+ fontSize: "14px",
5
+ bgcolor: "#fafafa",
6
+ "& fieldset": { borderColor: "#c1c1c1" },
7
+ "&.Mui-focused fieldset": {
8
+ borderColor: "#7A5AF8",
9
+ },
10
+ },
11
+ };