oa-componentbook 1.0.1-stage.444 → 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,8 +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.array.sort.js");
|
|
12
|
-
require("core-js/modules/es.json.stringify.js");
|
|
13
11
|
var _react = _interopRequireWildcard(require("react"));
|
|
14
12
|
var _Search = _interopRequireDefault(require("@material-ui/icons/Search"));
|
|
15
13
|
var _FilterList = _interopRequireDefault(require("@material-ui/icons/FilterList"));
|
|
@@ -135,6 +133,47 @@ function TableWithSearchAndFilter(_ref) {
|
|
|
135
133
|
}
|
|
136
134
|
};
|
|
137
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
|
+
|
|
138
177
|
// Filter handlers
|
|
139
178
|
const handleOpenFilterDrawer = () => setIsFilterDrawerVisible(true);
|
|
140
179
|
const handleCloseFilterDrawer = () => setIsFilterDrawerVisible(false);
|
|
@@ -145,8 +184,15 @@ function TableWithSearchAndFilter(_ref) {
|
|
|
145
184
|
const updatedFilters = _objectSpread(_objectSpread({}, filterValues), {}, {
|
|
146
185
|
[key]: normalizedValue
|
|
147
186
|
});
|
|
187
|
+
|
|
188
|
+
// Update filter values
|
|
148
189
|
setFilterValues(updatedFilters);
|
|
149
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
|
+
|
|
150
196
|
// Call onChange callback if provided for real-time filter changes
|
|
151
197
|
if (onFilterChange) {
|
|
152
198
|
onFilterChange(key, normalizedValue, updatedFilters, action);
|
|
@@ -160,78 +206,21 @@ function TableWithSearchAndFilter(_ref) {
|
|
|
160
206
|
};
|
|
161
207
|
const handleClearFilters = () => {
|
|
162
208
|
setFilterValues({});
|
|
209
|
+
// Update validation state immediately
|
|
210
|
+
const isValid = validateRequiredFields({}, requiredKeys);
|
|
211
|
+
setAreAllRequiredFieldsFilled(isValid);
|
|
163
212
|
if (onFiltersClear) {
|
|
164
213
|
onFiltersClear();
|
|
165
214
|
}
|
|
166
215
|
};
|
|
167
216
|
|
|
168
|
-
//
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
required,
|
|
176
|
-
fields = []
|
|
177
|
-
} = filter;
|
|
178
|
-
if (required) {
|
|
179
|
-
if (type === 'dateRange' || type === 'group') {
|
|
180
|
-
fields.forEach(field => {
|
|
181
|
-
keys.push(field.key);
|
|
182
|
-
});
|
|
183
|
-
} else {
|
|
184
|
-
keys.push(key);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
});
|
|
188
|
-
return keys;
|
|
189
|
-
}, [filterConfig]);
|
|
190
|
-
|
|
191
|
-
// Create a stable string signature of required field values for reliable dependency tracking
|
|
192
|
-
const requiredFieldsSignature = (0, _react.useMemo)(() => {
|
|
193
|
-
if (requiredKeys.length === 0) return '';
|
|
194
|
-
return requiredKeys.map(key => {
|
|
195
|
-
const value = filterValues[key];
|
|
196
|
-
if (value === undefined || value === null) return "".concat(key, ":null");
|
|
197
|
-
if (value instanceof Date) return "".concat(key, ":").concat(value.getTime());
|
|
198
|
-
if (Array.isArray(value)) return "".concat(key, ":array[").concat(value.length, "]");
|
|
199
|
-
if (typeof value === 'object') return "".concat(key, ":obj[").concat(Object.keys(value).length, "]");
|
|
200
|
-
return "".concat(key, ":").concat(JSON.stringify(value));
|
|
201
|
-
}).sort().join('|');
|
|
202
|
-
}, [requiredKeys, filterValues]);
|
|
203
|
-
|
|
204
|
-
// Use useEffect to update validation state whenever filterValues or requiredKeys change
|
|
205
|
-
// Using signature ensures reliable updates in production builds where object reference comparison might fail
|
|
206
|
-
(0, _react.useEffect)(() => {
|
|
207
|
-
// If no required fields, button should be enabled
|
|
208
|
-
if (requiredKeys.length === 0) {
|
|
209
|
-
setAreAllRequiredFieldsFilled(true);
|
|
210
|
-
return;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
// Check each required field has a valid value
|
|
214
|
-
const allFilled = requiredKeys.every(requiredKey => {
|
|
215
|
-
const value = filterValues[requiredKey];
|
|
216
|
-
|
|
217
|
-
// Check if value exists and is not empty/null/undefined
|
|
218
|
-
if (value === undefined || value === null || value === '') {
|
|
219
|
-
return false;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
// Handle arrays
|
|
223
|
-
if (Array.isArray(value)) {
|
|
224
|
-
return value.length > 0;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
// Handle objects (but allow Date objects and other valid objects)
|
|
228
|
-
if (typeof value === 'object' && !(value instanceof Date)) {
|
|
229
|
-
return Object.keys(value).length > 0;
|
|
230
|
-
}
|
|
231
|
-
return true;
|
|
232
|
-
});
|
|
233
|
-
setAreAllRequiredFieldsFilled(allFilled);
|
|
234
|
-
}, [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]);
|
|
235
224
|
|
|
236
225
|
// Helper function to determine notFoundContent message
|
|
237
226
|
const getNotFoundContent = (isApiCallInProgress, query) => {
|