rez-table-listing-mui 1.2.19 → 1.3.1
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/package.json +2 -3
- package/src/index.ts +1 -0
- package/src/listing/components/common/loader/loader.tsx +1 -0
- package/src/listing/components/filter/components/attributes-filter.tsx +3 -91
- package/src/listing/components/filter/components/forms/components/Date.tsx +2 -2
- package/src/listing/components/filter/components/forms/components/Dropdown.tsx +2 -2
- package/src/listing/components/filter/components/forms/components/Filter-criteria.tsx +31 -82
- package/src/listing/components/filter/components/forms/components/Multi-Select.tsx +2 -2
- package/src/listing/components/filter/components/forms/components/Select.tsx +2 -2
- package/src/listing/components/filter/components/forms/components/Textfield.tsx +2 -2
- package/src/listing/components/filter/components/forms/components/empty-list.tsx +17 -0
- package/src/listing/components/filter/components/forms/components/filter-criteria-entity-list.tsx +92 -0
- package/src/listing/components/filter/components/forms/components/filter-criteria-list.tsx +104 -0
- package/src/listing/components/filter/components/forms/components/styles.tsx +2 -1
- package/src/listing/components/filter/components/forms/index.tsx +238 -174
- package/src/listing/components/filter/components/main-filter.tsx +6 -14
- package/src/listing/components/filter/components/saved-edit-filter.tsx +0 -31
- package/src/listing/components/filter/components/saved-filter.tsx +0 -22
- package/src/listing/components/filter/components/search/index.tsx +2 -2
- package/src/listing/components/filter/index.tsx +162 -130
- package/src/listing/components/filter/style.ts +20 -3
- package/src/listing/libs/hooks/useCraftTable.tsx +9 -0
- package/src/listing/libs/hooks/useEntityTableAPI.tsx +25 -0
- package/src/listing/libs/utils/apiColumn.ts +27 -1
- package/src/listing/libs/utils/deep-merge-objects.ts +18 -0
- package/src/listing/types/common.ts +0 -2
- package/src/listing/types/filter.ts +54 -7
- package/src/listing/types/table-options.ts +8 -0
- package/src/view/FIlterWrapper.tsx +45 -6
- package/dist/index.d.ts +0 -361
- package/dist/index.js +0 -2
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -2
- package/dist/index.mjs.map +0 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "rez-table-listing-mui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A rez table listing component built on TanStack Table",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -25,8 +25,7 @@
|
|
|
25
25
|
"@dnd-kit/modifiers": "^7.0.0",
|
|
26
26
|
"@dnd-kit/sortable": "^8.0.0",
|
|
27
27
|
"@dnd-kit/utilities": "^3.2.2",
|
|
28
|
-
"@tanstack/react-table": "^8.20.5"
|
|
29
|
-
"@tanstack/react-query": "^5.76.1"
|
|
28
|
+
"@tanstack/react-table": "^8.20.5"
|
|
30
29
|
},
|
|
31
30
|
"peerDependencies": {
|
|
32
31
|
"@dnd-kit/core": "^6.1.0",
|
package/src/index.ts
CHANGED
|
@@ -27,25 +27,6 @@ const AttributesFilter = ({
|
|
|
27
27
|
|
|
28
28
|
const selectedAttribute = filterMaster?.attributes?.selected;
|
|
29
29
|
|
|
30
|
-
// Get the current filter value (single selection)
|
|
31
|
-
// const currentFilterValue = useMemo(() => {
|
|
32
|
-
// if (!selectedAttribute) return [];
|
|
33
|
-
|
|
34
|
-
// const matchingColumn = columnsData?.column_list?.find(
|
|
35
|
-
// (column) => column.datasource_list === selectedAttribute
|
|
36
|
-
// );
|
|
37
|
-
|
|
38
|
-
// if (!matchingColumn) return [];
|
|
39
|
-
|
|
40
|
-
// const existingFilter = filters.find(
|
|
41
|
-
// (filter) => filter.filter_attribute === matchingColumn.attribute_key
|
|
42
|
-
// );
|
|
43
|
-
|
|
44
|
-
// return Array.isArray(existingFilter?.filter_value)
|
|
45
|
-
// ? existingFilter?.filter_value
|
|
46
|
-
// : [];
|
|
47
|
-
// }, [selectedAttribute, filters, columnsData]);
|
|
48
|
-
|
|
49
30
|
const currentRadio = useMemo(() => {
|
|
50
31
|
return Array.isArray(filterMaster?.attributes?.radio)
|
|
51
32
|
? (filterMaster!.attributes!.radio as string[])
|
|
@@ -74,76 +55,6 @@ const AttributesFilter = ({
|
|
|
74
55
|
onChangeFunction && onChangeFunction(newState);
|
|
75
56
|
};
|
|
76
57
|
|
|
77
|
-
// const setFiltersForRadio = (
|
|
78
|
-
// value: string,
|
|
79
|
-
// columnsData: FilterColumnsDataProps,
|
|
80
|
-
// prevFilters: FilterStateProps[]
|
|
81
|
-
// ) => {
|
|
82
|
-
// const selectedAttr = filterMaster?.attributes.selected;
|
|
83
|
-
// if (!selectedAttr) return;
|
|
84
|
-
|
|
85
|
-
// const matchingColumn = columnsData?.column_list?.find(
|
|
86
|
-
// (column) => column.datasource_list === selectedAttr
|
|
87
|
-
// );
|
|
88
|
-
// if (!matchingColumn) return;
|
|
89
|
-
|
|
90
|
-
// const defaultOperator =
|
|
91
|
-
// columnsData.operation_list[matchingColumn.data_type]?.[0]?.value || "in";
|
|
92
|
-
|
|
93
|
-
// const newFilter = {
|
|
94
|
-
// filter_attribute: matchingColumn.attribute_key,
|
|
95
|
-
// filter_operator: defaultOperator,
|
|
96
|
-
// filter_value: [value], // single selection
|
|
97
|
-
// };
|
|
98
|
-
|
|
99
|
-
// const exists = prevFilters.some(
|
|
100
|
-
// (f) => f.filter_attribute === matchingColumn.attribute_key
|
|
101
|
-
// );
|
|
102
|
-
// if (exists) {
|
|
103
|
-
// return prevFilters.map((f) =>
|
|
104
|
-
// f.filter_attribute === matchingColumn.attribute_key ? newFilter : f
|
|
105
|
-
// );
|
|
106
|
-
// } else {
|
|
107
|
-
// return [...prevFilters, newFilter];
|
|
108
|
-
// }
|
|
109
|
-
// };
|
|
110
|
-
|
|
111
|
-
// const setFilterMasterForRadio = (
|
|
112
|
-
// value: string,
|
|
113
|
-
// prevFilterMaster: FilterMasterStateProps | null
|
|
114
|
-
// ) => {
|
|
115
|
-
// /**
|
|
116
|
-
// * If no attribute is selected, return the previous state without changes
|
|
117
|
-
// * This prevents errors when trying to access properties of undefined
|
|
118
|
-
// */
|
|
119
|
-
// if (!prevFilterMaster || !prevFilterMaster.attributes.selected)
|
|
120
|
-
// return prevFilterMaster;
|
|
121
|
-
|
|
122
|
-
// return {
|
|
123
|
-
// ...prevFilterMaster,
|
|
124
|
-
// attributes: {
|
|
125
|
-
// ...prevFilterMaster.attributes,
|
|
126
|
-
// radio: [value],
|
|
127
|
-
// },
|
|
128
|
-
// activeFilterTabIndex: tabValue as number,
|
|
129
|
-
// };
|
|
130
|
-
// };
|
|
131
|
-
|
|
132
|
-
// const handleSingleRadioSelect = (value: string) => {
|
|
133
|
-
// const newFiltersState = setFiltersForRadio(value, columnsData, filters);
|
|
134
|
-
// setFilters(newFiltersState || []);
|
|
135
|
-
|
|
136
|
-
// const newFilterMasterState = setFilterMasterForRadio(value, filterMaster);
|
|
137
|
-
// setFilterMaster(newFilterMasterState as FilterMasterStateProps);
|
|
138
|
-
|
|
139
|
-
// const newState = {
|
|
140
|
-
// filterMaster: newFilterMasterState,
|
|
141
|
-
// filters: newFiltersState,
|
|
142
|
-
// };
|
|
143
|
-
|
|
144
|
-
// onChangeFunction && onChangeFunction(newState);
|
|
145
|
-
// };
|
|
146
|
-
|
|
147
58
|
const handleSingleRadioSelect = (value: string) => {
|
|
148
59
|
const selectedAttr = filterMaster?.attributes.selected;
|
|
149
60
|
if (!selectedAttr) return;
|
|
@@ -158,16 +69,17 @@ const AttributesFilter = ({
|
|
|
158
69
|
|
|
159
70
|
if (value === "") {
|
|
160
71
|
// If deselecting, remove the filter
|
|
161
|
-
updatedFilters = filters
|
|
72
|
+
updatedFilters = filters?.filter(
|
|
162
73
|
(f) => f.filter_attribute !== matchingColumn.attribute_key
|
|
163
74
|
);
|
|
164
75
|
} else {
|
|
165
76
|
// Else, replace with new single selection
|
|
166
77
|
const defaultOperator =
|
|
167
|
-
columnsData
|
|
78
|
+
columnsData?.operation_list[matchingColumn.data_type]?.[0]?.value ||
|
|
168
79
|
"in";
|
|
169
80
|
|
|
170
81
|
const newFilter = {
|
|
82
|
+
...matchingColumn,
|
|
171
83
|
filter_attribute: matchingColumn.attribute_key,
|
|
172
84
|
filter_operator: defaultOperator,
|
|
173
85
|
filter_value: [value],
|
|
@@ -3,11 +3,11 @@ import { LocalizationProvider } from "@mui/x-date-pickers/LocalizationProvider";
|
|
|
3
3
|
import { DatePicker } from "@mui/x-date-pickers/DatePicker";
|
|
4
4
|
import { AdapterDateFns } from "@mui/x-date-pickers/AdapterDateFns";
|
|
5
5
|
import moment from "moment";
|
|
6
|
-
import {
|
|
6
|
+
import { FilterStateProps } from "../../../../../types/filter";
|
|
7
7
|
import { SxProps, Theme, Box } from "@mui/material";
|
|
8
8
|
|
|
9
9
|
type FormDatePickerProps = {
|
|
10
|
-
filter:
|
|
10
|
+
filter: FilterStateProps;
|
|
11
11
|
control: any;
|
|
12
12
|
sx?: SxProps<Theme>;
|
|
13
13
|
views?: Array<"year" | "month" | "day">;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { FormControl, MenuItem, Select, SxProps, Theme } from "@mui/material";
|
|
2
2
|
import { Controller, UseFormSetValue } from "react-hook-form";
|
|
3
|
-
import {
|
|
3
|
+
import { FilterStateProps } from "../../../../../types/filter";
|
|
4
4
|
import moment from "moment";
|
|
5
5
|
|
|
6
6
|
interface FormDropdownProps {
|
|
7
|
-
filter:
|
|
7
|
+
filter: FilterStateProps;
|
|
8
8
|
control: any;
|
|
9
9
|
setValue: UseFormSetValue<any>;
|
|
10
10
|
dropdownList: {
|
|
@@ -1,38 +1,24 @@
|
|
|
1
|
-
import {
|
|
2
|
-
Box,
|
|
3
|
-
Button,
|
|
4
|
-
styled,
|
|
5
|
-
List,
|
|
6
|
-
ListItem,
|
|
7
|
-
Paper,
|
|
8
|
-
ListItemText,
|
|
9
|
-
} from "@mui/material";
|
|
1
|
+
import { Box, Button, styled, Paper } from "@mui/material";
|
|
10
2
|
import { useRef } from "react";
|
|
11
3
|
import { AddIcon } from "../../../../../../assets/svg";
|
|
12
4
|
import {
|
|
13
5
|
FilterColumnsDataProps,
|
|
14
|
-
|
|
15
|
-
UpdatedFilterStateProps,
|
|
6
|
+
FilterDataMainFilterEntityWiseCriteriaProps,
|
|
16
7
|
} from "../../../../../types/filter";
|
|
17
8
|
import { CraftTableOptionsProps } from "../../../../../types/table-options";
|
|
18
|
-
import CustomSearch from "../../search";
|
|
19
9
|
import { filterStyles } from "../../../style";
|
|
20
10
|
import useElementWidth from "../../../../../libs/hooks/useElementWidth";
|
|
21
11
|
import { onFilterChangeFunctionProps } from "../../../../../types/common";
|
|
12
|
+
import FilterCriteriaEntityList from "./filter-criteria-entity-list";
|
|
13
|
+
import FilterCriteriaList from "./filter-criteria-list";
|
|
22
14
|
|
|
23
15
|
const FilterCriteria = ({
|
|
24
16
|
columnsData,
|
|
25
17
|
tableStates,
|
|
26
|
-
setSelectedFilters,
|
|
27
|
-
searchTerm,
|
|
28
|
-
setSearchTerm,
|
|
29
18
|
onChangeFunction,
|
|
30
19
|
}: {
|
|
31
20
|
columnsData: FilterColumnsDataProps;
|
|
32
21
|
tableStates: CraftTableOptionsProps;
|
|
33
|
-
setSelectedFilters: React.Dispatch<
|
|
34
|
-
React.SetStateAction<UpdatedFilterStateProps[]>
|
|
35
|
-
>;
|
|
36
22
|
searchTerm: string;
|
|
37
23
|
setSearchTerm: React.Dispatch<React.SetStateAction<string>>;
|
|
38
24
|
onChangeFunction: ({
|
|
@@ -57,47 +43,46 @@ const FilterCriteria = ({
|
|
|
57
43
|
showFilterOptions,
|
|
58
44
|
setShowFilterOption,
|
|
59
45
|
filterMaster,
|
|
46
|
+
selectedFilterEntity,
|
|
47
|
+
setSelectedFilterEntity,
|
|
60
48
|
} = tableStates;
|
|
61
49
|
|
|
62
50
|
const filterButtonRef = useRef<HTMLButtonElement>(null);
|
|
63
51
|
|
|
64
52
|
const filterButtonWidth = useElementWidth(filterButtonRef);
|
|
65
53
|
|
|
66
|
-
const handleAddFilter = (
|
|
67
|
-
|
|
54
|
+
const handleAddFilter = (
|
|
55
|
+
attribute: FilterDataMainFilterEntityWiseCriteriaProps
|
|
56
|
+
) => {
|
|
57
|
+
const dropdownOptions =
|
|
58
|
+
columnsData?.operation_list[attribute?.element_type];
|
|
68
59
|
|
|
69
|
-
const defaultValue =
|
|
60
|
+
const defaultValue = attribute.element_type === "multiselect" ? [] : "";
|
|
70
61
|
|
|
71
62
|
const defaultOperator = dropdownOptions?.[0]?.value || "";
|
|
72
63
|
|
|
73
64
|
const matchingDropdownList =
|
|
74
|
-
columnsData
|
|
65
|
+
columnsData?.operation_list[attribute.element_type] || [];
|
|
75
66
|
|
|
76
67
|
const newFilter = {
|
|
77
|
-
filter_attribute:
|
|
68
|
+
filter_attribute: attribute.attribute_key,
|
|
78
69
|
filter_operator: defaultOperator,
|
|
79
70
|
filter_value: defaultValue,
|
|
71
|
+
filter_entity_type: selectedFilterEntity?.value,
|
|
80
72
|
};
|
|
81
73
|
|
|
82
74
|
const newSelectedFilter = {
|
|
83
75
|
...newFilter,
|
|
84
|
-
id:
|
|
85
|
-
name:
|
|
86
|
-
data_type:
|
|
76
|
+
id: attribute.id,
|
|
77
|
+
name: attribute.name,
|
|
78
|
+
data_type: attribute.element_type,
|
|
87
79
|
dropdown_list: matchingDropdownList,
|
|
80
|
+
filter_entity_name: selectedFilterEntity?.label,
|
|
88
81
|
};
|
|
89
82
|
|
|
90
|
-
setFilters((prev) => [...prev,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
// setEditFilters((prev) => [...prev, newFilter]);
|
|
94
|
-
// setSelectedFilters((prev) => [...prev, newSelectedFilter]);
|
|
95
|
-
// } else {
|
|
96
|
-
// setFilters((prev) => [...prev, newFilter]);
|
|
97
|
-
// setSelectedFilters((prev) => [...prev, newSelectedFilter]);
|
|
98
|
-
// }
|
|
99
|
-
|
|
100
|
-
const newFilterState = [...filters, newFilter];
|
|
83
|
+
setFilters((prev) => [...prev, newSelectedFilter]);
|
|
84
|
+
|
|
85
|
+
const newFilterState = [...filters, newSelectedFilter];
|
|
101
86
|
const newState = {
|
|
102
87
|
filterMaster: filterMaster,
|
|
103
88
|
filters: newFilterState,
|
|
@@ -106,6 +91,7 @@ const FilterCriteria = ({
|
|
|
106
91
|
onChangeFunction && onChangeFunction(newState);
|
|
107
92
|
|
|
108
93
|
setShowFilterOption(false);
|
|
94
|
+
setSelectedFilterEntity(undefined);
|
|
109
95
|
};
|
|
110
96
|
|
|
111
97
|
const toggleFilterOptions = () => {
|
|
@@ -135,7 +121,7 @@ const FilterCriteria = ({
|
|
|
135
121
|
sx={{
|
|
136
122
|
width: filterButtonWidth || 360, // Dynamic width based on button
|
|
137
123
|
p: 1,
|
|
138
|
-
mt:
|
|
124
|
+
mt: 1.5,
|
|
139
125
|
cursor: "pointer",
|
|
140
126
|
position: "absolute",
|
|
141
127
|
zIndex: 1300,
|
|
@@ -149,51 +135,14 @@ const FilterCriteria = ({
|
|
|
149
135
|
...filterStyles.scrollbarCustom,
|
|
150
136
|
}}
|
|
151
137
|
>
|
|
152
|
-
|
|
153
|
-
<
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
onChange={setSearchTerm}
|
|
138
|
+
{selectedFilterEntity ? (
|
|
139
|
+
<FilterCriteriaList
|
|
140
|
+
tableStates={tableStates}
|
|
141
|
+
handleAddFilter={handleAddFilter}
|
|
157
142
|
/>
|
|
158
|
-
|
|
159
|
-
<
|
|
160
|
-
|
|
161
|
-
my: 2,
|
|
162
|
-
overflowY: "auto",
|
|
163
|
-
transition: "all 0.4s ease-in-out",
|
|
164
|
-
}}
|
|
165
|
-
>
|
|
166
|
-
{columnsData?.column_list
|
|
167
|
-
?.filter(
|
|
168
|
-
(column) =>
|
|
169
|
-
column.name.toLowerCase() !== "action" && // Exclude Action column in filter criteria options
|
|
170
|
-
column.name
|
|
171
|
-
.toLowerCase()
|
|
172
|
-
.includes(searchTerm.toLowerCase())
|
|
173
|
-
)
|
|
174
|
-
.map((column, index) => {
|
|
175
|
-
const isAlreadySelected = filters?.some(
|
|
176
|
-
(filter) =>
|
|
177
|
-
filter.filter_attribute === column.attribute_key
|
|
178
|
-
);
|
|
179
|
-
|
|
180
|
-
return (
|
|
181
|
-
<ListItem
|
|
182
|
-
key={index}
|
|
183
|
-
onClick={() =>
|
|
184
|
-
!isAlreadySelected && handleAddFilter(column)
|
|
185
|
-
} // Prevent click if already selected
|
|
186
|
-
sx={{
|
|
187
|
-
opacity: isAlreadySelected ? 0.5 : 1,
|
|
188
|
-
cursor: isAlreadySelected ? "not-allowed" : "pointer",
|
|
189
|
-
}}
|
|
190
|
-
>
|
|
191
|
-
<ListItemText primary={column.name} />
|
|
192
|
-
</ListItem>
|
|
193
|
-
);
|
|
194
|
-
})}
|
|
195
|
-
</Box>
|
|
196
|
-
</List>
|
|
143
|
+
) : (
|
|
144
|
+
<FilterCriteriaEntityList tableStates={tableStates} />
|
|
145
|
+
)}
|
|
197
146
|
</Box>
|
|
198
147
|
</Paper>
|
|
199
148
|
)}
|
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
SxProps,
|
|
8
8
|
Checkbox,
|
|
9
9
|
} from "@mui/material";
|
|
10
|
-
import {
|
|
10
|
+
import { FilterStateProps } from "../../../../../types/filter";
|
|
11
11
|
import { DropdownOption } from "../../../../../types/common";
|
|
12
12
|
|
|
13
13
|
const FormMultiSelect = ({
|
|
@@ -17,7 +17,7 @@ const FormMultiSelect = ({
|
|
|
17
17
|
sx,
|
|
18
18
|
onValueChange,
|
|
19
19
|
}: {
|
|
20
|
-
filter:
|
|
20
|
+
filter: FilterStateProps;
|
|
21
21
|
control: any;
|
|
22
22
|
dropdownData: Record<string, DropdownOption[]>;
|
|
23
23
|
sx?: SxProps<Theme>;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { FormControl, MenuItem, Select, SxProps, Theme } from "@mui/material";
|
|
2
2
|
import { Controller } from "react-hook-form";
|
|
3
|
-
import {
|
|
3
|
+
import { FilterStateProps } from "../../../../../types/filter";
|
|
4
4
|
import { DropdownOption } from "../../../../../types/common";
|
|
5
5
|
|
|
6
6
|
interface FormSelectProps {
|
|
7
|
-
filter:
|
|
7
|
+
filter: FilterStateProps;
|
|
8
8
|
control: any;
|
|
9
9
|
dropdownData: Record<string, DropdownOption[]>;
|
|
10
10
|
isLoading?: boolean;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { TextField } from "@mui/material";
|
|
2
2
|
import { Controller } from "react-hook-form";
|
|
3
3
|
import { TextFieldStyles } from "./styles";
|
|
4
|
-
import {
|
|
4
|
+
import { FilterStateProps } from "../../../../../types/filter";
|
|
5
5
|
|
|
6
6
|
interface FormTextfieldProps {
|
|
7
|
-
filter:
|
|
7
|
+
filter: FilterStateProps;
|
|
8
8
|
control: any;
|
|
9
9
|
isLoading?: boolean;
|
|
10
10
|
onValueChange?: () => void;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Typography } from "@mui/material";
|
|
2
|
+
|
|
3
|
+
const EmptyList = ({ label }: { label?: string }) => {
|
|
4
|
+
return (
|
|
5
|
+
<Typography
|
|
6
|
+
variant="body2"
|
|
7
|
+
align="center"
|
|
8
|
+
fontSize={14}
|
|
9
|
+
fontStyle={"italic"}
|
|
10
|
+
color="text.secondary"
|
|
11
|
+
>
|
|
12
|
+
{label ? label : "No results found"}
|
|
13
|
+
</Typography>
|
|
14
|
+
);
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export default EmptyList;
|
package/src/listing/components/filter/components/forms/components/filter-criteria-entity-list.tsx
ADDED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Box, List, ListItem, ListItemText } from "@mui/material";
|
|
2
|
+
import React from "react";
|
|
3
|
+
import CustomSearch from "../../search";
|
|
4
|
+
import { CraftTableOptionsProps } from "../../../../../types/table-options";
|
|
5
|
+
import { FilterDataMainFilterEntityListProps } from "../../../../../types/filter";
|
|
6
|
+
import EmptyList from "./empty-list";
|
|
7
|
+
|
|
8
|
+
interface Props {
|
|
9
|
+
tableStates: CraftTableOptionsProps;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const FilterCriteriaEntityList = ({ tableStates }: Props) => {
|
|
13
|
+
const [searchTerm, setSearchTerm] = React.useState<string>("");
|
|
14
|
+
|
|
15
|
+
const { filterData, filters, setSelectedFilterEntity } = tableStates;
|
|
16
|
+
|
|
17
|
+
const handleSelectEntity = (entity: FilterDataMainFilterEntityListProps) => {
|
|
18
|
+
setSelectedFilterEntity(entity);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
return (
|
|
22
|
+
<List>
|
|
23
|
+
<CustomSearch
|
|
24
|
+
placeholder="Filter by..."
|
|
25
|
+
value={searchTerm}
|
|
26
|
+
onChange={setSearchTerm}
|
|
27
|
+
/>
|
|
28
|
+
|
|
29
|
+
<Box
|
|
30
|
+
sx={{
|
|
31
|
+
my: 2,
|
|
32
|
+
overflowY: "auto",
|
|
33
|
+
transition: "all 0.4s ease-in-out",
|
|
34
|
+
}}
|
|
35
|
+
>
|
|
36
|
+
{(() => {
|
|
37
|
+
const filteredEntities =
|
|
38
|
+
filterData?.mainFilter?.entityList?.data?.filter((entity) =>
|
|
39
|
+
entity.label.toLowerCase().includes(searchTerm.toLowerCase())
|
|
40
|
+
) || [];
|
|
41
|
+
|
|
42
|
+
if (filteredEntities?.length === 0) {
|
|
43
|
+
return <EmptyList />;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return filteredEntities.map((entity, index) => {
|
|
47
|
+
const isAlreadySelected = filters?.some(
|
|
48
|
+
(filter) => filter.filter_attribute === entity.value
|
|
49
|
+
);
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<ListItem
|
|
53
|
+
key={index}
|
|
54
|
+
sx={{
|
|
55
|
+
opacity: isAlreadySelected ? 0.5 : 1,
|
|
56
|
+
cursor: isAlreadySelected ? "not-allowed" : "pointer",
|
|
57
|
+
}}
|
|
58
|
+
onClick={() => handleSelectEntity(entity)}
|
|
59
|
+
>
|
|
60
|
+
<ListItemText primary={entity.label} />
|
|
61
|
+
</ListItem>
|
|
62
|
+
);
|
|
63
|
+
});
|
|
64
|
+
})()}
|
|
65
|
+
{/* {filterData?.mainFilter?.entityList
|
|
66
|
+
?.filter((entity) =>
|
|
67
|
+
entity.label.toLowerCase().includes(searchTerm.toLowerCase())
|
|
68
|
+
)
|
|
69
|
+
.map((entity, index) => {
|
|
70
|
+
const isAlreadySelected = filters?.some(
|
|
71
|
+
(filter) => filter.filter_attribute === entity.value
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<ListItem
|
|
76
|
+
key={index}
|
|
77
|
+
sx={{
|
|
78
|
+
opacity: isAlreadySelected ? 0.5 : 1,
|
|
79
|
+
cursor: isAlreadySelected ? "not-allowed" : "pointer",
|
|
80
|
+
}}
|
|
81
|
+
onClick={() => handleSelectEntity(entity)}
|
|
82
|
+
>
|
|
83
|
+
<ListItemText primary={entity.label} />
|
|
84
|
+
</ListItem>
|
|
85
|
+
);
|
|
86
|
+
})} */}
|
|
87
|
+
</Box>
|
|
88
|
+
</List>
|
|
89
|
+
);
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
export default FilterCriteriaEntityList;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Box,
|
|
3
|
+
IconButton,
|
|
4
|
+
List,
|
|
5
|
+
ListItem,
|
|
6
|
+
ListItemText,
|
|
7
|
+
Typography,
|
|
8
|
+
} from "@mui/material";
|
|
9
|
+
import CustomSearch from "../../search";
|
|
10
|
+
import React from "react";
|
|
11
|
+
import { CraftTableOptionsProps } from "../../../../../types/table-options";
|
|
12
|
+
import { filterFormStyles } from "../../../style";
|
|
13
|
+
import { CloseIcon } from "../../../../../../assets/svg";
|
|
14
|
+
import EmptyList from "./empty-list";
|
|
15
|
+
import Loader from "../../../../common/loader/loader";
|
|
16
|
+
import { FilterDataMainFilterEntityWiseCriteriaProps } from "../../../../../types/filter";
|
|
17
|
+
|
|
18
|
+
interface Props {
|
|
19
|
+
tableStates: CraftTableOptionsProps;
|
|
20
|
+
handleAddFilter: (
|
|
21
|
+
column: FilterDataMainFilterEntityWiseCriteriaProps
|
|
22
|
+
) => void;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const FilterCriteriaList = ({ tableStates, handleAddFilter }: Props) => {
|
|
26
|
+
const [searchTerm, setSearchTerm] = React.useState<string>("");
|
|
27
|
+
|
|
28
|
+
const { filterData, filters, selectedFilterEntity, setSelectedFilterEntity } =
|
|
29
|
+
tableStates;
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<>
|
|
33
|
+
<Box
|
|
34
|
+
className="group-header"
|
|
35
|
+
sx={{
|
|
36
|
+
...filterFormStyles.formListSectionHeader,
|
|
37
|
+
position: "sticky",
|
|
38
|
+
top: 0,
|
|
39
|
+
zIndex: 1,
|
|
40
|
+
}}
|
|
41
|
+
>
|
|
42
|
+
<Typography fontSize={14}>{selectedFilterEntity?.label}</Typography>
|
|
43
|
+
<IconButton
|
|
44
|
+
size="small"
|
|
45
|
+
onClick={() => setSelectedFilterEntity(undefined)}
|
|
46
|
+
>
|
|
47
|
+
<CloseIcon />
|
|
48
|
+
</IconButton>
|
|
49
|
+
</Box>
|
|
50
|
+
{filterData?.mainFilter?.entityWiseCriteria?.isPending ? (
|
|
51
|
+
<Loader />
|
|
52
|
+
) : (
|
|
53
|
+
<List>
|
|
54
|
+
<CustomSearch
|
|
55
|
+
placeholder="Filter by..."
|
|
56
|
+
value={searchTerm}
|
|
57
|
+
onChange={setSearchTerm}
|
|
58
|
+
/>
|
|
59
|
+
|
|
60
|
+
<Box
|
|
61
|
+
sx={{
|
|
62
|
+
my: 2,
|
|
63
|
+
overflowY: "auto",
|
|
64
|
+
transition: "all 0.4s ease-in-out",
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
{(() => {
|
|
68
|
+
const filteredEntities =
|
|
69
|
+
filterData?.mainFilter?.entityWiseCriteria?.data?.filter(
|
|
70
|
+
(entity) =>
|
|
71
|
+
entity.name.toLowerCase().includes(searchTerm.toLowerCase())
|
|
72
|
+
) ?? [];
|
|
73
|
+
|
|
74
|
+
if (filteredEntities.length === 0) {
|
|
75
|
+
return <EmptyList />;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
return filteredEntities.map((entity, index) => {
|
|
79
|
+
const isAlreadySelected = filters?.some(
|
|
80
|
+
(filter) => filter.filter_attribute === entity.attribute_key
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
return (
|
|
84
|
+
<ListItem
|
|
85
|
+
key={index}
|
|
86
|
+
sx={{
|
|
87
|
+
opacity: isAlreadySelected ? 0.5 : 1,
|
|
88
|
+
cursor: isAlreadySelected ? "not-allowed" : "pointer",
|
|
89
|
+
}}
|
|
90
|
+
onClick={() => handleAddFilter(entity)}
|
|
91
|
+
>
|
|
92
|
+
<ListItemText primary={entity.name} />
|
|
93
|
+
</ListItem>
|
|
94
|
+
);
|
|
95
|
+
});
|
|
96
|
+
})()}
|
|
97
|
+
</Box>
|
|
98
|
+
</List>
|
|
99
|
+
)}
|
|
100
|
+
</>
|
|
101
|
+
);
|
|
102
|
+
};
|
|
103
|
+
|
|
104
|
+
export default FilterCriteriaList;
|