rez-table-listing-mui 1.3.12 → 1.3.14

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rez-table-listing-mui",
3
- "version": "1.3.12",
3
+ "version": "1.3.14",
4
4
  "type": "module",
5
5
  "description": "A rez table listing component built on TanStack Table",
6
6
  "main": "dist/index.js",
@@ -1,4 +1,4 @@
1
- import { Box, Button, styled, Paper } from "@mui/material";
1
+ import { Box, Button, styled, Paper, ClickAwayListener } from "@mui/material";
2
2
  import { useMemo, useRef } from "react";
3
3
  import { AddIcon } from "../../../../../../assets/svg";
4
4
  import {
@@ -73,7 +73,7 @@ const FilterCriteria = ({
73
73
 
74
74
  const newSelectedFilter = {
75
75
  ...newFilter,
76
- id: attribute?.id,
76
+ // id: attribute?.id,
77
77
  filter_attribute_name: attribute?.name,
78
78
  filter_attribute_data_type:
79
79
  attribute?.data_type || attribute?.element_type,
@@ -128,34 +128,40 @@ const FilterCriteria = ({
128
128
  </FilterButton>
129
129
 
130
130
  {showFilterOptions && (
131
- <Paper
132
- sx={{
133
- width: filterButtonWidth || 360, // Dynamic width based on button
134
- p: 1,
135
- mt: 1.5,
136
- cursor: "pointer",
137
- position: "absolute",
138
- zIndex: 1300,
139
- }}
140
- >
141
- <Box
131
+ <ClickAwayListener onClickAway={() => setShowFilterOption(false)}>
132
+ <Paper
142
133
  sx={{
143
- maxHeight: `calc(100vh - 440px)`,
144
- overflowY: "auto",
145
- width: "100%",
146
- ...filterStyles.scrollbarCustom,
134
+ width: filterButtonWidth || 360, // Dynamic width based on button
135
+ p: 1,
136
+ mt: 1.5,
137
+ cursor: "pointer",
138
+ position: "absolute",
139
+ zIndex: 1300,
147
140
  }}
148
141
  >
149
- {selectedFilterEntity ? (
150
- <FilterCriteriaList
151
- tableStates={tableStates}
152
- handleAddFilter={handleAddFilter}
153
- />
154
- ) : (
155
- <FilterCriteriaEntityList tableStates={tableStates} />
156
- )}
157
- </Box>
158
- </Paper>
142
+ <Box
143
+ sx={{
144
+ maxHeight: `calc(100vh - 440px)`,
145
+ overflowY: "auto",
146
+ width: "100%",
147
+ ...filterStyles.scrollbarCustom,
148
+ }}
149
+ >
150
+ {selectedFilterEntity ? (
151
+ <FilterCriteriaList
152
+ tableStates={tableStates}
153
+ handleAddFilter={handleAddFilter}
154
+ filterComponentOptions={filterComponentOptions}
155
+ />
156
+ ) : (
157
+ <FilterCriteriaEntityList
158
+ tableStates={tableStates}
159
+ filterComponentOptions={filterComponentOptions}
160
+ />
161
+ )}
162
+ </Box>
163
+ </Paper>
164
+ </ClickAwayListener>
159
165
  )}
160
166
  </Box>
161
167
  );
@@ -2,22 +2,50 @@ import { Box, List, ListItem, ListItemText } from "@mui/material";
2
2
  import React from "react";
3
3
  import CustomSearch from "../../search";
4
4
  import { CraftTableOptionsProps } from "../../../../../types/table-options";
5
- import { FilterDataMainFilterEntityListProps } from "../../../../../types/filter";
5
+ import {
6
+ FilterComponentOptions,
7
+ FilterDataMainFilterEntityListProps,
8
+ } from "../../../../../types/filter";
6
9
  import EmptyList from "./empty-list";
7
10
 
8
11
  interface Props {
9
12
  tableStates: CraftTableOptionsProps;
13
+ filterComponentOptions?: FilterComponentOptions;
10
14
  }
11
15
 
12
- const FilterCriteriaEntityList = ({ tableStates }: Props) => {
16
+ const FilterCriteriaEntityList = ({
17
+ tableStates,
18
+ filterComponentOptions,
19
+ }: Props) => {
13
20
  const [searchTerm, setSearchTerm] = React.useState<string>("");
14
21
 
15
- const { filterData, filters, setSelectedFilterEntity } = tableStates;
22
+ const { filters, filterData, setSelectedFilterEntity } = tableStates;
16
23
 
17
24
  const handleSelectEntity = (entity: FilterDataMainFilterEntityListProps) => {
18
25
  setSelectedFilterEntity(entity);
19
26
  };
20
27
 
28
+ const isSingleEntity = filterComponentOptions?.tabOptions?.isSingleEntity;
29
+
30
+ // 🔍 get all entities from main filter data
31
+ const allEntities = filterData?.mainFilter?.entityList?.data || [];
32
+
33
+ // ✅ determine which entities should be displayed
34
+ const entitiesToShow = React.useMemo(() => {
35
+ // Case 1: isSingleEntity is true and filters already has entities
36
+ if (isSingleEntity && filters?.length > 0) {
37
+ const filterEntityTypes = filters.map((f) => f?.filter_entity_type);
38
+ return allEntities.filter((entity) =>
39
+ filterEntityTypes.includes(entity.value)
40
+ );
41
+ }
42
+
43
+ // Case 2: default behavior (apply search filter)
44
+ return allEntities.filter((entity) =>
45
+ entity.label.toLowerCase().includes(searchTerm.toLowerCase())
46
+ );
47
+ }, [isSingleEntity, filters, allEntities, searchTerm]);
48
+
21
49
  return (
22
50
  <List>
23
51
  <CustomSearch
@@ -33,57 +61,22 @@ const FilterCriteriaEntityList = ({ tableStates }: Props) => {
33
61
  transition: "all 0.4s ease-in-out",
34
62
  }}
35
63
  >
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
- })} */}
64
+ {entitiesToShow.length === 0 ? (
65
+ <EmptyList />
66
+ ) : (
67
+ entitiesToShow.map((entity, index) => (
68
+ <ListItem
69
+ key={index}
70
+ onClick={() => handleSelectEntity(entity)}
71
+ sx={{
72
+ cursor: "pointer",
73
+ "&:hover": { backgroundColor: "#f4f4f4" },
74
+ }}
75
+ >
76
+ <ListItemText primary={entity.label} />
77
+ </ListItem>
78
+ ))
79
+ )}
87
80
  </Box>
88
81
  </List>
89
82
  );
@@ -7,27 +7,51 @@ import {
7
7
  Typography,
8
8
  } from "@mui/material";
9
9
  import CustomSearch from "../../search";
10
- import React from "react";
10
+ import React, { useMemo } from "react";
11
11
  import { CraftTableOptionsProps } from "../../../../../types/table-options";
12
12
  import { filterFormStyles } from "../../../style";
13
13
  import { CloseIcon } from "../../../../../../assets/svg";
14
14
  import EmptyList from "./empty-list";
15
15
  import Loader from "../../../../common/loader/loader";
16
- import { FilterDataMainFilterEntityWiseCriteriaProps } from "../../../../../types/filter";
16
+ import {
17
+ FilterComponentOptions,
18
+ FilterDataMainFilterEntityWiseCriteriaProps,
19
+ } from "../../../../../types/filter";
17
20
 
18
21
  interface Props {
19
22
  tableStates: CraftTableOptionsProps;
20
23
  handleAddFilter: (
21
24
  column: FilterDataMainFilterEntityWiseCriteriaProps
22
25
  ) => void;
26
+ filterComponentOptions?: FilterComponentOptions;
23
27
  }
24
28
 
25
- const FilterCriteriaList = ({ tableStates, handleAddFilter }: Props) => {
29
+ const FilterCriteriaList = ({
30
+ tableStates,
31
+ handleAddFilter,
32
+ filterComponentOptions,
33
+ }: Props) => {
26
34
  const [searchTerm, setSearchTerm] = React.useState<string>("");
27
35
 
28
36
  const { filterData, filters, selectedFilterEntity, setSelectedFilterEntity } =
29
37
  tableStates;
30
38
 
39
+ const isSingleEntity = filterComponentOptions?.tabOptions?.isSingleEntity;
40
+
41
+ // Show Close button if:
42
+ // - isSingleEntity is false → always show
43
+ // - isSingleEntity is true → only show if filters is empty OR
44
+ // no filter exists with same filter_entity_type as selectedFilterEntity.value
45
+ const shouldShowCloseButton = useMemo(() => {
46
+ return isSingleEntity
47
+ ? filters?.length === 0 ||
48
+ !filters?.some(
49
+ (filter) =>
50
+ filter?.filter_entity_type === selectedFilterEntity?.value
51
+ )
52
+ : true;
53
+ }, [filters, isSingleEntity, selectedFilterEntity?.value]);
54
+
31
55
  return (
32
56
  <>
33
57
  <Box
@@ -40,12 +64,14 @@ const FilterCriteriaList = ({ tableStates, handleAddFilter }: Props) => {
40
64
  }}
41
65
  >
42
66
  <Typography fontSize={14}>{selectedFilterEntity?.label}</Typography>
43
- <IconButton
44
- size="small"
45
- onClick={() => setSelectedFilterEntity(undefined)}
46
- >
47
- <CloseIcon />
48
- </IconButton>
67
+ {shouldShowCloseButton && (
68
+ <IconButton
69
+ size="small"
70
+ onClick={() => setSelectedFilterEntity(undefined)}
71
+ >
72
+ <CloseIcon />
73
+ </IconButton>
74
+ )}
49
75
  </Box>
50
76
  {filterData?.mainFilter?.entityWiseCriteria?.isPending ? (
51
77
  <Loader />
@@ -86,8 +112,15 @@ const FilterCriteriaList = ({ tableStates, handleAddFilter }: Props) => {
86
112
  sx={{
87
113
  opacity: isAlreadySelected ? 0.5 : 1,
88
114
  cursor: isAlreadySelected ? "not-allowed" : "pointer",
115
+ "&:hover": {
116
+ backgroundColor: isAlreadySelected
117
+ ? "inherit"
118
+ : "#f4f4f4",
119
+ },
89
120
  }}
90
- onClick={() => handleAddFilter(entity)}
121
+ onClick={() =>
122
+ !isAlreadySelected && handleAddFilter(entity)
123
+ }
91
124
  >
92
125
  <ListItemText primary={entity.name} />
93
126
  </ListItem>
@@ -51,6 +51,7 @@ export function TableFilter({
51
51
  showTabs: true,
52
52
  tabOptions: {
53
53
  isSingleFilter: false,
54
+ isSingleEntity: false,
54
55
  showFilter: "main",
55
56
  mainFilter: {
56
57
  showSaveButton: true,
@@ -107,6 +107,7 @@ interface FilterComponentTabOptions {
107
107
  mainFilter?: FilterComponentOptionsMainFilterOptions;
108
108
  savedFilter?: FilterComponentOptionsSavedFilterOptions;
109
109
  isSingleFilter?: boolean;
110
+ isSingleEntity?: boolean;
110
111
  showFilter?: TabType;
111
112
  }
112
113
 
@@ -177,7 +178,7 @@ export interface FilterStateProps {
177
178
  filter_attribute: string;
178
179
  filter_operator: string;
179
180
  filter_value: string | string[];
180
- id: string | number;
181
+ // id: string | number; // removed as per backend req
181
182
  filter_attribute_name: string | undefined;
182
183
  filter_attribute_data_type: FilterInputDataTypes | undefined;
183
184
  attribute_key?: string;
@@ -324,10 +324,11 @@ function ListingView() {
324
324
  // onSaveFilter={handleSaveFilter}
325
325
  onChangeFunction={handleChangeFunction}
326
326
  filterComponentOptions={{
327
- showMainHeader: false,
327
+ showMainHeader: true,
328
328
  showTabs: true,
329
329
  isRuleEngine: true,
330
330
  tabOptions: {
331
+ // isSingleEntity: true,
331
332
  mainFilter: {
332
333
  showSaveButton: true,
333
334
  showClearAllButton: true,