@adaptabletools/adaptable 22.1.0-canary.1 → 22.1.1-canary.0
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/index.css +8 -9
- package/package.json +1 -1
- package/src/AdaptableInterfaces/IAdaptable.d.ts +2 -2
- package/src/AdaptableOptions/AdaptableOptions.d.ts +2 -21
- package/src/AdaptableOptions/AlertOptions.d.ts +0 -5
- package/src/AdaptableOptions/CellSummaryOptions.d.ts +2 -0
- package/src/AdaptableOptions/ChartingOptions.d.ts +2 -0
- package/src/AdaptableOptions/ColumnOptions.d.ts +0 -2
- package/src/AdaptableOptions/CommentOptions.d.ts +6 -0
- package/src/AdaptableOptions/ContainerOptions.d.ts +0 -6
- package/src/AdaptableOptions/DashboardOptions.d.ts +0 -2
- package/src/AdaptableOptions/DataChangeHistoryOptions.d.ts +0 -2
- package/src/AdaptableOptions/DataSetOptions.d.ts +2 -0
- package/src/AdaptableOptions/DefaultAdaptableOptions.js +35 -3
- package/src/AdaptableOptions/EditOptions.d.ts +0 -1
- package/src/AdaptableOptions/EntitlementOptions.d.ts +0 -2
- package/src/AdaptableOptions/ExportOptions.d.ts +1 -7
- package/src/AdaptableOptions/ExpressionOptions.d.ts +0 -18
- package/src/AdaptableOptions/Fdc3Options.d.ts +5 -1
- package/src/AdaptableOptions/FilterOptions.d.ts +3 -18
- package/src/AdaptableOptions/NoteOptions.d.ts +6 -0
- package/src/AdaptableOptions/NotificationsOptions.d.ts +0 -10
- package/src/AdaptableOptions/PredicateOptions.d.ts +12 -1
- package/src/AdaptableOptions/QuickSearchOptions.d.ts +0 -4
- package/src/AdaptableOptions/SettingsPanelOptions.d.ts +15 -5
- package/src/AdaptableOptions/TeamSharingOptions.d.ts +0 -4
- package/src/AdaptableOptions/ToolPanelOptions.d.ts +0 -1
- package/src/AdaptableOptions/UserInterfaceOptions.d.ts +6 -7
- package/src/AdaptableState/Common/AdaptableFormat.d.ts +9 -0
- package/src/AdaptableState/Common/AdaptableFormatPresets.d.ts +31 -0
- package/src/AdaptableState/Common/AdaptableFormatPresets.js +181 -0
- package/src/AdaptableState/Common/Menu.d.ts +1 -1
- package/src/AdaptableState/Common/Menu.js +2 -0
- package/src/AdaptableState/FormatColumnState.d.ts +6 -3
- package/src/Api/EventApi.d.ts +6 -6
- package/src/Api/Implementation/EntitlementApiImpl.js +5 -4
- package/src/Api/Implementation/FormatColumnApiImpl.js +8 -3
- package/src/Api/Implementation/GridApiImpl.js +1 -12
- package/src/Api/Internal/FormatColumnInternalApi.js +4 -2
- package/src/Api/Internal/LayoutInternalApi.js +5 -2
- package/src/Redux/Store/AdaptableStore.js +4 -4
- package/src/Strategy/AdaptableModuleBase.js +8 -7
- package/src/Strategy/AlertModule.d.ts +1 -1
- package/src/Strategy/BulkUpdateModule.d.ts +1 -1
- package/src/Strategy/BulkUpdateModule.js +2 -1
- package/src/Strategy/CalculatedColumnModule.d.ts +1 -1
- package/src/Strategy/CellSummaryModule.d.ts +1 -1
- package/src/Strategy/CellSummaryModule.js +2 -1
- package/src/Strategy/ColumnFilterModule.js +7 -3
- package/src/Strategy/ColumnInfoModule.d.ts +1 -1
- package/src/Strategy/ColumnInfoModule.js +2 -1
- package/src/Strategy/CommentModule.d.ts +1 -1
- package/src/Strategy/CommentModule.js +12 -2
- package/src/Strategy/ExportModule.d.ts +1 -1
- package/src/Strategy/Fdc3Module.d.ts +1 -1
- package/src/Strategy/FlashingCellModule.d.ts +1 -1
- package/src/Strategy/GridFilterModule.js +2 -1
- package/src/Strategy/GridInfoModule.d.ts +1 -1
- package/src/Strategy/GridInfoModule.js +2 -1
- package/src/Strategy/LayoutModule.d.ts +1 -1
- package/src/Strategy/NamedQueryModule.js +0 -16
- package/src/Strategy/NoteModule.d.ts +1 -1
- package/src/Strategy/NoteModule.js +16 -3
- package/src/Strategy/PlusMinusModule.js +8 -2
- package/src/Strategy/ScheduleModule.js +5 -4
- package/src/Strategy/SettingsPanelModule.d.ts +1 -1
- package/src/Strategy/ShortcutModule.js +5 -4
- package/src/Strategy/SmartEditModule.d.ts +1 -1
- package/src/Strategy/SmartEditModule.js +4 -4
- package/src/Strategy/SystemStatusModule.d.ts +1 -1
- package/src/Utilities/Constants/GeneralConstants.d.ts +4 -0
- package/src/Utilities/Constants/GeneralConstants.js +4 -0
- package/src/Utilities/Extensions/NumberExtensions.d.ts +2 -0
- package/src/Utilities/Extensions/NumberExtensions.js +8 -0
- package/src/Utilities/Helpers/AdaptableHelper.js +3 -2
- package/src/Utilities/Helpers/FormatHelper.js +26 -15
- package/src/Utilities/Services/AnnotationsService.js +10 -1
- package/src/Utilities/Services/Interface/IMetamodelService.d.ts +0 -1
- package/src/Utilities/Services/MetamodelService.d.ts +0 -2
- package/src/Utilities/Services/MetamodelService.js +6 -12
- package/src/View/AdaptableWizardView/AdaptableConfigurationDialog/EntitlementsForm.js +7 -6
- package/src/View/Alert/AlertEmptyView.js +2 -1
- package/src/View/BulkUpdate/BulkUpdateViewPanel.js +1 -1
- package/src/View/CellSummary/CellSummaryViewPanel.js +2 -1
- package/src/View/Comments/CommentsEditor.js +2 -1
- package/src/View/Comments/CommentsPopup.js +3 -1
- package/src/View/Components/Buttons/ButtonBase/index.js +3 -2
- package/src/View/Components/Buttons/EntityListActionButtons.js +7 -6
- package/src/View/Components/Buttons/SuspendToggleButton/SuspendToggleButton.js +2 -1
- package/src/View/Components/ColumnFilter/components/ColumnFilterInput.js +3 -2
- package/src/View/Components/ColumnFilter/components/ColumnFilterInputList.js +4 -1
- package/src/View/Components/Panels/PanelDashboard/index.js +2 -1
- package/src/View/Components/Popups/AdaptablePopup/AdaptablePopup.js +4 -2
- package/src/View/Components/Popups/AdaptablePopup/AdaptablePopupModuleView.js +2 -1
- package/src/View/Components/ToolPanel/AdaptableToolPanel.js +3 -2
- package/src/View/Components/ToolPanel/CustomToolPanelContent.js +2 -1
- package/src/View/Dashboard/CustomDashboardButton.js +3 -2
- package/src/View/Dashboard/Dashboard.js +3 -2
- package/src/View/Dashboard/DashboardPopup.js +3 -2
- package/src/View/Dashboard/PinnedToolbarsSelector.js +2 -1
- package/src/View/DataChangeHistory/DataChangeHistoryGrid.js +2 -1
- package/src/View/Export/ExportViewPanel.js +3 -1
- package/src/View/Filter/FilterViewPanel.js +2 -1
- package/src/View/FormatColumn/Wizard/FormatColumnFormatWizardSection.js +137 -181
- package/src/View/FormatColumn/Wizard/FormatColumnWizard.js +20 -8
- package/src/View/GridFilter/GridFilterPopupUI/index.d.ts +3 -2
- package/src/View/GridFilter/GridFilterPopupUI/index.js +2 -1
- package/src/View/GridFilter/GridFilterViewPanel.js +3 -2
- package/src/View/GridInfo/GridInfoPopup/GridInfoPopup.js +179 -6
- package/src/View/Layout/LayoutCloneButton.js +2 -1
- package/src/View/Layout/LayoutViewPanel.js +3 -1
- package/src/View/Layout/TransposedPopup.js +2 -1
- package/src/View/Layout/Wizard/sections/RowSelectionSection.js +6 -6
- package/src/View/Note/NotePopup.js +3 -1
- package/src/View/SmartEdit/SmartEditViewPanel.js +2 -1
- package/src/View/StateManagement/StateManagementViewPanel.js +3 -1
- package/src/View/StatusBar/StatusBarPopup.js +2 -1
- package/src/View/Theme/ThemeEditor.js +2 -1
- package/src/View/Theme/ThemePopup.js +2 -1
- package/src/View/Theme/ThemeSelector.js +3 -1
- package/src/View/Theme/ThemeViewPanel.js +3 -1
- package/src/View/Wizard/OnePageWizards.js +3 -2
- package/src/agGrid/AdaptableAgGrid.d.ts +2 -2
- package/src/agGrid/AdaptableAgGrid.js +7 -29
- package/src/agGrid/AgGridAdapter.js +2 -2
- package/src/agGrid/AgGridColumnAdapter.js +11 -4
- package/src/agGrid/AgGridExportAdapter.js +4 -2
- package/src/agGrid/cellRenderers/ActionColumnRenderer.js +2 -1
- package/src/components/Dashboard/Dashboard.js +2 -1
- package/src/components/Dashboard/DashboardToolbar.js +2 -1
- package/src/components/Datepicker/index.js +2 -1
- package/src/components/ExpressionEditor/QueryBuilder/QueryBuilderInputs.js +1 -1
- package/src/components/Select/Select.js +4 -3
- package/src/components/SimpleButton/index.js +3 -2
- package/src/env.js +2 -2
- package/src/metamodel/adaptable-metamodel-model.d.ts +0 -2
- package/src/metamodel/adaptable.metamodel.d.ts +10 -197
- package/src/metamodel/adaptable.metamodel.js +1 -1
- package/src/types.d.ts +2 -0
- package/src/types.js +1 -0
- package/themes/dark.css +3 -1
- package/tsconfig.esm.tsbuildinfo +1 -1
- package/index.css.map +0 -1
|
@@ -7,6 +7,7 @@ import Panel from '../../../components/Panel';
|
|
|
7
7
|
import { Tabs } from '../../../components/Tabs';
|
|
8
8
|
import { PopupPanel } from '../../Components/Popups/AdaptablePopup/PopupPanel';
|
|
9
9
|
import { AdaptableObjectsSummary } from './AdaptableObjectsSummary';
|
|
10
|
+
import { getDefaultAdaptableOptions } from '../../../AdaptableOptions/DefaultAdaptableOptions';
|
|
10
11
|
import clsx from 'clsx';
|
|
11
12
|
const adaptableVersion = ADAPTABLE_VERSION;
|
|
12
13
|
const agGridVersion = AG_GRID_VERSION;
|
|
@@ -36,6 +37,7 @@ export const GridInfoPopup = (props) => {
|
|
|
36
37
|
if (api.optionsApi.getUserInterfaceOptions()?.showAgGridVersion) {
|
|
37
38
|
keyValuePairs.push({ Key: 'AG Grid Version', Value: agGridVersion });
|
|
38
39
|
}
|
|
40
|
+
keyValuePairs.push({ Key: 'License Key', Value: api.optionsApi.getAdaptableOptions().licenseKey });
|
|
39
41
|
keyValuePairs.push({ Key: 'Sorted Columns', Value: ArrayExtensions.IsNotNullOrEmpty(sorts) ? sorts.join('; ') : 'None' });
|
|
40
42
|
keyValuePairs.push({ Key: 'Column Filters', Value: columnFilterDescription });
|
|
41
43
|
keyValuePairs.push({ Key: 'Grid Filter', Value: gridFilterExpression });
|
|
@@ -68,16 +70,187 @@ export const GridInfoPopup = (props) => {
|
|
|
68
70
|
Key: { field: 'Key', header: 'Property', defaultFlex: 1 },
|
|
69
71
|
Value: { field: 'Value', header: 'Value', defaultFlex: 3 },
|
|
70
72
|
};
|
|
73
|
+
// Variant used by the Grid Options tab — the Value column allows newlines
|
|
74
|
+
// in the rendered string (preserved via `white-space: pre-line`), so a
|
|
75
|
+
// nested *Options object can show one `"key": value` per line.
|
|
76
|
+
const optionsColumnsMap = {
|
|
77
|
+
Key: { field: 'Key', header: 'Property', defaultFlex: 1 },
|
|
78
|
+
Value: {
|
|
79
|
+
field: 'Value',
|
|
80
|
+
header: 'Value',
|
|
81
|
+
defaultFlex: 3,
|
|
82
|
+
render: ({ value }) => (React.createElement("span", { style: {
|
|
83
|
+
whiteSpace: 'pre-wrap',
|
|
84
|
+
wordBreak: 'break-word',
|
|
85
|
+
overflowWrap: 'anywhere',
|
|
86
|
+
display: 'block',
|
|
87
|
+
lineHeight: '18px',
|
|
88
|
+
paddingTop: 4,
|
|
89
|
+
paddingBottom: 4,
|
|
90
|
+
} }, String(value ?? ''))),
|
|
91
|
+
},
|
|
92
|
+
};
|
|
93
|
+
// ---- Grid Options tab: build one InfiniteTableGrid section per non-empty
|
|
94
|
+
// ---- options group on the AdaptableOptions object.
|
|
95
|
+
const titleCase = (camel) => camel
|
|
96
|
+
.replace(/([a-z])([A-Z])/g, '$1 $2')
|
|
97
|
+
.replace(/^./, (c) => c.toUpperCase())
|
|
98
|
+
.replace(/\s./g, (c) => c.toUpperCase());
|
|
99
|
+
// Renders a single primitive / function / array / nested-object value
|
|
100
|
+
// (used for the inner key:value pairs when expanding a nested options
|
|
101
|
+
// object). Short objects/arrays stay on one line; longer ones get
|
|
102
|
+
// pretty-printed across multiple lines so they don't blow past the cell.
|
|
103
|
+
const ONE_LINE_MAX = 60;
|
|
104
|
+
const fnReplacer = (_k, val) => typeof val === 'function' ? '[Function]' : val;
|
|
105
|
+
const formatValuePart = (v) => {
|
|
106
|
+
if (typeof v === 'function')
|
|
107
|
+
return '[Function]';
|
|
108
|
+
if (v === undefined)
|
|
109
|
+
return 'undefined';
|
|
110
|
+
if (v === null)
|
|
111
|
+
return 'null';
|
|
112
|
+
if (typeof v === 'string')
|
|
113
|
+
return JSON.stringify(v);
|
|
114
|
+
if (Array.isArray(v) || typeof v === 'object') {
|
|
115
|
+
try {
|
|
116
|
+
const oneLine = JSON.stringify(v, fnReplacer);
|
|
117
|
+
if (oneLine !== undefined && oneLine.length <= ONE_LINE_MAX)
|
|
118
|
+
return oneLine;
|
|
119
|
+
return JSON.stringify(v, fnReplacer, 2);
|
|
120
|
+
}
|
|
121
|
+
catch {
|
|
122
|
+
return String(v);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return String(v);
|
|
126
|
+
};
|
|
127
|
+
const displayValue = (v) => {
|
|
128
|
+
if (typeof v === 'function')
|
|
129
|
+
return '[Function]';
|
|
130
|
+
if (v === undefined)
|
|
131
|
+
return '(undefined)';
|
|
132
|
+
if (v === null)
|
|
133
|
+
return '(null)';
|
|
134
|
+
if (Array.isArray(v)) {
|
|
135
|
+
// Top-level array values (e.g. `colorPalette`, `systemFilterPredicates`).
|
|
136
|
+
// Short arrays stay on one line; longer ones get pretty-printed across
|
|
137
|
+
// multiple lines so they don't blow past the cell.
|
|
138
|
+
return formatValuePart(v);
|
|
139
|
+
}
|
|
140
|
+
if (typeof v === 'object') {
|
|
141
|
+
// Nested options-style object → render as one `key: value` per line.
|
|
142
|
+
// `undefined` entries are filtered out so empty defaults don't show up.
|
|
143
|
+
const entries = Object.entries(v).filter(([, val]) => val !== undefined);
|
|
144
|
+
if (entries.length === 0)
|
|
145
|
+
return '{}';
|
|
146
|
+
return entries.map(([k, val]) => `${k}: ${formatValuePart(val)}`).join('\n');
|
|
147
|
+
}
|
|
148
|
+
return String(v);
|
|
149
|
+
};
|
|
150
|
+
const gridOptionsSections = (() => {
|
|
151
|
+
const opts = api.optionsApi.getAdaptableOptions();
|
|
152
|
+
const defaults = getDefaultAdaptableOptions();
|
|
153
|
+
const baseRows = [];
|
|
154
|
+
const groupSections = [];
|
|
155
|
+
// A function value should only be displayed when it has been explicitly
|
|
156
|
+
// provided by the user. AdapTable ships a handful of identity-function
|
|
157
|
+
// defaults (e.g. `stateOptions.applyState`) that are not interesting to
|
|
158
|
+
// surface here — we suppress those by reference-comparing against the
|
|
159
|
+
// values returned from `getDefaultAdaptableOptions()`.
|
|
160
|
+
const isUserProvidedFunction = (groupKey, propKey, fn) => {
|
|
161
|
+
if (typeof fn !== 'function')
|
|
162
|
+
return false;
|
|
163
|
+
const defaultGroup = defaults[groupKey];
|
|
164
|
+
if (!defaultGroup || typeof defaultGroup !== 'object')
|
|
165
|
+
return true;
|
|
166
|
+
return defaultGroup[propKey] !== fn;
|
|
167
|
+
};
|
|
168
|
+
Object.keys(opts).forEach((key) => {
|
|
169
|
+
if (key === 'licenseKey' || key === 'initialState')
|
|
170
|
+
return;
|
|
171
|
+
const value = opts[key];
|
|
172
|
+
if (value == null)
|
|
173
|
+
return;
|
|
174
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
175
|
+
const rows = Object.keys(value)
|
|
176
|
+
.filter((sk) => {
|
|
177
|
+
const sv = value[sk];
|
|
178
|
+
// skip empties (undefined / null)
|
|
179
|
+
if (sv == null)
|
|
180
|
+
return false;
|
|
181
|
+
// suppress AdapTable's default callback implementations — keep
|
|
182
|
+
// only user-provided overrides
|
|
183
|
+
if (typeof sv === 'function' && !isUserProvidedFunction(key, sk, sv)) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
return true;
|
|
187
|
+
})
|
|
188
|
+
.map((sk) => ({ Key: sk, Value: displayValue(value[sk]) }));
|
|
189
|
+
if (rows.length === 0)
|
|
190
|
+
return;
|
|
191
|
+
groupSections.push({ title: titleCase(key), rows });
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
// top-level function defaults aren't a concern (none exist on the
|
|
195
|
+
// root of `AdaptableOptions`), but apply the same rule for safety
|
|
196
|
+
if (typeof value === 'function' && defaults[key] === value)
|
|
197
|
+
return;
|
|
198
|
+
baseRows.push({ Key: key, Value: displayValue(value) });
|
|
199
|
+
}
|
|
200
|
+
});
|
|
201
|
+
const sections = [];
|
|
202
|
+
if (baseRows.length > 0)
|
|
203
|
+
sections.push({ title: 'Base Properties', rows: baseRows });
|
|
204
|
+
sections.push(...groupSections);
|
|
205
|
+
return sections;
|
|
206
|
+
})();
|
|
207
|
+
// Variable row height for Grid Options sections — counts the number of
|
|
208
|
+
// lines in the formatted value string (including visual wraps for very
|
|
209
|
+
// long unbroken lines) and grows the row to fit.
|
|
210
|
+
const VALUE_CHARS_PER_LINE = 70; // rough estimate at the Value column width
|
|
211
|
+
const visualLineCount = (text) => {
|
|
212
|
+
if (!text)
|
|
213
|
+
return 1;
|
|
214
|
+
return text
|
|
215
|
+
.split('\n')
|
|
216
|
+
.reduce((acc, line) => acc + Math.max(1, Math.ceil(line.length / VALUE_CHARS_PER_LINE)), 0);
|
|
217
|
+
};
|
|
218
|
+
const calculateRowHeight = (row) => {
|
|
219
|
+
const lines = visualLineCount(String(row?.Value ?? ''));
|
|
220
|
+
if (lines <= 1)
|
|
221
|
+
return 32;
|
|
222
|
+
return lines * 18 + 12;
|
|
223
|
+
};
|
|
224
|
+
const sectionHeight = (rows) => {
|
|
225
|
+
const total = rows.reduce((acc, r) => acc + calculateRowHeight(r), 0);
|
|
226
|
+
// 40px header, capped so a single huge group can't dominate the popup
|
|
227
|
+
return Math.min(total + 40, 400);
|
|
228
|
+
};
|
|
229
|
+
// Which tabs the user has opted in to. Falls back to all three (matching
|
|
230
|
+
// the default in `DefaultAdaptableOptions`) when the option isn't set.
|
|
231
|
+
const enabledTabs = api.optionsApi.getSettingsPanelOptions()?.gridInfoTabs ??
|
|
232
|
+
['Grid Options', 'Grid Summary', 'Grid State'];
|
|
233
|
+
const showSummary = enabledTabs.includes('Grid Summary');
|
|
234
|
+
const showState = enabledTabs.includes('Grid State');
|
|
235
|
+
const showOptions = enabledTabs.includes('Grid Options');
|
|
71
236
|
const baseClassName = 'ab-GridInfo';
|
|
72
237
|
return (React.createElement(PopupPanel, { className: clsx(baseClassName), headerText: 'Grid Info', glyphicon: 'info', scrollable: false },
|
|
73
238
|
React.createElement(Panel, { className: "twa:flex-1 twa:border-none twa:shadow-md twa:overflow-hidden" },
|
|
74
239
|
React.createElement(Panel.FlexBody, null,
|
|
75
240
|
React.createElement(Tabs, { className: "twa:flex-1 twa:min-h-0" },
|
|
76
|
-
React.createElement(Tabs.Tab, null, "Grid Summary"),
|
|
77
|
-
React.createElement(Tabs.Tab, null, "Grid State"),
|
|
78
|
-
React.createElement(Tabs.
|
|
241
|
+
showSummary ? React.createElement(Tabs.Tab, null, "Grid Summary") : null,
|
|
242
|
+
showState ? React.createElement(Tabs.Tab, null, "Grid State") : null,
|
|
243
|
+
showOptions ? React.createElement(Tabs.Tab, null, "Grid Options") : null,
|
|
244
|
+
showSummary ? (React.createElement(Tabs.Content, null,
|
|
79
245
|
React.createElement(DataSource, { data: keyValuePairs, primaryKey: "Key" },
|
|
80
|
-
React.createElement(InfiniteTableGrid, { domProps: domProps, columns: columnsMap }))),
|
|
81
|
-
React.createElement(Tabs.Content, null,
|
|
82
|
-
React.createElement(AdaptableObjectsSummary, { className: "twa:min-h-0 twa:overflow-auto twa:p-2" })))
|
|
246
|
+
React.createElement(InfiniteTableGrid, { domProps: domProps, columns: columnsMap })))) : null,
|
|
247
|
+
showState ? (React.createElement(Tabs.Content, null,
|
|
248
|
+
React.createElement(AdaptableObjectsSummary, { className: "twa:min-h-0 twa:overflow-auto twa:p-2" }))) : null,
|
|
249
|
+
showOptions ? (React.createElement(Tabs.Content, null,
|
|
250
|
+
React.createElement("div", { className: "twa:min-h-0 twa:overflow-auto twa:p-2 twa:flex twa:flex-col twa:gap-4" }, gridOptionsSections.map((section) => (React.createElement("div", { key: section.title },
|
|
251
|
+
React.createElement("h4", { className: "twa:font-semibold twa:mb-1" }, section.title),
|
|
252
|
+
React.createElement(DataSource, { data: section.rows, primaryKey: "Key" },
|
|
253
|
+
React.createElement(InfiniteTableGrid, { domProps: {
|
|
254
|
+
style: { height: sectionHeight(section.rows), width: '100%' },
|
|
255
|
+
}, rowHeight: (rowInfo) => calculateRowHeight(rowInfo.data), columns: optionsColumnsMap })))))))) : null)))));
|
|
83
256
|
};
|
|
@@ -2,9 +2,10 @@ import * as React from 'react';
|
|
|
2
2
|
import SimpleButton from '../../components/SimpleButton';
|
|
3
3
|
import { useAdaptable } from '../AdaptableContext';
|
|
4
4
|
import { isPivotLayout } from '../../Utilities/isPivotLayout';
|
|
5
|
+
import { ACCESS_LEVEL_READ_ONLY } from '../../Utilities/Constants/GeneralConstants';
|
|
5
6
|
export const LayoutCloneButton = ({ data, accessLevel }) => {
|
|
6
7
|
const adaptable = useAdaptable();
|
|
7
|
-
const isDisabled = accessLevel ===
|
|
8
|
+
const isDisabled = accessLevel === ACCESS_LEVEL_READ_ONLY;
|
|
8
9
|
const handleClick = React.useCallback(() => {
|
|
9
10
|
adaptable.api.layoutApi.showLayoutEditor(data.Name, isPivotLayout(data) ? 'pivot' : 'table', 'Clone');
|
|
10
11
|
}, []);
|
|
@@ -41,7 +41,9 @@ const LayoutViewPanelComponent = (props) => {
|
|
|
41
41
|
return (React.createElement(Flex, { flexDirection: "row", className: `ab-${elementType}__Layout__wrap`, flexWrap: viewType === 'ToolPanel' ? 'wrap' : 'nowrap' },
|
|
42
42
|
React.createElement(Flex, { style: layoutSelectStyle, className: "twa:flex-1" },
|
|
43
43
|
React.createElement(Select, { "aria-label": 'Select Layout', disabled: isErrorLayout, style: { width: '100%' }, options: availableLayoutOptions, className: `ab-${elementType}__Layout__select`, value: layoutEntity ? layoutEntity.Name : null, onChange: (layout) => onSelectLayout(layout) })),
|
|
44
|
-
React.createElement(Flex, { flexDirection: "row", className: join(accessLevel ===
|
|
44
|
+
React.createElement(Flex, { flexDirection: "row", className: join(accessLevel === GeneralConstants.ACCESS_LEVEL_READ_ONLY
|
|
45
|
+
? GeneralConstants.READ_ONLY_STYLE
|
|
46
|
+
: '', `ab-${elementType}__Layout__wrap`) },
|
|
45
47
|
React.createElement(ButtonEdit, { disabled: isErrorLayout, onClick: () => api.layoutApi.showLayoutEditor(layoutEntity.Name), tooltip: LAYOUT_EDIT_TOOLTIP, className: `ab-${elementType}__Layout__edit`, accessLevel: entityAccessLevel }),
|
|
46
48
|
React.createElement(ButtonClone, { disabled: isErrorLayout, onClick: () => api.layoutApi.showLayoutEditor(layoutEntity.Name, isPivotLayout(layoutEntity) ? 'pivot' : 'table', 'Clone'), tooltip: LAYOUT_CLONE_TOOLTIP, className: `ab-${elementType}__Layout__clone`, tone: "neutral", variant: "text", children: null, accessLevel: cloneAccessLevel }),
|
|
47
49
|
React.createElement(DropdownButton, { variant: "text", tooltip: LAYOUT_NEW_TABLE_OR_PIVOT_TOOLTIP, columns: ['label'], "data-name": "new", items: [
|
|
@@ -5,6 +5,7 @@ import { useAdaptable } from '../AdaptableContext';
|
|
|
5
5
|
import { ColumnSelector } from '../Components/Selectors/ColumnSelector';
|
|
6
6
|
import { AdaptableAgGrid } from '../../agGrid/AdaptableAgGrid';
|
|
7
7
|
import { Box, Flex } from '../../components/Flex';
|
|
8
|
+
import { ACCESS_LEVEL_HIDDEN } from '../../Utilities/Constants/GeneralConstants';
|
|
8
9
|
import { ExportModuleId } from '../../Utilities/Constants/ModuleConstants';
|
|
9
10
|
import StringExtensions from '../../Utilities/Extensions/StringExtensions';
|
|
10
11
|
const ADAPTABLE_CONTAINER_ID = 'transposed-adaptable-container';
|
|
@@ -23,7 +24,7 @@ function buildTransposedAdaptableOptions({ hostOptions, transposedRowsAndColumns
|
|
|
23
24
|
adaptableContainer: ADAPTABLE_CONTAINER_ID,
|
|
24
25
|
agGridContainer: AG_GRID_CONTAINER_ID,
|
|
25
26
|
},
|
|
26
|
-
entitlementOptions: { defaultAccessLevel:
|
|
27
|
+
entitlementOptions: { defaultAccessLevel: ACCESS_LEVEL_HIDDEN },
|
|
27
28
|
initialState: {
|
|
28
29
|
Layout: {
|
|
29
30
|
Revision: Date.now(),
|
|
@@ -104,17 +104,17 @@ export const RowSelectionSection = (props) => {
|
|
|
104
104
|
!rowSelection && React.createElement(HelpBlock, null, "There is no Row Selection configured for this Layout"),
|
|
105
105
|
rowSelection && (React.createElement(React.Fragment, null,
|
|
106
106
|
React.createElement(Tabs, { className: "twa:mt-2" },
|
|
107
|
-
React.createElement(Tabs.Tab, null, "Row Selection Column"),
|
|
107
|
+
React.createElement(Tabs.Tab, null, "Row Selection Column Checkboxes"),
|
|
108
108
|
React.createElement(Tabs.Content, null,
|
|
109
109
|
React.createElement(Flex, { flexDirection: "row", className: "twa:gap-6" },
|
|
110
|
-
React.createElement(CheckBox, { className: "twa:flex-1", checked: rowSelection.Checkboxes ?? true, onChange: (checked) => updateRowSelection({ Checkboxes: checked }) }, "
|
|
111
|
-
mode === 'multiRow' && (React.createElement(CheckBox, { className: "twa:flex-1", checked: rowSelection.HeaderCheckbox ?? true, onChange: (checked) => updateRowSelection({ HeaderCheckbox: checked }) }, "
|
|
110
|
+
React.createElement(CheckBox, { className: "twa:flex-1", checked: rowSelection.Checkboxes ?? true, onChange: (checked) => updateRowSelection({ Checkboxes: checked }) }, "Checkboxes in Column Cells"),
|
|
111
|
+
mode === 'multiRow' && (React.createElement(CheckBox, { className: "twa:flex-1", checked: rowSelection.HeaderCheckbox ?? true, onChange: (checked) => updateRowSelection({ HeaderCheckbox: checked }) }, "Checkbox in Column Header (to enable Select All)"))))),
|
|
112
112
|
(rowSelection.Checkboxes ?? true) && (React.createElement(Tabs, { className: "twa:mt-2" },
|
|
113
|
-
React.createElement(Tabs.Tab, null, "Row Grouping"),
|
|
113
|
+
React.createElement(Tabs.Tab, null, "Row Grouping Selection Checkboxes"),
|
|
114
114
|
React.createElement(Tabs.Content, null,
|
|
115
115
|
React.createElement(RadioGroup, { orientation: "vertical", value: rowSelection.CheckboxInGroupColumn ?? false, name: "checkboxLocation", onRadioChange: (value) => updateRowSelection({ CheckboxInGroupColumn: value }) },
|
|
116
|
-
React.createElement(Radio, { value: false }, "
|
|
117
|
-
React.createElement(Radio, { value: true }, "
|
|
116
|
+
React.createElement(Radio, { value: false }, "Display in dedicated Selection Column"),
|
|
117
|
+
React.createElement(Radio, { value: true }, "Display in Row Grouped Column"))))),
|
|
118
118
|
React.createElement(Tabs, { className: "twa:mt-2" },
|
|
119
119
|
React.createElement(Tabs.Tab, null, "Row Click Selection (when user clicks on Row outside of Selection Checkbox)"),
|
|
120
120
|
React.createElement(Tabs.Content, null,
|
|
@@ -7,6 +7,7 @@ import { AdaptableButtonComponent } from '../Components/AdaptableButton';
|
|
|
7
7
|
import { PopupPanel } from '../Components/Popups/AdaptablePopup/PopupPanel';
|
|
8
8
|
import StringExtensions from '../../Utilities/Extensions/StringExtensions';
|
|
9
9
|
import FormatHelper from '../../Utilities/Helpers/FormatHelper';
|
|
10
|
+
import { ACCESS_LEVEL_READ_ONLY } from '../../Utilities/Constants/GeneralConstants';
|
|
10
11
|
const tableDOMProps = {
|
|
11
12
|
style: {
|
|
12
13
|
height: '100%',
|
|
@@ -31,7 +32,8 @@ export const NotePopup = (props) => {
|
|
|
31
32
|
? adaptable.api.columnApi.getFriendlyNameForColumnId(adaptable.api.columnApi.getPrimaryKeyColumn().columnId)
|
|
32
33
|
: StringExtensions.Humanize(adaptable.adaptableOptions.primaryKey);
|
|
33
34
|
const allNotes = useSelector((state) => GetAllNotesSelector(state.Note));
|
|
34
|
-
const isReadOnlyModule = adaptable.api.entitlementApi.getEntitlementAccessLevelForModule('Note') ===
|
|
35
|
+
const isReadOnlyModule = adaptable.api.entitlementApi.getEntitlementAccessLevelForModule('Note') ===
|
|
36
|
+
ACCESS_LEVEL_READ_ONLY;
|
|
35
37
|
const formatDate = (date, format) => {
|
|
36
38
|
return FormatHelper.DateFormatter(date, { Pattern: format });
|
|
37
39
|
};
|
|
@@ -6,6 +6,7 @@ import { StringExtensions } from '../../Utilities/Extensions/StringExtensions';
|
|
|
6
6
|
import { PreviewResultsPanel } from '../Components/PreviewResultsPanel';
|
|
7
7
|
import { EnumExtensions } from '../../Utilities/Extensions/EnumExtensions';
|
|
8
8
|
import Input from '../../components/Input';
|
|
9
|
+
import { ACCESS_LEVEL_READ_ONLY } from '../../Utilities/Constants/GeneralConstants';
|
|
9
10
|
import { ButtonApply } from '../Components/Buttons/ButtonApply';
|
|
10
11
|
import { AdaptablePopover } from '../AdaptablePopover';
|
|
11
12
|
import { UIHelper } from '../UIHelper';
|
|
@@ -62,7 +63,7 @@ class SmartEditViewPanelComponent extends React.Component {
|
|
|
62
63
|
color: statusColour,
|
|
63
64
|
fill: 'currentColor',
|
|
64
65
|
};
|
|
65
|
-
let shouldDisable = this.props.accessLevel ==
|
|
66
|
+
let shouldDisable = this.props.accessLevel == ACCESS_LEVEL_READ_ONLY ||
|
|
66
67
|
!this.props.IsValidSelection ||
|
|
67
68
|
this.props.api.layoutApi.isCurrentLayoutPivot() == true;
|
|
68
69
|
const elementType = this.props.viewType === 'Toolbar' ? 'DashboardToolbar' : 'ToolPanel';
|
|
@@ -8,7 +8,9 @@ import { Flex } from '../../components/Flex';
|
|
|
8
8
|
export const StateManagementViewPanel = (props) => {
|
|
9
9
|
const isToolbar = props.viewType === 'Toolbar';
|
|
10
10
|
const elementType = isToolbar ? 'DashboardToolbar' : 'ToolPanel';
|
|
11
|
-
return (React.createElement(Flex, { flexDirection: isToolbar ? 'row' : 'column', className: join(props.accessLevel ==
|
|
11
|
+
return (React.createElement(Flex, { flexDirection: isToolbar ? 'row' : 'column', className: join(props.accessLevel == GeneralConstants.ACCESS_LEVEL_READ_ONLY
|
|
12
|
+
? GeneralConstants.READ_ONLY_STYLE
|
|
13
|
+
: '', `ab-${elementType}__StateManagement__wrap twa:min-h-input`) },
|
|
12
14
|
React.createElement(Flex, { flexDirection: "row" },
|
|
13
15
|
React.createElement(LoadButton, { tooltip: "Load Initial Adaptable State", variant: "text", icon: "upload", onLoad: (json) => props.api.stateApi.reloadInitialState(json), accessLevel: props.accessLevel }, !isToolbar && 'Load'),
|
|
14
16
|
React.createElement(ClearButton, { icon: "delete", tooltip: "Clear User State", variant: "text", onClick: () => props.api.stateApi.reloadInitialState(), accessLevel: props.accessLevel }, !isToolbar && 'Clear')),
|
|
@@ -6,6 +6,7 @@ import { ALL_STATUS_SUB_PANELS } from '../../AdaptableState/Common/Types';
|
|
|
6
6
|
import { getStatusPanelsSelector } from '../../Redux/ActionsReducers/StatusBarRedux';
|
|
7
7
|
import { useAdaptable } from '../AdaptableContext';
|
|
8
8
|
import { PopupPanel } from '../Components/Popups/AdaptablePopup/PopupPanel';
|
|
9
|
+
import { ACCESS_LEVEL_READ_ONLY } from '../../Utilities/Constants/GeneralConstants';
|
|
9
10
|
export const StatusBarPopup = (props) => {
|
|
10
11
|
const statusPanels = useSelector(getStatusPanelsSelector);
|
|
11
12
|
const adaptable = useAdaptable();
|
|
@@ -32,7 +33,7 @@ export const StatusBarPopup = (props) => {
|
|
|
32
33
|
const module = adaptable.ModuleService.getModuleById(panel);
|
|
33
34
|
return { Id: panel, Title: module.moduleInfo.FriendlyName };
|
|
34
35
|
});
|
|
35
|
-
const disabled = props.accessLevel ===
|
|
36
|
+
const disabled = props.accessLevel === ACCESS_LEVEL_READ_ONLY;
|
|
36
37
|
return (React.createElement(PopupPanel, { headerText: props.moduleInfo.FriendlyName, glyphicon: props.moduleInfo.Glyph, infoLink: props.moduleInfo.HelpPage, infoLinkDisabled: !props.api.internalApi.isDocumentationLinksDisplayed() }, statusPanels.length ? (React.createElement(ModuleManager, { permittedActions: {
|
|
37
38
|
createTab: false,
|
|
38
39
|
dragAndDropTab: false,
|
|
@@ -8,6 +8,7 @@ import Panel from '../../components/Panel';
|
|
|
8
8
|
import { Field } from './ThemeField';
|
|
9
9
|
import { VariantSelector } from './VariantSelector';
|
|
10
10
|
import { getAccessLevelForObject } from '../../Utilities/Helpers/AdaptableHelper';
|
|
11
|
+
import { ACCESS_LEVEL_FULL } from '../../Utilities/Constants/GeneralConstants';
|
|
11
12
|
import { Box, Flex } from '../../components/Flex';
|
|
12
13
|
const fields = [
|
|
13
14
|
{
|
|
@@ -53,7 +54,7 @@ export const ThemeEditor = (props) => {
|
|
|
53
54
|
return adaptable.api.themeApi.getCurrentThemeObject();
|
|
54
55
|
});
|
|
55
56
|
const currentThemeAccessLevel = getAccessLevelForObject(currentThemeObject, props.accessLevel);
|
|
56
|
-
const currentThemeIsReadOnly = currentThemeAccessLevel !==
|
|
57
|
+
const currentThemeIsReadOnly = currentThemeAccessLevel !== ACCESS_LEVEL_FULL;
|
|
57
58
|
// THEME variables
|
|
58
59
|
const themeVariables = currentThemeObject?.CSSVariables;
|
|
59
60
|
const valuesFromTheme = fields.reduce((acc, field) => {
|
|
@@ -6,6 +6,7 @@ import FormLayout, { FormRow } from '../../components/FormLayout';
|
|
|
6
6
|
import DropdownButton from '../../components/DropdownButton';
|
|
7
7
|
import { ThemeEditor } from './ThemeEditor';
|
|
8
8
|
import ObjectFactory from '../../Utilities/ObjectFactory';
|
|
9
|
+
import { ACCESS_LEVEL_READ_ONLY } from '../../Utilities/Constants/GeneralConstants';
|
|
9
10
|
import SimpleButton from '../../components/SimpleButton';
|
|
10
11
|
import { Icon } from '../../components/icons';
|
|
11
12
|
import { ThemeSelector } from './ThemeSelector';
|
|
@@ -15,7 +16,7 @@ class ThemePopupComponent extends React.Component {
|
|
|
15
16
|
const isCustomTheme = this.props.api.themeApi
|
|
16
17
|
.getUserThemes()
|
|
17
18
|
.some((theme) => theme.Name === this.props.CurrentTheme);
|
|
18
|
-
const disabled = this.props.accessLevel ===
|
|
19
|
+
const disabled = this.props.accessLevel === ACCESS_LEVEL_READ_ONLY;
|
|
19
20
|
const newButton = (React.createElement(DropdownButton, { className: "twa:ml-2", disabled: disabled, tone: "accent", variant: "raised", columns: ['label'], items: [
|
|
20
21
|
{
|
|
21
22
|
label: 'Dark',
|
|
@@ -2,6 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import { useDispatch, useSelector } from 'react-redux';
|
|
3
3
|
import { Select } from '../../components/Select';
|
|
4
4
|
import * as ThemeRedux from '../../Redux/ActionsReducers/ThemeRedux';
|
|
5
|
+
import { ACCESS_LEVEL_READ_ONLY } from '../../Utilities/Constants/GeneralConstants';
|
|
5
6
|
import { ThemeModuleId } from '../../Utilities/Constants/ModuleConstants';
|
|
6
7
|
import { useAdaptable } from '../AdaptableContext';
|
|
7
8
|
export const ThemeSelector = (props) => {
|
|
@@ -9,7 +10,8 @@ export const ThemeSelector = (props) => {
|
|
|
9
10
|
const dispatch = useDispatch();
|
|
10
11
|
const availableThemes = adaptable.api.themeApi.getThemes();
|
|
11
12
|
const currentTheme = useSelector((state) => state.Theme.CurrentTheme);
|
|
12
|
-
const disabled = adaptable.api.entitlementApi.getEntitlementAccessLevelForModule(ThemeModuleId) ===
|
|
13
|
+
const disabled = adaptable.api.entitlementApi.getEntitlementAccessLevelForModule(ThemeModuleId) ===
|
|
14
|
+
ACCESS_LEVEL_READ_ONLY;
|
|
13
15
|
const optionThemes = availableThemes.map((theme) => {
|
|
14
16
|
if (typeof theme === 'string') {
|
|
15
17
|
// protection against old state, which could be string
|
|
@@ -4,6 +4,8 @@ import * as GeneralConstants from '../../Utilities/Constants/GeneralConstants';
|
|
|
4
4
|
import { ThemeSelector } from './ThemeSelector';
|
|
5
5
|
export const ThemeViewPanelControl = (props) => {
|
|
6
6
|
const elementType = props.viewType === 'Toolbar' ? 'DashboardToolbar' : 'ToolPanel';
|
|
7
|
-
return (React.createElement("div", { className: join(props.accessLevel ==
|
|
7
|
+
return (React.createElement("div", { className: join(props.accessLevel == GeneralConstants.ACCESS_LEVEL_READ_ONLY
|
|
8
|
+
? GeneralConstants.READ_ONLY_STYLE
|
|
9
|
+
: '', `ab-${elementType}__Theme__wrap`) },
|
|
8
10
|
React.createElement(ThemeSelector, null)));
|
|
9
11
|
};
|
|
@@ -5,6 +5,7 @@ import Dialog from '../../components/Dialog';
|
|
|
5
5
|
import SimpleButton from '../../components/SimpleButton';
|
|
6
6
|
import useProperty from '../../components/utils/useProperty';
|
|
7
7
|
import { isMacLike } from '../../Utilities/isMacLike';
|
|
8
|
+
import { ACCESS_LEVEL_FULL } from '../../Utilities/Constants/GeneralConstants';
|
|
8
9
|
import { KeyHint } from '../KeyHint';
|
|
9
10
|
import { Icon } from '../../components/icons';
|
|
10
11
|
import { useResizeObserver } from '../../components/ResizeObserver';
|
|
@@ -176,8 +177,8 @@ export const OnePageWizard = (props) => {
|
|
|
176
177
|
"to navigate")),
|
|
177
178
|
React.createElement(Flex, { flexDirection: "column", className: "ab-OnePageWizard__section-container twa:min-h-0 twa:min-w-0 twa:flex-1" }, renderSection(currentSection))),
|
|
178
179
|
React.createElement(Flex, { flexDirection: "row", alignItems: "center", className: "ab-WizardDialog__footer ab-OnePageWizard__footer twa:p-2" },
|
|
179
|
-
React.createElement(SimpleButton, { tone: "neutral", variant: "text", "data-name": "close", onClick: () => props.onHide?.(), tooltip: props.closeTooltip ?? 'Close wizard', accessLevel:
|
|
180
|
+
React.createElement(SimpleButton, { tone: "neutral", variant: "text", "data-name": "close", onClick: () => props.onHide?.(), tooltip: props.closeTooltip ?? 'Close wizard', accessLevel: ACCESS_LEVEL_FULL }, props.closeText ?? 'CLOSE'),
|
|
180
181
|
React.createElement(KeyHint, { className: "twa:ml-2" }, "Esc"),
|
|
181
182
|
React.createElement(Box, { className: "ab-OnePageWizard__error twa:text-2 twa:mr-3 twa:flex-1 twa:text-error twa:text-end" }, firstErrorMessage),
|
|
182
|
-
React.createElement(SimpleButton, { tone: "accent", "data-name": "finish", variant: "raised", disabled: canFinish !== true, onClick: () => handleClickFinish(), icon: 'check', accessLevel:
|
|
183
|
+
React.createElement(SimpleButton, { tone: "accent", "data-name": "finish", variant: "raised", disabled: canFinish !== true, onClick: () => handleClickFinish(), icon: 'check', accessLevel: ACCESS_LEVEL_FULL }, props.finishText ?? 'Finish')))))));
|
|
183
184
|
};
|
|
@@ -26,7 +26,7 @@ import { RenderReactRootFn } from '../renderReactRoot';
|
|
|
26
26
|
import { AgGridOptionsService } from './AgGridOptionsService';
|
|
27
27
|
import { AgGridColumnAdapter } from './AgGridColumnAdapter';
|
|
28
28
|
import { RowFormService } from '../Utilities/Services/RowFormService';
|
|
29
|
-
import { GridCellWithChildren, GridCellWithCount } from '../AdaptableState/Selection/GridCell';
|
|
29
|
+
import { CellUpdateRequest, GridCellWithChildren, GridCellWithCount } from '../AdaptableState/Selection/GridCell';
|
|
30
30
|
import { FlashingCellService } from '../Utilities/Services/FlashingCellService';
|
|
31
31
|
import { AgGridExportAdapter } from './AgGridExportAdapter';
|
|
32
32
|
import { PivotLayoutModel, TableLayoutModel } from '../layout-manager/src/LayoutManagerModel';
|
|
@@ -300,7 +300,7 @@ export declare class AdaptableAgGrid implements IAdaptable {
|
|
|
300
300
|
getRowNodesForPrimaryKeys(primaryKeyValues: any[]): any[];
|
|
301
301
|
getRowNodeByIndex(index: number): IRowNode;
|
|
302
302
|
getAgGridStatusPanels(): StatusPanelDef[];
|
|
303
|
-
|
|
303
|
+
updateCell(cellUpdateRequest: CellUpdateRequest): void;
|
|
304
304
|
forAllRowNodesDo(func: (rowNode: IRowNode, rowIndex: number) => void, config?: {
|
|
305
305
|
includeGroupRows?: boolean;
|
|
306
306
|
filterFn?: (rowNode: IRowNode) => boolean;
|
|
@@ -3301,38 +3301,16 @@ export class AdaptableAgGrid {
|
|
|
3301
3301
|
getAgGridStatusPanels() {
|
|
3302
3302
|
return this.agGridAdapter.getGridOption('statusBar')?.statusPanels ?? [];
|
|
3303
3303
|
}
|
|
3304
|
-
|
|
3304
|
+
updateCell(cellUpdateRequest) {
|
|
3305
3305
|
// note: because we use RowNode.setDataValue() this will cause Validation to fire
|
|
3306
3306
|
// see https://www.ag-grid.com/javascript-data-grid/change-detection/#triggering-value-change-detection
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
return; // no point continuing as probably a wrong column
|
|
3312
|
-
}
|
|
3313
|
-
if (rowNode) {
|
|
3314
|
-
rowNode.setDataValue(column.columnId, newValue);
|
|
3315
|
-
}
|
|
3316
|
-
else {
|
|
3317
|
-
if (this.useRowNodeLookUp) {
|
|
3318
|
-
const rowNode = this.agGridAdapter.getAgGridApi().getRowNode(primaryKeyValue);
|
|
3319
|
-
if (rowNode != null) {
|
|
3320
|
-
rowNode.setDataValue(column.columnId, newValue);
|
|
3321
|
-
}
|
|
3322
|
-
}
|
|
3323
|
-
else {
|
|
3324
|
-
let isUpdated = false;
|
|
3325
|
-
// prefer not to use this method but if we do then at least we can prevent further lookups once we find
|
|
3326
|
-
this.agGridAdapter.getAgGridApi().forEachNode((rowNode) => {
|
|
3327
|
-
if (!isUpdated) {
|
|
3328
|
-
if (primaryKeyValue == this.getPrimaryKeyValueFromRowNode(rowNode)) {
|
|
3329
|
-
rowNode.setDataValue(column.columnId, newValue);
|
|
3330
|
-
isUpdated = true;
|
|
3331
|
-
}
|
|
3332
|
-
}
|
|
3333
|
-
});
|
|
3334
|
-
}
|
|
3307
|
+
const rowNode = cellUpdateRequest.rowNode ?? this.getRowNodeForPrimaryKey(cellUpdateRequest.primaryKeyValue);
|
|
3308
|
+
if (!rowNode) {
|
|
3309
|
+
this.logger.warn(`updateCell() - rowNode not found for primaryKeyValue: ${cellUpdateRequest.primaryKeyValue}`);
|
|
3310
|
+
return;
|
|
3335
3311
|
}
|
|
3312
|
+
// update the row node and set it as an edit (for AG Grid Cell Change Detection)
|
|
3313
|
+
rowNode.setDataValue(cellUpdateRequest.columnId, cellUpdateRequest.newValue, 'edit');
|
|
3336
3314
|
}
|
|
3337
3315
|
forAllRowNodesDo(func, config) {
|
|
3338
3316
|
this.agGridAdapter.getAgGridApi().forEachNode((rowNode, rowIndex) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ColumnApiModule, } from 'ag-grid-enterprise';
|
|
2
2
|
import { ACTION_COLUMN_TYPE, CALCULATED_COLUMN_TYPE, FDC3_COLUMN_TYPE, FREE_TEXT_COLUMN_TYPE, } from '../AdaptableState/Common/AdaptableColumn';
|
|
3
|
-
import { ADAPTABLE_FDC3_ACTION_COLUMN_FRIENDLY_NAME } from '../Utilities/Constants/GeneralConstants';
|
|
3
|
+
import { ACCESS_LEVEL_HIDDEN, ADAPTABLE_FDC3_ACTION_COLUMN_FRIENDLY_NAME, } from '../Utilities/Constants/GeneralConstants';
|
|
4
4
|
import { createUuid } from '../AdaptableState/Uuid';
|
|
5
5
|
import ArrayExtensions from '../Utilities/Extensions/ArrayExtensions';
|
|
6
6
|
import * as ModuleConstants from '../Utilities/Constants/ModuleConstants';
|
|
@@ -746,7 +746,7 @@ export class AgGridAdapter {
|
|
|
746
746
|
}
|
|
747
747
|
isColumnFilterable(colDef) {
|
|
748
748
|
// follow agGrid logic which is that ONLY filterable if explicitly set
|
|
749
|
-
if (this.adaptableApi.entitlementApi.getEntitlementAccessLevelForModule(ModuleConstants.ColumnFilterModuleId) ==
|
|
749
|
+
if (this.adaptableApi.entitlementApi.getEntitlementAccessLevelForModule(ModuleConstants.ColumnFilterModuleId) == ACCESS_LEVEL_HIDDEN) {
|
|
750
750
|
return false;
|
|
751
751
|
}
|
|
752
752
|
return colDef != null && colDef.filter != null && colDef.filter != false;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import kebabCase from '../Utilities/utils/kebabCase';
|
|
2
|
+
import { resolveDisplayFormat } from '../AdaptableState/Common/AdaptableFormatPresets';
|
|
2
3
|
import merge from '../Utilities/utils/merge';
|
|
3
4
|
import { convertAdaptableStyleToCSS, getVariableColor, normalizeStyleForAgGrid, } from '../Utilities/Helpers/StyleHelper';
|
|
4
5
|
import StringExtensions from '../Utilities/Extensions/StringExtensions';
|
|
@@ -730,8 +731,14 @@ export class AgGridColumnAdapter {
|
|
|
730
731
|
// ALL FormatColumns are conditional and NONE of them are relevant for this row
|
|
731
732
|
return value;
|
|
732
733
|
}
|
|
733
|
-
|
|
734
|
-
|
|
734
|
+
// Resolve once: a preset name (e.g. 'Dollar') is materialised
|
|
735
|
+
// into the concrete AdaptableFormat for this render call.
|
|
736
|
+
const resolvedDisplayFormat = resolveDisplayFormat(mostRelevantFormatColumn.DisplayFormat);
|
|
737
|
+
if (!resolvedDisplayFormat) {
|
|
738
|
+
return value;
|
|
739
|
+
}
|
|
740
|
+
const formatterOptions = resolvedDisplayFormat.Options;
|
|
741
|
+
if (resolvedDisplayFormat.Formatter === 'NumberFormatter') {
|
|
735
742
|
// change the Number format - if the scope allows it
|
|
736
743
|
if (this.adaptableApi.columnScopeApi.isColumnInNumericScope(abColumn, mostRelevantFormatColumn.Scope)) {
|
|
737
744
|
let cellValue = params.value;
|
|
@@ -743,7 +750,7 @@ export class AgGridColumnAdapter {
|
|
|
743
750
|
return this.adaptableApi.formatColumnApi.internalApi.getNumberFormattedValue(cellValue, params.node, abColumn, formatterOptions);
|
|
744
751
|
}
|
|
745
752
|
}
|
|
746
|
-
if (
|
|
753
|
+
if (resolvedDisplayFormat.Formatter === 'DateFormatter') {
|
|
747
754
|
// change the Date format - if the scope allows it
|
|
748
755
|
if (this.adaptableApi.columnScopeApi.isColumnInDateScope(abColumn, mostRelevantFormatColumn.Scope)) {
|
|
749
756
|
let cellValue = params.value;
|
|
@@ -755,7 +762,7 @@ export class AgGridColumnAdapter {
|
|
|
755
762
|
return this.adaptableApi.formatColumnApi.internalApi.getDateFormattedValue(cellValue, params.node, abColumn, formatterOptions);
|
|
756
763
|
}
|
|
757
764
|
}
|
|
758
|
-
if (
|
|
765
|
+
if (resolvedDisplayFormat.Formatter === 'StringFormatter') {
|
|
759
766
|
// change the String format - if the scope allows it
|
|
760
767
|
if (this.adaptableApi.columnScopeApi.isColumnInTextScope(abColumn, mostRelevantFormatColumn.Scope)) {
|
|
761
768
|
let cellValue = params.value;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import tinycolor from 'tinycolor2';
|
|
2
2
|
import { inferSchema, initParser } from 'udsv';
|
|
3
|
+
import { resolveDisplayFormat } from '../AdaptableState/Common/AdaptableFormatPresets';
|
|
3
4
|
import { createUuid } from '../AdaptableState/Uuid';
|
|
4
5
|
import { AG_GRID_GROUPED_COLUMN, AG_GRID_SELECTION_COLUMN, } from '../Utilities/Constants/GeneralConstants';
|
|
5
6
|
import { ExportModuleId } from '../Utilities/Constants/ModuleConstants';
|
|
@@ -639,9 +640,10 @@ export class AgGridExportAdapter {
|
|
|
639
640
|
const abColumn = getAdaptableColumnWithColumnId(column.getColId());
|
|
640
641
|
if (!dateFormatPattern) {
|
|
641
642
|
const mostRelevantFormatColumn = this.adaptableApi.formatColumnApi.internalApi.getMostRelevantFormatColumnForColumn(getFormatColumnsWithDisplayFormatForColumn(column.getColId()), abColumn, { node, value: rawValue });
|
|
643
|
+
const resolvedDisplayFormat = resolveDisplayFormat(mostRelevantFormatColumn?.DisplayFormat);
|
|
642
644
|
dateFormatPattern =
|
|
643
|
-
|
|
644
|
-
|
|
645
|
+
resolvedDisplayFormat?.Formatter === 'DateFormatter' &&
|
|
646
|
+
resolvedDisplayFormat?.Options?.Pattern;
|
|
645
647
|
}
|
|
646
648
|
if (dateFormatPattern) {
|
|
647
649
|
const customDateFormatPattern = typeof dateFormatPattern === 'function'
|
|
@@ -3,6 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { useRerender } from '../../components/utils/useRerender';
|
|
4
4
|
import { renderWithAdaptableContext } from '../../View/renderWithAdaptableContext';
|
|
5
5
|
import { LAYOUT_SELECT } from '../../Redux/ActionsReducers/LayoutRedux';
|
|
6
|
+
import { ACCESS_LEVEL_FULL } from '../../Utilities/Constants/GeneralConstants';
|
|
6
7
|
const ActionButtons = (props) => {
|
|
7
8
|
const { buttons, adaptableApi, context, rerender } = props;
|
|
8
9
|
return (React.createElement(React.Fragment, null, buttons.map((button, index) => {
|
|
@@ -30,7 +31,7 @@ const ActionButtons = (props) => {
|
|
|
30
31
|
button.icon?.name ??
|
|
31
32
|
button.tooltip ??
|
|
32
33
|
`${index + 1}`;
|
|
33
|
-
return (React.createElement(SimpleButton, { key: button.Uuid, "data-name": `action-button-${identifier}`, variant: buttonStyle?.variant ?? 'text', disabled: disabled, tooltip: buttonTooltip, icon: buttonIcon, tone: buttonStyle?.tone ?? 'none', onClick: handleClick, className: buttonStyle?.className, accessLevel:
|
|
34
|
+
return (React.createElement(SimpleButton, { key: button.Uuid, "data-name": `action-button-${identifier}`, variant: buttonStyle?.variant ?? 'text', disabled: disabled, tooltip: buttonTooltip, icon: buttonIcon, tone: buttonStyle?.tone ?? 'none', onClick: handleClick, className: buttonStyle?.className, accessLevel: ACCESS_LEVEL_FULL }, buttonLabel));
|
|
34
35
|
})));
|
|
35
36
|
};
|
|
36
37
|
export const ReactActionColumnRenderer = (props) => {
|
|
@@ -4,6 +4,7 @@ import join from '../utils/join';
|
|
|
4
4
|
import useProperty from '../utils/useProperty';
|
|
5
5
|
import { DashboardToolbar } from './DashboardToolbar';
|
|
6
6
|
import DropdownButton from '../DropdownButton';
|
|
7
|
+
import { ACCESS_LEVEL_FULL } from '../../Utilities/Constants/GeneralConstants';
|
|
7
8
|
export function Dashboard(props) {
|
|
8
9
|
const { title, children, left, right, onShowDashboardPopup } = props;
|
|
9
10
|
const [activeTabIndex, setActiveTabIndex] = useProperty(props, 'activeTabIndex', 0);
|
|
@@ -64,7 +65,7 @@ export function Dashboard(props) {
|
|
|
64
65
|
!floating && renderTabs()),
|
|
65
66
|
floating ? (React.createElement("div", { className: "ab-Dashboard__title", ref: handleRef, key: "title-drag", style: { cursor: 'move' } }, title)) : (React.createElement("div", { className: "ab-Dashboard__title", key: "title" }, title)),
|
|
66
67
|
React.createElement("div", { className: "ab-Dashboard__header-right" }, right)));
|
|
67
|
-
const renderHomeToolbar = () => (React.createElement(DashboardToolbar, { onConfigure: onShowDashboardPopup, className: "ab-Dashboard__home-toolbar", title: title, tooltip: `Configure Dashboard`, showConfigure: true, showClose: false, accessLevel:
|
|
68
|
+
const renderHomeToolbar = () => (React.createElement(DashboardToolbar, { onConfigure: onShowDashboardPopup, className: "ab-Dashboard__home-toolbar", title: title, tooltip: `Configure Dashboard`, showConfigure: true, showClose: false, accessLevel: ACCESS_LEVEL_FULL },
|
|
68
69
|
left,
|
|
69
70
|
right,
|
|
70
71
|
children && children.length > 1,
|