oa-componentbook 1.0.1-stage.443 → 1.0.1-stage.445
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/build/components/oa-component-table-with-search-and-filter/TableWithSearchAndFilter.js
CHANGED
|
@@ -8,7 +8,6 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
8
8
|
});
|
|
9
9
|
exports.default = void 0;
|
|
10
10
|
require("core-js/modules/web.dom-collections.iterator.js");
|
|
11
|
-
require("core-js/modules/es.json.stringify.js");
|
|
12
11
|
var _react = _interopRequireWildcard(require("react"));
|
|
13
12
|
var _Search = _interopRequireDefault(require("@material-ui/icons/Search"));
|
|
14
13
|
var _FilterList = _interopRequireDefault(require("@material-ui/icons/FilterList"));
|
|
@@ -116,6 +115,7 @@ function TableWithSearchAndFilter(_ref) {
|
|
|
116
115
|
// Filter drawer state
|
|
117
116
|
const [isFilterDrawerVisible, setIsFilterDrawerVisible] = (0, _react.useState)(false);
|
|
118
117
|
const [filterValues, setFilterValues] = (0, _react.useState)({});
|
|
118
|
+
const [areAllRequiredFieldsFilled, setAreAllRequiredFieldsFilled] = (0, _react.useState)(true);
|
|
119
119
|
|
|
120
120
|
// Search handlers
|
|
121
121
|
const handleSearchChange = e => {
|
|
@@ -133,6 +133,47 @@ function TableWithSearchAndFilter(_ref) {
|
|
|
133
133
|
}
|
|
134
134
|
};
|
|
135
135
|
|
|
136
|
+
// Memoized required keys calculation for better performance
|
|
137
|
+
const requiredKeys = (0, _react.useMemo)(() => {
|
|
138
|
+
const keys = [];
|
|
139
|
+
filterConfig.forEach(filter => {
|
|
140
|
+
const {
|
|
141
|
+
type,
|
|
142
|
+
key,
|
|
143
|
+
required,
|
|
144
|
+
fields = []
|
|
145
|
+
} = filter;
|
|
146
|
+
if (required) {
|
|
147
|
+
if (type === 'dateRange' || type === 'group') {
|
|
148
|
+
fields.forEach(field => {
|
|
149
|
+
keys.push(field.key);
|
|
150
|
+
});
|
|
151
|
+
} else {
|
|
152
|
+
keys.push(key);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
});
|
|
156
|
+
return keys;
|
|
157
|
+
}, [filterConfig]);
|
|
158
|
+
|
|
159
|
+
// Helper function to validate if all required fields are filled
|
|
160
|
+
const validateRequiredFields = (filters, keys) => {
|
|
161
|
+
if (keys.length === 0) return true;
|
|
162
|
+
return keys.every(requiredKey => {
|
|
163
|
+
const val = filters[requiredKey];
|
|
164
|
+
if (val === undefined || val === null || val === '') {
|
|
165
|
+
return false;
|
|
166
|
+
}
|
|
167
|
+
if (Array.isArray(val)) {
|
|
168
|
+
return val.length > 0;
|
|
169
|
+
}
|
|
170
|
+
if (typeof val === 'object' && !(val instanceof Date)) {
|
|
171
|
+
return Object.keys(val).length > 0;
|
|
172
|
+
}
|
|
173
|
+
return true;
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
|
|
136
177
|
// Filter handlers
|
|
137
178
|
const handleOpenFilterDrawer = () => setIsFilterDrawerVisible(true);
|
|
138
179
|
const handleCloseFilterDrawer = () => setIsFilterDrawerVisible(false);
|
|
@@ -143,8 +184,15 @@ function TableWithSearchAndFilter(_ref) {
|
|
|
143
184
|
const updatedFilters = _objectSpread(_objectSpread({}, filterValues), {}, {
|
|
144
185
|
[key]: normalizedValue
|
|
145
186
|
});
|
|
187
|
+
|
|
188
|
+
// Update filter values
|
|
146
189
|
setFilterValues(updatedFilters);
|
|
147
190
|
|
|
191
|
+
// Immediately update validation state to ensure button state is always correct
|
|
192
|
+
// This avoids React production optimization issues with dependency tracking
|
|
193
|
+
const isValid = validateRequiredFields(updatedFilters, requiredKeys);
|
|
194
|
+
setAreAllRequiredFieldsFilled(isValid);
|
|
195
|
+
|
|
148
196
|
// Call onChange callback if provided for real-time filter changes
|
|
149
197
|
if (onFilterChange) {
|
|
150
198
|
onFilterChange(key, normalizedValue, updatedFilters, action);
|
|
@@ -158,73 +206,21 @@ function TableWithSearchAndFilter(_ref) {
|
|
|
158
206
|
};
|
|
159
207
|
const handleClearFilters = () => {
|
|
160
208
|
setFilterValues({});
|
|
209
|
+
// Update validation state immediately
|
|
210
|
+
const isValid = validateRequiredFields({}, requiredKeys);
|
|
211
|
+
setAreAllRequiredFieldsFilled(isValid);
|
|
161
212
|
if (onFiltersClear) {
|
|
162
213
|
onFiltersClear();
|
|
163
214
|
}
|
|
164
215
|
};
|
|
165
216
|
|
|
166
|
-
//
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
required,
|
|
174
|
-
fields = []
|
|
175
|
-
} = filter;
|
|
176
|
-
if (required) {
|
|
177
|
-
if (type === 'dateRange' || type === 'group') {
|
|
178
|
-
fields.forEach(field => {
|
|
179
|
-
keys.push(field.key);
|
|
180
|
-
});
|
|
181
|
-
} else {
|
|
182
|
-
keys.push(key);
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
});
|
|
186
|
-
return keys;
|
|
187
|
-
}, [filterConfig]);
|
|
188
|
-
|
|
189
|
-
// Create a stable string representation of filterValues for required keys
|
|
190
|
-
// This ensures reliable dependency tracking in production builds
|
|
191
|
-
const requiredFieldsSignature = (0, _react.useMemo)(() => requiredKeys.map(key => {
|
|
192
|
-
const value = filterValues[key];
|
|
193
|
-
// Create a stable string representation that changes when value changes
|
|
194
|
-
if (value === undefined || value === null) return "".concat(key, ":null");
|
|
195
|
-
if (value instanceof Date) return "".concat(key, ":").concat(value.getTime());
|
|
196
|
-
return "".concat(key, ":").concat(JSON.stringify(value));
|
|
197
|
-
}).join('|'), [requiredKeys, filterValues]);
|
|
198
|
-
|
|
199
|
-
// Memoized check if all required fields are filled
|
|
200
|
-
const areAllRequiredFieldsFilled = (0, _react.useMemo)(() => {
|
|
201
|
-
// If no required fields, button should be enabled
|
|
202
|
-
if (requiredKeys.length === 0) {
|
|
203
|
-
return true;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
// Check each required field has a valid value
|
|
207
|
-
return requiredKeys.every(requiredKey => {
|
|
208
|
-
const value = filterValues[requiredKey];
|
|
209
|
-
|
|
210
|
-
// Check if value exists and is not empty/null/undefined
|
|
211
|
-
// Also handle edge cases: empty arrays, empty objects, etc.
|
|
212
|
-
if (value === undefined || value === null || value === '') {
|
|
213
|
-
return false;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Handle arrays
|
|
217
|
-
if (Array.isArray(value)) {
|
|
218
|
-
return value.length > 0;
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Handle objects (but allow Date objects and other valid objects)
|
|
222
|
-
if (typeof value === 'object' && !(value instanceof Date)) {
|
|
223
|
-
return Object.keys(value).length > 0;
|
|
224
|
-
}
|
|
225
|
-
return true;
|
|
226
|
-
});
|
|
227
|
-
}, [requiredKeys, requiredFieldsSignature, filterValues]);
|
|
217
|
+
// Initialize/update validation state when requiredKeys or filterConfig changes
|
|
218
|
+
// This handles cases where filterConfig prop changes externally
|
|
219
|
+
_react.default.useEffect(() => {
|
|
220
|
+
const isValid = validateRequiredFields(filterValues, requiredKeys);
|
|
221
|
+
setAreAllRequiredFieldsFilled(isValid);
|
|
222
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
223
|
+
}, [requiredKeys]);
|
|
228
224
|
|
|
229
225
|
// Helper function to determine notFoundContent message
|
|
230
226
|
const getNotFoundContent = (isApiCallInProgress, query) => {
|