rez-table-listing-mui 1.2.8 → 1.2.10

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.2.8",
3
+ "version": "1.2.10",
4
4
  "type": "module",
5
5
  "description": "A rez table listing component built on TanStack Table",
6
6
  "main": "dist/index.js",
@@ -80,7 +80,11 @@ const ConfirmModal: React.FC<ConfirmModalProps> = ({
80
80
  return (
81
81
  <Dialog
82
82
  open={open}
83
- onClose={handleClose}
83
+ onClose={(event, reason) => {
84
+ if (reason !== "backdropClick" && reason !== "escapeKeyDown") {
85
+ handleClose();
86
+ }
87
+ }}
84
88
  maxWidth={maxWidth}
85
89
  fullWidth={fullWidth}
86
90
  PaperProps={{
@@ -26,7 +26,7 @@ const AttributesFilter = ({
26
26
 
27
27
  const selectedAttribute = filterMaster?.attributes?.selected;
28
28
 
29
- // Get the current filter value(s) to determine selected options
29
+ // Get the current filter value (single selection)
30
30
  const currentFilterValue = useMemo(() => {
31
31
  if (!selectedAttribute) return [];
32
32
 
@@ -61,7 +61,7 @@ const AttributesFilter = ({
61
61
  );
62
62
  };
63
63
 
64
- const handleMultiRadioToggle = (value: string) => {
64
+ const handleSingleRadioSelect = (value: string) => {
65
65
  const selectedAttr = filterMaster?.attributes.selected;
66
66
  if (!selectedAttr) return;
67
67
 
@@ -70,27 +70,13 @@ const AttributesFilter = ({
70
70
  );
71
71
  if (!matchingColumn) return;
72
72
 
73
- const existingFilter = filters.find(
74
- (f) => f.filter_attribute === matchingColumn.attribute_key
75
- );
76
-
77
- const currentValues: string[] = Array.isArray(existingFilter?.filter_value)
78
- ? existingFilter.filter_value
79
- : [];
80
-
81
- const isAlreadySelected = currentValues.includes(value);
82
-
83
- const updatedValues = isAlreadySelected
84
- ? currentValues.filter((v) => v !== value)
85
- : [...currentValues, value];
86
-
87
73
  const defaultOperator =
88
74
  columnsData.operation_list[matchingColumn.data_type]?.[0]?.value || "in";
89
75
 
90
76
  const newFilter = {
91
77
  filter_attribute: matchingColumn.attribute_key,
92
78
  filter_operator: defaultOperator,
93
- filter_value: updatedValues,
79
+ filter_value: [value], // single selection
94
80
  };
95
81
 
96
82
  setFilters((prevFilters) => {
@@ -113,7 +99,7 @@ const AttributesFilter = ({
113
99
  ...prev,
114
100
  attributes: {
115
101
  ...prev.attributes,
116
- radio: updatedValues,
102
+ radio: [value],
117
103
  },
118
104
  activeFilterTabIndex: tabValue as number,
119
105
  };
@@ -137,6 +123,7 @@ const AttributesFilter = ({
137
123
  }}
138
124
  className="attributes-filter-component-wrapper"
139
125
  >
126
+ {/* Attribute Select Dropdown */}
140
127
  <FormControl fullWidth size="small">
141
128
  <Select
142
129
  value={selectedAttribute || ""}
@@ -185,6 +172,7 @@ const AttributesFilter = ({
185
172
  </Select>
186
173
  </FormControl>
187
174
 
175
+ {/* Search and Single Radio Options */}
188
176
  <Box>
189
177
  {selectedAttribute && (
190
178
  <CustomSearch value={searchTerm} onChange={setSearchTerm} />
@@ -199,7 +187,6 @@ const AttributesFilter = ({
199
187
  {selectedAttributeOptions
200
188
  ?.filter((option) => {
201
189
  if (!searchTerm) return true;
202
-
203
190
  return option.label
204
191
  .toLowerCase()
205
192
  .includes(searchTerm.toLowerCase());
@@ -213,7 +200,7 @@ const AttributesFilter = ({
213
200
  control={
214
201
  <Radio
215
202
  checked={isSelected}
216
- onClick={() => handleMultiRadioToggle(option.value)}
203
+ onChange={() => handleSingleRadioSelect(option.value)}
217
204
  />
218
205
  }
219
206
  label={option.label}
@@ -153,7 +153,11 @@ const FilterForm = ({
153
153
  }, []);
154
154
 
155
155
  return (
156
- <form>
156
+ <form
157
+ onSubmit={(e) => {
158
+ e.preventDefault(); // 🔥 This prevents the page from reloading
159
+ }}
160
+ >
157
161
  <Box sx={editMode ? filterFormStyles.formEditModeStyle : {}}>
158
162
  {editMode && (
159
163
  <Box
@@ -107,6 +107,62 @@ function Topbar<T>({
107
107
  handler: () => setShowSearchInput(false),
108
108
  });
109
109
 
110
+ useEffect(() => {
111
+ const handleExternalLayoutTrigger = (e: Event) => {
112
+ const target = (e as CustomEvent).detail?.target as HTMLElement;
113
+ setLayoutAnchorEl(target);
114
+ };
115
+
116
+ const handleExternalFilterTrigger = () => {
117
+ onFilterButtonClick?.();
118
+ };
119
+
120
+ const handleExternalViewMoreTrigger = (e: Event) => {
121
+ const target = (e as CustomEvent).detail?.target as HTMLElement;
122
+ if (target) setViewMoreAnchorEl(target);
123
+ };
124
+
125
+ const handleExternalSearchTrigger = () => {
126
+ setShowSearchInput(true);
127
+ setTimeout(() => {
128
+ searchContainerRef.current?.querySelector("input")?.focus();
129
+ }, 100);
130
+ };
131
+
132
+ window.addEventListener(
133
+ "triggerLayoutPopover",
134
+ handleExternalLayoutTrigger
135
+ );
136
+ window.addEventListener("triggerFilterButton", handleExternalFilterTrigger);
137
+ window.addEventListener("triggerViewMore", handleExternalViewMoreTrigger);
138
+ window.addEventListener("triggerSearchInput", handleExternalSearchTrigger); // ✅
139
+
140
+ return () => {
141
+ window.removeEventListener(
142
+ "triggerLayoutPopover",
143
+ handleExternalLayoutTrigger
144
+ );
145
+ window.removeEventListener(
146
+ "triggerFilterButton",
147
+ handleExternalFilterTrigger
148
+ );
149
+ window.removeEventListener(
150
+ "triggerViewMore",
151
+ handleExternalViewMoreTrigger
152
+ );
153
+ window.removeEventListener(
154
+ "triggerSearchInput",
155
+ handleExternalSearchTrigger
156
+ ); // ✅
157
+ };
158
+ }, [onFilterButtonClick]);
159
+
160
+ const [viewMoreAnchorEl, setViewMoreAnchorEl] = useState<HTMLElement | null>(
161
+ null
162
+ );
163
+
164
+ const isViewMoreOpen = Boolean(viewMoreAnchorEl);
165
+
110
166
  return (
111
167
  <div className="ts-topbar">
112
168
  <div className="tabs-section">
@@ -131,28 +187,38 @@ function Topbar<T>({
131
187
  {showChangeLayoutToggle && (
132
188
  <>
133
189
  <div className="change-layout ts--button" title="Layout">
134
- <div onClick={handleLayoutIconClick}>
190
+ {/* <div onClick={handleLayoutIconClick}>
191
+ <ChangeLayoutIcon />
192
+ </div> */}
193
+ <div
194
+ onClick={(e) => {
195
+ const customEvent = new CustomEvent("triggerLayoutPopover", {
196
+ detail: { target: e.currentTarget },
197
+ });
198
+ window.dispatchEvent(customEvent);
199
+ }}
200
+ className="external-layout-trigger"
201
+ >
135
202
  <ChangeLayoutIcon />
136
203
  </div>
137
204
  </div>
138
- <Popover
139
- open={Boolean(layoutAnchorEl)}
140
- anchorEl={layoutAnchorEl}
141
- onClose={() => setLayoutAnchorEl(null)}
142
- anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
143
- container={fullscreenContainer}
144
- sx={{
145
- mt: 2.2,
146
- }}
147
- >
148
- <LayoutSelector
149
- onSelect={handleLayoutSelect}
150
- selectedLayout={selectedLayout}
151
- />
152
- </Popover>
153
205
  </>
154
206
  )}
155
-
207
+ <Popover
208
+ open={Boolean(layoutAnchorEl)}
209
+ anchorEl={layoutAnchorEl}
210
+ onClose={() => setLayoutAnchorEl(null)}
211
+ anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
212
+ container={fullscreenContainer}
213
+ sx={{
214
+ mt: 2.2,
215
+ }}
216
+ >
217
+ <LayoutSelector
218
+ onSelect={handleLayoutSelect}
219
+ selectedLayout={selectedLayout}
220
+ />
221
+ </Popover>
156
222
  {showColumnToggle && (
157
223
  <>
158
224
  <div
@@ -199,13 +265,11 @@ function Topbar<T>({
199
265
  title="Filter"
200
266
  onClick={onFilterButtonClick && onFilterButtonClick}
201
267
  >
202
- <FilterationIcon
203
- color={tableStates.filters.length ? "#1C1B1F" : "#888"}
204
- />
268
+ <FilterationIcon color="#1C1B1F" />
205
269
  </div>
206
270
  )}
207
271
 
208
- {viewMoreToggle && (
272
+ {/* {viewMoreToggle && (
209
273
  <div className="view-more ts--button" title="View More">
210
274
  <ViewMore
211
275
  compactMode={isCompactTable}
@@ -219,7 +283,54 @@ function Topbar<T>({
219
283
  tableStates={tableStates}
220
284
  />
221
285
  </div>
222
- )}
286
+ )} */}
287
+ {/* {viewMoreToggle && (
288
+ <div
289
+ className="view-more ts--button view-more-trigger"
290
+ title="View More"
291
+ >
292
+ <ViewMore
293
+ compactMode={isCompactTable}
294
+ onCompactToggle={(value: string) =>
295
+ setIsCompactTable(value === "Compact")
296
+ }
297
+ isFullscreen={isFullscreen}
298
+ onFullscreenToggle={fullscreenToggle}
299
+ groupBy={groupBy}
300
+ onGroupByChange={(value: string) => setGroupBy(value)}
301
+ tableStates={tableStates}
302
+ />
303
+ </div>
304
+ )} */}
305
+ <Popover
306
+ open={isViewMoreOpen}
307
+ anchorEl={viewMoreAnchorEl}
308
+ onClose={() => setViewMoreAnchorEl(null)}
309
+ anchorOrigin={{ vertical: "bottom", horizontal: "left" }}
310
+ transformOrigin={{ vertical: "top", horizontal: "left" }}
311
+ // PaperProps={{
312
+ // sx: {
313
+ // mt: 2,
314
+ // padding: 0,
315
+ // width: 380,
316
+ // borderRadius: 1,
317
+ // boxShadow: 4,
318
+ // },
319
+ // }}
320
+ >
321
+ <ViewMore
322
+ compactMode={isCompactTable}
323
+ onCompactToggle={(value: string) =>
324
+ setIsCompactTable(value === "Compact")
325
+ }
326
+ isFullscreen={isFullscreen}
327
+ onFullscreenToggle={fullscreenToggle}
328
+ groupBy={groupBy}
329
+ onGroupByChange={(value: string) => setGroupBy(value)}
330
+ tableStates={tableStates}
331
+ onClose={() => setViewMoreAnchorEl(null)}
332
+ />
333
+ </Popover>
223
334
  </div>
224
335
  </div>
225
336
  );