@oneuptime/common 11.7.2 → 11.7.3
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/Models/AnalyticsModels/KubernetesCostAllocation.ts +103 -0
- package/Models/DatabaseModels/TableView.ts +40 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.ts +13 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +2 -0
- package/Tests/Models/AnalyticsModels/KubernetesCostAllocation.test.ts +16 -0
- package/Tests/Types/JSONFunctions.test.ts +103 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +679 -0
- package/Tests/UI/Components/ModelTable/ColumnCustomizationModal.test.tsx +572 -0
- package/Tests/UI/Components/ModelTable/ColumnPreference.test.ts +1678 -0
- package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1094 -0
- package/Tests/Utils/UserPreferences.test.ts +563 -0
- package/Types/JSONFunctions.ts +7 -2
- package/Types/Kubernetes/KubernetesCostIngest.ts +37 -1
- package/UI/Components/MasterPage/MasterPage.tsx +65 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +387 -4
- package/UI/Components/ModelTable/Column.ts +17 -0
- package/UI/Components/ModelTable/ColumnCustomizationModal.tsx +420 -0
- package/UI/Components/ModelTable/ColumnPreference.ts +482 -0
- package/UI/Components/ModelTable/CustomFieldColumns.tsx +326 -0
- package/UI/Components/ModelTable/TableView.tsx +24 -2
- package/UI/Components/ModelTable/useCustomFieldColumns.ts +150 -0
- package/UI/Components/SideMenu/SideMenu.tsx +24 -4
- package/UI/Components/Table/Table.tsx +14 -1
- package/UI/Components/Table/TableRow.tsx +180 -175
- package/UI/Components/Table/Types/Column.ts +2 -0
- package/Utils/UserPreferences.ts +53 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js +86 -0
- package/build/dist/Models/AnalyticsModels/KubernetesCostAllocation.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TableView.js +40 -0
- package/build/dist/Models/DatabaseModels/TableView.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js +12 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1785241000000-AddColumnsToTableView.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +2 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Types/JSONFunctions.js +8 -3
- package/build/dist/Types/JSONFunctions.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesCostIngest.js.map +1 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js +50 -1
- package/build/dist/UI/Components/MasterPage/MasterPage.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +239 -7
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js +189 -0
- package/build/dist/UI/Components/ModelTable/ColumnCustomizationModal.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js +258 -0
- package/build/dist/UI/Components/ModelTable/ColumnPreference.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js +168 -0
- package/build/dist/UI/Components/ModelTable/CustomFieldColumns.js.map +1 -0
- package/build/dist/UI/Components/ModelTable/TableView.js +13 -2
- package/build/dist/UI/Components/ModelTable/TableView.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js +84 -0
- package/build/dist/UI/Components/ModelTable/useCustomFieldColumns.js.map +1 -0
- package/build/dist/UI/Components/SideMenu/SideMenu.js +15 -5
- package/build/dist/UI/Components/SideMenu/SideMenu.js.map +1 -1
- package/build/dist/UI/Components/Table/Table.js +15 -2
- package/build/dist/UI/Components/Table/Table.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +11 -6
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/Utils/UserPreferences.js +33 -0
- package/build/dist/Utils/UserPreferences.js.map +1 -1
- package/package.json +1 -1
|
@@ -25,6 +25,10 @@ import OrderedStatesList from "../OrderedStatesList/OrderedStatesList";
|
|
|
25
25
|
import Pill from "../Pill/Pill";
|
|
26
26
|
import Table from "../Table/Table";
|
|
27
27
|
import FieldType from "../Types/FieldType";
|
|
28
|
+
import ColumnCustomizationModal from "./ColumnCustomizationModal";
|
|
29
|
+
import { applyColumnPreference, buildColumnPreference, fromJSON as columnPreferenceFromJSON, getCustomizableColumns, isEmptyColumnPreference, sanitizeColumnPreference, getColumnIds, toJSON as columnPreferenceToJSON, } from "./ColumnPreference";
|
|
30
|
+
import { CustomFieldsColumnKey } from "./CustomFieldColumns";
|
|
31
|
+
import useCustomFieldColumns from "./useCustomFieldColumns";
|
|
28
32
|
import { getExportKeysFromColumn } from "./ExportFromColumns";
|
|
29
33
|
import { getRelationSelectFromColumns, getSelectFromColumns, } from "./SelectFromColumns";
|
|
30
34
|
import AnalyticsBaseModel from "../../../Models/AnalyticsModels/AnalyticsBaseModel/AnalyticsBaseModel";
|
|
@@ -110,6 +114,83 @@ const BaseModelTable = (props) => {
|
|
|
110
114
|
const [showHelpModal, setShowHelpModal] = useState(false);
|
|
111
115
|
const [viewId, setViewId] = useState(null);
|
|
112
116
|
const [tableColumns, setColumns] = useState([]);
|
|
117
|
+
/*
|
|
118
|
+
* ---------------------------------------------------------------------
|
|
119
|
+
* Viewer-customizable columns
|
|
120
|
+
* ---------------------------------------------------------------------
|
|
121
|
+
*
|
|
122
|
+
* The viewer's layout (which columns are on, and in what order) is a
|
|
123
|
+
* personal, presentational preference, so it lives in localStorage next to
|
|
124
|
+
* the page size rather than on the server: saved views are named, explicit,
|
|
125
|
+
* plan-gated and need write permission, none of which should stand between
|
|
126
|
+
* someone and hiding a column they don't care about. A saved view can still
|
|
127
|
+
* carry a layout of its own, and when one is active it wins.
|
|
128
|
+
*
|
|
129
|
+
* Custom fields are appended to the declared columns as additional,
|
|
130
|
+
* off-by-default columns; from here on they are ordinary columns.
|
|
131
|
+
*/
|
|
132
|
+
const customFieldColumns = useCustomFieldColumns({
|
|
133
|
+
customFieldsModelType: props.customFieldsModelType,
|
|
134
|
+
});
|
|
135
|
+
const isColumnCustomizationEnabled = Boolean(!props.disableColumnCustomization &&
|
|
136
|
+
props.userPreferencesKey &&
|
|
137
|
+
showAs !== ShowAs.OrderedStatesList);
|
|
138
|
+
const allColumns = useMemo(() => {
|
|
139
|
+
if (customFieldColumns.columns.length === 0) {
|
|
140
|
+
return props.columns || [];
|
|
141
|
+
}
|
|
142
|
+
return [...(props.columns || []), ...customFieldColumns.columns];
|
|
143
|
+
}, [props.columns, customFieldColumns.columns]);
|
|
144
|
+
const readStoredColumnPreference = () => {
|
|
145
|
+
if (!props.userPreferencesKey) {
|
|
146
|
+
return null;
|
|
147
|
+
}
|
|
148
|
+
return columnPreferenceFromJSON(UserPreferences.getUserPreferenceByTypeAsJSON({
|
|
149
|
+
key: props.userPreferencesKey,
|
|
150
|
+
userPreferenceType: UserPreferenceType.BaseModelTableColumns,
|
|
151
|
+
}));
|
|
152
|
+
};
|
|
153
|
+
const [columnPreference, setColumnPreference] = useState(readStoredColumnPreference);
|
|
154
|
+
const [showColumnCustomizationModal, setShowColumnCustomizationModal] = useState(false);
|
|
155
|
+
/*
|
|
156
|
+
* Ids are derived over the *whole* declared set, so a column dropping out
|
|
157
|
+
* for lack of permission can never renumber the ones that remain.
|
|
158
|
+
*/
|
|
159
|
+
const allColumnIds = useMemo(() => {
|
|
160
|
+
return getColumnIds(allColumns);
|
|
161
|
+
}, [allColumns]);
|
|
162
|
+
const effectiveColumnPreference = useMemo(() => {
|
|
163
|
+
if (!isColumnCustomizationEnabled) {
|
|
164
|
+
return null;
|
|
165
|
+
}
|
|
166
|
+
/*
|
|
167
|
+
* A stored layout outlives the release that wrote it, so anything naming
|
|
168
|
+
* a column this table no longer has is dropped before it is applied.
|
|
169
|
+
*/
|
|
170
|
+
return sanitizeColumnPreference({
|
|
171
|
+
preference: columnPreference,
|
|
172
|
+
knownColumnIds: allColumnIds,
|
|
173
|
+
});
|
|
174
|
+
}, [columnPreference, allColumnIds, isColumnCustomizationEnabled]);
|
|
175
|
+
const saveColumnPreference = (preference) => {
|
|
176
|
+
setColumnPreference(preference);
|
|
177
|
+
if (!props.userPreferencesKey) {
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
const json = columnPreferenceToJSON(preference);
|
|
181
|
+
if (!json) {
|
|
182
|
+
UserPreferences.removeUserPreferenceByType({
|
|
183
|
+
key: props.userPreferencesKey,
|
|
184
|
+
userPreferenceType: UserPreferenceType.BaseModelTableColumns,
|
|
185
|
+
});
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
UserPreferences.saveUserPreferenceByTypeAsJSON({
|
|
189
|
+
key: props.userPreferencesKey,
|
|
190
|
+
userPreferenceType: UserPreferenceType.BaseModelTableColumns,
|
|
191
|
+
value: json,
|
|
192
|
+
});
|
|
193
|
+
};
|
|
113
194
|
const [classicTableFilters, setClassicTableFilters] = useState([]);
|
|
114
195
|
const [cardButtons, setCardButtons] = useState([]);
|
|
115
196
|
const [actionButtonSchema, setActionButtonSchema] = useState([]);
|
|
@@ -496,8 +577,11 @@ const BaseModelTable = (props) => {
|
|
|
496
577
|
}
|
|
497
578
|
}, [tableColumns]);
|
|
498
579
|
const getRelationSelect = () => {
|
|
580
|
+
/*
|
|
581
|
+
* Deliberately the *unfiltered* column set. See getSelect() below.
|
|
582
|
+
*/
|
|
499
583
|
return getRelationSelectFromColumns({
|
|
500
|
-
columns:
|
|
584
|
+
columns: allColumns,
|
|
501
585
|
model: model,
|
|
502
586
|
});
|
|
503
587
|
};
|
|
@@ -530,7 +614,21 @@ const BaseModelTable = (props) => {
|
|
|
530
614
|
selectFields = props.callbacks.addSlugToSelect(selectFields);
|
|
531
615
|
const userPermissions = getUserPermissions();
|
|
532
616
|
const accessControl = model.getColumnAccessControlForAllColumns();
|
|
533
|
-
|
|
617
|
+
/*
|
|
618
|
+
* The viewer's layout is applied to the *input* of this loop, never to
|
|
619
|
+
* the finished array: the Actions column is appended below and has to
|
|
620
|
+
* stay last, and it is generated rather than declared, so it is not the
|
|
621
|
+
* viewer's to move or switch off.
|
|
622
|
+
*/
|
|
623
|
+
const columnsToRender = applyColumnPreference({
|
|
624
|
+
columns: allColumns,
|
|
625
|
+
preference: effectiveColumnPreference,
|
|
626
|
+
});
|
|
627
|
+
const columnIdByColumn = new Map();
|
|
628
|
+
allColumns.forEach((column, index) => {
|
|
629
|
+
columnIdByColumn.set(column, allColumnIds[index]);
|
|
630
|
+
});
|
|
631
|
+
for (const column of columnsToRender) {
|
|
534
632
|
const hasPermission = hasPermissionToReadColumn(column) || User.isMasterAdmin();
|
|
535
633
|
const key = getColumnKey(column);
|
|
536
634
|
if (hasPermission) {
|
|
@@ -550,7 +648,7 @@ const BaseModelTable = (props) => {
|
|
|
550
648
|
"." +
|
|
551
649
|
column.selectedProperty)
|
|
552
650
|
: key;
|
|
553
|
-
columns.push(Object.assign(Object.assign({}, column), { disableSort: column.disableSort || shouldDisableSort(key), key: columnKey,
|
|
651
|
+
columns.push(Object.assign(Object.assign({}, column), { id: columnIdByColumn.get(column), disableSort: column.disableSort || shouldDisableSort(key), key: columnKey,
|
|
554
652
|
/*
|
|
555
653
|
* `key` is only the first declared field, so a cell composed from
|
|
556
654
|
* several of them would export just that one. Hand the exporter
|
|
@@ -1065,13 +1163,35 @@ const BaseModelTable = (props) => {
|
|
|
1065
1163
|
});
|
|
1066
1164
|
}, []);
|
|
1067
1165
|
const getSelect = () => {
|
|
1166
|
+
/*
|
|
1167
|
+
* Every declared column, including the ones the viewer has switched off.
|
|
1168
|
+
*
|
|
1169
|
+
* Hiding must not narrow the request. A column's `getElement` is arbitrary
|
|
1170
|
+
* caller code that can read any field on the row — a "Status" cell that
|
|
1171
|
+
* also reads `currentMonitorStatus`, say — so dropping a hidden column's
|
|
1172
|
+
* fields from the select would silently blank a *different*, visible cell,
|
|
1173
|
+
* and there is no way to detect that statically. The sort field is
|
|
1174
|
+
* likewise independent of what is on screen. The cost is a few unused
|
|
1175
|
+
* fields on the wire.
|
|
1176
|
+
*/
|
|
1068
1177
|
const selectFields = getSelectFromColumns({
|
|
1069
|
-
columns:
|
|
1178
|
+
columns: allColumns,
|
|
1070
1179
|
model: model,
|
|
1071
1180
|
hasPermissionToReadField: (field) => {
|
|
1072
1181
|
return hasPermissionToReadField(field);
|
|
1073
1182
|
},
|
|
1074
1183
|
});
|
|
1184
|
+
/*
|
|
1185
|
+
* Custom field columns arrive asynchronously, but the table does not
|
|
1186
|
+
* refetch when its column set changes — so the JSON column that backs
|
|
1187
|
+
* every one of them is selected up front, off the synchronous prop, and
|
|
1188
|
+
* the values are there the moment the definitions land.
|
|
1189
|
+
*/
|
|
1190
|
+
if (props.customFieldsModelType &&
|
|
1191
|
+
model.hasColumn(CustomFieldsColumnKey) &&
|
|
1192
|
+
hasPermissionToReadField(CustomFieldsColumnKey)) {
|
|
1193
|
+
selectFields[CustomFieldsColumnKey] = true;
|
|
1194
|
+
}
|
|
1075
1195
|
const selectMoreFields = props.selectMoreFields
|
|
1076
1196
|
? Object.keys(props.selectMoreFields)
|
|
1077
1197
|
: [];
|
|
@@ -1102,7 +1222,7 @@ const BaseModelTable = (props) => {
|
|
|
1102
1222
|
return React.createElement(React.Fragment, null);
|
|
1103
1223
|
}
|
|
1104
1224
|
if (props.saveFilterProps && props.saveFilterProps.tableId) {
|
|
1105
|
-
return (React.createElement(TableViewElement, { tableId: props.saveFilterProps.tableId, tableView: tableView, currentQuery: query, currentSortBy: sortBy, currentItemsOnPage: itemsOnPage, currentSortOrder: sortOrder, currentFacetState: props.currentFacetState, onViewChange: async (tableView) => {
|
|
1225
|
+
return (React.createElement(TableViewElement, { tableId: props.saveFilterProps.tableId, tableView: tableView, currentQuery: query, currentSortBy: sortBy, currentItemsOnPage: itemsOnPage, currentSortOrder: sortOrder, currentFacetState: props.currentFacetState, currentColumns: columnPreferenceToJSON(effectiveColumnPreference) || undefined, onViewChange: async (tableView) => {
|
|
1106
1226
|
var _a;
|
|
1107
1227
|
setTableView(tableView);
|
|
1108
1228
|
if (tableView) {
|
|
@@ -1128,6 +1248,15 @@ const BaseModelTable = (props) => {
|
|
|
1128
1248
|
if (props.onFacetStateRestored) {
|
|
1129
1249
|
props.onFacetStateRestored(tableView.facets || null);
|
|
1130
1250
|
}
|
|
1251
|
+
/*
|
|
1252
|
+
* A saved view carries the columns it was saved with. Views
|
|
1253
|
+
* created before this existed have none, which restores the
|
|
1254
|
+
* table's default layout rather than leaving the previous
|
|
1255
|
+
* view's columns in place.
|
|
1256
|
+
*/
|
|
1257
|
+
if (isColumnCustomizationEnabled) {
|
|
1258
|
+
saveColumnPreference(columnPreferenceFromJSON(tableView.columns || null));
|
|
1259
|
+
}
|
|
1131
1260
|
}
|
|
1132
1261
|
else {
|
|
1133
1262
|
setQuery({});
|
|
@@ -1145,6 +1274,12 @@ const BaseModelTable = (props) => {
|
|
|
1145
1274
|
if (props.onFacetStateRestored) {
|
|
1146
1275
|
props.onFacetStateRestored(null);
|
|
1147
1276
|
}
|
|
1277
|
+
/*
|
|
1278
|
+
* Columns are deliberately left alone here. Clearing a saved
|
|
1279
|
+
* view means "stop filtering like that", not "throw away the
|
|
1280
|
+
* column layout I built" - which the viewer may well have set
|
|
1281
|
+
* up long before this view existed.
|
|
1282
|
+
*/
|
|
1148
1283
|
}
|
|
1149
1284
|
} }));
|
|
1150
1285
|
}
|
|
@@ -1252,6 +1387,22 @@ const BaseModelTable = (props) => {
|
|
|
1252
1387
|
icon: IconProp.Filter,
|
|
1253
1388
|
});
|
|
1254
1389
|
}
|
|
1390
|
+
/*
|
|
1391
|
+
* Only worth offering once there is a choice to make. A single-column
|
|
1392
|
+
* table has nothing to hide and nothing to reorder.
|
|
1393
|
+
*/
|
|
1394
|
+
if (isColumnCustomizationEnabled && allColumns.length > 1) {
|
|
1395
|
+
headerbuttons.push({
|
|
1396
|
+
title: "",
|
|
1397
|
+
buttonStyle: ButtonStyleType.ICON,
|
|
1398
|
+
buttonSize: ButtonSize.Small,
|
|
1399
|
+
className: "",
|
|
1400
|
+
onClick: () => {
|
|
1401
|
+
setShowColumnCustomizationModal(true);
|
|
1402
|
+
},
|
|
1403
|
+
icon: IconProp.TableCells,
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1255
1406
|
setCardButtons(headerbuttons);
|
|
1256
1407
|
};
|
|
1257
1408
|
useEffect(() => {
|
|
@@ -1350,6 +1501,13 @@ const BaseModelTable = (props) => {
|
|
|
1350
1501
|
useEffect(() => {
|
|
1351
1502
|
serializeToTableColumns();
|
|
1352
1503
|
}, [props.columns]);
|
|
1504
|
+
/*
|
|
1505
|
+
* The viewer changed their layout, or the project's custom field
|
|
1506
|
+
* definitions finally arrived.
|
|
1507
|
+
*/
|
|
1508
|
+
useEffect(() => {
|
|
1509
|
+
serializeToTableColumns();
|
|
1510
|
+
}, [effectiveColumnPreference, customFieldColumns.columns]);
|
|
1353
1511
|
const setActionSchema = () => {
|
|
1354
1512
|
const permissions = PermissionUtil.getAllPermissions();
|
|
1355
1513
|
const actionsSchema = [];
|
|
@@ -2091,6 +2249,8 @@ const BaseModelTable = (props) => {
|
|
|
2091
2249
|
return "Watch Demo";
|
|
2092
2250
|
case IconProp.Search:
|
|
2093
2251
|
return "Search";
|
|
2252
|
+
case IconProp.TableCells:
|
|
2253
|
+
return "Columns";
|
|
2094
2254
|
default:
|
|
2095
2255
|
return "Action";
|
|
2096
2256
|
}
|
|
@@ -2186,6 +2346,77 @@ const BaseModelTable = (props) => {
|
|
|
2186
2346
|
const getCardHeaderTitle = (originalTitle) => {
|
|
2187
2347
|
return originalTitle;
|
|
2188
2348
|
};
|
|
2349
|
+
/*
|
|
2350
|
+
* A column the viewer cannot read is left out of the picker entirely.
|
|
2351
|
+
* Listing it would advertise a field they have no access to, and switching
|
|
2352
|
+
* it on would put that field in the select — which the API rejects for the
|
|
2353
|
+
* whole request, blanking the table.
|
|
2354
|
+
*/
|
|
2355
|
+
const isPickableColumn = (column) => {
|
|
2356
|
+
if (column.isNotCustomizable) {
|
|
2357
|
+
return false;
|
|
2358
|
+
}
|
|
2359
|
+
return hasPermissionToReadColumn(column) || User.isMasterAdmin();
|
|
2360
|
+
};
|
|
2361
|
+
const getPickerEntries = (preference) => {
|
|
2362
|
+
return getCustomizableColumns({
|
|
2363
|
+
columns: allColumns,
|
|
2364
|
+
preference: preference,
|
|
2365
|
+
}).filter((entry) => {
|
|
2366
|
+
return isPickableColumn(entry.column);
|
|
2367
|
+
});
|
|
2368
|
+
};
|
|
2369
|
+
// Mirrors how serializeToTableColumns derives the key the header sorts on.
|
|
2370
|
+
const getColumnSortKey = (column) => {
|
|
2371
|
+
const key = getColumnKey(column);
|
|
2372
|
+
if (!key) {
|
|
2373
|
+
return null;
|
|
2374
|
+
}
|
|
2375
|
+
return column.selectedProperty
|
|
2376
|
+
? `${String(key)}.${column.selectedProperty}`
|
|
2377
|
+
: String(key);
|
|
2378
|
+
};
|
|
2379
|
+
const onColumnCustomizationSave = (entries) => {
|
|
2380
|
+
const preference = buildColumnPreference(entries);
|
|
2381
|
+
/*
|
|
2382
|
+
* If the layout the viewer just saved matches what the table ships with,
|
|
2383
|
+
* store nothing. Otherwise every table anyone ever opened the picker on
|
|
2384
|
+
* would be pinned to the column set of the release they opened it in, and
|
|
2385
|
+
* columns added later would arrive already stale.
|
|
2386
|
+
*/
|
|
2387
|
+
const defaultPreference = buildColumnPreference(getPickerEntries(null));
|
|
2388
|
+
const isBackToDefault = JSON.stringify(preference) === JSON.stringify(defaultPreference);
|
|
2389
|
+
/*
|
|
2390
|
+
* Sorting by a column that is no longer on screen leaves the viewer with
|
|
2391
|
+
* an ordering they can neither see nor undo — there is no header left to
|
|
2392
|
+
* click. Fall back to the table's own default sort.
|
|
2393
|
+
*/
|
|
2394
|
+
if (sortBy) {
|
|
2395
|
+
const hiddenIds = new Set(preference.hidden);
|
|
2396
|
+
const isSortedColumnHidden = entries.some((entry) => {
|
|
2397
|
+
return (hiddenIds.has(entry.id) &&
|
|
2398
|
+
getColumnSortKey(entry.column) === String(sortBy));
|
|
2399
|
+
});
|
|
2400
|
+
if (isSortedColumnHidden) {
|
|
2401
|
+
setSortBy(props.sortBy || null);
|
|
2402
|
+
setSortOrder(props.sortOrder || SortOrder.Ascending);
|
|
2403
|
+
setCurrentPageNumber(1);
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
saveColumnPreference(isBackToDefault ? null : preference);
|
|
2407
|
+
setShowColumnCustomizationModal(false);
|
|
2408
|
+
};
|
|
2409
|
+
const getColumnCustomizationModal = () => {
|
|
2410
|
+
if (!showColumnCustomizationModal || !isColumnCustomizationEnabled) {
|
|
2411
|
+
return null;
|
|
2412
|
+
}
|
|
2413
|
+
return (React.createElement(ColumnCustomizationModal, { columns: getPickerEntries(effectiveColumnPreference), isDefaultLayout: isEmptyColumnPreference(effectiveColumnPreference), title: tx("Customize Columns"), onSave: onColumnCustomizationSave, onReset: () => {
|
|
2414
|
+
saveColumnPreference(null);
|
|
2415
|
+
setShowColumnCustomizationModal(false);
|
|
2416
|
+
}, onClose: () => {
|
|
2417
|
+
setShowColumnCustomizationModal(false);
|
|
2418
|
+
} }));
|
|
2419
|
+
};
|
|
2189
2420
|
const getCardComponent = () => {
|
|
2190
2421
|
const headerButtons = getHeaderButtonsWithSearch();
|
|
2191
2422
|
if (showAs === ShowAs.Table || showAs === ShowAs.List) {
|
|
@@ -2193,7 +2424,7 @@ const BaseModelTable = (props) => {
|
|
|
2193
2424
|
props.cardProps && (React.createElement(Card, Object.assign({}, props.cardProps, { buttons: headerButtons, bodyClassName: showAs === ShowAs.List
|
|
2194
2425
|
? "-ml-6 -mr-6 bg-gray-50 border-top"
|
|
2195
2426
|
: "", title: getCardHeaderTitle(getCardTitle(props.cardProps.title || "")) }),
|
|
2196
|
-
tableColumns.length === 0 &&
|
|
2427
|
+
tableColumns.length === 0 && allColumns.length > 0 ? (React.createElement(ErrorMessage, { message: `You are not authorized to view this table. You need any one of these permissions: ${PermissionHelper.getPermissionTitles(model.getReadPermissions()).join(", ")}` })) : (React.createElement(React.Fragment, null)),
|
|
2197
2428
|
props.topContent || React.createElement(React.Fragment, null),
|
|
2198
2429
|
tableColumns.length > 0 && showAs === ShowAs.Table ? (getTable()) : (React.createElement(React.Fragment, null)),
|
|
2199
2430
|
tableColumns.length > 0 && showAs === ShowAs.List ? (getList()) : (React.createElement(React.Fragment, null)))),
|
|
@@ -2279,7 +2510,8 @@ const BaseModelTable = (props) => {
|
|
|
2279
2510
|
setShowHelpModal(false);
|
|
2280
2511
|
} },
|
|
2281
2512
|
React.createElement("div", { className: "p-2" },
|
|
2282
|
-
React.createElement(MarkdownViewer, { text: props.helpContent.markdown }))))
|
|
2513
|
+
React.createElement(MarkdownViewer, { text: props.helpContent.markdown })))),
|
|
2514
|
+
getColumnCustomizationModal()));
|
|
2283
2515
|
};
|
|
2284
2516
|
export default BaseModelTable;
|
|
2285
2517
|
//# sourceMappingURL=BaseModelTable.js.map
|