rez-table-listing-mui 1.0.48 → 1.0.50
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.
- package/dist/index.d.ts +7 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/src/App.tsx +81 -24
- package/src/assets/svg.tsx +5 -5
- package/src/components/filter/components/attributes-filter.tsx +78 -52
- package/src/components/filter/components/forms/components/Date.tsx +178 -109
- package/src/components/filter/components/forms/components/Dropdown.tsx +36 -3
- package/src/components/filter/components/forms/components/Filter-criteria.tsx +3 -3
- package/src/components/filter/components/forms/components/Multi-Select.tsx +62 -34
- package/src/components/filter/components/forms/index.tsx +29 -7
- package/src/components/filter/components/main-filter.tsx +3 -0
- package/src/components/filter/components/saved-edit-filter.tsx +6 -0
- package/src/components/filter/components/saved-filter.tsx +66 -9
- package/src/components/filter/components/search/index.tsx +18 -1
- package/src/components/filter/index.tsx +21 -6
- package/src/components/filter/style.ts +1 -1
- package/src/components/index.scss +1 -1
- package/src/components/table-settings/common/info-alert.tsx +37 -0
- package/src/components/table-settings/common/listing-values.tsx +102 -54
- package/src/components/table-settings/components/column.tsx +206 -173
- package/src/components/table-settings/components/quick-tab.tsx +281 -153
- package/src/components/table-settings/components/sorting.tsx +135 -120
- package/src/components/table-settings/components/toggle-button-switch.tsx +2 -2
- package/src/components/table-settings/index.tsx +3 -5
- package/src/components/table-settings/style.ts +1 -0
- package/src/components/topbar/index.tsx +3 -1
- package/src/libs/hooks/useCraftTable.tsx +5 -0
- package/src/libs/hooks/useElementWidth.tsx +2 -2
- package/src/libs/hooks/useEntityTableAPI.tsx +1 -16
- package/src/libs/utils/apiColumn.ts +1 -11
- package/src/libs/utils/common.ts +4 -3
- package/src/types/filter-settings.ts +11 -0
- package/src/types/filter.ts +1 -2
- package/src/types/table-options.ts +2 -0
|
@@ -13,9 +13,10 @@ import {
|
|
|
13
13
|
Typography,
|
|
14
14
|
} from "@mui/material";
|
|
15
15
|
import CustomSearch from "./search";
|
|
16
|
-
import { DeleteIcon } from "../../../assets/svg";
|
|
16
|
+
import { DeleteIcon, EditIcon } from "../../../assets/svg";
|
|
17
17
|
import SavedFilterEditComponent from "./saved-edit-filter";
|
|
18
18
|
import { filterStyles } from "../style";
|
|
19
|
+
import { CheckBox } from "../../../assets/svg";
|
|
19
20
|
|
|
20
21
|
const SavedFilter = ({
|
|
21
22
|
columnsData,
|
|
@@ -31,6 +32,7 @@ const SavedFilter = ({
|
|
|
31
32
|
}: FilterFormComponentProps) => {
|
|
32
33
|
const { setFilterMaster, setFilterToDelete } = tableStates;
|
|
33
34
|
const [searchTerm, setSearchTerm] = useState<string>("");
|
|
35
|
+
const [criteriaSearchTerm, setCriteriaSearchTerm] = useState<string>("");
|
|
34
36
|
|
|
35
37
|
// reset savedFilterEditValue when component unmounts
|
|
36
38
|
useEffect(() => {
|
|
@@ -65,11 +67,26 @@ const SavedFilter = ({
|
|
|
65
67
|
activeFilterTabIndex: tabValue,
|
|
66
68
|
} as FilterMasterStateProps)
|
|
67
69
|
);
|
|
68
|
-
|
|
70
|
+
// setEditfilter state on edit icon click
|
|
69
71
|
setEditMode && setEditMode(true);
|
|
70
72
|
setFilterToDelete(filter);
|
|
71
73
|
};
|
|
72
74
|
|
|
75
|
+
const handleAppyFilter = (filter: FilterOperationListProps) => {
|
|
76
|
+
setFilterMaster(
|
|
77
|
+
(prev) =>
|
|
78
|
+
({
|
|
79
|
+
...prev,
|
|
80
|
+
saved_filters: {
|
|
81
|
+
...prev?.attributes,
|
|
82
|
+
selectedId: filter?.value,
|
|
83
|
+
selectedName: filter?.label,
|
|
84
|
+
},
|
|
85
|
+
activeFilterTabIndex: tabValue,
|
|
86
|
+
} as FilterMasterStateProps)
|
|
87
|
+
);
|
|
88
|
+
};
|
|
89
|
+
|
|
73
90
|
const renderList = () => (
|
|
74
91
|
<>
|
|
75
92
|
<CustomSearch
|
|
@@ -98,24 +115,62 @@ const SavedFilter = ({
|
|
|
98
115
|
key={filter?.value}
|
|
99
116
|
sx={{
|
|
100
117
|
cursor: "pointer",
|
|
101
|
-
border:
|
|
118
|
+
border:
|
|
119
|
+
filter?.value ===
|
|
120
|
+
tableStates?.filterMaster?.saved_filters?.selectedId
|
|
121
|
+
? `3px solid #7a5af8`
|
|
122
|
+
: "1px solid #C5C5C5",
|
|
102
123
|
borderRadius: "8px",
|
|
103
124
|
display: "flex",
|
|
104
125
|
justifyContent: "space-between",
|
|
126
|
+
gap: 1,
|
|
105
127
|
alignItems: "center",
|
|
128
|
+
"&:hover .action-icons": {
|
|
129
|
+
opacity: 1,
|
|
130
|
+
visibility: "visible",
|
|
131
|
+
},
|
|
106
132
|
}}
|
|
107
|
-
onClick={() =>
|
|
133
|
+
onClick={() => handleAppyFilter(filter)}
|
|
108
134
|
>
|
|
135
|
+
{filter?.value ===
|
|
136
|
+
tableStates?.filterMaster?.saved_filters?.selectedId && (
|
|
137
|
+
<Box
|
|
138
|
+
sx={{
|
|
139
|
+
display: "flex",
|
|
140
|
+
alignItems: "center",
|
|
141
|
+
cursor: "pointer",
|
|
142
|
+
color: "green",
|
|
143
|
+
rounded: "full",
|
|
144
|
+
}}
|
|
145
|
+
>
|
|
146
|
+
<CheckBox />
|
|
147
|
+
</Box>
|
|
148
|
+
)}
|
|
109
149
|
<ListItemText primary={filter?.label} />
|
|
110
150
|
|
|
111
|
-
<Box
|
|
151
|
+
<Box
|
|
152
|
+
onClick={(e) => e.stopPropagation()}
|
|
153
|
+
className="action-icons"
|
|
154
|
+
sx={{
|
|
155
|
+
display: "flex",
|
|
156
|
+
gap: 1,
|
|
157
|
+
opacity: 0,
|
|
158
|
+
visibility: "hidden",
|
|
159
|
+
transition: "opacity 0.2s ease, visibility 0.2s ease",
|
|
160
|
+
}}
|
|
161
|
+
>
|
|
162
|
+
<IconButton
|
|
163
|
+
size="large"
|
|
164
|
+
onClick={() => handleListItemClick(filter)}
|
|
165
|
+
>
|
|
166
|
+
<EditIcon />
|
|
167
|
+
</IconButton>
|
|
168
|
+
|
|
112
169
|
<IconButton
|
|
113
170
|
size="small"
|
|
114
171
|
onClick={() => {
|
|
115
|
-
setFilterToDelete(filter);
|
|
116
|
-
|
|
117
|
-
setDeleteFilterModalOpen &&
|
|
118
|
-
setDeleteFilterModalOpen(true); // Open the delete confirmation modal
|
|
172
|
+
setFilterToDelete(filter);
|
|
173
|
+
setDeleteFilterModalOpen?.(true);
|
|
119
174
|
}}
|
|
120
175
|
>
|
|
121
176
|
<DeleteIcon />
|
|
@@ -149,6 +204,8 @@ const SavedFilter = ({
|
|
|
149
204
|
setEditMode={setEditMode}
|
|
150
205
|
searchTerm={searchTerm}
|
|
151
206
|
setSearchTerm={setSearchTerm}
|
|
207
|
+
criteriaSearchTerm={criteriaSearchTerm}
|
|
208
|
+
setCriteriaSearchTerm={setCriteriaSearchTerm}
|
|
152
209
|
setSavedFilterModalOpen={setSavedFilterModalOpen}
|
|
153
210
|
setDeleteFilterModalOpen={setDeleteFilterModalOpen}
|
|
154
211
|
/>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React, { useState } from "react";
|
|
2
|
-
import { TextField, InputAdornment } from "@mui/material";
|
|
2
|
+
import { TextField, InputAdornment, IconButton } from "@mui/material";
|
|
3
3
|
import SearchIcon from "@mui/icons-material/Search";
|
|
4
|
+
import { CloseIcon } from "../../../../assets/svg";
|
|
4
5
|
|
|
5
6
|
interface SearchInputProps {
|
|
6
7
|
value: string;
|
|
@@ -22,6 +23,11 @@ const CustomSearch = ({
|
|
|
22
23
|
onChange?.(val);
|
|
23
24
|
};
|
|
24
25
|
|
|
26
|
+
const handleClear = () => {
|
|
27
|
+
setSearch(""); // Clear the search value
|
|
28
|
+
onChange?.(""); // Propagate the cleared value
|
|
29
|
+
};
|
|
30
|
+
|
|
25
31
|
return (
|
|
26
32
|
<TextField
|
|
27
33
|
fullWidth
|
|
@@ -39,6 +45,17 @@ const CustomSearch = ({
|
|
|
39
45
|
/>
|
|
40
46
|
</InputAdornment>
|
|
41
47
|
),
|
|
48
|
+
endAdornment: search && ( // Show the clear icon only when there's a value
|
|
49
|
+
<InputAdornment position="end">
|
|
50
|
+
<IconButton
|
|
51
|
+
edge="end"
|
|
52
|
+
onClick={handleClear}
|
|
53
|
+
sx={{ color: "#888888", fontSize: "20px" }}
|
|
54
|
+
>
|
|
55
|
+
<CloseIcon />
|
|
56
|
+
</IconButton>
|
|
57
|
+
</InputAdornment>
|
|
58
|
+
),
|
|
42
59
|
}}
|
|
43
60
|
sx={{
|
|
44
61
|
"& .MuiOutlinedInput-root": {
|
|
@@ -36,8 +36,14 @@ export function TableFilter({
|
|
|
36
36
|
|
|
37
37
|
const [searchTerm, setSearchTerm] = useState<string>("");
|
|
38
38
|
|
|
39
|
-
const {
|
|
40
|
-
|
|
39
|
+
const {
|
|
40
|
+
filters,
|
|
41
|
+
setFilters,
|
|
42
|
+
filterToDelete,
|
|
43
|
+
filterMaster,
|
|
44
|
+
setFilterMaster,
|
|
45
|
+
setShowFilterOption,
|
|
46
|
+
} = tableStates;
|
|
41
47
|
|
|
42
48
|
const filterNameInput: InputField = {
|
|
43
49
|
label: "Filter Name",
|
|
@@ -73,7 +79,7 @@ export function TableFilter({
|
|
|
73
79
|
|
|
74
80
|
const handleTabChange = (_: React.SyntheticEvent, newValue: number) => {
|
|
75
81
|
setTabValue(newValue);
|
|
76
|
-
if (newValue
|
|
82
|
+
if (newValue === 0) {
|
|
77
83
|
setEditMode(false);
|
|
78
84
|
setSelectedFilters([]);
|
|
79
85
|
}
|
|
@@ -83,7 +89,7 @@ export function TableFilter({
|
|
|
83
89
|
const tabItems: TabItem[] = [
|
|
84
90
|
{ label: "Filter" },
|
|
85
91
|
{ label: "Saved Filter" },
|
|
86
|
-
|
|
92
|
+
{ label: "Attributes" },
|
|
87
93
|
];
|
|
88
94
|
|
|
89
95
|
const handleTabCrossClick = (index: number) => {
|
|
@@ -116,7 +122,7 @@ export function TableFilter({
|
|
|
116
122
|
({
|
|
117
123
|
...prev,
|
|
118
124
|
attributes: {
|
|
119
|
-
radio:
|
|
125
|
+
radio: [],
|
|
120
126
|
selected: "",
|
|
121
127
|
},
|
|
122
128
|
} as FilterMasterStateProps)
|
|
@@ -137,6 +143,7 @@ export function TableFilter({
|
|
|
137
143
|
onClick={(e) => {
|
|
138
144
|
e.stopPropagation();
|
|
139
145
|
onClose && onClose();
|
|
146
|
+
setShowFilterOption(false);
|
|
140
147
|
}}
|
|
141
148
|
aria-label="close"
|
|
142
149
|
>
|
|
@@ -256,11 +263,19 @@ export function TableFilter({
|
|
|
256
263
|
},
|
|
257
264
|
{
|
|
258
265
|
label: "Delete",
|
|
259
|
-
|
|
260
266
|
onClick: () => {
|
|
261
267
|
onDeleteFilter && onDeleteFilter();
|
|
262
268
|
setDeleteFilterModalOpen(false);
|
|
263
269
|
setEditMode && setEditMode(false);
|
|
270
|
+
setSelectedFilters([]);
|
|
271
|
+
setFilters([]);
|
|
272
|
+
setFilterMaster(
|
|
273
|
+
(prev) =>
|
|
274
|
+
({
|
|
275
|
+
...prev,
|
|
276
|
+
activeFilterTabIndex: -1,
|
|
277
|
+
} as FilterMasterStateProps)
|
|
278
|
+
);
|
|
264
279
|
},
|
|
265
280
|
variant: "contained",
|
|
266
281
|
sx: {
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { Alert, Box } from "@mui/material";
|
|
2
|
+
|
|
3
|
+
interface InfoAlertProps {
|
|
4
|
+
message: string;
|
|
5
|
+
width?: string | number;
|
|
6
|
+
top?: number | string;
|
|
7
|
+
color?: string;
|
|
8
|
+
zIndex?: number;
|
|
9
|
+
position?: "absolute" | "relative" | "fixed" | "sticky";
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const InfoAlert = ({
|
|
13
|
+
message,
|
|
14
|
+
width = "100%",
|
|
15
|
+
top = 10,
|
|
16
|
+
color = "#088AB2",
|
|
17
|
+
zIndex = 0,
|
|
18
|
+
position = "absolute",
|
|
19
|
+
}: InfoAlertProps) => {
|
|
20
|
+
return (
|
|
21
|
+
<Box
|
|
22
|
+
sx={{
|
|
23
|
+
fontSize: "12px",
|
|
24
|
+
color,
|
|
25
|
+
width,
|
|
26
|
+
height: "fit-content",
|
|
27
|
+
position,
|
|
28
|
+
zIndex,
|
|
29
|
+
top,
|
|
30
|
+
}}
|
|
31
|
+
>
|
|
32
|
+
<Alert severity="info">{message}</Alert>
|
|
33
|
+
</Box>
|
|
34
|
+
);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export default InfoAlert;
|
|
@@ -1,4 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import {
|
|
2
|
+
Alert,
|
|
3
|
+
Box,
|
|
4
|
+
Button,
|
|
5
|
+
Grid,
|
|
6
|
+
IconButton,
|
|
7
|
+
Typography,
|
|
8
|
+
} from "@mui/material";
|
|
2
9
|
import CustomSearch from "../../filter/components/search/index.tsx";
|
|
3
10
|
import {
|
|
4
11
|
SortableContext,
|
|
@@ -9,6 +16,8 @@ import DraggableListItem from "./draggable-listitem.tsx";
|
|
|
9
16
|
import { listingValuesStyles } from "../style.ts";
|
|
10
17
|
import Loader from "../../common/loader/loader.tsx";
|
|
11
18
|
import { ClosedEyeIcon, EyeIcon } from "../../../assets/svg.tsx";
|
|
19
|
+
import InfoAlert from "./info-alert.tsx";
|
|
20
|
+
import React from "react";
|
|
12
21
|
``;
|
|
13
22
|
|
|
14
23
|
interface FilterValue {
|
|
@@ -26,8 +35,42 @@ interface ListingValuesProps {
|
|
|
26
35
|
containerId: string;
|
|
27
36
|
tabsApiDataLoading?: boolean;
|
|
28
37
|
onItemToggle: (itemId: string, fromContainerId: string) => void;
|
|
38
|
+
enableDragAndDrop?: boolean;
|
|
39
|
+
isQuickTabActive?: boolean;
|
|
40
|
+
AlertComponenet?: React.ReactNode;
|
|
29
41
|
}
|
|
30
42
|
|
|
43
|
+
const ListingValuesContent = ({
|
|
44
|
+
item,
|
|
45
|
+
containerId,
|
|
46
|
+
onItemToggle,
|
|
47
|
+
}: {
|
|
48
|
+
item: FilterValue;
|
|
49
|
+
containerId: string;
|
|
50
|
+
onItemToggle: (itemId: string, fromContainerId: string) => void;
|
|
51
|
+
}) => {
|
|
52
|
+
return (
|
|
53
|
+
<Box
|
|
54
|
+
sx={{
|
|
55
|
+
display: "flex",
|
|
56
|
+
alignItems: "center",
|
|
57
|
+
justifyContent: "space-between",
|
|
58
|
+
gap: 1,
|
|
59
|
+
flex: 1,
|
|
60
|
+
color: containerId === "tabs" ? "black" : "#9e9d9b",
|
|
61
|
+
}}
|
|
62
|
+
>
|
|
63
|
+
<Typography>{item.label}</Typography>
|
|
64
|
+
<IconButton
|
|
65
|
+
size="small"
|
|
66
|
+
onClick={() => onItemToggle(item.id, containerId)}
|
|
67
|
+
>
|
|
68
|
+
{containerId === "tabs" ? <EyeIcon /> : <ClosedEyeIcon />}
|
|
69
|
+
</IconButton>
|
|
70
|
+
</Box>
|
|
71
|
+
);
|
|
72
|
+
};
|
|
73
|
+
|
|
31
74
|
const ListingValues = ({
|
|
32
75
|
filteredValues,
|
|
33
76
|
buttonText,
|
|
@@ -38,6 +81,8 @@ const ListingValues = ({
|
|
|
38
81
|
containerId,
|
|
39
82
|
tabsApiDataLoading,
|
|
40
83
|
onItemToggle,
|
|
84
|
+
enableDragAndDrop = true,
|
|
85
|
+
AlertComponenet,
|
|
41
86
|
}: ListingValuesProps) => {
|
|
42
87
|
const { setNodeRef } = useDroppable({
|
|
43
88
|
id: containerId,
|
|
@@ -52,62 +97,65 @@ const ListingValues = ({
|
|
|
52
97
|
{tabsApiDataLoading ? (
|
|
53
98
|
<Loader />
|
|
54
99
|
) : (
|
|
55
|
-
|
|
56
|
-
<Box sx={
|
|
57
|
-
<
|
|
58
|
-
{
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
{searchTerm !== undefined && setSearchTerm !== undefined && (
|
|
72
|
-
<CustomSearch value={searchTerm} onChange={setSearchTerm} />
|
|
73
|
-
)}
|
|
100
|
+
<>
|
|
101
|
+
<Box sx={{ p: 2, zIndex: 10 }}>
|
|
102
|
+
<Box sx={listingValuesStyles.headerContainer}>
|
|
103
|
+
<Typography variant="h6" sx={listingValuesStyles.heading}>
|
|
104
|
+
{headerText}
|
|
105
|
+
</Typography>
|
|
106
|
+
<Button
|
|
107
|
+
onClick={onClick}
|
|
108
|
+
variant="text"
|
|
109
|
+
size="small"
|
|
110
|
+
sx={listingValuesStyles.button}
|
|
111
|
+
disabled={filteredValues.length === 0}
|
|
112
|
+
>
|
|
113
|
+
{buttonText}
|
|
114
|
+
</Button>
|
|
115
|
+
</Box>
|
|
74
116
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
strategy={verticalListSortingStrategy}
|
|
79
|
-
>
|
|
80
|
-
<Box sx={listingValuesStyles.draggableCover}>
|
|
81
|
-
{filteredValues.map((item) => (
|
|
82
|
-
<DraggableListItem
|
|
83
|
-
key={item.id}
|
|
84
|
-
id={item.id}
|
|
85
|
-
containerId={containerId}
|
|
86
|
-
>
|
|
87
|
-
<Box
|
|
88
|
-
sx={{
|
|
89
|
-
display: "flex",
|
|
90
|
-
alignItems: "center",
|
|
91
|
-
flex: 1,
|
|
92
|
-
color: containerId === "tabs" ? "black" : "#9e9d9b",
|
|
93
|
-
}}
|
|
94
|
-
>
|
|
95
|
-
<Typography>{item.label}</Typography>
|
|
96
|
-
</Box>
|
|
117
|
+
{searchTerm !== undefined && setSearchTerm !== undefined && (
|
|
118
|
+
<CustomSearch value={searchTerm} onChange={setSearchTerm} />
|
|
119
|
+
)}
|
|
97
120
|
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
121
|
+
<Box ref={setNodeRef} sx={listingValuesStyles.draggableContainer}>
|
|
122
|
+
{enableDragAndDrop ? (
|
|
123
|
+
<SortableContext
|
|
124
|
+
items={filteredValues.map((item) => item.id)}
|
|
125
|
+
strategy={verticalListSortingStrategy}
|
|
126
|
+
>
|
|
127
|
+
<Box sx={listingValuesStyles.draggableCover}>
|
|
128
|
+
{filteredValues.map((item) => (
|
|
129
|
+
<DraggableListItem
|
|
130
|
+
key={item.id}
|
|
131
|
+
id={item.id}
|
|
132
|
+
containerId={containerId}
|
|
133
|
+
>
|
|
134
|
+
<ListingValuesContent
|
|
135
|
+
item={item}
|
|
136
|
+
containerId={containerId}
|
|
137
|
+
onItemToggle={onItemToggle}
|
|
138
|
+
/>
|
|
139
|
+
</DraggableListItem>
|
|
140
|
+
))}
|
|
141
|
+
</Box>
|
|
142
|
+
</SortableContext>
|
|
143
|
+
) : (
|
|
144
|
+
<Box sx={listingValuesStyles.draggableCover}>
|
|
145
|
+
{filteredValues.map((item) => (
|
|
146
|
+
<ListingValuesContent
|
|
147
|
+
key={item.id}
|
|
148
|
+
item={item}
|
|
149
|
+
containerId={containerId}
|
|
150
|
+
onItemToggle={onItemToggle}
|
|
151
|
+
/>
|
|
152
|
+
))}
|
|
153
|
+
</Box>
|
|
154
|
+
)}
|
|
155
|
+
</Box>
|
|
109
156
|
</Box>
|
|
110
|
-
|
|
157
|
+
{AlertComponenet && AlertComponenet}
|
|
158
|
+
</>
|
|
111
159
|
)}
|
|
112
160
|
</Grid>
|
|
113
161
|
);
|