@adaptabletools/adaptable 23.0.5 → 23.0.7
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 +10 -1
- package/package.json +1 -1
- package/src/AdaptableOptions/AdaptableOptions.d.ts +9 -0
- package/src/AdaptableOptions/DataChangeHistoryOptions.d.ts +7 -0
- package/src/AdaptableOptions/DefaultAdaptableOptions.d.ts +17 -0
- package/src/AdaptableOptions/DefaultAdaptableOptions.js +8 -46
- package/src/AdaptableOptions/EditOptions.d.ts +10 -2
- package/src/AdaptableOptions/SettingsPanelOptions.d.ts +3 -28
- package/src/AdaptableOptions/WizardOptions.d.ts +25 -0
- package/src/AdaptableOptions/WizardOptions.js +1 -0
- package/src/AdaptableState/Common/CustomWindowConfig.d.ts +2 -14
- package/src/AdaptableState/Common/Window.d.ts +33 -0
- package/src/AdaptableState/Common/Window.js +1 -0
- package/src/AdaptableState/InitialState.d.ts +2 -1
- package/src/AdaptableState/PlusMinusState.d.ts +12 -2
- package/src/Api/Implementation/DataChangeHistoryApiImpl.js +10 -9
- package/src/Redux/ActionsReducers/InternalRedux.d.ts +2 -1
- package/src/Redux/ActionsReducers/InternalRedux.js +25 -27
- package/src/Strategy/DataChangeHistoryModule.js +1 -1
- package/src/Strategy/PlusMinusModule.js +5 -3
- package/src/Utilities/Extensions/ObjectExtensions.d.ts +16 -0
- package/src/Utilities/Extensions/ObjectExtensions.js +41 -0
- package/src/Utilities/Helpers/PlusMinusHelper.d.ts +62 -9
- package/src/Utilities/Helpers/PlusMinusHelper.js +180 -25
- package/src/View/Components/Popups/AdaptablePopup/AdaptablePopup.js +5 -1
- package/src/View/Components/Popups/AdaptablePopup/AdaptablePopupDialog.js +7 -3
- package/src/View/Components/Popups/Utilities.d.ts +11 -0
- package/src/View/Components/Popups/Utilities.js +8 -0
- package/src/View/DataChangeHistory/DataChangeHistoryViewPanel.js +3 -4
- package/src/View/DataChangeHistory/dataChangeHistoryHelpers.js +1 -1
- package/src/View/PlusMinus/Wizard/KeyComboCaptureInput.d.ts +30 -0
- package/src/View/PlusMinus/Wizard/KeyComboCaptureInput.js +161 -0
- package/src/View/PlusMinus/Wizard/PlusMinusSettingsWizardSection.js +30 -60
- package/src/View/Wizard/OnePageWizards.js +27 -2
- package/src/agGrid/AdaptableAgGrid.js +2 -0
- package/src/components/ui/input-group.js +0 -1
- package/src/env.js +2 -2
- package/src/migration/DeprecatedStateKeys.d.ts +37 -0
- package/src/migration/DeprecatedStateKeys.js +42 -0
- package/src/migration/VersionUpgrade23.d.ts +9 -0
- package/src/migration/VersionUpgrade23.js +1 -2
- package/src/types.d.ts +4 -2
- package/tsconfig.esm.tsbuildinfo +1 -1
|
@@ -269,3 +269,44 @@ export function mergeWith(target, ...args) {
|
|
|
269
269
|
}
|
|
270
270
|
return target;
|
|
271
271
|
}
|
|
272
|
+
export function defaultsDeep(target, ...sources) {
|
|
273
|
+
for (const source of sources) {
|
|
274
|
+
_baseDefaultsDeep(target, source);
|
|
275
|
+
}
|
|
276
|
+
return target;
|
|
277
|
+
}
|
|
278
|
+
function _baseDefaultsDeep(target, defaults) {
|
|
279
|
+
if (defaults == null) {
|
|
280
|
+
return target;
|
|
281
|
+
}
|
|
282
|
+
const keys = Object.keys(defaults);
|
|
283
|
+
for (const key of keys) {
|
|
284
|
+
const defaultValue = defaults[key];
|
|
285
|
+
const targetValue = target[key];
|
|
286
|
+
if (targetValue === undefined) {
|
|
287
|
+
target[key] = _cloneDefaultValue(defaultValue);
|
|
288
|
+
}
|
|
289
|
+
else if (isPlainObject(defaultValue) && isPlainObject(targetValue)) {
|
|
290
|
+
const childCopy = { ...targetValue };
|
|
291
|
+
_baseDefaultsDeep(childCopy, defaultValue);
|
|
292
|
+
target[key] = childCopy;
|
|
293
|
+
}
|
|
294
|
+
}
|
|
295
|
+
return target;
|
|
296
|
+
}
|
|
297
|
+
function _cloneDefaultValue(value) {
|
|
298
|
+
if (value === null || typeof value !== 'object') {
|
|
299
|
+
return value;
|
|
300
|
+
}
|
|
301
|
+
if (Array.isArray(value)) {
|
|
302
|
+
return value.map(_cloneDefaultValue);
|
|
303
|
+
}
|
|
304
|
+
if (isPlainObject(value)) {
|
|
305
|
+
const out = {};
|
|
306
|
+
for (const k of Object.keys(value)) {
|
|
307
|
+
out[k] = _cloneDefaultValue(value[k]);
|
|
308
|
+
}
|
|
309
|
+
return out;
|
|
310
|
+
}
|
|
311
|
+
return value;
|
|
312
|
+
}
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
import type { EditOptions, PlusMinusOptions } from '../../AdaptableOptions/EditOptions';
|
|
2
2
|
import type { PlusMinusNudge } from '../../AdaptableState/PlusMinusState';
|
|
3
|
+
/**
|
|
4
|
+
* Minimal shape required to match a key press against a Plus/Minus trigger.
|
|
5
|
+
* Compatible with the native `KeyboardEvent`.
|
|
6
|
+
*/
|
|
7
|
+
export type PlusMinusKeyEvent = {
|
|
8
|
+
key: string;
|
|
9
|
+
metaKey?: boolean;
|
|
10
|
+
altKey?: boolean;
|
|
11
|
+
ctrlKey?: boolean;
|
|
12
|
+
shiftKey?: boolean;
|
|
13
|
+
};
|
|
3
14
|
/**
|
|
4
15
|
* Resolve increment/decrement trigger strings for a single nudge.
|
|
5
16
|
* Per-nudge fields win; otherwise {@link PlusMinusOptions}; otherwise `+` / `-`.
|
|
@@ -11,26 +22,68 @@ export declare function resolvePlusMinusTriggerKeysForNudge(nudge: Pick<PlusMinu
|
|
|
11
22
|
/** True when resolved increment and decrement would match the same key press. */
|
|
12
23
|
export declare function plusMinusResolvedKeysConflict(nudge: Pick<PlusMinusNudge, 'IncrementKey' | 'DecrementKey'>, globalOptions: Readonly<EditOptions['plusMinusOptions']> | undefined): boolean;
|
|
13
24
|
/**
|
|
14
|
-
* Match a pressed key against a configured trigger.
|
|
15
|
-
*
|
|
25
|
+
* Match a pressed key (with its modifier state) against a configured trigger.
|
|
26
|
+
* Single-character triggers (including the defaults `+` / `-`) are compared
|
|
27
|
+
* case-insensitively against the pressed key. Multi-character triggers are
|
|
28
|
+
* parsed as keyboard shortcut combinations (e.g. `shift+Enter`) and delegated
|
|
29
|
+
* to {@link eventMatchesKeyboardShortcut}.
|
|
16
30
|
*/
|
|
17
|
-
export declare function
|
|
31
|
+
export declare function plusMinusEventMatchesTrigger(event: PlusMinusKeyEvent, configuredKey: string): boolean;
|
|
18
32
|
/** Increment key from `AdaptableOptions.plusMinusOptions` only, then built-in `+`. */
|
|
19
33
|
export declare function plusMinusIncrementKeyFromOptionsOnly(globalOptions: Readonly<PlusMinusOptions> | undefined): string;
|
|
20
34
|
/** Decrement key from `AdaptableOptions.plusMinusOptions` only, then built-in `-`. */
|
|
21
35
|
export declare function plusMinusDecrementKeyFromOptionsOnly(globalOptions: Readonly<PlusMinusOptions> | undefined): string;
|
|
22
36
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
37
|
+
* Canonical, comparable form of a trigger so equivalent descriptors compare
|
|
38
|
+
* equal regardless of case or modifier ordering (e.g. `Shift+Enter` and
|
|
39
|
+
* `shift+enter` normalise to the same value). Single characters are lowercased.
|
|
40
|
+
*/
|
|
41
|
+
export declare function normalizePlusMinusTrigger(trigger: string | undefined): string;
|
|
42
|
+
/**
|
|
43
|
+
* True when `candidate` is the same trigger as `baseline` for “no nudge override
|
|
44
|
+
* to persist” (normalised comparison, see {@link normalizePlusMinusTrigger}).
|
|
25
45
|
*/
|
|
26
46
|
export declare function plusMinusTriggerSameAsBaseline(candidate: string, baseline: string): boolean;
|
|
47
|
+
/** Result of interpreting a key press inside a "record shortcut" UI. */
|
|
48
|
+
export type PlusMinusCaptureResult = {
|
|
49
|
+
kind: 'pending';
|
|
50
|
+
modifiers: string[];
|
|
51
|
+
} | {
|
|
52
|
+
kind: 'invalid';
|
|
53
|
+
reason: string;
|
|
54
|
+
} | {
|
|
55
|
+
kind: 'captured';
|
|
56
|
+
trigger: string;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Interpret a key press (from a "record shortcut" UI, à la VS Code) into a
|
|
60
|
+
* Plus/Minus trigger:
|
|
61
|
+
* - `pending`: only modifier keys are held so far (waiting for a real key).
|
|
62
|
+
* - `captured`: a complete, representable trigger — a single literal character
|
|
63
|
+
* (such as the default `+`), a named key (e.g. `Enter`), or a modifier
|
|
64
|
+
* combination (e.g. `shift+Enter`).
|
|
65
|
+
* - `invalid`: the press cannot be represented as a trigger (e.g. a `+`
|
|
66
|
+
* character combined with modifiers, since `+` is the glue between parts).
|
|
67
|
+
*/
|
|
68
|
+
export declare function capturePlusMinusTriggerFromEvent(event: PlusMinusKeyEvent): PlusMinusCaptureResult;
|
|
69
|
+
/** Human-friendly label for a single trigger token (a modifier or a key). */
|
|
70
|
+
export declare function plusMinusKeyLabel(token: string): string;
|
|
71
|
+
/**
|
|
72
|
+
* Split a stored trigger into human-friendly key tokens for kbd-style display
|
|
73
|
+
* (e.g. `shift+Enter` -> `['Shift', 'Enter']`, `+` -> `['+']`).
|
|
74
|
+
*/
|
|
75
|
+
export declare function plusMinusTriggerDisplayParts(trigger: string): string[];
|
|
27
76
|
/**
|
|
28
|
-
* Precomputed keys for fast keydown filtering
|
|
29
|
-
*
|
|
77
|
+
* Precomputed keys for fast keydown filtering. Stores the lowercased
|
|
78
|
+
* non-modifier key of each trigger (the default `+` / `-`, a literal single
|
|
79
|
+
* char, or the key part of a combination such as `enter` for `shift+Enter`),
|
|
80
|
+
* so a pressed `event.key` can be cheaply rejected before running nudge rules.
|
|
30
81
|
*/
|
|
31
82
|
export type PlusMinusTriggerKeyLookup = {
|
|
32
|
-
|
|
33
|
-
|
|
83
|
+
/** Lowercased non-modifier keys that could trigger a nudge. */
|
|
84
|
+
effectiveKeysLower: Set<string>;
|
|
85
|
+
/** True when a trigger uses the `*` wildcard, so any key could match. */
|
|
86
|
+
matchAnyKey: boolean;
|
|
34
87
|
};
|
|
35
88
|
/** Build a lookup of all increment/decrement keys across active nudges (resolved). */
|
|
36
89
|
export declare function buildPlusMinusTriggerKeyLookup(nudges: PlusMinusNudge[], globalOptions: Readonly<PlusMinusOptions> | undefined): PlusMinusTriggerKeyLookup;
|
|
@@ -1,5 +1,12 @@
|
|
|
1
|
+
import { eventMatchesKeyboardShortcut } from '@infinite-table/infinite-react';
|
|
1
2
|
const DEFAULT_INCREMENT_KEY = '+';
|
|
2
3
|
const DEFAULT_DECREMENT_KEY = '-';
|
|
4
|
+
const MODIFIER_TOKENS = new Set(['cmd', 'meta', 'ctrl', 'control', 'alt', 'shift']);
|
|
5
|
+
const MODIFIER_ALIASES = { control: 'ctrl', meta: 'cmd' };
|
|
6
|
+
const KEY_ALIASES = { esc: 'escape' };
|
|
7
|
+
function isPlusMinusCombination(trigger) {
|
|
8
|
+
return trigger.length > 1;
|
|
9
|
+
}
|
|
3
10
|
export function resolvePlusMinusTriggerKeysForNudge(nudge, globalOptions) {
|
|
4
11
|
const incrementKey = nudge.IncrementKey?.trim() || plusMinusIncrementKeyFromOptionsOnly(globalOptions);
|
|
5
12
|
const decrementKey = nudge.DecrementKey?.trim() || plusMinusDecrementKeyFromOptionsOnly(globalOptions);
|
|
@@ -7,25 +14,32 @@ export function resolvePlusMinusTriggerKeysForNudge(nudge, globalOptions) {
|
|
|
7
14
|
}
|
|
8
15
|
export function plusMinusResolvedKeysConflict(nudge, globalOptions) {
|
|
9
16
|
const { incrementKey, decrementKey } = resolvePlusMinusTriggerKeysForNudge(nudge, globalOptions);
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
return incrementKey.toLowerCase() === decrementKey.toLowerCase();
|
|
17
|
+
const normalizedIncrement = normalizePlusMinusTrigger(incrementKey);
|
|
18
|
+
const normalizedDecrement = normalizePlusMinusTrigger(decrementKey);
|
|
19
|
+
if (!normalizedIncrement || !normalizedDecrement) {
|
|
20
|
+
return false;
|
|
15
21
|
}
|
|
16
|
-
return
|
|
22
|
+
return normalizedIncrement === normalizedDecrement;
|
|
17
23
|
}
|
|
18
|
-
export function
|
|
19
|
-
|
|
24
|
+
export function plusMinusEventMatchesTrigger(event, configuredKey) {
|
|
25
|
+
const trigger = (configuredKey ?? '').trim();
|
|
26
|
+
if (!trigger) {
|
|
20
27
|
return false;
|
|
21
28
|
}
|
|
22
|
-
|
|
23
|
-
|
|
29
|
+
const pressedKey = event?.key;
|
|
30
|
+
if (!pressedKey) {
|
|
31
|
+
return false;
|
|
24
32
|
}
|
|
25
|
-
if (
|
|
26
|
-
return
|
|
33
|
+
if (!isPlusMinusCombination(trigger)) {
|
|
34
|
+
return pressedKey.length === 1 && pressedKey.toLowerCase() === trigger.toLowerCase();
|
|
27
35
|
}
|
|
28
|
-
return
|
|
36
|
+
return eventMatchesKeyboardShortcut({
|
|
37
|
+
key: pressedKey,
|
|
38
|
+
metaKey: !!event.metaKey,
|
|
39
|
+
altKey: !!event.altKey,
|
|
40
|
+
ctrlKey: !!event.ctrlKey,
|
|
41
|
+
shiftKey: !!event.shiftKey,
|
|
42
|
+
}, trigger);
|
|
29
43
|
}
|
|
30
44
|
export function plusMinusIncrementKeyFromOptionsOnly(globalOptions) {
|
|
31
45
|
return globalOptions?.incrementKey?.trim() || DEFAULT_INCREMENT_KEY;
|
|
@@ -33,24 +47,165 @@ export function plusMinusIncrementKeyFromOptionsOnly(globalOptions) {
|
|
|
33
47
|
export function plusMinusDecrementKeyFromOptionsOnly(globalOptions) {
|
|
34
48
|
return globalOptions?.decrementKey?.trim() || DEFAULT_DECREMENT_KEY;
|
|
35
49
|
}
|
|
50
|
+
export function normalizePlusMinusTrigger(trigger) {
|
|
51
|
+
const value = (trigger ?? '').trim();
|
|
52
|
+
if (!value) {
|
|
53
|
+
return '';
|
|
54
|
+
}
|
|
55
|
+
if (!isPlusMinusCombination(value)) {
|
|
56
|
+
return value.toLowerCase();
|
|
57
|
+
}
|
|
58
|
+
const parts = value
|
|
59
|
+
.split('+')
|
|
60
|
+
.map((part) => part.trim().toLowerCase())
|
|
61
|
+
.filter(Boolean);
|
|
62
|
+
const modifiers = [];
|
|
63
|
+
const keys = [];
|
|
64
|
+
for (const part of parts) {
|
|
65
|
+
if (MODIFIER_TOKENS.has(part)) {
|
|
66
|
+
modifiers.push(MODIFIER_ALIASES[part] ?? part);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
keys.push(KEY_ALIASES[part] ?? part);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
modifiers.sort();
|
|
73
|
+
return [...modifiers, ...keys].join('+');
|
|
74
|
+
}
|
|
36
75
|
export function plusMinusTriggerSameAsBaseline(candidate, baseline) {
|
|
37
|
-
return
|
|
76
|
+
return normalizePlusMinusTrigger(candidate) === normalizePlusMinusTrigger(baseline);
|
|
77
|
+
}
|
|
78
|
+
const MODIFIER_KEY_NAMES = new Set([
|
|
79
|
+
'Shift',
|
|
80
|
+
'Control',
|
|
81
|
+
'Alt',
|
|
82
|
+
'Meta',
|
|
83
|
+
'OS',
|
|
84
|
+
'AltGraph',
|
|
85
|
+
'CapsLock',
|
|
86
|
+
'NumLock',
|
|
87
|
+
'ScrollLock',
|
|
88
|
+
'Hyper',
|
|
89
|
+
'Super',
|
|
90
|
+
'Fn',
|
|
91
|
+
'FnLock',
|
|
92
|
+
'Dead',
|
|
93
|
+
]);
|
|
94
|
+
function activeModifierTokens(event) {
|
|
95
|
+
const tokens = [];
|
|
96
|
+
if (event.ctrlKey) {
|
|
97
|
+
tokens.push('ctrl');
|
|
98
|
+
}
|
|
99
|
+
if (event.altKey) {
|
|
100
|
+
tokens.push('alt');
|
|
101
|
+
}
|
|
102
|
+
if (event.metaKey) {
|
|
103
|
+
tokens.push('cmd');
|
|
104
|
+
}
|
|
105
|
+
if (event.shiftKey) {
|
|
106
|
+
tokens.push('shift');
|
|
107
|
+
}
|
|
108
|
+
return tokens;
|
|
109
|
+
}
|
|
110
|
+
export function capturePlusMinusTriggerFromEvent(event) {
|
|
111
|
+
const key = event?.key;
|
|
112
|
+
const modifiers = activeModifierTokens(event);
|
|
113
|
+
if (!key || MODIFIER_KEY_NAMES.has(key)) {
|
|
114
|
+
return { kind: 'pending', modifiers };
|
|
115
|
+
}
|
|
116
|
+
const isPrintable = key.length === 1;
|
|
117
|
+
const keyPart = isPrintable ? key.toLowerCase() : key;
|
|
118
|
+
if (!modifiers.length) {
|
|
119
|
+
return { kind: 'captured', trigger: keyPart };
|
|
120
|
+
}
|
|
121
|
+
const shiftOnly = modifiers.length === 1 && modifiers[0] === 'shift';
|
|
122
|
+
const isLetter = isPrintable && /^[a-z]$/.test(keyPart);
|
|
123
|
+
if (isPrintable && shiftOnly && !isLetter) {
|
|
124
|
+
return { kind: 'captured', trigger: keyPart };
|
|
125
|
+
}
|
|
126
|
+
if (keyPart.includes('+')) {
|
|
127
|
+
return { kind: 'invalid', reason: 'This key cannot be combined with modifiers.' };
|
|
128
|
+
}
|
|
129
|
+
return { kind: 'captured', trigger: [...modifiers, keyPart].join('+') };
|
|
130
|
+
}
|
|
131
|
+
const KEY_DISPLAY_LABELS = {
|
|
132
|
+
ctrl: 'Ctrl',
|
|
133
|
+
cmd: 'Cmd',
|
|
134
|
+
alt: 'Alt',
|
|
135
|
+
shift: 'Shift',
|
|
136
|
+
enter: 'Enter',
|
|
137
|
+
escape: 'Esc',
|
|
138
|
+
esc: 'Esc',
|
|
139
|
+
tab: 'Tab',
|
|
140
|
+
space: 'Space',
|
|
141
|
+
backspace: 'Backspace',
|
|
142
|
+
delete: 'Delete',
|
|
143
|
+
insert: 'Insert',
|
|
144
|
+
arrowup: '↑',
|
|
145
|
+
arrowdown: '↓',
|
|
146
|
+
arrowleft: '←',
|
|
147
|
+
arrowright: '→',
|
|
148
|
+
pageup: 'Page Up',
|
|
149
|
+
pagedown: 'Page Down',
|
|
150
|
+
home: 'Home',
|
|
151
|
+
end: 'End',
|
|
152
|
+
};
|
|
153
|
+
export function plusMinusKeyLabel(token) {
|
|
154
|
+
const value = (token ?? '').trim();
|
|
155
|
+
if (!value) {
|
|
156
|
+
return '';
|
|
157
|
+
}
|
|
158
|
+
const lower = value.toLowerCase();
|
|
159
|
+
if (KEY_DISPLAY_LABELS[lower]) {
|
|
160
|
+
return KEY_DISPLAY_LABELS[lower];
|
|
161
|
+
}
|
|
162
|
+
if (value.length === 1) {
|
|
163
|
+
return value;
|
|
164
|
+
}
|
|
165
|
+
return value.charAt(0).toUpperCase() + value.slice(1);
|
|
166
|
+
}
|
|
167
|
+
export function plusMinusTriggerDisplayParts(trigger) {
|
|
168
|
+
const value = (trigger ?? '').trim();
|
|
169
|
+
if (!value) {
|
|
170
|
+
return [];
|
|
171
|
+
}
|
|
172
|
+
if (!isPlusMinusCombination(value)) {
|
|
173
|
+
return [plusMinusKeyLabel(value)];
|
|
174
|
+
}
|
|
175
|
+
return value
|
|
176
|
+
.split('+')
|
|
177
|
+
.map((part) => part.trim())
|
|
178
|
+
.filter(Boolean)
|
|
179
|
+
.map(plusMinusKeyLabel);
|
|
38
180
|
}
|
|
39
181
|
function addConfiguredKeyToLookup(lookup, configuredKey) {
|
|
40
|
-
|
|
182
|
+
const trigger = (configuredKey ?? '').trim();
|
|
183
|
+
if (!trigger) {
|
|
41
184
|
return;
|
|
42
185
|
}
|
|
43
|
-
if (
|
|
44
|
-
lookup.
|
|
186
|
+
if (!isPlusMinusCombination(trigger)) {
|
|
187
|
+
lookup.effectiveKeysLower.add(trigger.toLowerCase());
|
|
188
|
+
return;
|
|
45
189
|
}
|
|
46
|
-
|
|
47
|
-
|
|
190
|
+
const parts = trigger
|
|
191
|
+
.split('+')
|
|
192
|
+
.map((part) => part.trim().toLowerCase())
|
|
193
|
+
.filter(Boolean);
|
|
194
|
+
for (const part of parts) {
|
|
195
|
+
if (MODIFIER_TOKENS.has(part)) {
|
|
196
|
+
continue;
|
|
197
|
+
}
|
|
198
|
+
if (part === '*') {
|
|
199
|
+
lookup.matchAnyKey = true;
|
|
200
|
+
continue;
|
|
201
|
+
}
|
|
202
|
+
lookup.effectiveKeysLower.add(KEY_ALIASES[part] ?? part);
|
|
48
203
|
}
|
|
49
204
|
}
|
|
50
205
|
export function buildPlusMinusTriggerKeyLookup(nudges, globalOptions) {
|
|
51
206
|
const lookup = {
|
|
52
|
-
|
|
53
|
-
|
|
207
|
+
effectiveKeysLower: new Set(),
|
|
208
|
+
matchAnyKey: false,
|
|
54
209
|
};
|
|
55
210
|
for (const nudge of nudges) {
|
|
56
211
|
const { incrementKey, decrementKey } = resolvePlusMinusTriggerKeysForNudge(nudge, globalOptions);
|
|
@@ -60,11 +215,11 @@ export function buildPlusMinusTriggerKeyLookup(nudges, globalOptions) {
|
|
|
60
215
|
return lookup;
|
|
61
216
|
}
|
|
62
217
|
export function plusMinusKeyCouldTrigger(keyEventString, lookup) {
|
|
218
|
+
if (lookup.matchAnyKey) {
|
|
219
|
+
return true;
|
|
220
|
+
}
|
|
63
221
|
if (!keyEventString) {
|
|
64
222
|
return false;
|
|
65
223
|
}
|
|
66
|
-
|
|
67
|
-
return lookup.singleCharLower.has(keyEventString.toLowerCase());
|
|
68
|
-
}
|
|
69
|
-
return lookup.exactKeys.has(keyEventString);
|
|
224
|
+
return lookup.effectiveKeysLower.has(keyEventString.toLowerCase());
|
|
70
225
|
}
|
|
@@ -16,9 +16,9 @@ import { Box } from '../../../../components/Flex';
|
|
|
16
16
|
export const AdaptablePopup = (props) => {
|
|
17
17
|
const adaptable = useAdaptable();
|
|
18
18
|
const settingsPanelOptions = adaptable.adaptableOptions.settingsPanelOptions;
|
|
19
|
+
const wizardOptions = adaptable.adaptableOptions.wizardOptions;
|
|
19
20
|
const settingsPanelTitle = adaptable.ModuleService.getModuleFriendlyName('SettingsPanel');
|
|
20
21
|
const menuItems = useMenuItems();
|
|
21
|
-
const isWindowModal = settingsPanelOptions.popupType === 'window';
|
|
22
22
|
const modalContainer = resolveContainerElement(adaptable.adaptableOptions?.containerOptions?.modalContainer, props.api.internalApi.buildBaseContext());
|
|
23
23
|
let friendlyName = null;
|
|
24
24
|
let isStandalone = false;
|
|
@@ -54,6 +54,10 @@ export const AdaptablePopup = (props) => {
|
|
|
54
54
|
activeItem = moduleInfo.ModuleName;
|
|
55
55
|
moduleViewContent = (_jsx(AdaptablePopupBody, { api: props.api, module: module, componentName: props.componentName, moduleParams: props.moduleParams, onClearParams: props.onClearParams, onHide: props.onHide }));
|
|
56
56
|
}
|
|
57
|
+
const effectivePopupType = isStandalone
|
|
58
|
+
? wizardOptions?.popupType ?? settingsPanelOptions.popupType
|
|
59
|
+
: settingsPanelOptions.popupType;
|
|
60
|
+
const isWindowModal = effectivePopupType === 'window';
|
|
57
61
|
const baseClassName = 'ab-Adaptable-Popup';
|
|
58
62
|
const className = join(baseClassName, `${baseClassName}--${isWindowModal ? 'window' : 'modal'}`, isStandalone ? `${baseClassName}--action-popup` : `${baseClassName}--settings-popup`);
|
|
59
63
|
return (_jsx(PopupContext.Provider, { value: {
|
|
@@ -11,17 +11,21 @@ const WindowDialog = (props) => {
|
|
|
11
11
|
const adaptable = useAdaptable();
|
|
12
12
|
const dispatch = useDispatch();
|
|
13
13
|
const settingsPanelOptions = adaptable.adaptableOptions.settingsPanelOptions;
|
|
14
|
+
const wizardOptions = adaptable.adaptableOptions.wizardOptions;
|
|
14
15
|
let popupSettings = useSelector((state) => state?.Internal?.SettingsPanel?.[settingsPanelOptionsKey]);
|
|
15
16
|
const handleWindowSettings = (settings) => {
|
|
16
17
|
dispatch(SettingsPanelSet(settingsPanelOptionsKey, settings));
|
|
17
18
|
};
|
|
18
19
|
if (!popupSettings) {
|
|
19
20
|
const size = isActionModule
|
|
20
|
-
? getActionPanelSize()
|
|
21
|
+
? wizardOptions?.size ?? getActionPanelSize()
|
|
21
22
|
: settingsPanelOptions.size ?? getSettingsPanelSize();
|
|
23
|
+
const position = isActionModule
|
|
24
|
+
? wizardOptions?.position ?? getMiddlePosition(size)
|
|
25
|
+
: settingsPanelOptions.position ?? getMiddlePosition(size);
|
|
22
26
|
popupSettings = {
|
|
23
|
-
size
|
|
24
|
-
position
|
|
27
|
+
size,
|
|
28
|
+
position,
|
|
25
29
|
};
|
|
26
30
|
}
|
|
27
31
|
const windowModalProps = {
|
|
@@ -13,6 +13,17 @@ export declare const getSettingsPanelSize: () => {
|
|
|
13
13
|
height: number;
|
|
14
14
|
width: number;
|
|
15
15
|
};
|
|
16
|
+
/**
|
|
17
|
+
* Default size for the One Page Wizard when it renders as a window (i.e.
|
|
18
|
+
* `wizardOptions.popupType === 'window'` and the user has not provided an
|
|
19
|
+
* explicit `wizardOptions.size`). Mirrors the historical modal sizing of
|
|
20
|
+
* 90vh tall and 90vw wide, capped at 1200px wide so the wizard stays
|
|
21
|
+
* readable on very large monitors.
|
|
22
|
+
*/
|
|
23
|
+
export declare const getWizardSize: () => {
|
|
24
|
+
height: number;
|
|
25
|
+
width: number;
|
|
26
|
+
};
|
|
16
27
|
export declare const getWindowPopupSize: () => {
|
|
17
28
|
height: number;
|
|
18
29
|
width: number;
|
|
@@ -23,6 +23,14 @@ export const getSettingsPanelSize = () => {
|
|
|
23
23
|
width: clamp(width * 0.9, 0, 800),
|
|
24
24
|
};
|
|
25
25
|
};
|
|
26
|
+
export const getWizardSize = () => {
|
|
27
|
+
const height = window.innerHeight;
|
|
28
|
+
const width = window.innerWidth;
|
|
29
|
+
return {
|
|
30
|
+
height: height * 0.9,
|
|
31
|
+
width: clamp(width * 0.9, 0, 1200),
|
|
32
|
+
};
|
|
33
|
+
};
|
|
26
34
|
export const getWindowPopupSize = () => {
|
|
27
35
|
return getSettingsPanelSize();
|
|
28
36
|
};
|
|
@@ -21,10 +21,9 @@ export const DataChangeHistoryViewPanelControl = (props) => {
|
|
|
21
21
|
const handleOpenPopup = React.useCallback(() => {
|
|
22
22
|
adaptable.api.settingsPanelApi.openSettingsPanel('DataChangeHistory');
|
|
23
23
|
}, []);
|
|
24
|
-
const
|
|
25
|
-
const
|
|
26
|
-
const
|
|
27
|
-
const suspensionTime = dataChangeHistoryState.suspendTime;
|
|
24
|
+
const changeHistoryMode = useSelector((state) => state.Internal.DataChangeHistory.currentMode);
|
|
25
|
+
const activationTime = useSelector((state) => state.Internal.DataChangeHistory.enableTime);
|
|
26
|
+
const suspensionTime = useSelector((state) => state.Internal.DataChangeHistory.suspendTime);
|
|
28
27
|
const enabled = changeHistoryMode === 'ACTIVE';
|
|
29
28
|
const disabled = changeHistoryMode === 'INACTIVE';
|
|
30
29
|
const suspended = changeHistoryMode === 'SUSPENDED';
|
|
@@ -21,7 +21,7 @@ export const mapChangeHistoryRowData = (changeHistoryLog = {}, mainAdaptableInst
|
|
|
21
21
|
changedColumnLabel: getColumnHeaderLabel(changeInfo.column.columnId, mainAdaptableInstance),
|
|
22
22
|
changeInfo,
|
|
23
23
|
}))
|
|
24
|
-
.
|
|
24
|
+
.reverse();
|
|
25
25
|
};
|
|
26
26
|
export const getChangeHistoryRowChangeInfo = (rowData) => {
|
|
27
27
|
if (!isValidChangeHistoryLogEntry(rowData?.changeInfo)) {
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
export interface KeyComboCaptureInputProps {
|
|
3
|
+
/** Resolved trigger to display when not recording (e.g. `+` or `shift+Enter`). */
|
|
4
|
+
value: string;
|
|
5
|
+
/** When true, `value` comes from the default/global setting (shown as a hint). */
|
|
6
|
+
isUsingDefault?: boolean;
|
|
7
|
+
/** Hint shown when there is no value and the field is not recording. */
|
|
8
|
+
placeholder?: string;
|
|
9
|
+
disabled?: boolean;
|
|
10
|
+
'data-name'?: string;
|
|
11
|
+
/** Called with a complete, valid trigger once the user records one. */
|
|
12
|
+
onCapture: (trigger: string) => void;
|
|
13
|
+
/** Reset back to the default/global trigger (clears the per-nudge override). */
|
|
14
|
+
onReset?: () => void;
|
|
15
|
+
/**
|
|
16
|
+
* Optional validation run on a captured trigger before committing.
|
|
17
|
+
* Return an error message to reject the capture (e.g. increment/decrement clash).
|
|
18
|
+
*/
|
|
19
|
+
validateCapture?: (trigger: string) => string | undefined;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* VS Code-style keyboard shortcut recorder. While focused the field shows the
|
|
23
|
+
* current value and a "Hit Enter to edit" hint; pressing Enter enters edit mode
|
|
24
|
+
* (the value is cleared) where the next key press / combination is detected from
|
|
25
|
+
* the event. A valid press is persisted and edit mode ends; incomplete
|
|
26
|
+
* (modifier-only) and unrepresentable presses are rejected, and an optional
|
|
27
|
+
* `validateCapture` guards against clashes. The revert button restores the
|
|
28
|
+
* default once a custom value has been set.
|
|
29
|
+
*/
|
|
30
|
+
export declare const KeyComboCaptureInput: React.FunctionComponent<KeyComboCaptureInputProps>;
|