@finos/legend-application 9.0.1 → 10.0.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/lib/application/LegendApplication.d.ts.map +1 -1
- package/lib/application/LegendApplication.js +7 -0
- package/lib/application/LegendApplication.js.map +1 -1
- package/lib/components/ActionAlert.d.ts.map +1 -1
- package/lib/components/ActionAlert.js +4 -5
- package/lib/components/ActionAlert.js.map +1 -1
- package/lib/components/LegendApplicationComponentFrameworkProvider.d.ts +10 -0
- package/lib/components/LegendApplicationComponentFrameworkProvider.d.ts.map +1 -1
- package/lib/components/LegendApplicationComponentFrameworkProvider.js +53 -2
- package/lib/components/LegendApplicationComponentFrameworkProvider.js.map +1 -1
- package/lib/components/VirtualAssistant.js +3 -4
- package/lib/components/VirtualAssistant.js.map +1 -1
- package/lib/components/execution-plan-viewer/ExecutionPlanViewer.d.ts.map +1 -1
- package/lib/components/execution-plan-viewer/ExecutionPlanViewer.js +2 -2
- package/lib/components/execution-plan-viewer/ExecutionPlanViewer.js.map +1 -1
- package/lib/components/shared/TextInputEditor.d.ts +5 -5
- package/lib/components/shared/TextInputEditor.d.ts.map +1 -1
- package/lib/components/shared/TextInputEditor.js +17 -16
- package/lib/components/shared/TextInputEditor.js.map +1 -1
- package/lib/components/{ApplicationNavigationContextServiceUtils.d.ts → useApplicationNavigationContext.d.ts} +1 -1
- package/lib/components/useApplicationNavigationContext.d.ts.map +1 -0
- package/lib/components/{ApplicationNavigationContextServiceUtils.js → useApplicationNavigationContext.js} +1 -1
- package/lib/components/useApplicationNavigationContext.js.map +1 -0
- package/lib/components/useCommands.d.ts +18 -0
- package/lib/components/useCommands.d.ts.map +1 -0
- package/lib/components/useCommands.js +23 -0
- package/lib/components/useCommands.js.map +1 -0
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/index.d.ts +3 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +3 -1
- package/lib/index.js.map +1 -1
- package/lib/stores/ApplicationEvent.d.ts +2 -0
- package/lib/stores/ApplicationEvent.d.ts.map +1 -1
- package/lib/stores/ApplicationEvent.js +2 -0
- package/lib/stores/ApplicationEvent.js.map +1 -1
- package/lib/stores/ApplicationStore.d.ts +11 -0
- package/lib/stores/ApplicationStore.d.ts.map +1 -1
- package/lib/stores/ApplicationStore.js +33 -1
- package/lib/stores/ApplicationStore.js.map +1 -1
- package/lib/stores/CommandCenter.d.ts +45 -0
- package/lib/stores/CommandCenter.d.ts.map +1 -0
- package/lib/stores/CommandCenter.js +54 -0
- package/lib/stores/CommandCenter.js.map +1 -0
- package/lib/stores/DocumentationService.d.ts +3 -3
- package/lib/stores/DocumentationService.d.ts.map +1 -1
- package/lib/stores/DocumentationService.js.map +1 -1
- package/lib/stores/KeyboardShortcutsService.d.ts +55 -0
- package/lib/stores/KeyboardShortcutsService.d.ts.map +1 -0
- package/lib/stores/KeyboardShortcutsService.js +113 -0
- package/lib/stores/KeyboardShortcutsService.js.map +1 -0
- package/lib/stores/LegendApplicationPlugin.d.ts +5 -0
- package/lib/stores/LegendApplicationPlugin.d.ts.map +1 -1
- package/lib/stores/LegendApplicationPlugin.js.map +1 -1
- package/lib/stores/PureLanguageSupport.d.ts.map +1 -1
- package/lib/stores/PureLanguageSupport.js +10 -1
- package/lib/stores/PureLanguageSupport.js.map +1 -1
- package/lib/stores/WebApplicationNavigator.d.ts +37 -26
- package/lib/stores/WebApplicationNavigator.d.ts.map +1 -1
- package/lib/stores/WebApplicationNavigator.js +58 -32
- package/lib/stores/WebApplicationNavigator.js.map +1 -1
- package/lib/stores/WebApplicationRouter.d.ts +1 -1
- package/lib/stores/WebApplicationRouter.d.ts.map +1 -1
- package/lib/stores/WebApplicationRouter.js +1 -1
- package/lib/stores/WebApplicationRouter.js.map +1 -1
- package/package.json +10 -10
- package/src/application/LegendApplication.tsx +8 -0
- package/src/components/ActionAlert.tsx +4 -5
- package/src/components/LegendApplicationComponentFrameworkProvider.tsx +88 -3
- package/src/components/VirtualAssistant.tsx +3 -3
- package/src/components/execution-plan-viewer/ExecutionPlanViewer.tsx +5 -9
- package/src/components/shared/TextInputEditor.tsx +14 -21
- package/src/components/{ApplicationNavigationContextServiceUtils.tsx → useApplicationNavigationContext.tsx} +0 -0
- package/src/components/useCommands.tsx +25 -0
- package/src/index.ts +3 -1
- package/src/stores/ApplicationEvent.ts +3 -0
- package/src/stores/ApplicationStore.ts +34 -1
- package/src/stores/CommandCenter.ts +89 -0
- package/src/stores/DocumentationService.ts +3 -3
- package/src/stores/KeyboardShortcutsService.ts +142 -0
- package/src/stores/LegendApplicationPlugin.ts +6 -0
- package/src/stores/PureLanguageSupport.ts +10 -0
- package/src/stores/WebApplicationNavigator.ts +102 -62
- package/src/stores/WebApplicationRouter.ts +1 -0
- package/tsconfig.json +4 -1
- package/lib/components/ApplicationNavigationContextServiceUtils.d.ts.map +0 -1
- package/lib/components/ApplicationNavigationContextServiceUtils.js.map +0 -1
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright (c) 2020-present, Goldman Sachs
|
|
3
|
+
*
|
|
4
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
* you may not use this file except in compliance with the License.
|
|
6
|
+
* You may obtain a copy of the License at
|
|
7
|
+
*
|
|
8
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
*
|
|
10
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
* See the License for the specific language governing permissions and
|
|
14
|
+
* limitations under the License.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
import { addUniqueEntry, LogEvent } from '@finos/legend-shared';
|
|
18
|
+
import { action, makeObservable, observable } from 'mobx';
|
|
19
|
+
import { APPLICATION_EVENT } from './ApplicationEvent.js';
|
|
20
|
+
import type { GenericLegendApplicationStore } from './ApplicationStore.js';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* List of keyboard named key
|
|
24
|
+
* See https://www.w3.org/TR/uievents-key/#named-key-attribute-values
|
|
25
|
+
* See https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values
|
|
26
|
+
*/
|
|
27
|
+
export enum KEYBOARD_NAMED_KEY {
|
|
28
|
+
TAB = 'Tab',
|
|
29
|
+
|
|
30
|
+
CAPSLOCK = 'CapsLock',
|
|
31
|
+
|
|
32
|
+
SHIFT = 'Shift',
|
|
33
|
+
META = 'Meta',
|
|
34
|
+
ALT = 'Alt',
|
|
35
|
+
CTRL = 'Control',
|
|
36
|
+
|
|
37
|
+
SPACE = 'Space',
|
|
38
|
+
|
|
39
|
+
ESC = 'Escape',
|
|
40
|
+
|
|
41
|
+
LEFT = 'ArrowLeft',
|
|
42
|
+
RIGHT = 'ArrowRight',
|
|
43
|
+
UP = 'ArrowUp',
|
|
44
|
+
DOWN = 'ArrowDown',
|
|
45
|
+
|
|
46
|
+
ENTER = 'Enter',
|
|
47
|
+
DELETE = 'Delete',
|
|
48
|
+
BACKSPACE = 'Backspace',
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export class KeyboardShortcutsService {
|
|
52
|
+
readonly applicationStore: GenericLegendApplicationStore;
|
|
53
|
+
readonly keyMap = new Map<string, string[]>();
|
|
54
|
+
/**
|
|
55
|
+
* NOTE: we want to leave the value of the map as optional because we want
|
|
56
|
+
* to use this map to quickly construct the key-binding view: some commands
|
|
57
|
+
* don't already have a hotkey
|
|
58
|
+
*/
|
|
59
|
+
readonly commandKeyMap = new Map<string, string | undefined>();
|
|
60
|
+
isHotkeysBlocked = false;
|
|
61
|
+
|
|
62
|
+
constructor(applicationStore: GenericLegendApplicationStore) {
|
|
63
|
+
makeObservable(this, {
|
|
64
|
+
keyMap: observable,
|
|
65
|
+
commandKeyMap: observable,
|
|
66
|
+
isHotkeysBlocked: observable,
|
|
67
|
+
updateHotkey: action,
|
|
68
|
+
blockGlobalHotkeys: action,
|
|
69
|
+
unblockGlobalHotkeys: action,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
this.applicationStore = applicationStore;
|
|
73
|
+
const commandsWithMultipleKeyBindings: string[] = [];
|
|
74
|
+
this.applicationStore.pluginManager
|
|
75
|
+
.getApplicationPlugins()
|
|
76
|
+
.flatMap((plugin) => plugin.getExtraKeyedCommandConfigEntries?.() ?? [])
|
|
77
|
+
.forEach((entry) => {
|
|
78
|
+
if (
|
|
79
|
+
entry.content.defaultKeyboardShortcut &&
|
|
80
|
+
this.commandKeyMap.get(entry.key)
|
|
81
|
+
) {
|
|
82
|
+
addUniqueEntry(commandsWithMultipleKeyBindings, entry.key);
|
|
83
|
+
}
|
|
84
|
+
this.updateHotkey(entry.key, entry.content.defaultKeyboardShortcut);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
if (commandsWithMultipleKeyBindings.length) {
|
|
88
|
+
this.applicationStore.log.warn(
|
|
89
|
+
LogEvent.create(
|
|
90
|
+
APPLICATION_EVENT.APPLICATION_KEYBOARD_SHORTCUTS_CONFIGURATION_CHECK_FAILURE,
|
|
91
|
+
),
|
|
92
|
+
`Found multiple key bindings in configuration for commands:\n${commandsWithMultipleKeyBindings
|
|
93
|
+
.map((key) => `- ${key}`)
|
|
94
|
+
.join('\n')}`,
|
|
95
|
+
);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
blockGlobalHotkeys(): void {
|
|
100
|
+
this.isHotkeysBlocked = true;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
unblockGlobalHotkeys(): void {
|
|
104
|
+
this.isHotkeysBlocked = false;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
updateHotkey(commandKey: string, keyCombination: string | undefined): void {
|
|
108
|
+
const currentKeyCombination = this.commandKeyMap.get(commandKey);
|
|
109
|
+
this.commandKeyMap.set(commandKey, keyCombination);
|
|
110
|
+
// remove old key map
|
|
111
|
+
if (currentKeyCombination) {
|
|
112
|
+
this.keyMap.set(
|
|
113
|
+
currentKeyCombination,
|
|
114
|
+
(this.keyMap.get(currentKeyCombination) ?? []).filter(
|
|
115
|
+
(key) => key === commandKey,
|
|
116
|
+
),
|
|
117
|
+
);
|
|
118
|
+
}
|
|
119
|
+
// add new key map
|
|
120
|
+
if (keyCombination) {
|
|
121
|
+
this.keyMap.set(keyCombination, [
|
|
122
|
+
...(this.keyMap.get(keyCombination) ?? []).filter(
|
|
123
|
+
(key) => key !== commandKey,
|
|
124
|
+
),
|
|
125
|
+
commandKey,
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
dispatch(keyCombination: string): void {
|
|
131
|
+
if (this.isHotkeysBlocked) {
|
|
132
|
+
return;
|
|
133
|
+
}
|
|
134
|
+
const mappedCommandKeys = this.keyMap.get(keyCombination) ?? [];
|
|
135
|
+
for (const commandKey of mappedCommandKeys) {
|
|
136
|
+
// find the first command that works then escape
|
|
137
|
+
if (this.applicationStore.commandCenter.runCommand(commandKey)) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
|
|
17
17
|
import { AbstractPlugin } from '@finos/legend-shared';
|
|
18
18
|
import type { LegendApplicationPluginManager } from '../application/LegendApplicationPluginManager.js';
|
|
19
|
+
import type { KeyedCommandConfigEntry } from './CommandCenter.js';
|
|
19
20
|
import type {
|
|
20
21
|
ContextualDocumentationEntry,
|
|
21
22
|
DocumentationRegistryEntry,
|
|
@@ -52,6 +53,11 @@ export abstract class LegendApplicationPlugin extends AbstractPlugin {
|
|
|
52
53
|
*/
|
|
53
54
|
getExtraApplicationPageEntries?(): ApplicationPageEntry[];
|
|
54
55
|
|
|
56
|
+
/**
|
|
57
|
+
* Get the list of keyed command config entries to be registered with command center.
|
|
58
|
+
*/
|
|
59
|
+
getExtraKeyedCommandConfigEntries?(): KeyedCommandConfigEntry[];
|
|
60
|
+
|
|
55
61
|
/**
|
|
56
62
|
* Get the list of documentation registry entries from which the application can fetch
|
|
57
63
|
* documentation config data and load the documentation registry
|
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
} from '@finos/legend-graph';
|
|
25
25
|
import {
|
|
26
26
|
editor as monacoEditorAPI,
|
|
27
|
+
KeyCode,
|
|
27
28
|
languages as monacoLanguagesAPI,
|
|
28
29
|
} from 'monaco-editor';
|
|
29
30
|
import { EDITOR_LANGUAGE, EDITOR_THEME } from '../const.js';
|
|
@@ -357,6 +358,15 @@ export const setupPureLanguageService = (
|
|
|
357
358
|
): void => {
|
|
358
359
|
// register Pure language in `monaco-editor`
|
|
359
360
|
monacoEditorAPI.defineTheme(EDITOR_THEME.LEGEND, theme);
|
|
361
|
+
// Override `monaco-editor` native hotkeys
|
|
362
|
+
// See https://github.com/microsoft/monaco-editor/issues/102#issuecomment-1282897640
|
|
363
|
+
monacoEditorAPI.addKeybindingRules([
|
|
364
|
+
{
|
|
365
|
+
// disable show error command
|
|
366
|
+
keybinding: KeyCode.F8,
|
|
367
|
+
command: null,
|
|
368
|
+
},
|
|
369
|
+
]);
|
|
360
370
|
monacoLanguagesAPI.register({ id: EDITOR_LANGUAGE.PURE });
|
|
361
371
|
monacoLanguagesAPI.setLanguageConfiguration(
|
|
362
372
|
EDITOR_LANGUAGE.PURE,
|
|
@@ -38,56 +38,67 @@ type Address = string;
|
|
|
38
38
|
*/
|
|
39
39
|
interface ApplicationNavigator {
|
|
40
40
|
/**
|
|
41
|
-
*
|
|
41
|
+
* Reload the application using the same address
|
|
42
42
|
*/
|
|
43
|
-
|
|
43
|
+
reload(): void;
|
|
44
44
|
|
|
45
45
|
/**
|
|
46
|
-
* Navigate to the specified location
|
|
46
|
+
* Navigate to the specified location
|
|
47
|
+
*
|
|
48
|
+
* NOTE: this will reload the application
|
|
49
|
+
* so application states will not be preserved
|
|
50
|
+
* after navigation
|
|
47
51
|
*/
|
|
48
|
-
|
|
52
|
+
goToLocation(
|
|
49
53
|
location: Location,
|
|
50
54
|
options?: { ignoreBlocking?: boolean | undefined },
|
|
51
55
|
): void;
|
|
52
56
|
|
|
53
|
-
/**
|
|
54
|
-
* Reload the application using the same address
|
|
55
|
-
*/
|
|
56
|
-
reload(): void;
|
|
57
|
-
|
|
58
57
|
/**
|
|
59
58
|
* Visit the specified address
|
|
60
|
-
*
|
|
61
|
-
* NOTE: unless specified, the visit will be done in a new window
|
|
62
59
|
*/
|
|
63
|
-
|
|
60
|
+
goToAddress(
|
|
64
61
|
address: Address,
|
|
65
|
-
options?: {
|
|
66
|
-
useSameWindow?: boolean | undefined;
|
|
67
|
-
},
|
|
62
|
+
options?: { ignoreBlocking?: boolean | undefined },
|
|
68
63
|
): void;
|
|
69
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Visit the specified address in a new window
|
|
67
|
+
*/
|
|
68
|
+
visitAddress(address: Address): void;
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* Update the current location
|
|
72
|
+
*
|
|
73
|
+
* NOTE: any navigation actions: reload, go to address, go to location, etc.
|
|
74
|
+
* explicitly updates the current location, this action will just update the
|
|
75
|
+
* location without doing any navigation
|
|
76
|
+
*/
|
|
77
|
+
updateCurrentLocation(location: Location): void;
|
|
70
78
|
getCurrentAddress(): Address;
|
|
71
79
|
getCurrentLocation(): Location;
|
|
72
80
|
generateAddress(location: Location): Address;
|
|
73
81
|
|
|
74
82
|
/**
|
|
75
|
-
*
|
|
76
|
-
*
|
|
77
|
-
*
|
|
83
|
+
* Block all kinds of navigation, including going to another location,
|
|
84
|
+
* changing address, and native platform navigation (e.g. in web browser, we will
|
|
85
|
+
* block back/forward buttons), etc.
|
|
78
86
|
*/
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
87
|
+
blockNavigation(
|
|
88
|
+
blockCheckers: (() => boolean)[],
|
|
89
|
+
onBlock?: ((onProceed: () => void) => void) | undefined,
|
|
90
|
+
): void;
|
|
91
|
+
unblockNavigation(): void;
|
|
92
|
+
get isNavigationBlocked(): boolean;
|
|
82
93
|
}
|
|
83
94
|
|
|
84
95
|
export class WebApplicationNavigator implements ApplicationNavigator {
|
|
85
96
|
private readonly historyAPI: History;
|
|
86
|
-
private
|
|
87
|
-
private
|
|
97
|
+
private _isNavigationBlocked = false;
|
|
98
|
+
private _forceBypassNavigationBlocking = false;
|
|
88
99
|
private _blockCheckers: (() => boolean)[] = [];
|
|
89
100
|
private _beforeUnloadListener = (event: BeforeUnloadEvent): void => {
|
|
90
|
-
if (this.
|
|
101
|
+
if (this._forceBypassNavigationBlocking) {
|
|
91
102
|
return;
|
|
92
103
|
}
|
|
93
104
|
if (this._blockCheckers.some((checker) => checker())) {
|
|
@@ -97,18 +108,15 @@ export class WebApplicationNavigator implements ApplicationNavigator {
|
|
|
97
108
|
}
|
|
98
109
|
};
|
|
99
110
|
|
|
100
|
-
|
|
111
|
+
onBlock?: ((onProceed: () => void) => void) | undefined;
|
|
101
112
|
|
|
102
113
|
constructor(historyApiClient: History) {
|
|
103
|
-
makeObservable<WebApplicationNavigator, '
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
unblockPlatformNavigation: action,
|
|
110
|
-
},
|
|
111
|
-
);
|
|
114
|
+
makeObservable<WebApplicationNavigator, '_isNavigationBlocked'>(this, {
|
|
115
|
+
_isNavigationBlocked: observable,
|
|
116
|
+
isNavigationBlocked: computed,
|
|
117
|
+
blockNavigation: action,
|
|
118
|
+
unblockNavigation: action,
|
|
119
|
+
});
|
|
112
120
|
|
|
113
121
|
this.historyAPI = historyApiClient;
|
|
114
122
|
}
|
|
@@ -120,47 +128,74 @@ export class WebApplicationNavigator implements ApplicationNavigator {
|
|
|
120
128
|
);
|
|
121
129
|
}
|
|
122
130
|
|
|
123
|
-
goToLocation(
|
|
124
|
-
this.historyAPI.push(location);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
reloadToLocation(
|
|
131
|
+
goToLocation(
|
|
128
132
|
location: Location,
|
|
129
133
|
options?: { ignoreBlocking?: boolean | undefined },
|
|
130
134
|
): void {
|
|
131
135
|
if (options?.ignoreBlocking) {
|
|
132
|
-
this.
|
|
136
|
+
this._forceBypassNavigationBlocking = true;
|
|
137
|
+
}
|
|
138
|
+
const onProceed = (): void => {
|
|
139
|
+
this._forceBypassNavigationBlocking = true; // make sure to not trigger `BeforeUnloadEvent`
|
|
140
|
+
this.window.location.href = this.generateAddress(location);
|
|
141
|
+
};
|
|
142
|
+
if (
|
|
143
|
+
!this._forceBypassNavigationBlocking &&
|
|
144
|
+
this._blockCheckers.some((checker) => checker())
|
|
145
|
+
) {
|
|
146
|
+
this.onBlock?.(onProceed);
|
|
147
|
+
} else {
|
|
148
|
+
onProceed();
|
|
133
149
|
}
|
|
134
|
-
// if (
|
|
135
|
-
// this._isPlatformNavigationBlocked &&
|
|
136
|
-
// !this._forceBypassPlatformNavigationBlocking
|
|
137
|
-
// ) {
|
|
138
|
-
// this.notifier
|
|
139
|
-
// return;
|
|
140
|
-
// }
|
|
141
|
-
this.window.location.href = this.generateAddress(location);
|
|
142
150
|
}
|
|
143
151
|
|
|
144
152
|
reload(options?: { ignoreBlocking?: boolean | undefined }): void {
|
|
145
153
|
if (options?.ignoreBlocking) {
|
|
146
|
-
this.
|
|
154
|
+
this._forceBypassNavigationBlocking = true;
|
|
155
|
+
}
|
|
156
|
+
const onProceed = (): void => {
|
|
157
|
+
this._forceBypassNavigationBlocking = true; // make sure to not trigger `BeforeUnloadEvent`
|
|
158
|
+
this.window.location.reload();
|
|
159
|
+
};
|
|
160
|
+
if (
|
|
161
|
+
!this._forceBypassNavigationBlocking &&
|
|
162
|
+
this._blockCheckers.some((checker) => checker())
|
|
163
|
+
) {
|
|
164
|
+
this.onBlock?.(onProceed);
|
|
165
|
+
} else {
|
|
166
|
+
onProceed();
|
|
147
167
|
}
|
|
148
|
-
this.window.location.reload();
|
|
149
168
|
}
|
|
150
169
|
|
|
151
|
-
|
|
170
|
+
goToAddress(
|
|
152
171
|
address: Address,
|
|
153
|
-
options?: {
|
|
154
|
-
useSameWindow?: boolean | undefined;
|
|
155
|
-
},
|
|
172
|
+
options?: { ignoreBlocking?: boolean | undefined },
|
|
156
173
|
): void {
|
|
157
|
-
if (options?.
|
|
174
|
+
if (options?.ignoreBlocking) {
|
|
175
|
+
this._forceBypassNavigationBlocking = true;
|
|
176
|
+
}
|
|
177
|
+
const onProceed = (): void => {
|
|
178
|
+
this._forceBypassNavigationBlocking = true; // make sure to not trigger `BeforeUnloadEvent`
|
|
158
179
|
this.window.location.href = address;
|
|
180
|
+
};
|
|
181
|
+
if (
|
|
182
|
+
!this._forceBypassNavigationBlocking &&
|
|
183
|
+
this._blockCheckers.some((checker) => checker())
|
|
184
|
+
) {
|
|
185
|
+
this.onBlock?.(onProceed);
|
|
159
186
|
} else {
|
|
160
|
-
|
|
187
|
+
onProceed();
|
|
161
188
|
}
|
|
162
189
|
}
|
|
163
190
|
|
|
191
|
+
visitAddress(address: Address): void {
|
|
192
|
+
this.window.open(address, '_blank');
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
updateCurrentLocation(location: Location): void {
|
|
196
|
+
this.historyAPI.push(location);
|
|
197
|
+
}
|
|
198
|
+
|
|
164
199
|
getCurrentAddress(): Address {
|
|
165
200
|
return this.window.location.href;
|
|
166
201
|
}
|
|
@@ -176,8 +211,12 @@ export class WebApplicationNavigator implements ApplicationNavigator {
|
|
|
176
211
|
);
|
|
177
212
|
}
|
|
178
213
|
|
|
179
|
-
|
|
180
|
-
|
|
214
|
+
blockNavigation(
|
|
215
|
+
blockCheckers: (() => boolean)[],
|
|
216
|
+
onBlock?: ((onProceed: () => void) => void) | undefined,
|
|
217
|
+
): void {
|
|
218
|
+
this._isNavigationBlocked = true;
|
|
219
|
+
this.onBlock = onBlock;
|
|
181
220
|
|
|
182
221
|
// Here we attempt to cancel the effect of the back button
|
|
183
222
|
// See https://medium.com/codex/angular-guards-disabling-browsers-back-button-for-specific-url-fdf05d9fe155#4f13
|
|
@@ -196,14 +235,15 @@ export class WebApplicationNavigator implements ApplicationNavigator {
|
|
|
196
235
|
this.window.addEventListener('beforeunload', this._beforeUnloadListener);
|
|
197
236
|
}
|
|
198
237
|
|
|
199
|
-
|
|
200
|
-
this.
|
|
238
|
+
unblockNavigation(): void {
|
|
239
|
+
this._isNavigationBlocked = false;
|
|
240
|
+
this.onBlock = undefined;
|
|
201
241
|
this.window.onpopstate = null;
|
|
202
242
|
this._blockCheckers = [];
|
|
203
243
|
this.window.removeEventListener('beforeunload', this._beforeUnloadListener);
|
|
204
244
|
}
|
|
205
245
|
|
|
206
|
-
get
|
|
207
|
-
return this.
|
|
246
|
+
get isNavigationBlocked(): boolean {
|
|
247
|
+
return this._isNavigationBlocked;
|
|
208
248
|
}
|
|
209
249
|
}
|
package/tsconfig.json
CHANGED
|
@@ -37,9 +37,11 @@
|
|
|
37
37
|
"./src/stores/ApplicationStoreTestUtils.ts",
|
|
38
38
|
"./src/stores/ApplicationTelemetry.ts",
|
|
39
39
|
"./src/stores/AssistantService.ts",
|
|
40
|
+
"./src/stores/CommandCenter.ts",
|
|
40
41
|
"./src/stores/DocumentationService.ts",
|
|
41
42
|
"./src/stores/EventService.ts",
|
|
42
43
|
"./src/stores/ExecutionPlanState.ts",
|
|
44
|
+
"./src/stores/KeyboardShortcutsService.ts",
|
|
43
45
|
"./src/stores/LegendApplicationDocumentation.ts",
|
|
44
46
|
"./src/stores/LegendApplicationPlugin.ts",
|
|
45
47
|
"./src/stores/PureLanguageSupport.ts",
|
|
@@ -50,7 +52,6 @@
|
|
|
50
52
|
"./src/application/LegendApplication.tsx",
|
|
51
53
|
"./src/application/LegendApplicationPluginManager.tsx",
|
|
52
54
|
"./src/components/ActionAlert.tsx",
|
|
53
|
-
"./src/components/ApplicationNavigationContextServiceUtils.tsx",
|
|
54
55
|
"./src/components/ApplicationStoreProvider.tsx",
|
|
55
56
|
"./src/components/ApplicationStoreProviderTestUtils.tsx",
|
|
56
57
|
"./src/components/BlockingAlert.tsx",
|
|
@@ -59,6 +60,8 @@
|
|
|
59
60
|
"./src/components/VirtualAssistant.tsx",
|
|
60
61
|
"./src/components/WebApplicationNavigatorProvider.tsx",
|
|
61
62
|
"./src/components/WebApplicationNavigatorProviderTestUtils.tsx",
|
|
63
|
+
"./src/components/useApplicationNavigationContext.tsx",
|
|
64
|
+
"./src/components/useCommands.tsx",
|
|
62
65
|
"./src/components/execution-plan-viewer/ExecutionPlanViewer.tsx",
|
|
63
66
|
"./src/components/execution-plan-viewer/SQLExecutionNodeViewer.tsx",
|
|
64
67
|
"./src/components/shared/DocumentationLink.tsx",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationNavigationContextServiceUtils.d.ts","sourceRoot":"","sources":["../../src/components/ApplicationNavigationContextServiceUtils.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,+BAA+B,UAAW,MAAM,KAAG,IAQ/D,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,0CAA0C,UAC9C,MAAM,aACF,OAAO,KACjB,IAeF,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ApplicationNavigationContextServiceUtils.js","sourceRoot":"","sources":["../../src/components/ApplicationNavigationContextServiceUtils.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,EAAE,gCAAgC,EAAE,MAAM,kDAAkD,CAAC;AACpG,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEpE;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,KAAa,EAAQ,EAAE;IACrE,MAAM,gBAAgB,GAAG,mBAAmB,EAAE,CAAC;IAE/C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,gCAAgC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/D,gBAAgB,CAAC,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACxD,OAAO,GAAG,EAAE,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACtE,CAAC,EAAE,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAAC,CAAC;AAChC,CAAC,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,0CAA0C,GAAG,CACxD,KAAa,EACb,SAAkB,EACZ,EAAE;IACR,MAAM,gBAAgB,GAAG,mBAAmB,EAAE,CAAC;IAE/C,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,OAAO,GAAG,gCAAgC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAC/D,IAAI,SAAS,EAAE;YACb,gBAAgB,CAAC,wBAAwB,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;SACzD;aAAM;YACL,gBAAgB,CAAC,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;SACxD;QACD,sEAAsE;QACtE,oFAAoF;QACpF,kBAAkB;QAClB,OAAO,GAAG,EAAE,CAAC,gBAAgB,CAAC,wBAAwB,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IACtE,CAAC,EAAE,CAAC,gBAAgB,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;AAC3C,CAAC,CAAC"}
|