@adaptabletools/adaptable 22.0.0-canary.6 → 22.0.0-canary.8
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 +63 -74
- package/index.css.map +1 -1
- package/package.json +1 -1
- package/src/AdaptableInterfaces/IAdaptable.d.ts +6 -6
- package/src/AdaptableOptions/ContainerOptions.d.ts +55 -15
- package/src/AdaptableState/AdaptableState.d.ts +2 -0
- package/src/AdaptableState/AlertState.d.ts +1 -2
- package/src/AdaptableState/Common/AdaptableColumnContext.d.ts +9 -0
- package/src/AdaptableState/Common/AdaptableObject.d.ts +4 -0
- package/src/AdaptableState/Common/AdaptableRowContext.d.ts +11 -0
- package/src/AdaptableState/Common/AdaptableRowContext.js +1 -0
- package/src/AdaptableState/Common/BaseContext.d.ts +2 -0
- package/src/AdaptableState/Common/DataUpdateConfig.d.ts +7 -0
- package/src/AdaptableState/Common/NamedObject.d.ts +10 -0
- package/src/AdaptableState/Common/NamedObject.js +1 -0
- package/src/AdaptableState/Common/RowSummary.d.ts +1 -1
- package/src/AdaptableState/Common/Schedule.d.ts +2 -2
- package/src/AdaptableState/Common/SuspendableObject.d.ts +10 -0
- package/src/AdaptableState/Common/SuspendableObject.js +1 -0
- package/src/AdaptableState/Common/TransposeConfig.d.ts +11 -9
- package/src/AdaptableState/CustomSortState.d.ts +1 -1
- package/src/AdaptableState/FormatColumnState.d.ts +1 -1
- package/src/AdaptableState/InitialState.d.ts +9 -0
- package/src/AdaptableState/LayoutState.d.ts +2 -3
- package/src/AdaptableState/PlusMinusState.d.ts +1 -1
- package/src/AdaptableState/ShortcutState.d.ts +1 -1
- package/src/AdaptableState/StyledColumnState.d.ts +1 -1
- package/src/AdaptableState/UserInterfaceState.d.ts +14 -0
- package/src/AdaptableState/UserInterfaceState.js +1 -0
- package/src/Api/AlertApi.d.ts +6 -0
- package/src/Api/CustomSortApi.d.ts +6 -0
- package/src/Api/FlashingCellApi.d.ts +6 -0
- package/src/Api/FormatColumnApi.d.ts +10 -4
- package/src/Api/GridApi.d.ts +5 -9
- package/src/Api/Implementation/AlertApiImpl.d.ts +1 -0
- package/src/Api/Implementation/AlertApiImpl.js +5 -6
- package/src/Api/Implementation/ChartingApiImpl.js +2 -2
- package/src/Api/Implementation/CustomSortApiImpl.d.ts +1 -0
- package/src/Api/Implementation/CustomSortApiImpl.js +3 -0
- package/src/Api/Implementation/FlashingCellApiImpl.d.ts +1 -0
- package/src/Api/Implementation/FlashingCellApiImpl.js +3 -0
- package/src/Api/Implementation/FormatColumnApiImpl.d.ts +6 -5
- package/src/Api/Implementation/FormatColumnApiImpl.js +6 -5
- package/src/Api/Implementation/GridApiImpl.d.ts +2 -6
- package/src/Api/Implementation/GridApiImpl.js +9 -9
- package/src/Api/Implementation/LayoutApiImpl.d.ts +1 -0
- package/src/Api/Implementation/LayoutApiImpl.js +4 -1
- package/src/Api/Implementation/NamedQueryApiImpl.js +2 -2
- package/src/Api/Implementation/PlusMinusApiImpl.d.ts +1 -0
- package/src/Api/Implementation/PlusMinusApiImpl.js +3 -0
- package/src/Api/Implementation/ScheduleApiImpl.d.ts +1 -0
- package/src/Api/Implementation/ScheduleApiImpl.js +3 -0
- package/src/Api/Implementation/ShortcutApiImpl.d.ts +1 -0
- package/src/Api/Implementation/ShortcutApiImpl.js +3 -0
- package/src/Api/Implementation/SystemStatusApiImpl.js +6 -9
- package/src/Api/Implementation/UserInterfaceApiImpl.d.ts +5 -0
- package/src/Api/Implementation/UserInterfaceApiImpl.js +13 -0
- package/src/Api/Internal/CalculatedColumnInternalApi.js +2 -2
- package/src/Api/Internal/FreeTextColumnInternalApi.js +2 -2
- package/src/Api/Internal/LayoutInternalApi.js +1 -1
- package/src/Api/Internal/NamedQueryInternalApi.js +4 -4
- package/src/Api/LayoutApi.d.ts +6 -0
- package/src/Api/PlusMinusApi.d.ts +6 -0
- package/src/Api/ScheduleApi.d.ts +6 -0
- package/src/Api/ShortcutApi.d.ts +6 -0
- package/src/Api/UserInterfaceApi.d.ts +17 -0
- package/src/Redux/ActionsReducers/FormatColumnRedux.d.ts +8 -0
- package/src/Redux/ActionsReducers/FormatColumnRedux.js +15 -0
- package/src/Redux/ActionsReducers/UserInterfaceRedux.d.ts +11 -0
- package/src/Redux/ActionsReducers/UserInterfaceRedux.js +21 -0
- package/src/Redux/Store/AdaptableStore.js +45 -16
- package/src/Strategy/BulkUpdateModule.js +8 -8
- package/src/Strategy/PlusMinusModule.js +1 -1
- package/src/Strategy/QuickSearchModule.js +1 -1
- package/src/Strategy/SettingsPanelModule.js +11 -7
- package/src/Strategy/SmartEditModule.js +10 -10
- package/src/Utilities/Services/DataService.js +1 -1
- package/src/Utilities/Services/Fdc3Service.js +4 -4
- package/src/Utilities/Services/ModuleService.js +1 -3
- package/src/Utilities/Services/ThemeService.js +2 -6
- package/src/Utilities/Services/ValidationService.js +1 -1
- package/src/Utilities/logDeprecation.js +3 -4
- package/src/Utilities/resolveContainerElement.d.ts +23 -0
- package/src/Utilities/resolveContainerElement.js +44 -0
- package/src/View/Alert/Wizard/isValidAlertRules.js +1 -1
- package/src/View/CalculatedColumn/Wizard/CalculatedColumnDefinitionWizardSection.js +2 -2
- package/src/View/CalculatedColumn/Wizard/CalculatedColumnExpressionWizardSection.js +2 -2
- package/src/View/CalculatedColumn/Wizard/CalculatedColumnSettingsWizardSection.js +1 -1
- package/src/View/Charting/ChartingWizard/AgChargingWizard/SettingsSection.js +2 -2
- package/src/View/Charting/ChartingWizard/ExternalChartingWizard/SettingsSection.js +2 -2
- package/src/View/Components/CellPopup/index.js +1 -1
- package/src/View/Components/ColumnFilter/components/ColumnFilterInput.js +1 -1
- package/src/View/Components/EntityRulesEditor/Utilities.js +5 -5
- package/src/View/Components/NewScopeComponent.js +3 -3
- package/src/View/Components/Popups/AdaptablePopup/AdaptablePopup.js +2 -1
- package/src/View/Components/Popups/AdaptablePopup/AdaptablePopupBody.js +1 -1
- package/src/View/Components/Popups/AdaptablePopup/AdaptablePopupDialog.d.ts +1 -1
- package/src/View/Components/Popups/AdaptablePopup/AdaptablePopupDialog.js +1 -8
- package/src/View/Components/Popups/AdaptablePopupConfirmation.js +1 -1
- package/src/View/Components/Popups/WindowPopups/WindowPopups.js +36 -1
- package/src/View/Components/WizardSummaryPage.js +1 -1
- package/src/View/CustomSort/Wizard/CustomSortColumnWizardSection.js +3 -3
- package/src/View/CustomSort/Wizard/CustomSortValuesWizardSection.js +1 -1
- package/src/View/Dashboard/CustomToolbar.js +1 -1
- package/src/View/DataChangeHistory/DataChangeHistoryViewPanel.js +1 -1
- package/src/View/FlashingCell/Wizard/isValidFlashingCellRules.js +1 -1
- package/src/View/FreeTextColumn/Wizard/FreeTextColumnSettingsWizardSection.d.ts +1 -1
- package/src/View/FreeTextColumn/Wizard/FreeTextColumnSettingsWizardSection.js +3 -3
- package/src/View/Layout/LayoutViewPanel.js +1 -1
- package/src/View/Layout/TransposedPopup.js +144 -138
- package/src/View/Layout/Wizard/sections/AggregationsSection.js +1 -1
- package/src/View/Layout/Wizard/sections/FilterSection.js +1 -1
- package/src/View/Layout/Wizard/sections/GridFilterSection.js +1 -1
- package/src/View/Layout/Wizard/sections/PivotAggregationsSection.js +3 -3
- package/src/View/Layout/Wizard/sections/RowSummarySection.js +1 -1
- package/src/View/NamedQuery/Wizard/NamedQueryExpressionWizardSection.js +2 -2
- package/src/View/PlusMinus/Wizard/PlusMinusSettingsWizardSection.js +5 -5
- package/src/View/Schedule/Wizard/ScheduleSettingsWizard/ScheduleSettingsReminder.js +1 -1
- package/src/View/Schedule/Wizard/ScheduleSettingsWizard/isSettingsValid.d.ts +1 -1
- package/src/View/Schedule/Wizard/ScheduleSettingsWizard/isSettingsValid.js +11 -11
- package/src/View/StateManagement/handleExportState.js +1 -1
- package/src/View/StyledColumn/Wizard/StyledColumnWizardColumnSection.js +1 -1
- package/src/View/UIHelper.d.ts +2 -1
- package/src/View/UIHelper.js +8 -14
- package/src/agGrid/Adaptable.js +11 -11
- package/src/agGrid/AdaptableAgGrid.d.ts +12 -8
- package/src/agGrid/AdaptableAgGrid.js +150 -82
- package/src/agGrid/AgGridAdapter.js +8 -8
- package/src/agGrid/AgGridColumnAdapter.js +1 -1
- package/src/agGrid/AgGridExportAdapter.js +5 -5
- package/src/agGrid/AgGridFloatingFilterAdapter.js +1 -1
- package/src/agGrid/AgGridMenuAdapter.js +9 -1
- package/src/agGrid/AgGridThemeAdapter.js +2 -2
- package/src/components/CheckBox/index.js +1 -1
- package/src/components/Dropdown/Arrows.js +1 -1
- package/src/components/ExpressionEditor/DataTableEditor.js +3 -3
- package/src/components/FormLayout/index.js +1 -1
- package/src/components/OverlayTrigger/index.js +1 -1
- package/src/components/Select/Select.js +1 -1
- package/src/components/Tree/TreeDropdown/index.js +1 -1
- package/src/env.js +2 -2
- package/src/metamodel/adaptable.metamodel.d.ts +62 -0
- package/src/metamodel/adaptable.metamodel.js +1 -1
- package/src/migration/AdaptableUpgradeHelper.js +2 -2
- package/src/migration/VersionUpgrade17.js +4 -4
- package/src/migration/VersionUpgrade20.js +4 -4
- package/src/types.d.ts +5 -2
- package/themes/dark.css +30 -29
- package/themes/light.css +4 -2
- package/tsconfig.esm.tsbuildinfo +1 -1
|
@@ -43,8 +43,8 @@ export class SmartEditModule extends AdaptableModuleBase {
|
|
|
43
43
|
return {
|
|
44
44
|
Alert: {
|
|
45
45
|
alertType: 'generic',
|
|
46
|
-
header: 'Smart Edit
|
|
47
|
-
message: '
|
|
46
|
+
header: 'Smart Edit',
|
|
47
|
+
message: 'Editing is not available in Pivot Mode.',
|
|
48
48
|
alertDefinition: ObjectFactory.CreateInternalAlertDefinitionForMessages('Error'),
|
|
49
49
|
},
|
|
50
50
|
};
|
|
@@ -53,8 +53,8 @@ export class SmartEditModule extends AdaptableModuleBase {
|
|
|
53
53
|
return {
|
|
54
54
|
Alert: {
|
|
55
55
|
alertType: 'generic',
|
|
56
|
-
header: 'Smart Edit
|
|
57
|
-
message: 'No cells
|
|
56
|
+
header: 'Smart Edit',
|
|
57
|
+
message: 'No cells selected. Please select one or more cells to continue.',
|
|
58
58
|
alertDefinition: ObjectFactory.CreateInternalAlertDefinitionForMessages('Error'),
|
|
59
59
|
},
|
|
60
60
|
};
|
|
@@ -63,8 +63,8 @@ export class SmartEditModule extends AdaptableModuleBase {
|
|
|
63
63
|
return {
|
|
64
64
|
Alert: {
|
|
65
65
|
alertType: 'generic',
|
|
66
|
-
header: 'Smart Edit
|
|
67
|
-
message: 'Smart Edit
|
|
66
|
+
header: 'Smart Edit',
|
|
67
|
+
message: 'Smart Edit supports editing a single column at a time. Please adjust your selection.',
|
|
68
68
|
alertDefinition: ObjectFactory.CreateInternalAlertDefinitionForMessages('Error'),
|
|
69
69
|
},
|
|
70
70
|
};
|
|
@@ -75,8 +75,8 @@ export class SmartEditModule extends AdaptableModuleBase {
|
|
|
75
75
|
return {
|
|
76
76
|
Alert: {
|
|
77
77
|
alertType: 'generic',
|
|
78
|
-
header: 'Smart Edit
|
|
79
|
-
message: 'Smart Edit only
|
|
78
|
+
header: 'Smart Edit',
|
|
79
|
+
message: 'Smart Edit only applies to numeric columns. Please adjust your selection.',
|
|
80
80
|
alertDefinition: ObjectFactory.CreateInternalAlertDefinitionForMessages('Error'),
|
|
81
81
|
},
|
|
82
82
|
};
|
|
@@ -87,8 +87,8 @@ export class SmartEditModule extends AdaptableModuleBase {
|
|
|
87
87
|
return {
|
|
88
88
|
Alert: {
|
|
89
89
|
alertType: 'generic',
|
|
90
|
-
header: 'Smart Edit
|
|
91
|
-
message: 'Smart Edit is not
|
|
90
|
+
header: 'Smart Edit',
|
|
91
|
+
message: 'Smart Edit is not available for read-only cells. Please adjust your selection.',
|
|
92
92
|
alertDefinition: ObjectFactory.CreateInternalAlertDefinitionForMessages('Error'),
|
|
93
93
|
},
|
|
94
94
|
};
|
|
@@ -64,7 +64,7 @@ export class DataService {
|
|
|
64
64
|
// why 2 and not 3 or 1? no good reason, only seems like a reasonable waiting time :)
|
|
65
65
|
const UNDO_WAIT = 2000;
|
|
66
66
|
const timeoutId = setTimeout(() => {
|
|
67
|
-
this.adaptable.logger.warn(`Undo change was
|
|
67
|
+
this.adaptable.logger.warn(`Undo change was not handled within timeout: column="${change.column}", primaryKey="${change.primaryKeyValue}", from=${change.newValue} to=${change.oldValue}.`);
|
|
68
68
|
this.extractUndoChange(change);
|
|
69
69
|
}, UNDO_WAIT);
|
|
70
70
|
this.undoChangeTimers.set(undoChangeKey, timeoutId);
|
|
@@ -78,7 +78,7 @@ export class Fdc3Service {
|
|
|
78
78
|
getDesktopAgent() {
|
|
79
79
|
if (globalThis.fdc3 == null && !this.loggedAgentError) {
|
|
80
80
|
this.loggedAgentError = true;
|
|
81
|
-
this.adaptableApi.consoleError('FDC3 Desktop Agent not found.
|
|
81
|
+
this.adaptableApi.consoleError('FDC3 Desktop Agent not found. The host application must provide the FDC3 agent on globalThis.fdc3.');
|
|
82
82
|
}
|
|
83
83
|
return globalThis.fdc3;
|
|
84
84
|
}
|
|
@@ -161,11 +161,11 @@ export class Fdc3Service {
|
|
|
161
161
|
if (!this.getFdc3Options().enableLogging) {
|
|
162
162
|
return;
|
|
163
163
|
}
|
|
164
|
-
this.adaptableApi.consoleLog(`FDC3
|
|
164
|
+
this.adaptableApi.consoleLog(`FDC3 ${type}: ${params.join(' : ')}`);
|
|
165
165
|
}
|
|
166
166
|
logFdc3Error(error) {
|
|
167
|
-
this.adaptableApi.consoleError(
|
|
168
|
-
this.adaptableApi.alertApi.showAlertError('FDC3
|
|
167
|
+
this.adaptableApi.consoleError('FDC3 operation failed.', error);
|
|
168
|
+
this.adaptableApi.alertApi.showAlertError('FDC3', 'An error occurred. See the browser console for details.');
|
|
169
169
|
}
|
|
170
170
|
getFdc3Api() {
|
|
171
171
|
return this.adaptableApi.fdc3Api;
|
|
@@ -32,9 +32,7 @@ export class ModuleService {
|
|
|
32
32
|
const registeredAgGridModuleNames = agGridModulesAdapter.getAgGridRegisteredModuleNames();
|
|
33
33
|
const missingAgGridModuleNames = mandatoryAgGridModuleNames.filter((moduleName) => !registeredAgGridModuleNames.includes(moduleName));
|
|
34
34
|
if (missingAgGridModuleNames.length) {
|
|
35
|
-
this.adaptableApi.consoleError(`
|
|
36
|
-
|
|
37
|
-
See for more information: ${AgGridRequiredModulesDocsLink}`);
|
|
35
|
+
this.adaptableApi.consoleError(`Adaptable requires these AG Grid modules: ${missingAgGridModuleNames.join(', ')}. Please register them. See: ${AgGridRequiredModulesDocsLink}`);
|
|
38
36
|
}
|
|
39
37
|
// log optional missing AG Grid dependencies for all modules
|
|
40
38
|
this.getModuleCollection().forEach((adaptableModule) => {
|
|
@@ -70,15 +70,11 @@ export class ThemeService {
|
|
|
70
70
|
return val;
|
|
71
71
|
});
|
|
72
72
|
if (abLoaded !== '777') {
|
|
73
|
-
logger.consoleError('
|
|
73
|
+
logger.consoleError('Adaptable styles not detected. Please import "@adaptabletools/adaptable/index.css".');
|
|
74
74
|
}
|
|
75
75
|
const isCustomUserTheme = !this.api.themeApi.internalApi.isSystemTheme(themeName);
|
|
76
76
|
if (!isCustomUserTheme && abThemeLoaded !== themeName) {
|
|
77
|
-
logger.consoleWarn(`Theme "${themeName}"
|
|
78
|
-
|
|
79
|
-
If it's an AdapTable system theme, try
|
|
80
|
-
|
|
81
|
-
import "@adaptabletools/adaptable/themes/${themeName}.css"`);
|
|
77
|
+
logger.consoleWarn(`Theme "${themeName}" does not appear to be loaded. Ensure the CSS file is imported, e.g.: import "@adaptabletools/adaptable/themes/${themeName}.css".`);
|
|
82
78
|
}
|
|
83
79
|
}
|
|
84
80
|
// prefers-color-scheme
|
|
@@ -53,7 +53,7 @@ export class ValidationService {
|
|
|
53
53
|
let alert = {
|
|
54
54
|
alertType: 'cellChanged',
|
|
55
55
|
header: 'Alert',
|
|
56
|
-
message: '
|
|
56
|
+
message: 'A validation rule was triggered for this edit.',
|
|
57
57
|
alertDefinition: failedRules[0],
|
|
58
58
|
cellDataChangedInfo: cellDataChangedInfo,
|
|
59
59
|
};
|
|
@@ -11,13 +11,12 @@ const doOnce = (func, key) => {
|
|
|
11
11
|
};
|
|
12
12
|
export const logDeprecation = (logger, typeName, oldProp, newProp, message) => {
|
|
13
13
|
const newPropMsg = newProp ? `Please use '${typeName}.${newProp}()' instead. ` : '';
|
|
14
|
-
doOnce(() => logger.consoleWarn(
|
|
14
|
+
doOnce(() => logger.consoleWarn(`${typeName}.${oldProp}() is deprecated. ${newPropMsg}${message ?? ''}`), `Deprecated_${oldProp}`);
|
|
15
15
|
};
|
|
16
16
|
export const logDeprecationExternal = (logger, oldTypeName, oldProp, newTypeName, newProp, message) => {
|
|
17
17
|
const newPropMsg = newProp ? `Please use '${newTypeName}.${newProp}()' instead. ` : '';
|
|
18
|
-
doOnce(() => logger.consoleWarn(
|
|
18
|
+
doOnce(() => logger.consoleWarn(`${oldTypeName}.${oldProp}() is deprecated. ${newPropMsg}${message ?? ''}`), `Deprecated_${oldProp}`);
|
|
19
19
|
};
|
|
20
20
|
export const logDeprecationInternal = (logger, typeName, oldProp) => {
|
|
21
|
-
doOnce(() => logger.consoleWarn(
|
|
22
|
-
Please contact support if you need the missing functionality.`), `Deprecated_${oldProp}`);
|
|
21
|
+
doOnce(() => logger.consoleWarn(`${typeName}.${oldProp}() is deprecated and will be removed in the next major release. Contact support if you need this functionality.`), `Deprecated_${oldProp}`);
|
|
23
22
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { AdaptableContainerValue, ContainerContext, InitContainerContext } from '../AdaptableOptions/ContainerOptions';
|
|
2
|
+
/**
|
|
3
|
+
* The union type representing any container option value (static or function).
|
|
4
|
+
*/
|
|
5
|
+
type AnyContainerOption = AdaptableContainerValue | ((context: any) => AdaptableContainerValue);
|
|
6
|
+
/**
|
|
7
|
+
* Resolves a container option value to an `HTMLElement`.
|
|
8
|
+
*
|
|
9
|
+
* Resolution order:
|
|
10
|
+
* 1. If `container` is `null`/`undefined`, returns `null`.
|
|
11
|
+
* 2. If `container` is a function, it is called with the provided `context` and the result is resolved.
|
|
12
|
+
* 3. If the value is an `HTMLElement`, it is returned directly.
|
|
13
|
+
* 4. If the value is an `AdaptableCSSSelector` (`{ selector: string }`), `document.querySelectorAll` is used.
|
|
14
|
+
* If multiple elements match, the first is returned and a console warning is logged.
|
|
15
|
+
* 5. If the value is a `string`, it is treated as an element ID and `document.getElementById` is used.
|
|
16
|
+
*
|
|
17
|
+
* @param container - The container reference to resolve.
|
|
18
|
+
* @param context - Optional context passed to the function form of the container.
|
|
19
|
+
* @param doc - The document to query against (defaults to `globalThis.document`).
|
|
20
|
+
* @returns The resolved `HTMLElement`, or `null` if not found.
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveContainerElement(container: AnyContainerOption | undefined | null, context?: ContainerContext | InitContainerContext, doc?: Document): HTMLElement | null;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a container option value to an `HTMLElement`.
|
|
3
|
+
*
|
|
4
|
+
* Resolution order:
|
|
5
|
+
* 1. If `container` is `null`/`undefined`, returns `null`.
|
|
6
|
+
* 2. If `container` is a function, it is called with the provided `context` and the result is resolved.
|
|
7
|
+
* 3. If the value is an `HTMLElement`, it is returned directly.
|
|
8
|
+
* 4. If the value is an `AdaptableCSSSelector` (`{ selector: string }`), `document.querySelectorAll` is used.
|
|
9
|
+
* If multiple elements match, the first is returned and a console warning is logged.
|
|
10
|
+
* 5. If the value is a `string`, it is treated as an element ID and `document.getElementById` is used.
|
|
11
|
+
*
|
|
12
|
+
* @param container - The container reference to resolve.
|
|
13
|
+
* @param context - Optional context passed to the function form of the container.
|
|
14
|
+
* @param doc - The document to query against (defaults to `globalThis.document`).
|
|
15
|
+
* @returns The resolved `HTMLElement`, or `null` if not found.
|
|
16
|
+
*/
|
|
17
|
+
export function resolveContainerElement(container, context, doc = globalThis.document) {
|
|
18
|
+
if (container == null) {
|
|
19
|
+
return null;
|
|
20
|
+
}
|
|
21
|
+
// Unwrap function form — pass context if the container is a function
|
|
22
|
+
const value = typeof container === 'function' ? container(context) : container;
|
|
23
|
+
// Guard against null/undefined returned by a callback (e.g. document.getElementById(...))
|
|
24
|
+
if (value == null) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
// Direct HTMLElement reference
|
|
28
|
+
if (value instanceof HTMLElement) {
|
|
29
|
+
return value;
|
|
30
|
+
}
|
|
31
|
+
// CSS Selector object
|
|
32
|
+
if (typeof value === 'object' && 'selector' in value) {
|
|
33
|
+
const matches = doc.querySelectorAll(value.selector);
|
|
34
|
+
if (matches.length > 1) {
|
|
35
|
+
console.warn(`[AdapTable] CSS selector "${value.selector}" matched ${matches.length} elements. Using the first match. Consider using a more specific selector.`);
|
|
36
|
+
}
|
|
37
|
+
return matches[0] ?? null;
|
|
38
|
+
}
|
|
39
|
+
// String element ID
|
|
40
|
+
if (typeof value === 'string') {
|
|
41
|
+
return doc.getElementById(value);
|
|
42
|
+
}
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
@@ -4,7 +4,7 @@ export const isValidAlertRules = (alert, api, context) => {
|
|
|
4
4
|
!alert.Rule.BooleanExpression &&
|
|
5
5
|
!alert.Rule.ObservableExpression &&
|
|
6
6
|
!alert.Rule.AggregatedBooleanExpression) {
|
|
7
|
-
return '
|
|
7
|
+
return 'A rule is required for the Alert.';
|
|
8
8
|
}
|
|
9
9
|
const isRuleValid = isAdaptableRuleValid(alert, api, context);
|
|
10
10
|
if (typeof isRuleValid === 'string') {
|
|
@@ -21,11 +21,11 @@ export const renderCalculatedColumnDefinitionSummary = (data) => {
|
|
|
21
21
|
export const isValidCalculatedColumnDefinition = (data, api) => {
|
|
22
22
|
const columns = api.columnApi.getColumns();
|
|
23
23
|
if (!data.ColumnId) {
|
|
24
|
-
return 'Column
|
|
24
|
+
return 'A Column ID is required.';
|
|
25
25
|
}
|
|
26
26
|
const columnsWithSameIdCount = columns.filter((c) => c.columnId === data.ColumnId).length;
|
|
27
27
|
const hasAlreadyExistingId = data.Uuid ? columnsWithSameIdCount > 1 : columnsWithSameIdCount > 0;
|
|
28
|
-
return hasAlreadyExistingId ? 'A
|
|
28
|
+
return hasAlreadyExistingId ? 'A column with this ID already exists.' : true;
|
|
29
29
|
};
|
|
30
30
|
export const CalculatedColumnDefinitionWizardSection = (props) => {
|
|
31
31
|
const { data, api } = useOnePageAdaptableWizardContext();
|
|
@@ -17,11 +17,11 @@ export const isValidCalculatedColumnExpression = (data, api) => {
|
|
|
17
17
|
const calculatedColumnExpressionService = api.internalApi.getCalculatedColumnExpressionService();
|
|
18
18
|
const expression = api.expressionApi.getAdaptableQueryExpression(data.Query)?.trim();
|
|
19
19
|
if (!expression) {
|
|
20
|
-
return '
|
|
20
|
+
return 'An expression is required for the Calculated Column.';
|
|
21
21
|
}
|
|
22
22
|
const isValid = calculatedColumnExpressionService.isCalculatedColumnQueryValid(data.Query);
|
|
23
23
|
if (!isValid) {
|
|
24
|
-
return 'Calculated Column
|
|
24
|
+
return 'The Calculated Column expression is not valid.';
|
|
25
25
|
}
|
|
26
26
|
return true;
|
|
27
27
|
};
|
|
@@ -16,7 +16,7 @@ export const renderCalculatedColumnSettingsSummary = (data) => {
|
|
|
16
16
|
};
|
|
17
17
|
export const isValidCalculatedColumnSettings = (data) => {
|
|
18
18
|
if (!data.CalculatedColumnSettings?.DataType) {
|
|
19
|
-
return '
|
|
19
|
+
return 'A data type is required. It could not be inferred from the expression.';
|
|
20
20
|
}
|
|
21
21
|
return true;
|
|
22
22
|
};
|
|
@@ -5,12 +5,12 @@ import FormLayout, { FormRow } from '../../../../components/FormLayout';
|
|
|
5
5
|
import AdaptableInput from '../../../Components/AdaptableInput';
|
|
6
6
|
export const isSettingsValid = (chartDefinition, api) => {
|
|
7
7
|
if (!chartDefinition.Name) {
|
|
8
|
-
return '
|
|
8
|
+
return 'A name is required.';
|
|
9
9
|
}
|
|
10
10
|
const allChartDefinitions = api.chartingApi.getChartDefinitions();
|
|
11
11
|
if (allChartDefinitions.some((chartDefinitionLoopItem) => chartDefinitionLoopItem.Uuid !== chartDefinition.Uuid &&
|
|
12
12
|
chartDefinitionLoopItem.Name === chartDefinition.Name)) {
|
|
13
|
-
return '
|
|
13
|
+
return 'A Chart with this name already exists.';
|
|
14
14
|
}
|
|
15
15
|
return true;
|
|
16
16
|
};
|
|
@@ -3,12 +3,12 @@ import FormLayout, { FormRow } from '../../../../components/FormLayout';
|
|
|
3
3
|
import AdaptableInput from '../../../Components/AdaptableInput';
|
|
4
4
|
export const isSettingsValid = (chartDefinition, api) => {
|
|
5
5
|
if (!chartDefinition.Name) {
|
|
6
|
-
return '
|
|
6
|
+
return 'A name is required.';
|
|
7
7
|
}
|
|
8
8
|
const allChartDefinitions = api.chartingApi.getExternalChartDefinitions();
|
|
9
9
|
if (allChartDefinitions.some((chartDefinitionLoopItem) => chartDefinitionLoopItem.Uuid !== chartDefinition.Uuid &&
|
|
10
10
|
chartDefinitionLoopItem.Name === chartDefinition.Name)) {
|
|
11
|
-
return '
|
|
11
|
+
return 'A Chart with this name already exists.';
|
|
12
12
|
}
|
|
13
13
|
return true;
|
|
14
14
|
};
|
|
@@ -32,7 +32,7 @@ export const CellPopup = React.forwardRef((props, ref) => {
|
|
|
32
32
|
const cellSelector = `[row-id="${props.primaryKeyValue}"] [col-id="${props.columnId}"]`;
|
|
33
33
|
const alignTo = document.querySelector(cellSelector);
|
|
34
34
|
if (!alignTo) {
|
|
35
|
-
adaptable.logger.consoleError(`
|
|
35
|
+
adaptable.logger.consoleError(`Cell not found for selector "${cellSelector}". Unable to display popup.`);
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
const showOverlayOptions = {
|
|
@@ -93,7 +93,7 @@ export const ColumnFilterInput = (props) => {
|
|
|
93
93
|
return (React.createElement(AdaptableInput, { style: filterType === 'floating'
|
|
94
94
|
? {
|
|
95
95
|
width: '100%',
|
|
96
|
-
padding: 'var(--ab-space
|
|
96
|
+
padding: 'var(--ab-base-space)',
|
|
97
97
|
borderRadius: 0,
|
|
98
98
|
border: 'none',
|
|
99
99
|
}
|
|
@@ -1,28 +1,28 @@
|
|
|
1
1
|
export const isAdaptableRuleValid = (abObject, api, context) => {
|
|
2
2
|
if (abObject?.Rule?.Predicates?.length) {
|
|
3
3
|
if (!api.predicateApi.isEveryPredicateValid(abObject?.Rule?.Predicates)) {
|
|
4
|
-
return `The
|
|
4
|
+
return `The predicate${abObject?.Rule?.Predicates?.length === 1 ? ' is' : 's are'} not valid.`;
|
|
5
5
|
}
|
|
6
6
|
}
|
|
7
7
|
if (abObject?.Rule?.BooleanExpression) {
|
|
8
8
|
if (!api.expressionApi.isValidBooleanExpression(abObject?.Rule?.BooleanExpression, context.moduleInfo.ModuleName)) {
|
|
9
|
-
return 'The
|
|
9
|
+
return 'The Boolean expression is not valid.';
|
|
10
10
|
}
|
|
11
11
|
}
|
|
12
12
|
if (abObject?.Rule?.ObservableExpression) {
|
|
13
13
|
if (!api.expressionApi.isValidObservableExpression(abObject?.Rule?.ObservableExpression, context.moduleInfo.ModuleName)) {
|
|
14
|
-
return 'The
|
|
14
|
+
return 'The Observable expression is not valid.';
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
17
|
if (abObject?.Rule?.AggregatedBooleanExpression) {
|
|
18
18
|
if (!api.expressionApi.isValidAggregatedBooleanExpression(abObject?.Rule?.AggregatedBooleanExpression, context.moduleInfo.ModuleName)) {
|
|
19
|
-
return 'The
|
|
19
|
+
return 'The Aggregated Boolean expression is not valid.';
|
|
20
20
|
}
|
|
21
21
|
}
|
|
22
22
|
if (abObject?.Rule?.Predicates?.length) {
|
|
23
23
|
const isAPredicateWithInvalidColumnId = abObject?.Rule?.Predicates?.some((predicate) => predicate.ColumnId !== undefined && predicate.ColumnId === '');
|
|
24
24
|
if (isAPredicateWithInvalidColumnId) {
|
|
25
|
-
return 'Predicates with custom scope
|
|
25
|
+
return 'Predicates with a custom scope require a valid column.';
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
return true;
|
|
@@ -14,13 +14,13 @@ import { TagList } from '../../components/Tag/Tag';
|
|
|
14
14
|
export const isScopeValid = ({ Scope }) => {
|
|
15
15
|
const result = [];
|
|
16
16
|
if (!Scope) {
|
|
17
|
-
return '
|
|
17
|
+
return 'A scope is required.';
|
|
18
18
|
}
|
|
19
19
|
if (Scope && 'ColumnIds' in Scope && Scope.ColumnIds.length === 0) {
|
|
20
|
-
result.push('
|
|
20
|
+
result.push('Please select at least one column for the scope.');
|
|
21
21
|
}
|
|
22
22
|
if (Scope && 'DataTypes' in Scope && Scope.DataTypes.length === 0) {
|
|
23
|
-
result.push('
|
|
23
|
+
result.push('Please select at least one data type for the scope.');
|
|
24
24
|
}
|
|
25
25
|
return result.length ? result.join(', ') : true;
|
|
26
26
|
};
|
|
@@ -9,6 +9,7 @@ import { AdaptablePopupBody } from './AdaptablePopupBody';
|
|
|
9
9
|
import { useAdaptable } from '../../../AdaptableContext';
|
|
10
10
|
import { CustomSettingsPanelView } from './CustomSettingsPanelView';
|
|
11
11
|
import { useMenuItems } from './useMenuItems';
|
|
12
|
+
import { resolveContainerElement } from '../../../../Utilities/resolveContainerElement';
|
|
12
13
|
import { AdaptablePopupDialog } from './AdaptablePopupDialog';
|
|
13
14
|
import { Box } from '../../../../components/Flex';
|
|
14
15
|
export const AdaptablePopup = (props) => {
|
|
@@ -17,7 +18,7 @@ export const AdaptablePopup = (props) => {
|
|
|
17
18
|
const settingsPanelTitle = adaptable.ModuleService.getModuleFriendlyName('SettingsPanel');
|
|
18
19
|
const menuItems = useMenuItems();
|
|
19
20
|
const isWindowModal = settingsPanelOptions.popupType === 'window';
|
|
20
|
-
const modalContainer = adaptable.adaptableOptions?.containerOptions?.modalContainer;
|
|
21
|
+
const modalContainer = resolveContainerElement(adaptable.adaptableOptions?.containerOptions?.modalContainer, props.api.internalApi.buildBaseContext());
|
|
21
22
|
let friendlyName = null;
|
|
22
23
|
/**
|
|
23
24
|
* This means that it is not rendered in the context of Settings Panel
|
|
@@ -3,7 +3,7 @@ import { UIHelper } from '../../../UIHelper';
|
|
|
3
3
|
import { AdaptableViewFactory } from '../../../AdaptableViewFactory';
|
|
4
4
|
import { AdaptablePopupModuleView } from './AdaptablePopupModuleView';
|
|
5
5
|
export const AdaptablePopupBody = (props) => {
|
|
6
|
-
const modalContainer = UIHelper.getModalContainer(props.api.optionsApi.getAdaptableOptions(), document);
|
|
6
|
+
const modalContainer = UIHelper.getModalContainer(props.api.optionsApi.getAdaptableOptions(), document, props.api.internalApi.buildBaseContext());
|
|
7
7
|
const moduleName = props.module.moduleInfo.ModuleName;
|
|
8
8
|
const accessLevel = props.api.entitlementApi.getEntitlementAccessLevelForModule(moduleName);
|
|
9
9
|
const moduleInfo = props.api.internalApi.getModuleService().getModuleInfoByModule(moduleName);
|
|
@@ -43,14 +43,7 @@ const PopupDialog = (props) => {
|
|
|
43
43
|
export const AdaptablePopupDialog = (props) => {
|
|
44
44
|
const { isActionModule, style, friendlyName, baseClassName, className, children, onHide, isWindowModal, modalContainer, } = props;
|
|
45
45
|
if (modalContainer) {
|
|
46
|
-
|
|
47
|
-
if (typeof modalContainer === 'string') {
|
|
48
|
-
ref = globalThis.document.querySelector(modalContainer);
|
|
49
|
-
}
|
|
50
|
-
else {
|
|
51
|
-
ref = modalContainer;
|
|
52
|
-
}
|
|
53
|
-
return createPortal(React.createElement(Dialog, { "data-name": props.dataName, modal: false, fixed: false, onDismiss: onHide, className: className }, children), ref);
|
|
46
|
+
return createPortal(React.createElement(Dialog, { "data-name": props.dataName, modal: false, fixed: false, onDismiss: onHide, className: className }, children), modalContainer);
|
|
54
47
|
}
|
|
55
48
|
if (isWindowModal) {
|
|
56
49
|
const settingsPanelOptionsKey = isActionModule ? `action-${friendlyName}` : 'settings';
|
|
@@ -51,7 +51,7 @@ export const AdaptablePopupConfirmation = (props) => {
|
|
|
51
51
|
setDisableDeleteConfirmation(!disableDeleteConfirmation);
|
|
52
52
|
} }, "Do not show this again")),
|
|
53
53
|
props.showInputBox && (React.createElement(Box, { className: "twa:p-2", "data-name": "body" },
|
|
54
|
-
React.createElement("p", null, "Please enter a comment to confirm"),
|
|
54
|
+
React.createElement("p", null, "Please enter a comment to confirm."),
|
|
55
55
|
React.createElement(Input, { className: "twa:mt-2 twa:w-full", value: promptText, type: "string", placeholder: "Enter text", onChange: (e) => changeContent(e) }))),
|
|
56
56
|
React.createElement(Flex, { className: "twa:mt-3 twa:p-2", "data-name": "footer", justifyContent: "space-between" },
|
|
57
57
|
props.cancelButtonText != null ? (React.createElement(SimpleButton, { "data-name": "cancel", tone: "neutral", variant: "raised", onClick: () => onCancelForm() }, props.cancelButtonText)) : (React.createElement("div", null)),
|
|
@@ -1,16 +1,44 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
|
+
import { createPortal } from 'react-dom';
|
|
2
3
|
import { useDispatch, useSelector } from 'react-redux';
|
|
3
4
|
import Dialog from '../../../../components/Dialog';
|
|
4
5
|
import { PopupHideWindow } from '../../../../Redux/ActionsReducers/PopupRedux';
|
|
6
|
+
import { resolveContainerElement } from '../../../../Utilities/resolveContainerElement';
|
|
5
7
|
import { useAdaptable } from '../../../AdaptableContext';
|
|
6
8
|
import { ExternalRenderer } from '../../ExternalRenderer';
|
|
7
9
|
import { PanelWithImage } from '../../Panels/PanelWithImage';
|
|
8
10
|
import { getMiddlePosition, getWindowPopupSize } from '../Utilities';
|
|
9
|
-
import { windowFactory } from './windowFactory';
|
|
11
|
+
import { WINDOW_SHOW_TRANSPOSED_VIEW, windowFactory } from './windowFactory';
|
|
10
12
|
const NoopComponent = () => {
|
|
11
13
|
return React.createElement(React.Fragment, null);
|
|
12
14
|
};
|
|
13
15
|
export const CUSTOM_WINDOW_FACTORY_ID = 'CUSTOM_WINDOW_FACTORY_ID';
|
|
16
|
+
/**
|
|
17
|
+
* Portals children into a target container element.
|
|
18
|
+
* Monitors the container with a MutationObserver — if the container is removed
|
|
19
|
+
* from the DOM, `onContainerRemoved` is called so callers can clean up React/Redux state.
|
|
20
|
+
*/
|
|
21
|
+
const ContainerPortal = ({ container, onContainerRemoved, children }) => {
|
|
22
|
+
React.useEffect(() => {
|
|
23
|
+
// If the container is already detached, clean up immediately
|
|
24
|
+
if (!document.contains(container)) {
|
|
25
|
+
onContainerRemoved();
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
const observer = new MutationObserver(() => {
|
|
29
|
+
if (!document.contains(container)) {
|
|
30
|
+
onContainerRemoved();
|
|
31
|
+
observer.disconnect();
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
// Observe the entire document body for subtree removals
|
|
35
|
+
observer.observe(document.body, { childList: true, subtree: true });
|
|
36
|
+
return () => {
|
|
37
|
+
observer.disconnect();
|
|
38
|
+
};
|
|
39
|
+
}, [container, onContainerRemoved]);
|
|
40
|
+
return createPortal(children, container);
|
|
41
|
+
};
|
|
14
42
|
export const WindowPopups = () => {
|
|
15
43
|
const [windowModalSettings, setWindowModalSettings] = React.useState({});
|
|
16
44
|
const adaptable = useAdaptable();
|
|
@@ -37,6 +65,13 @@ export const WindowPopups = () => {
|
|
|
37
65
|
Component = Component ?? NoopComponent;
|
|
38
66
|
componentNode = (React.createElement(Component, { api: adaptable.api, onDismiss: handleDismiss, popupProps: restPopupProps }));
|
|
39
67
|
}
|
|
68
|
+
// Transposed View: portal into custom container if configured
|
|
69
|
+
if (windowItem.FactoryId === WINDOW_SHOW_TRANSPOSED_VIEW) {
|
|
70
|
+
const transposedContainer = resolveContainerElement(adaptable.adaptableOptions?.containerOptions?.transposedViewContainer, adaptable.api.internalApi.buildBaseContext());
|
|
71
|
+
if (transposedContainer) {
|
|
72
|
+
return (React.createElement(ContainerPortal, { key: windowItem.Id, container: transposedContainer, onContainerRemoved: handleDismiss }, componentNode));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
40
75
|
return (React.createElement(Dialog, { "data-name": windowItem.Id, className: "ab-Window-Modal twa:h-full twa:p-0", key: windowItem.Id, windowModal: true, windowModalProps: {
|
|
41
76
|
...windowModalProps,
|
|
42
77
|
onChange: (settings) => {
|
|
@@ -18,13 +18,13 @@ export const renderCustomSortColumn = (data) => {
|
|
|
18
18
|
};
|
|
19
19
|
export const isValidCustomSortColumn = (data, allCustomSorts) => {
|
|
20
20
|
if (!data.Name) {
|
|
21
|
-
return '
|
|
21
|
+
return 'A name is required.';
|
|
22
22
|
}
|
|
23
23
|
if (allCustomSorts.some((customSort) => customSort.Name === data.Name && customSort.Uuid !== data.Uuid)) {
|
|
24
|
-
return 'A Custom Sort
|
|
24
|
+
return 'A Custom Sort with this name already exists.';
|
|
25
25
|
}
|
|
26
26
|
if (!data.ColumnId) {
|
|
27
|
-
return '
|
|
27
|
+
return 'Please select a column for the Custom Sort.';
|
|
28
28
|
}
|
|
29
29
|
return true;
|
|
30
30
|
};
|
|
@@ -11,7 +11,7 @@ import { parseToISO } from '../../../Utilities/Helpers/DateHelper';
|
|
|
11
11
|
import { TagList } from '../../../components/Tag';
|
|
12
12
|
export const isValidCustomSortOrder = (data) => {
|
|
13
13
|
if (!data.SortedValues || !data.SortedValues.length) {
|
|
14
|
-
return '
|
|
14
|
+
return 'At least one value is required for the Custom Sort order.';
|
|
15
15
|
}
|
|
16
16
|
return true;
|
|
17
17
|
};
|
|
@@ -75,7 +75,7 @@ export const CustomToolbarCmp = (props) => {
|
|
|
75
75
|
const disabled = button.disabled && button.disabled(button, dashboardContext);
|
|
76
76
|
let buttonVariant = buttonStyle && buttonStyle.variant ? buttonStyle.variant : 'outlined';
|
|
77
77
|
let buttonTone = buttonStyle && buttonStyle.tone ? buttonStyle.tone : 'neutral';
|
|
78
|
-
return (React.createElement(AdaptableButtonComponent, { style: { marginLeft: index ? 'var(--ab-space
|
|
78
|
+
return (React.createElement(AdaptableButtonComponent, { style: { marginLeft: index ? 'var(--ab-base-space)' : 0 }, key: index, disabled: disabled, tooltip: buttonTooltip, icon: buttonIcon, variant: buttonVariant, tone: buttonTone, className: buttonStyle?.className || '', onClick: () => {
|
|
79
79
|
button.onClick ? button.onClick(button, dashboardContext) : null;
|
|
80
80
|
setTimeout(() => {
|
|
81
81
|
// mutate state to force a re-rendering
|
|
@@ -27,7 +27,7 @@ export const DataChangeHistoryViewPanelControl = (props) => {
|
|
|
27
27
|
const enabled = changeHistoryMode === 'ACTIVE';
|
|
28
28
|
const disabled = changeHistoryMode === 'INACTIVE';
|
|
29
29
|
const suspended = changeHistoryMode === 'SUSPENDED';
|
|
30
|
-
const gap = props.gap ?? 'var(--ab-space
|
|
30
|
+
const gap = props.gap ?? 'var(--ab-base-space)';
|
|
31
31
|
const buttonsPaddingY = props.buttonsPaddingY ?? 2;
|
|
32
32
|
const buttonPanel = (React.createElement(Flex, { className: "ab-DataChangeHistoryPanel--button-panel", style: { gap: gap, paddingBlock: buttonsPaddingY } },
|
|
33
33
|
disabled && (React.createElement(ButtonPlay, { "aria-label": "Enable Data Change History", className: "ab-DataChangeHistoryPanel--button-activate", "data-name": 'data-change-history--button-activate', tooltip: '', onClick: () => onChangeHistoryEnable() })),
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isAdaptableRuleValid } from '../../Components/EntityRulesEditor/Utilities';
|
|
2
2
|
export const isValidFlashingCellRules = (flashingCell, api, context) => {
|
|
3
3
|
if (!flashingCell.Rule?.Predicates?.length && !flashingCell.Rule.BooleanExpression) {
|
|
4
|
-
return '
|
|
4
|
+
return 'A rule is required for the Flashing Cell.';
|
|
5
5
|
}
|
|
6
6
|
const isRuleValid = isAdaptableRuleValid(flashingCell, api, context);
|
|
7
7
|
if (typeof isRuleValid === 'string') {
|
|
@@ -2,7 +2,7 @@ import * as React from 'react';
|
|
|
2
2
|
import { FreeTextColumn } from '../../../AdaptableState/FreeTextColumnState';
|
|
3
3
|
import { AdaptableApi } from '../../../Api/AdaptableApi';
|
|
4
4
|
export declare const renderFreeTextColumnSummary: (data: FreeTextColumn) => React.JSX.Element;
|
|
5
|
-
export declare const isValidFreeTextColumn: (data: FreeTextColumn, api: AdaptableApi) => true | "Column
|
|
5
|
+
export declare const isValidFreeTextColumn: (data: FreeTextColumn, api: AdaptableApi) => true | "A Column ID is required." | "A column with this ID already exists." | "A data type is required for the column.";
|
|
6
6
|
export type FreeTextColumnSettingsWizardSectionProps = {
|
|
7
7
|
onChange: (data: FreeTextColumn) => void;
|
|
8
8
|
isEdit: boolean;
|
|
@@ -40,15 +40,15 @@ export const renderFreeTextColumnSummary = (data) => {
|
|
|
40
40
|
export const isValidFreeTextColumn = (data, api) => {
|
|
41
41
|
const columns = api.columnApi.getUIAvailableColumns();
|
|
42
42
|
if (!data.ColumnId) {
|
|
43
|
-
return 'Column
|
|
43
|
+
return 'A Column ID is required.';
|
|
44
44
|
}
|
|
45
45
|
const columnsWithSameIdCount = columns.filter((c) => c.columnId === data.ColumnId).length;
|
|
46
46
|
const hasAlreadyExistingId = data.Uuid ? columnsWithSameIdCount > 1 : columnsWithSameIdCount > 0;
|
|
47
47
|
if (hasAlreadyExistingId) {
|
|
48
|
-
return 'A
|
|
48
|
+
return 'A column with this ID already exists.';
|
|
49
49
|
}
|
|
50
50
|
if (!data.FreeTextColumnSettings.DataType) {
|
|
51
|
-
return '
|
|
51
|
+
return 'A data type is required for the column.';
|
|
52
52
|
}
|
|
53
53
|
return true;
|
|
54
54
|
};
|
|
@@ -79,7 +79,7 @@ function mapDispatchToProps(dispatch) {
|
|
|
79
79
|
showMissingLayoutsError: () => {
|
|
80
80
|
dispatch(PopupRedux.PopupShowConfirmation({
|
|
81
81
|
Header: 'Missing Layouts',
|
|
82
|
-
Msg: '
|
|
82
|
+
Msg: 'No Layouts have been defined. Please check the console for details.',
|
|
83
83
|
ConfirmAction: null,
|
|
84
84
|
ConfirmButtonText: 'OK',
|
|
85
85
|
CancelButtonText: null,
|