@solidxai/core-ui 0.1.17 → 0.1.18-beta.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/dist/components/core/card/SolidCardView.d.ts +1 -0
- package/dist/components/core/card/SolidCardView.d.ts.map +1 -1
- package/dist/components/core/card/SolidCardView.js +2 -2
- package/dist/components/core/card/SolidCardView.js.map +1 -1
- package/dist/components/core/card/SolidCardView.tsx +3 -0
- package/dist/components/core/common/SolidGlobalSearchElement.d.ts.map +1 -1
- package/dist/components/core/common/SolidGlobalSearchElement.js +342 -114
- package/dist/components/core/common/SolidGlobalSearchElement.js.map +1 -1
- package/dist/components/core/common/SolidGlobalSearchElement.tsx +285 -47
- package/dist/components/core/form/fields/relations/SolidRelationOneToManyField.js +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationOneToManyField.js.map +1 -1
- package/dist/components/core/form/fields/relations/SolidRelationOneToManyField.tsx +1 -1
- package/dist/components/core/json/SolidJsonEditor.css +89 -0
- package/dist/components/core/kanban/SolidKanbanView.d.ts +1 -0
- package/dist/components/core/kanban/SolidKanbanView.d.ts.map +1 -1
- package/dist/components/core/kanban/SolidKanbanView.js +3 -1
- package/dist/components/core/kanban/SolidKanbanView.js.map +1 -1
- package/dist/components/core/kanban/SolidKanbanView.tsx +4 -1
- package/dist/components/core/list/SolidListView.d.ts +1 -0
- package/dist/components/core/list/SolidListView.d.ts.map +1 -1
- package/dist/components/core/list/SolidListView.js +2 -1
- package/dist/components/core/list/SolidListView.js.map +1 -1
- package/dist/components/core/list/SolidListView.tsx +3 -0
- package/dist/components/core/tree/SolidTreeView.d.ts +3 -0
- package/dist/components/core/tree/SolidTreeView.d.ts.map +1 -1
- package/dist/components/core/tree/SolidTreeView.js +7 -1
- package/dist/components/core/tree/SolidTreeView.js.map +1 -1
- package/dist/components/core/tree/SolidTreeView.tsx +10 -0
- package/dist/constants/error-messages.d.ts +4 -0
- package/dist/constants/error-messages.d.ts.map +1 -1
- package/dist/constants/error-messages.js +4 -0
- package/dist/constants/error-messages.js.map +1 -1
- package/dist/constants/error-messages.ts +4 -0
- package/dist/resources/solid-custom.css +3 -18
- package/dist/resources/themes/solid-dark-enterprise/theme.css +4 -481
- package/dist/resources/themes/solid-dark-modern/theme.css +1 -167
- package/dist/resources/themes/solid-light-enterprise/theme.css +4 -486
- package/dist/resources/themes/solid-light-modern/theme.css +7 -204
- package/dist/routes/pages/admin/core/DatasourceIntrospectionPage.css +1 -1
- package/package.json +1 -1
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import React, { forwardRef, useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from "react";
|
|
2
|
+
import { useDispatch } from "react-redux";
|
|
2
3
|
import FilterComponent, { FilterOperator, FilterRule, FilterRuleType } from "../../../components/core/common/FilterComponent";
|
|
3
4
|
import { toTitleCase } from "../../../helpers/helpers";
|
|
4
5
|
import {clearFilterObjectFromLocalStorage,getFilterObjectFromLocalStorage,setFilterObjectToLocalStorage,
|
|
5
6
|
} from "./globalSearchPersistence";
|
|
6
7
|
import { createSolidEntityApi } from "../../../redux/api/solidEntityApi";
|
|
8
|
+
import { showToast } from "../../../redux/features/toastSlice";
|
|
7
9
|
import qs from "qs";
|
|
8
10
|
import { SolidSaveCustomFilterForm } from "./SolidSaveCustomFilterForm";
|
|
9
11
|
import { ERROR_MESSAGES } from "../../../constants/error-messages";
|
|
@@ -418,10 +420,12 @@ export const mergeAllDiffFilters = (customFilter: any, searchFilter: any, savedF
|
|
|
418
420
|
return filters;
|
|
419
421
|
}
|
|
420
422
|
|
|
421
|
-
const SavedFilterList = ({ savedfilter, activeSavedFilterReference, applySavedFilter, openSavedCustomFilter, setSavedFilterTobeDeleted, setIsDeleteSQDialogVisible, isFocused, onMouseEnter, optionId }: any) => {
|
|
422
|
-
const isActive =
|
|
423
|
-
?
|
|
424
|
-
:
|
|
423
|
+
const SavedFilterList = ({ savedfilter, activeSavedFilterReference, activeSavedFilterReferences, applySavedFilter, openSavedCustomFilter, setSavedFilterTobeDeleted, setIsDeleteSQDialogVisible, isFocused, onMouseEnter, optionId }: any) => {
|
|
424
|
+
const isActive = activeSavedFilterReferences
|
|
425
|
+
? activeSavedFilterReferences.includes(savedfilter?.systemKey ? `system:${savedfilter.systemKey}` : `id:${savedfilter.id}`)
|
|
426
|
+
: savedfilter?.systemKey
|
|
427
|
+
? activeSavedFilterReference === savedfilter.systemKey
|
|
428
|
+
: String(activeSavedFilterReference) === String(savedfilter.id);
|
|
425
429
|
|
|
426
430
|
return (
|
|
427
431
|
<div className="solid-saved-filter-item" onMouseEnter={onMouseEnter}>
|
|
@@ -436,6 +440,10 @@ const SavedFilterList = ({ savedfilter, activeSavedFilterReference, applySavedFi
|
|
|
436
440
|
aria-label={`${savedfilter.name}${isActive ? ", applied" : ""}`}
|
|
437
441
|
onMouseDown={(e) => {
|
|
438
442
|
e.preventDefault();
|
|
443
|
+
e.stopPropagation();
|
|
444
|
+
}}
|
|
445
|
+
onClick={(e) => {
|
|
446
|
+
e.stopPropagation();
|
|
439
447
|
applySavedFilter(savedfilter);
|
|
440
448
|
}}
|
|
441
449
|
title={savedfilter?.description}
|
|
@@ -571,7 +579,8 @@ type RelationCache = Map<string, { label: string; value: number }>;
|
|
|
571
579
|
|
|
572
580
|
|
|
573
581
|
|
|
574
|
-
export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handleApplyCustomFilter, showSaveFilterPopup, setShowSaveFilterPopup, filterPredicates }: any, ref) => {
|
|
582
|
+
export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handleApplyCustomFilter, showSaveFilterPopup, setShowSaveFilterPopup, filterPredicates, allowMultipleSavedFilters = false }: any, ref) => {
|
|
583
|
+
const dispatch = useDispatch();
|
|
575
584
|
type OverlayOption =
|
|
576
585
|
| { id: string; kind: "field"; field: any }
|
|
577
586
|
| { id: string; kind: "predefined"; predefined: any }
|
|
@@ -681,6 +690,8 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
681
690
|
const [currentSavedFilterQuery, setCurrentSavedFilterQuery] = useState<any>();
|
|
682
691
|
const [currentSavedFilterVariables, setCurrentSavedFilterVariables] = useState<Record<string, any>>({});
|
|
683
692
|
const [currentSavedFilterRules, setCurrentSavedFilterRules] = useState<any>();
|
|
693
|
+
const [activeSavedFilters, setActiveSavedFilters] = useState<any[]>([]);
|
|
694
|
+
const [editingSavedFilterKey, setEditingSavedFilterKey] = useState<string | null>(null);
|
|
684
695
|
const [showSavedFilterComponent, setShowSavedFilterComponent] = useState<boolean>(false);
|
|
685
696
|
|
|
686
697
|
|
|
@@ -834,6 +845,27 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
834
845
|
viewData?.data?.solidView?.model?.id,
|
|
835
846
|
user?.id
|
|
836
847
|
])
|
|
848
|
+
|
|
849
|
+
const getSavedFilterKey = (savedFilter: any) =>
|
|
850
|
+
savedFilter?.systemKey ? `system:${savedFilter.systemKey}` : `id:${savedFilter?.id}`;
|
|
851
|
+
|
|
852
|
+
const getPersistedSavedFilterItems = (queryObject: any): any[] => {
|
|
853
|
+
if (!allowMultipleSavedFilters) return [];
|
|
854
|
+
if (Array.isArray(queryObject?.saved_filter_items)) {
|
|
855
|
+
return queryObject.saved_filter_items;
|
|
856
|
+
}
|
|
857
|
+
if (queryObject?.saved_filter_predicate) {
|
|
858
|
+
return [{
|
|
859
|
+
id: queryObject.saved_filter_id,
|
|
860
|
+
systemKey: queryObject.saved_filter_system_key,
|
|
861
|
+
name: queryObject.saved_filter_name || "Saved Filter",
|
|
862
|
+
predicate: queryObject.saved_filter_predicate,
|
|
863
|
+
variables: queryObject.saved_filter_variables || {},
|
|
864
|
+
}];
|
|
865
|
+
}
|
|
866
|
+
return [];
|
|
867
|
+
};
|
|
868
|
+
|
|
837
869
|
// Updates search, custom filter, grouping, aggregation, and UI state from a single shared filter source.
|
|
838
870
|
const syncFilterUiStateFromSharedSource = useCallback(async (queryObject: any | null) => {
|
|
839
871
|
const nextSearchFilter = queryObject?.search_predicate || null;
|
|
@@ -847,9 +879,33 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
847
879
|
nextPredefinedBaseFilter && queryObject?.predefined_search_chip
|
|
848
880
|
? queryObject.predefined_search_chip
|
|
849
881
|
: null;
|
|
850
|
-
const
|
|
882
|
+
const persistedSavedFilterItems = getPersistedSavedFilterItems(queryObject);
|
|
883
|
+
const nextSavedFilterItems = allowMultipleSavedFilters
|
|
884
|
+
? persistedSavedFilterItems.map((item: any) => {
|
|
885
|
+
const savedFilter = availableSavedFilters.find((candidate: any) =>
|
|
886
|
+
item?.systemKey
|
|
887
|
+
? candidate?.systemKey === item.systemKey
|
|
888
|
+
: String(candidate?.id) === String(item?.id)
|
|
889
|
+
);
|
|
890
|
+
return {
|
|
891
|
+
data: savedFilter || {
|
|
892
|
+
id: item?.id,
|
|
893
|
+
systemKey: item?.systemKey,
|
|
894
|
+
name: item?.name || "Saved Filter",
|
|
895
|
+
filterQueryJson: JSON.stringify(item?.predicate || {}),
|
|
896
|
+
},
|
|
897
|
+
query: item?.predicate || {},
|
|
898
|
+
variables: item?.variables || {},
|
|
899
|
+
};
|
|
900
|
+
})
|
|
901
|
+
: [];
|
|
902
|
+
const nextSavedFilter = allowMultipleSavedFilters
|
|
903
|
+
? (nextSavedFilterItems.length > 0 ? { $or: nextSavedFilterItems.map((item: any) => item.query) } : null)
|
|
904
|
+
: queryObject?.saved_filter_predicate || null;
|
|
851
905
|
const nextSavedFilterVariables = queryObject?.saved_filter_variables ?? {};
|
|
852
|
-
const nextSavedFilterData =
|
|
906
|
+
const nextSavedFilterData = allowMultipleSavedFilters
|
|
907
|
+
? (nextSavedFilterItems.length > 0 ? nextSavedFilterItems[nextSavedFilterItems.length - 1].data : null)
|
|
908
|
+
: nextSavedFilter
|
|
853
909
|
? availableSavedFilters.find((savedFilter: any) => {
|
|
854
910
|
if (queryObject?.saved_filter_system_key) {
|
|
855
911
|
return savedFilter?.systemKey === queryObject.saved_filter_system_key;
|
|
@@ -874,6 +930,7 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
874
930
|
setCurrentSavedFilterData((prev: any) => areFilterStateValuesEqual(prev, nextSavedFilterData) ? prev : nextSavedFilterData);
|
|
875
931
|
setCurrentSavedFilterQuery((prev: any) => areFilterStateValuesEqual(prev, nextSavedFilter) ? prev : nextSavedFilter);
|
|
876
932
|
setCurrentSavedFilterVariables((prev) => areFilterStateValuesEqual(prev, nextSavedFilterVariables) ? prev : nextSavedFilterVariables);
|
|
933
|
+
setActiveSavedFilters((prev) => areFilterStateValuesEqual(prev, nextSavedFilterItems) ? prev : nextSavedFilterItems);
|
|
877
934
|
|
|
878
935
|
if (nextCustomFilter && viewData?.data) {
|
|
879
936
|
const rules: FilterRule = transformFiltersToRules(nextCustomFilter);
|
|
@@ -909,7 +966,7 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
909
966
|
|
|
910
967
|
setGroupingRules((prev) => areFilterStateValuesEqual(prev, nextGroupingRules) ? prev : nextGroupingRules);
|
|
911
968
|
setAggregationRules((prev) => areFilterStateValuesEqual(prev, nextAggregationRules) ? prev : nextAggregationRules);
|
|
912
|
-
}, [availableSavedFilters, initialState, viewData]);
|
|
969
|
+
}, [allowMultipleSavedFilters, availableSavedFilters, initialState, viewData]);
|
|
913
970
|
|
|
914
971
|
const resetAppliedFilters = ({ preserveGrouping = false }: { preserveGrouping?: boolean } = {}) => {
|
|
915
972
|
setSearchChips([]);
|
|
@@ -922,6 +979,8 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
922
979
|
setCurrentSavedFilterQuery(null);
|
|
923
980
|
setCurrentSavedFilterVariables({});
|
|
924
981
|
setCurrentSavedFilterRules(null);
|
|
982
|
+
setActiveSavedFilters([]);
|
|
983
|
+
setEditingSavedFilterKey(null);
|
|
925
984
|
if (!preserveGrouping) {
|
|
926
985
|
setGroupingRules(defaultGroupingRules);
|
|
927
986
|
setAggregationRules(defaultAggregationRules);
|
|
@@ -1221,6 +1280,15 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1221
1280
|
// };
|
|
1222
1281
|
// }
|
|
1223
1282
|
setCurrentSavedFilterQuery(finalCustomFilter);
|
|
1283
|
+
if (allowMultipleSavedFilters && editingSavedFilterKey) {
|
|
1284
|
+
const nextItems = activeSavedFilters.map((item: any) =>
|
|
1285
|
+
getSavedFilterKey(item.data) === editingSavedFilterKey
|
|
1286
|
+
? { ...item, query: finalCustomFilter }
|
|
1287
|
+
: item
|
|
1288
|
+
);
|
|
1289
|
+
setActiveSavedFilters(nextItems);
|
|
1290
|
+
persistActiveSavedFilters(nextItems);
|
|
1291
|
+
}
|
|
1224
1292
|
setShowSavedFilterComponent(false);
|
|
1225
1293
|
setHasSearched(true)
|
|
1226
1294
|
setRefreshKey((prev) => prev + 1)
|
|
@@ -1262,7 +1330,9 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1262
1330
|
const finalSearchFilter = tranformSearchToFilters(formattedChips);
|
|
1263
1331
|
setSearchFilter(finalSearchFilter);
|
|
1264
1332
|
|
|
1265
|
-
|
|
1333
|
+
const finalSavedFilter: any = allowMultipleSavedFilters
|
|
1334
|
+
? (activeSavedFilters.length > 0 ? { $or: activeSavedFilters.map((item: any) => item.query) } : null)
|
|
1335
|
+
: currentSavedFilterQuery;
|
|
1266
1336
|
const finalPredefinedFilter = predefinedSearchBaseFilter
|
|
1267
1337
|
|
|
1268
1338
|
const finalCustomFilter = customFilter
|
|
@@ -1271,19 +1341,31 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1271
1341
|
finalPredefinedFilter && predefinedSearchChip
|
|
1272
1342
|
? predefinedSearchChip
|
|
1273
1343
|
: null;
|
|
1274
|
-
if (
|
|
1344
|
+
if (allowMultipleSavedFilters && activeSavedFilters.length > 0) {
|
|
1345
|
+
const resolvedItems = activeSavedFilters.map((item: any) => resolveSavedFilterVariables(item.query, user?.id, item.variables || {}));
|
|
1346
|
+
if (resolvedItems.some((item: any) => item.missingVariables.length > 0)) return;
|
|
1347
|
+
finalFilter.resolved_saved_filter_predicate = { $or: resolvedItems.map((item: any) => item.value) };
|
|
1348
|
+
finalFilter.saved_filter_variables = {};
|
|
1349
|
+
finalFilter.saved_filter_items = activeSavedFilters.map((item: any) => ({
|
|
1350
|
+
id: item.data?.id ?? null,
|
|
1351
|
+
systemKey: item.data?.systemKey ?? null,
|
|
1352
|
+
name: item.data?.name ?? null,
|
|
1353
|
+
predicate: item.query,
|
|
1354
|
+
variables: item.variables || {},
|
|
1355
|
+
}));
|
|
1356
|
+
} else if (finalSavedFilter && Object.keys(finalSavedFilter).length > 0) {
|
|
1275
1357
|
const resolved = resolveSavedFilterVariables(finalSavedFilter, user?.id, currentSavedFilterVariables);
|
|
1276
1358
|
if (resolved.missingVariables.length > 0) return;
|
|
1277
1359
|
finalFilter.resolved_saved_filter_predicate = resolved.value;
|
|
1278
1360
|
finalFilter.saved_filter_variables = currentSavedFilterVariables;
|
|
1279
1361
|
}
|
|
1280
|
-
if (currentSavedFilterData?.id) {
|
|
1362
|
+
if (!allowMultipleSavedFilters && currentSavedFilterData?.id) {
|
|
1281
1363
|
finalFilter.saved_filter_id = currentSavedFilterData.id;
|
|
1282
1364
|
}
|
|
1283
|
-
if (currentSavedFilterData?.systemKey) {
|
|
1365
|
+
if (!allowMultipleSavedFilters && currentSavedFilterData?.systemKey) {
|
|
1284
1366
|
finalFilter.saved_filter_system_key = currentSavedFilterData.systemKey;
|
|
1285
1367
|
}
|
|
1286
|
-
if (currentSavedFilterData?.name) {
|
|
1368
|
+
if (!allowMultipleSavedFilters && currentSavedFilterData?.name) {
|
|
1287
1369
|
finalFilter.saved_filter_name = currentSavedFilterData.name;
|
|
1288
1370
|
}
|
|
1289
1371
|
handleApplyCustomFilter(finalFilter, true);
|
|
@@ -1315,16 +1397,19 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1315
1397
|
// }
|
|
1316
1398
|
|
|
1317
1399
|
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1400
|
+
if (!allowMultipleSavedFilters) {
|
|
1401
|
+
setSearchChips([]);
|
|
1402
|
+
setSearchFilter(null);
|
|
1403
|
+
setFilterRules(initialState);
|
|
1404
|
+
setCustomFilter(null)
|
|
1405
|
+
setPredefinedSearchChip(null);
|
|
1406
|
+
setPredefinedSearchBaseFilter(null);
|
|
1407
|
+
}
|
|
1324
1408
|
|
|
1325
1409
|
if (savedfilter?.id) {
|
|
1326
1410
|
const savedfilterId = savedfilter.id;
|
|
1327
1411
|
setShowOverlay(false);
|
|
1412
|
+
setEditingSavedFilterKey(getSavedFilterKey(savedfilter));
|
|
1328
1413
|
const currentSavedFilterData: any = availableSavedFilters.find((savedFilter: any) => savedFilter.id === savedfilterId);
|
|
1329
1414
|
setCurrentSavedFilterData(currentSavedFilterData);
|
|
1330
1415
|
if (currentSavedFilterData) {
|
|
@@ -1346,7 +1431,32 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1346
1431
|
}
|
|
1347
1432
|
}
|
|
1348
1433
|
|
|
1434
|
+
const persistActiveSavedFilters = (items: any[]) => {
|
|
1435
|
+
const first = items[0];
|
|
1436
|
+
const persistedFilter = {
|
|
1437
|
+
...(getFilterObjectFromLocalStorage() || {}),
|
|
1438
|
+
saved_filter_items: items.map((item) => ({
|
|
1439
|
+
id: item.data?.id ?? null,
|
|
1440
|
+
systemKey: item.data?.systemKey ?? null,
|
|
1441
|
+
name: item.data?.name ?? null,
|
|
1442
|
+
predicate: item.query,
|
|
1443
|
+
variables: item.variables || {},
|
|
1444
|
+
})),
|
|
1445
|
+
saved_filter_predicate: items.length > 0 ? (items.length === 1 ? first.query : { $or: items.map((item) => item.query) }) : null,
|
|
1446
|
+
saved_filter_variables: items.length === 1 ? (first.variables || {}) : {},
|
|
1447
|
+
saved_filter_id: items.length === 1 ? first.data?.id ?? null : null,
|
|
1448
|
+
saved_filter_system_key: items.length === 1 ? first.data?.systemKey ?? null : null,
|
|
1449
|
+
saved_filter_name: items.length === 1 ? first.data?.name ?? null : null,
|
|
1450
|
+
};
|
|
1451
|
+
delete persistedFilter.finalFullFilter;
|
|
1452
|
+
setFilterObjectToLocalStorage(persistedFilter);
|
|
1453
|
+
};
|
|
1454
|
+
|
|
1349
1455
|
const persistActiveSavedFilter = (savedFilter: any, filterJson: any, variables: Record<string, any>) => {
|
|
1456
|
+
if (allowMultipleSavedFilters) {
|
|
1457
|
+
persistActiveSavedFilters([{ data: savedFilter, query: filterJson, variables }]);
|
|
1458
|
+
return;
|
|
1459
|
+
}
|
|
1350
1460
|
const persistedFilter = {
|
|
1351
1461
|
...(getFilterObjectFromLocalStorage() || {}),
|
|
1352
1462
|
custom_filter_predicate: null,
|
|
@@ -1372,6 +1482,7 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1372
1482
|
|
|
1373
1483
|
const persistedFilter = {
|
|
1374
1484
|
...(getFilterObjectFromLocalStorage() || {}),
|
|
1485
|
+
saved_filter_items: [],
|
|
1375
1486
|
saved_filter_predicate: null,
|
|
1376
1487
|
saved_filter_variables: {},
|
|
1377
1488
|
saved_filter_id: null,
|
|
@@ -1386,15 +1497,40 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1386
1497
|
};
|
|
1387
1498
|
|
|
1388
1499
|
const deleteSavedFilter = async () => {
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1500
|
+
try {
|
|
1501
|
+
await deleteEntity(savedFilterTobeDeleted).unwrap();
|
|
1502
|
+
dispatch(showToast({
|
|
1503
|
+
severity: "success",
|
|
1504
|
+
summary: ERROR_MESSAGES.DELETED,
|
|
1505
|
+
detail: ERROR_MESSAGES.ENTITY_DELETE,
|
|
1506
|
+
}));
|
|
1507
|
+
|
|
1508
|
+
if (allowMultipleSavedFilters) {
|
|
1509
|
+
const nextItems = activeSavedFilters.filter((item: any) => String(item.data?.id) !== String(savedFilterTobeDeleted));
|
|
1510
|
+
setActiveSavedFilters(nextItems);
|
|
1511
|
+
if (String(savedFilterTobeDeleted) === String(currentSavedFilterData?.id)) {
|
|
1512
|
+
setCurrentSavedFilterData(null);
|
|
1513
|
+
setCurrentSavedFilterQuery(null);
|
|
1514
|
+
setCurrentSavedFilterVariables({});
|
|
1515
|
+
}
|
|
1516
|
+
persistActiveSavedFilters(nextItems);
|
|
1517
|
+
setHasSearched(true);
|
|
1518
|
+
setRefreshKey((prev) => prev + 1);
|
|
1519
|
+
} else if (String(savedFilterTobeDeleted) === String(currentSavedFilterData?.id)) {
|
|
1520
|
+
removeSavedFilter();
|
|
1521
|
+
}
|
|
1522
|
+
setIsDeleteSQDialogVisible(false);
|
|
1523
|
+
setTimeout(() => {
|
|
1524
|
+
setSavedFilterFetchDataRefreshKey(prev => prev + 1)
|
|
1525
|
+
}, 500)
|
|
1526
|
+
} catch (error: any) {
|
|
1527
|
+
const errorMessage = error?.data?.message || error?.data?.error || error?.message || ERROR_MESSAGES.SOMETHING_WRONG;
|
|
1528
|
+
dispatch(showToast({
|
|
1529
|
+
severity: "error",
|
|
1530
|
+
summary: ERROR_MESSAGES.DELETE_FAIELD,
|
|
1531
|
+
detail: errorMessage,
|
|
1532
|
+
}));
|
|
1393
1533
|
}
|
|
1394
|
-
setIsDeleteSQDialogVisible(false);
|
|
1395
|
-
setTimeout(() => {
|
|
1396
|
-
setSavedFilterFetchDataRefreshKey(prev => prev + 1)
|
|
1397
|
-
}, 500)
|
|
1398
1534
|
}
|
|
1399
1535
|
const handleSaveFilter = async (formValues: any) => {
|
|
1400
1536
|
setShowSaveFilterPopup(false)
|
|
@@ -1411,13 +1547,20 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1411
1547
|
formData.append("userId", user?.id);
|
|
1412
1548
|
|
|
1413
1549
|
await updateEntity({ id: +formValues.id, data: formData }).unwrap();
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1550
|
+
dispatch(showToast({
|
|
1551
|
+
severity: "success",
|
|
1552
|
+
summary: ERROR_MESSAGES.SAVED_FILTER_UPDATED,
|
|
1553
|
+
detail: ERROR_MESSAGES.SAVED_FILTER_UPDATED_SUCCESSFULLY,
|
|
1554
|
+
}));
|
|
1555
|
+
|
|
1556
|
+
if (!allowMultipleSavedFilters) {
|
|
1557
|
+
setSearchChips([]);
|
|
1558
|
+
setSearchFilter(null);
|
|
1559
|
+
setFilterRules(initialState);
|
|
1560
|
+
setCustomFilter(null)
|
|
1561
|
+
setPredefinedSearchChip(null);
|
|
1562
|
+
setPredefinedSearchBaseFilter(null);
|
|
1563
|
+
}
|
|
1421
1564
|
// Apply the rename immediately, both to the active filter and to
|
|
1422
1565
|
// the cached list — otherwise the list still holds the pre-rename
|
|
1423
1566
|
// entry, which wins the id-based lookup the next time saved-filter
|
|
@@ -1427,7 +1570,17 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1427
1570
|
setSavedFilters((prev) => prev.map((f: any) => String(f?.id) === String(formValues.id) ? { ...f, ...savedFilterRecord } : f));
|
|
1428
1571
|
setCurrentSavedFilterData(savedFilterRecord);
|
|
1429
1572
|
setCurrentSavedFilterQuery(filterJson);
|
|
1430
|
-
|
|
1573
|
+
if (allowMultipleSavedFilters) {
|
|
1574
|
+
const nextItems = activeSavedFilters.map((item: any) =>
|
|
1575
|
+
getSavedFilterKey(item.data) === getSavedFilterKey(savedFilterRecord)
|
|
1576
|
+
? { data: savedFilterRecord, query: filterJson, variables: currentSavedFilterVariables }
|
|
1577
|
+
: item
|
|
1578
|
+
);
|
|
1579
|
+
setActiveSavedFilters(nextItems);
|
|
1580
|
+
persistActiveSavedFilters(nextItems);
|
|
1581
|
+
} else {
|
|
1582
|
+
persistActiveSavedFilter(savedFilterRecord, filterJson, currentSavedFilterVariables);
|
|
1583
|
+
}
|
|
1431
1584
|
setHasSearched(true);
|
|
1432
1585
|
setRefreshKey((prev) => prev + 1);
|
|
1433
1586
|
} else {
|
|
@@ -1441,6 +1594,11 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1441
1594
|
formData.append("isPrivate", formValues.isPrivate);
|
|
1442
1595
|
formData.append("userId", user?.id);
|
|
1443
1596
|
const result = await createEntity(formData).unwrap();
|
|
1597
|
+
dispatch(showToast({
|
|
1598
|
+
severity: "success",
|
|
1599
|
+
summary: ERROR_MESSAGES.SAVED_FILTER_CREATED,
|
|
1600
|
+
detail: ERROR_MESSAGES.SAVED_FILTER_CREATED_SUCCESSFULLY,
|
|
1601
|
+
}));
|
|
1444
1602
|
|
|
1445
1603
|
setSearchChips([]);
|
|
1446
1604
|
setSearchFilter(null);
|
|
@@ -1450,17 +1608,31 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1450
1608
|
setPredefinedSearchBaseFilter(null);
|
|
1451
1609
|
// The custom filter just became this saved filter — apply it, and
|
|
1452
1610
|
// seed the cached list with it, immediately (see rename branch above).
|
|
1611
|
+
// A newly created saved filter replaces any other active filters/saved
|
|
1612
|
+
// filters rather than joining them — only applying an existing saved
|
|
1613
|
+
// filter is additive when allowMultipleSavedFilters is on.
|
|
1453
1614
|
const savedFilterRecord = { id: result.data.id, name: formValues.name, isPrivate: formValues.isPrivate, filterQueryJson: JSON.stringify(filterJson, null, 2) };
|
|
1454
1615
|
setSavedFilters((prev) => [savedFilterRecord, ...prev]);
|
|
1455
1616
|
setCurrentSavedFilterData(savedFilterRecord);
|
|
1456
1617
|
setCurrentSavedFilterQuery(filterJson);
|
|
1457
1618
|
setCurrentSavedFilterVariables({});
|
|
1458
|
-
|
|
1619
|
+
if (allowMultipleSavedFilters) {
|
|
1620
|
+
const nextItems = [{ data: savedFilterRecord, query: filterJson, variables: {} }];
|
|
1621
|
+
setActiveSavedFilters(nextItems);
|
|
1622
|
+
persistActiveSavedFilters(nextItems);
|
|
1623
|
+
} else {
|
|
1624
|
+
persistActiveSavedFilter(savedFilterRecord, filterJson, {});
|
|
1625
|
+
}
|
|
1459
1626
|
setHasSearched(true);
|
|
1460
1627
|
setRefreshKey((prev) => prev + 1);
|
|
1461
1628
|
}
|
|
1462
|
-
} catch (error) {
|
|
1463
|
-
|
|
1629
|
+
} catch (error: any) {
|
|
1630
|
+
const errorMessage = error?.data?.message || error?.data?.error || error?.message || ERROR_MESSAGES.SOMETHING_WRONG;
|
|
1631
|
+
dispatch(showToast({
|
|
1632
|
+
severity: "error",
|
|
1633
|
+
summary: ERROR_MESSAGES.ERROR,
|
|
1634
|
+
detail: errorMessage,
|
|
1635
|
+
}));
|
|
1464
1636
|
}
|
|
1465
1637
|
}
|
|
1466
1638
|
|
|
@@ -1553,6 +1725,28 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1553
1725
|
return false;
|
|
1554
1726
|
}
|
|
1555
1727
|
|
|
1728
|
+
if (allowMultipleSavedFilters) {
|
|
1729
|
+
const key = getSavedFilterKey(savedfilter);
|
|
1730
|
+
const nextItem = { data: savedfilter, query: filterJson, variables };
|
|
1731
|
+
const existingItem = activeSavedFilters.find((item: any) => getSavedFilterKey(item.data) === key);
|
|
1732
|
+
if (existingItem && areFilterStateValuesEqual(existingItem.query, filterJson) && areFilterStateValuesEqual(existingItem.variables, variables)) {
|
|
1733
|
+
return true;
|
|
1734
|
+
}
|
|
1735
|
+
const nextItems = existingItem
|
|
1736
|
+
? activeSavedFilters.map((item: any) => getSavedFilterKey(item.data) === key ? nextItem : item)
|
|
1737
|
+
: [...activeSavedFilters, nextItem];
|
|
1738
|
+
setActiveSavedFilters(nextItems);
|
|
1739
|
+
setCurrentSavedFilterData(savedfilter);
|
|
1740
|
+
setCurrentSavedFilterQuery(filterJson);
|
|
1741
|
+
setCurrentSavedFilterVariables(variables);
|
|
1742
|
+
setEditingSavedFilterKey(null);
|
|
1743
|
+
persistActiveSavedFilters(nextItems);
|
|
1744
|
+
setShowOverlay(false);
|
|
1745
|
+
setHasSearched(true);
|
|
1746
|
+
setRefreshKey((prev) => prev + 1);
|
|
1747
|
+
return true;
|
|
1748
|
+
}
|
|
1749
|
+
|
|
1556
1750
|
// Applying the already-active filter must be a no-op. This is important
|
|
1557
1751
|
// for lifecycle extensions: applying a filter causes a new list load,
|
|
1558
1752
|
// which invokes onBeforeListDataLoad/onListLoad again.
|
|
@@ -1589,6 +1783,19 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1589
1783
|
}
|
|
1590
1784
|
|
|
1591
1785
|
const removeSavedFilter = () => {
|
|
1786
|
+
if (allowMultipleSavedFilters) {
|
|
1787
|
+
const key = getSavedFilterKey(currentSavedFilterData);
|
|
1788
|
+
const nextItems = activeSavedFilters.filter((item: any) => getSavedFilterKey(item.data) !== key);
|
|
1789
|
+
setActiveSavedFilters(nextItems);
|
|
1790
|
+
setCurrentSavedFilterData(null);
|
|
1791
|
+
setCurrentSavedFilterQuery(null);
|
|
1792
|
+
setCurrentSavedFilterVariables({});
|
|
1793
|
+
setEditingSavedFilterKey(null);
|
|
1794
|
+
persistActiveSavedFilters(nextItems);
|
|
1795
|
+
setHasSearched(true);
|
|
1796
|
+
setRefreshKey((prev) => prev + 1);
|
|
1797
|
+
return;
|
|
1798
|
+
}
|
|
1592
1799
|
clearActiveSavedFilter();
|
|
1593
1800
|
}
|
|
1594
1801
|
|
|
@@ -1698,14 +1905,35 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1698
1905
|
const managedChipItems = useMemo<ManagedChipItem[]>(() => {
|
|
1699
1906
|
const items: ManagedChipItem[] = [];
|
|
1700
1907
|
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1908
|
+
const savedItems = allowMultipleSavedFilters
|
|
1909
|
+
? activeSavedFilters
|
|
1910
|
+
: (currentSavedFilterData?.name ? [{ data: currentSavedFilterData }] : []);
|
|
1911
|
+
savedItems.forEach((item: any) => {
|
|
1912
|
+
if (item.data?.name) {
|
|
1913
|
+
items.push({
|
|
1914
|
+
id: `saved-filter:${getSavedFilterKey(item.data)}`,
|
|
1915
|
+
type: "saved",
|
|
1916
|
+
label: `Saved: ${item.data.name}`,
|
|
1917
|
+
onRemove: () => {
|
|
1918
|
+
if (!allowMultipleSavedFilters) {
|
|
1919
|
+
removeSavedFilter();
|
|
1920
|
+
return;
|
|
1921
|
+
}
|
|
1922
|
+
const nextItems = activeSavedFilters.filter((active: any) => getSavedFilterKey(active.data) !== getSavedFilterKey(item.data));
|
|
1923
|
+
setActiveSavedFilters(nextItems);
|
|
1924
|
+
if (getSavedFilterKey(currentSavedFilterData) === getSavedFilterKey(item.data)) {
|
|
1925
|
+
setCurrentSavedFilterData(null);
|
|
1926
|
+
setCurrentSavedFilterQuery(null);
|
|
1927
|
+
setCurrentSavedFilterVariables({});
|
|
1928
|
+
}
|
|
1929
|
+
persistActiveSavedFilters(nextItems);
|
|
1930
|
+
setHasSearched(true);
|
|
1931
|
+
setRefreshKey((prev) => prev + 1);
|
|
1932
|
+
},
|
|
1933
|
+
...(allowMultipleSavedFilters ? { onOpen: () => openSavedCustomFilter(item.data) } : {}),
|
|
1934
|
+
});
|
|
1935
|
+
}
|
|
1936
|
+
});
|
|
1709
1937
|
|
|
1710
1938
|
if (predefinedSearchChip?.name && predefinedSearchChip?.value) {
|
|
1711
1939
|
items.push({
|
|
@@ -1751,6 +1979,8 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1751
1979
|
return items;
|
|
1752
1980
|
}, [
|
|
1753
1981
|
currentSavedFilterData,
|
|
1982
|
+
activeSavedFilters,
|
|
1983
|
+
allowMultipleSavedFilters,
|
|
1754
1984
|
predefinedSearchChip,
|
|
1755
1985
|
customFilter,
|
|
1756
1986
|
customRuleCount,
|
|
@@ -1987,7 +2217,6 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
1987
2217
|
const removePredefinedSearchChip = () => {
|
|
1988
2218
|
setPredefinedSearchChip(null);
|
|
1989
2219
|
setPredefinedSearchBaseFilter(null)
|
|
1990
|
-
setCustomFilter(null);
|
|
1991
2220
|
setHasSearched(true);
|
|
1992
2221
|
setRefreshKey((prev) => prev + 1)
|
|
1993
2222
|
};
|
|
@@ -2192,6 +2421,10 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
2192
2421
|
className={`text-color solid-search-overlay-option ${focusedIndex === optionIndex ? "solid-search-overlay-option-active" : ""}`}
|
|
2193
2422
|
onMouseDown={(e) => {
|
|
2194
2423
|
e.preventDefault();
|
|
2424
|
+
e.stopPropagation();
|
|
2425
|
+
}}
|
|
2426
|
+
onClick={(e) => {
|
|
2427
|
+
e.stopPropagation();
|
|
2195
2428
|
handlePredefinedSearch(predefinedSearch);
|
|
2196
2429
|
}}
|
|
2197
2430
|
onMouseEnter={() => setFocusedIndex(optionIndex)}
|
|
@@ -2234,6 +2467,10 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
2234
2467
|
className={`text-color solid-search-overlay-option ${focusedIndex === optionIndex ? "solid-search-overlay-option-active" : ""}`}
|
|
2235
2468
|
onMouseDown={(e) => {
|
|
2236
2469
|
e.preventDefault();
|
|
2470
|
+
e.stopPropagation();
|
|
2471
|
+
}}
|
|
2472
|
+
onClick={(e) => {
|
|
2473
|
+
e.stopPropagation();
|
|
2237
2474
|
const currentValue = inputValue?.trim();
|
|
2238
2475
|
if (currentValue) {
|
|
2239
2476
|
const values = currentValue.split(",").map((v) => v.trim()).filter((v) => v !== "");
|
|
@@ -2317,6 +2554,7 @@ export const SolidGlobalSearchElement = forwardRef(({ viewData, viewType, handle
|
|
|
2317
2554
|
key={savedfilter.id}
|
|
2318
2555
|
savedfilter={savedfilter}
|
|
2319
2556
|
activeSavedFilterReference={currentSavedFilterData?.systemKey || currentSavedFilterData?.id}
|
|
2557
|
+
activeSavedFilterReferences={allowMultipleSavedFilters ? activeSavedFilters.map((item: any) => getSavedFilterKey(item.data)) : undefined}
|
|
2320
2558
|
applySavedFilter={applySavedFilter}
|
|
2321
2559
|
openSavedCustomFilter={openSavedCustomFilter}
|
|
2322
2560
|
setSavedFilterTobeDeleted={setSavedFilterTobeDeleted}
|
|
@@ -431,7 +431,7 @@ export var DefaultRelationOneToManyFormViewWidget = function (_a) {
|
|
|
431
431
|
var formReadonly = (_p = (_o = (_m = solidFormViewMetaData.data.solidView) === null || _m === void 0 ? void 0 : _m.layout) === null || _o === void 0 ? void 0 : _o.attrs) === null || _p === void 0 ? void 0 : _p.readonly;
|
|
432
432
|
return (_jsxs("div", { className: styles.fieldViewWrapper, children: [showFieldLabel != false &&
|
|
433
433
|
_jsxs("label", { htmlFor: fieldLayoutInfo.attrs.name, className: "".concat(styles.fieldViewLabel, " form-field-label"), children: [fieldLabel, fieldMetadata.required && _jsx("span", { className: "text-red-500", children: " *" }), _jsx(SolidFieldTooltip, { fieldContext: fieldContext })] }), listViewParams &&
|
|
434
|
-
_jsx(SolidListView, __assign({}, listViewParams, { handleAddClickForEmbeddedView: handleAddOrEditClickForEmbeddedView, handleEditClickForEmbeddedView: handleAddOrEditClickForEmbeddedView }), refreshList.toString()),
|
|
434
|
+
_jsx(SolidListView, __assign({}, listViewParams, { handleAddClickForEmbeddedView: handleAddOrEditClickForEmbeddedView, handleEditClickForEmbeddedView: handleAddOrEditClickForEmbeddedView }), refreshList.toString()), formViewParams &&
|
|
435
435
|
_jsx(RenderSolidFormEmbededView, { fieldLayoutInfo: fieldLayoutInfo, visibleCreateRelationEntity: visibleCreateRelationEntity, setvisibleCreateRelationEntity: setvisibleCreateRelationEntity, formViewParams: formViewParams, handlePopupClose: handlePopupClose })] }));
|
|
436
436
|
};
|
|
437
437
|
export var RenderSolidFormEmbededView = function (_a) {
|