@finos/legend-application 7.2.1 → 8.0.1
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/components/ActionAlert.d.ts +1 -0
- package/lib/components/ActionAlert.d.ts.map +1 -1
- package/lib/components/ActionAlert.js +2 -1
- package/lib/components/ActionAlert.js.map +1 -1
- package/lib/components/ApplicationStoreProvider.d.ts +3 -3
- package/lib/components/ApplicationStoreProvider.d.ts.map +1 -1
- package/lib/components/ApplicationStoreProviderTestUtils.d.ts +1 -1
- package/lib/components/ApplicationStoreProviderTestUtils.js.map +1 -1
- package/lib/components/BlockingAlert.d.ts +1 -0
- package/lib/components/BlockingAlert.d.ts.map +1 -1
- package/lib/components/NotificationManager.d.ts +1 -0
- package/lib/components/NotificationManager.d.ts.map +1 -1
- package/lib/components/VirtualAssistant.d.ts +1 -0
- package/lib/components/VirtualAssistant.d.ts.map +1 -1
- package/lib/components/VirtualAssistant.js +21 -12
- package/lib/components/VirtualAssistant.js.map +1 -1
- package/lib/components/shared/CustomDatePicker.d.ts.map +1 -1
- package/lib/components/shared/CustomDatePicker.js +31 -9
- package/lib/components/shared/CustomDatePicker.js.map +1 -1
- package/lib/components/shared/DocumentationLink.d.ts.map +1 -1
- package/lib/components/shared/DocumentationLink.js +11 -3
- package/lib/components/shared/DocumentationLink.js.map +1 -1
- package/lib/components/shared/LambdaEditor.d.ts +1 -0
- package/lib/components/shared/LambdaEditor.d.ts.map +1 -1
- package/lib/components/shared/LambdaParameterValuesEditor.d.ts +1 -0
- package/lib/components/shared/LambdaParameterValuesEditor.d.ts.map +1 -1
- package/lib/components/shared/TextSearchAdvancedConfigMenu.d.ts +23 -0
- package/lib/components/shared/TextSearchAdvancedConfigMenu.d.ts.map +1 -0
- package/lib/components/shared/TextSearchAdvancedConfigMenu.js +37 -0
- package/lib/components/shared/TextSearchAdvancedConfigMenu.js.map +1 -0
- package/lib/components/shared/execution-plan-viewer/ExecutionPlanViewer.d.ts.map +1 -1
- package/lib/components/shared/execution-plan-viewer/ExecutionPlanViewer.js +2 -2
- package/lib/components/shared/execution-plan-viewer/ExecutionPlanViewer.js.map +1 -1
- package/lib/const.d.ts +2 -0
- package/lib/const.d.ts.map +1 -1
- package/lib/const.js +2 -0
- package/lib/const.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/index.d.ts +2 -0
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +2 -0
- package/lib/index.js.map +1 -1
- package/lib/stores/ApplicationStore.d.ts +4 -4
- package/lib/stores/ApplicationStore.d.ts.map +1 -1
- package/lib/stores/ApplicationStore.js +7 -4
- package/lib/stores/ApplicationStore.js.map +1 -1
- package/lib/stores/ApplicationStoreTestUtils.d.ts +1 -1
- package/lib/stores/ApplicationStoreTestUtils.js.map +1 -1
- package/lib/stores/ApplicationTelemetry.d.ts +5 -0
- package/lib/stores/ApplicationTelemetry.d.ts.map +1 -1
- package/lib/stores/ApplicationTelemetry.js.map +1 -1
- package/lib/stores/AssistantService.d.ts +21 -2
- package/lib/stores/AssistantService.d.ts.map +1 -1
- package/lib/stores/AssistantService.js +71 -14
- package/lib/stores/AssistantService.js.map +1 -1
- package/lib/stores/LegendApplicationDocumentation.d.ts +19 -0
- package/lib/stores/LegendApplicationDocumentation.d.ts.map +1 -0
- package/lib/stores/LegendApplicationDocumentation.js +20 -0
- package/lib/stores/LegendApplicationDocumentation.js.map +1 -0
- package/lib/stores/PureLanguageSupport.js +3 -3
- package/lib/stores/PureLanguageSupport.js.map +1 -1
- package/lib/stores/shared/LambdaParameterState.d.ts +7 -3
- package/lib/stores/shared/LambdaParameterState.d.ts.map +1 -1
- package/lib/stores/shared/LambdaParameterState.js +25 -2
- package/lib/stores/shared/LambdaParameterState.js.map +1 -1
- package/lib/stores/shared/TextSearchAdvancedConfigState.d.ts +30 -0
- package/lib/stores/shared/TextSearchAdvancedConfigState.d.ts.map +1 -0
- package/lib/stores/shared/TextSearchAdvancedConfigState.js +59 -0
- package/lib/stores/shared/TextSearchAdvancedConfigState.js.map +1 -0
- package/package.json +13 -13
- package/src/components/ActionAlert.tsx +1 -1
- package/src/components/ApplicationStoreProvider.tsx +3 -3
- package/src/components/ApplicationStoreProviderTestUtils.tsx +2 -2
- package/src/components/VirtualAssistant.tsx +127 -76
- package/src/components/shared/CustomDatePicker.tsx +40 -2
- package/src/components/shared/DocumentationLink.tsx +14 -3
- package/src/components/shared/TextSearchAdvancedConfigMenu.tsx +73 -0
- package/src/components/shared/execution-plan-viewer/ExecutionPlanViewer.tsx +3 -2
- package/src/const.ts +2 -0
- package/src/index.ts +3 -0
- package/src/stores/ApplicationStore.ts +10 -11
- package/src/stores/ApplicationStoreTestUtils.ts +2 -2
- package/src/stores/ApplicationTelemetry.ts +5 -0
- package/src/stores/AssistantService.ts +93 -18
- package/src/stores/LegendApplicationDocumentation.ts +19 -0
- package/src/stores/PureLanguageSupport.ts +3 -3
- package/src/stores/shared/LambdaParameterState.ts +36 -4
- package/src/stores/shared/TextSearchAdvancedConfigState.ts +65 -0
- package/tsconfig.json +3 -0
|
@@ -0,0 +1,73 @@
|
|
|
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 { BaseRadioGroup, InfoCircleIcon } from '@finos/legend-art';
|
|
18
|
+
import { observer } from 'mobx-react-lite';
|
|
19
|
+
import { LEGEND_APPLICATION_DOCUMENTATION_KEY } from '../../stores/LegendApplicationDocumentation.js';
|
|
20
|
+
import {
|
|
21
|
+
ADVANCED_TEXT_SEARCH_MODE,
|
|
22
|
+
type TextSearchAdvancedConfigState,
|
|
23
|
+
} from '../../stores/shared/TextSearchAdvancedConfigState.js';
|
|
24
|
+
import { useApplicationStore } from '../ApplicationStoreProvider.js';
|
|
25
|
+
|
|
26
|
+
export const TextSearchAdvancedConfigMenu = observer(
|
|
27
|
+
(props: { configState: TextSearchAdvancedConfigState }) => {
|
|
28
|
+
const { configState } = props;
|
|
29
|
+
const applicationStore = useApplicationStore();
|
|
30
|
+
|
|
31
|
+
const handleSearchMode: React.ChangeEventHandler<HTMLInputElement> = (
|
|
32
|
+
event,
|
|
33
|
+
): void => {
|
|
34
|
+
const searchMode = event.target.value as ADVANCED_TEXT_SEARCH_MODE;
|
|
35
|
+
configState.setCurrentMode(searchMode);
|
|
36
|
+
};
|
|
37
|
+
const seeDocumentation = (): void =>
|
|
38
|
+
applicationStore.assistantService.openDocumentationEntry(
|
|
39
|
+
LEGEND_APPLICATION_DOCUMENTATION_KEY.QUESTION_HOW_TO_USE_ADVANCED_SEARCH_SYNTAX,
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<div className="text-search-advanced-config__panel">
|
|
44
|
+
<div className="text-search-advanced-config__panel__header__label">
|
|
45
|
+
search config
|
|
46
|
+
<button
|
|
47
|
+
className="text-search-advanced-config__panel__header__hint"
|
|
48
|
+
tabIndex={-1}
|
|
49
|
+
onClick={seeDocumentation}
|
|
50
|
+
title="Click to see more details on advanced search"
|
|
51
|
+
>
|
|
52
|
+
<InfoCircleIcon />
|
|
53
|
+
</button>
|
|
54
|
+
</div>
|
|
55
|
+
<div>
|
|
56
|
+
<BaseRadioGroup
|
|
57
|
+
className="text-search-advanced-config__options"
|
|
58
|
+
value={configState.currentMode}
|
|
59
|
+
onChange={handleSearchMode}
|
|
60
|
+
row={false}
|
|
61
|
+
options={[
|
|
62
|
+
ADVANCED_TEXT_SEARCH_MODE.STANDARD,
|
|
63
|
+
ADVANCED_TEXT_SEARCH_MODE.INCLUDE,
|
|
64
|
+
ADVANCED_TEXT_SEARCH_MODE.EXACT,
|
|
65
|
+
ADVANCED_TEXT_SEARCH_MODE.INVERSE,
|
|
66
|
+
]}
|
|
67
|
+
size={1}
|
|
68
|
+
/>
|
|
69
|
+
</div>
|
|
70
|
+
</div>
|
|
71
|
+
);
|
|
72
|
+
},
|
|
73
|
+
);
|
|
@@ -31,6 +31,7 @@ import {
|
|
|
31
31
|
MenuContent,
|
|
32
32
|
DropdownMenu,
|
|
33
33
|
BlankPanelContent,
|
|
34
|
+
PanelContent,
|
|
34
35
|
} from '@finos/legend-art';
|
|
35
36
|
import {
|
|
36
37
|
addUniqueEntry,
|
|
@@ -517,14 +518,14 @@ export const ExecutionPlanViewer = observer(
|
|
|
517
518
|
</div>
|
|
518
519
|
</div>
|
|
519
520
|
</div>
|
|
520
|
-
<
|
|
521
|
+
<PanelContent>
|
|
521
522
|
<TextInputEditor
|
|
522
523
|
inputValue={executionPlanState.debugText}
|
|
523
524
|
isReadOnly={true}
|
|
524
525
|
language={EDITOR_LANGUAGE.TEXT}
|
|
525
526
|
showMiniMap={true}
|
|
526
527
|
/>
|
|
527
|
-
</
|
|
528
|
+
</PanelContent>
|
|
528
529
|
</div>
|
|
529
530
|
</ResizablePanel>
|
|
530
531
|
</ResizablePanelGroup>
|
package/src/const.ts
CHANGED
package/src/index.ts
CHANGED
|
@@ -39,6 +39,9 @@ export * from './stores/AssistantService.js';
|
|
|
39
39
|
export * from './stores/ApplicationNavigationContextService.js';
|
|
40
40
|
export * from './stores/LegendApplicationPlugin.js';
|
|
41
41
|
|
|
42
|
+
export * from './components/shared/TextSearchAdvancedConfigMenu.js';
|
|
43
|
+
export * from './stores/shared/TextSearchAdvancedConfigState.js';
|
|
44
|
+
|
|
42
45
|
export * from './stores/ApplicationStoreTestUtils.js';
|
|
43
46
|
|
|
44
47
|
// ------------------------------------------- Shared components -------------------------------------------
|
|
@@ -25,7 +25,7 @@ import {
|
|
|
25
25
|
isString,
|
|
26
26
|
ApplicationError,
|
|
27
27
|
} from '@finos/legend-shared';
|
|
28
|
-
import {
|
|
28
|
+
import { action, makeObservable, observable } from 'mobx';
|
|
29
29
|
import { APPLICATION_EVENT } from './ApplicationEvent.js';
|
|
30
30
|
import type { LegendApplicationConfig } from '../application/LegendApplicationConfig.js';
|
|
31
31
|
import type { WebApplicationNavigator } from './WebApplicationNavigator.js';
|
|
@@ -105,15 +105,15 @@ export class Notification {
|
|
|
105
105
|
|
|
106
106
|
export type GenericLegendApplicationStore = ApplicationStore<
|
|
107
107
|
LegendApplicationConfig,
|
|
108
|
-
LegendApplicationPlugin
|
|
108
|
+
LegendApplicationPluginManager<LegendApplicationPlugin>
|
|
109
109
|
>;
|
|
110
110
|
|
|
111
111
|
export class ApplicationStore<
|
|
112
112
|
T extends LegendApplicationConfig,
|
|
113
|
-
V extends LegendApplicationPlugin
|
|
113
|
+
V extends LegendApplicationPluginManager<LegendApplicationPlugin>,
|
|
114
114
|
> {
|
|
115
|
-
pluginManager: LegendApplicationPluginManager<V>;
|
|
116
115
|
config: T;
|
|
116
|
+
pluginManager: V;
|
|
117
117
|
|
|
118
118
|
// navigation
|
|
119
119
|
navigator: WebApplicationNavigator;
|
|
@@ -144,13 +144,12 @@ export class ApplicationStore<
|
|
|
144
144
|
*/
|
|
145
145
|
TEMPORARY__isLightThemeEnabled = false;
|
|
146
146
|
|
|
147
|
-
constructor(
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
navigator: false,
|
|
147
|
+
constructor(config: T, navigator: WebApplicationNavigator, pluginManager: V) {
|
|
148
|
+
makeObservable(this, {
|
|
149
|
+
notification: observable,
|
|
150
|
+
blockingAlertInfo: observable,
|
|
151
|
+
actionAlertInfo: observable,
|
|
152
|
+
TEMPORARY__isLightThemeEnabled: observable,
|
|
154
153
|
setBlockingAlert: action,
|
|
155
154
|
setActionAlertInfo: action,
|
|
156
155
|
setNotification: action,
|
|
@@ -52,10 +52,10 @@ export const TEST__getGenericApplicationConfig = (
|
|
|
52
52
|
|
|
53
53
|
export const TEST__getTestApplicationStore = <
|
|
54
54
|
T extends LegendApplicationConfig,
|
|
55
|
-
V extends LegendApplicationPlugin
|
|
55
|
+
V extends LegendApplicationPluginManager<LegendApplicationPlugin>,
|
|
56
56
|
>(
|
|
57
57
|
config: T,
|
|
58
|
-
pluginManager:
|
|
58
|
+
pluginManager: V,
|
|
59
59
|
): ApplicationStore<T, V> =>
|
|
60
60
|
new ApplicationStore(
|
|
61
61
|
config,
|
|
@@ -18,6 +18,11 @@ import type { TelemetryService } from '@finos/legend-shared';
|
|
|
18
18
|
import { APPLICATION_EVENT } from './ApplicationEvent.js';
|
|
19
19
|
|
|
20
20
|
type ApplicationLoaded_TelemetryData = {
|
|
21
|
+
application: {
|
|
22
|
+
name: string;
|
|
23
|
+
version: string;
|
|
24
|
+
env: string;
|
|
25
|
+
};
|
|
21
26
|
browser: {
|
|
22
27
|
userAgent: string;
|
|
23
28
|
};
|
|
@@ -25,12 +25,15 @@ import {
|
|
|
25
25
|
isNonNullable,
|
|
26
26
|
ActionState,
|
|
27
27
|
} from '@finos/legend-shared';
|
|
28
|
+
import { TextSearchAdvancedConfigState } from './shared/TextSearchAdvancedConfigState.js';
|
|
28
29
|
|
|
29
30
|
export enum VIRTUAL_ASSISTANT_TAB {
|
|
30
31
|
SEARCH = 'SEARCH',
|
|
31
32
|
CONTEXTUAL_SUPPORT = 'CONTEXTUAL_SUPPORT',
|
|
32
33
|
}
|
|
33
34
|
|
|
35
|
+
export const DOCUMENTATION_SEARCH_RESULTS_LIMIT = 100;
|
|
36
|
+
|
|
34
37
|
export class VirtualAssistantDocumentationEntry {
|
|
35
38
|
uuid = uuid();
|
|
36
39
|
documentationKey: string;
|
|
@@ -77,9 +80,28 @@ export class VirtualAssistantContextualDocumentationEntry {
|
|
|
77
80
|
}
|
|
78
81
|
}
|
|
79
82
|
|
|
83
|
+
/**
|
|
84
|
+
* NOTE: since we're displaying the documentation entry in virtual assistant
|
|
85
|
+
* we want only user-friendly docs, we will discard anything that doesn't
|
|
86
|
+
* come with a title, or does not have any content/url
|
|
87
|
+
*/
|
|
88
|
+
export const isValidVirtualAssistantDocumentationEntry = (
|
|
89
|
+
entry: DocumentationEntry,
|
|
90
|
+
): boolean =>
|
|
91
|
+
Boolean(entry.title && (entry.url ?? entry.text ?? entry.markdownText));
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Check if the documentation entry should be displayed in virtual assistant,
|
|
95
|
+
* i.e. it has some text content, rather just a link
|
|
96
|
+
*/
|
|
97
|
+
export const shouldDisplayVirtualAssistantDocumentationEntry = (
|
|
98
|
+
entry: DocumentationEntry,
|
|
99
|
+
): boolean =>
|
|
100
|
+
isValidVirtualAssistantDocumentationEntry(entry) &&
|
|
101
|
+
Boolean(entry.text ?? entry.markdownText);
|
|
102
|
+
|
|
80
103
|
export class AssistantService {
|
|
81
104
|
readonly applicationStore: GenericLegendApplicationStore;
|
|
82
|
-
private readonly searchEngine: Fuse<DocumentationEntry>;
|
|
83
105
|
/**
|
|
84
106
|
* This key is used to allow programmatic re-rendering of the assistant panel
|
|
85
107
|
*/
|
|
@@ -87,19 +109,28 @@ export class AssistantService {
|
|
|
87
109
|
isHidden = false;
|
|
88
110
|
isOpen = false;
|
|
89
111
|
selectedTab = VIRTUAL_ASSISTANT_TAB.SEARCH;
|
|
112
|
+
currentDocumentationEntry: VirtualAssistantDocumentationEntry | undefined;
|
|
90
113
|
|
|
91
|
-
|
|
92
|
-
|
|
114
|
+
// search text
|
|
115
|
+
private readonly searchEngine: Fuse<DocumentationEntry>;
|
|
116
|
+
searchConfigurationState: TextSearchAdvancedConfigState;
|
|
117
|
+
searchState = ActionState.create();
|
|
93
118
|
searchText = '';
|
|
119
|
+
searchResults: VirtualAssistantDocumentationEntry[] = [];
|
|
120
|
+
showSearchConfigurationMenu = false;
|
|
121
|
+
isOverSearchLimit = false;
|
|
94
122
|
|
|
95
123
|
constructor(applicationStore: GenericLegendApplicationStore) {
|
|
96
124
|
makeObservable(this, {
|
|
97
125
|
isHidden: observable,
|
|
98
126
|
isOpen: observable,
|
|
99
127
|
panelRenderingKey: observable,
|
|
128
|
+
isOverSearchLimit: observable,
|
|
100
129
|
selectedTab: observable,
|
|
101
130
|
searchText: observable,
|
|
102
131
|
searchResults: observable,
|
|
132
|
+
currentDocumentationEntry: observable,
|
|
133
|
+
showSearchConfigurationMenu: observable,
|
|
103
134
|
currentContextualDocumentationEntry: computed,
|
|
104
135
|
setIsHidden: action,
|
|
105
136
|
setIsOpen: action,
|
|
@@ -107,17 +138,16 @@ export class AssistantService {
|
|
|
107
138
|
setSearchText: action,
|
|
108
139
|
resetSearch: action,
|
|
109
140
|
search: action,
|
|
141
|
+
openDocumentationEntry: action,
|
|
110
142
|
refreshPanelRendering: action,
|
|
143
|
+
setShowSearchConfigurationMenu: action,
|
|
111
144
|
});
|
|
112
145
|
|
|
113
146
|
this.applicationStore = applicationStore;
|
|
114
147
|
this.searchEngine = new Fuse(
|
|
115
|
-
this.applicationStore.documentationService
|
|
116
|
-
(
|
|
117
|
-
|
|
118
|
-
// doesn't come with a title, or does not have any content/url
|
|
119
|
-
entry.title && (entry.url ?? entry.text ?? entry.markdownText),
|
|
120
|
-
),
|
|
148
|
+
this.applicationStore.documentationService
|
|
149
|
+
.getAllDocEntries()
|
|
150
|
+
.filter(isValidVirtualAssistantDocumentationEntry),
|
|
121
151
|
{
|
|
122
152
|
includeScore: true,
|
|
123
153
|
shouldSort: true,
|
|
@@ -143,8 +173,14 @@ export class AssistantService {
|
|
|
143
173
|
weight: 1,
|
|
144
174
|
},
|
|
145
175
|
],
|
|
176
|
+
// extended search allows for exact word match through single quote
|
|
177
|
+
// See https://fusejs.io/examples.html#extended-search
|
|
178
|
+
useExtendedSearch: true,
|
|
146
179
|
},
|
|
147
180
|
);
|
|
181
|
+
this.searchConfigurationState = new TextSearchAdvancedConfigState(() => {
|
|
182
|
+
this.search();
|
|
183
|
+
});
|
|
148
184
|
}
|
|
149
185
|
|
|
150
186
|
get currentContextualDocumentationEntry():
|
|
@@ -159,6 +195,7 @@ export class AssistantService {
|
|
|
159
195
|
this.applicationStore.documentationService.getContextualDocEntry(
|
|
160
196
|
currentContext,
|
|
161
197
|
);
|
|
198
|
+
|
|
162
199
|
return currentContextualDocumentationEntry
|
|
163
200
|
? new VirtualAssistantContextualDocumentationEntry(
|
|
164
201
|
currentContext,
|
|
@@ -168,19 +205,28 @@ export class AssistantService {
|
|
|
168
205
|
this.applicationStore.documentationService.getDocEntry(entry),
|
|
169
206
|
)
|
|
170
207
|
.filter(isNonNullable)
|
|
171
|
-
.filter(
|
|
172
|
-
(entry) =>
|
|
173
|
-
// NOTE: since we're searching for user-friendly docs, we will discard anything that
|
|
174
|
-
// doesn't come with a title, or does not have any content/url
|
|
175
|
-
//
|
|
176
|
-
// We could also consider having a flag in each documentation entry to be hidden from users
|
|
177
|
-
entry.title && (entry.url ?? entry.text ?? entry.markdownText),
|
|
178
|
-
)
|
|
208
|
+
.filter(isValidVirtualAssistantDocumentationEntry)
|
|
179
209
|
.map((entry) => new VirtualAssistantDocumentationEntry(entry)),
|
|
180
210
|
)
|
|
181
211
|
: undefined;
|
|
182
212
|
}
|
|
183
213
|
|
|
214
|
+
openDocumentationEntry(docKey: string): void {
|
|
215
|
+
const matchingDocEntry = this.applicationStore.documentationService
|
|
216
|
+
.getAllDocEntries()
|
|
217
|
+
.find((entry) => entry._documentationKey === docKey);
|
|
218
|
+
|
|
219
|
+
if (matchingDocEntry) {
|
|
220
|
+
this.setIsOpen(true);
|
|
221
|
+
this.setIsHidden(false);
|
|
222
|
+
this.currentDocumentationEntry = new VirtualAssistantDocumentationEntry(
|
|
223
|
+
matchingDocEntry,
|
|
224
|
+
);
|
|
225
|
+
this.currentDocumentationEntry.setIsOpen(true);
|
|
226
|
+
this.resetSearch();
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
|
|
184
230
|
setIsHidden(val: boolean): void {
|
|
185
231
|
this.isHidden = val;
|
|
186
232
|
}
|
|
@@ -222,10 +268,39 @@ export class AssistantService {
|
|
|
222
268
|
}
|
|
223
269
|
|
|
224
270
|
search(): void {
|
|
271
|
+
if (!this.searchText) {
|
|
272
|
+
this.searchResults = [];
|
|
273
|
+
return;
|
|
274
|
+
}
|
|
275
|
+
this.currentDocumentationEntry = undefined;
|
|
225
276
|
this.searchState.inProgress();
|
|
226
277
|
this.searchResults = Array.from(
|
|
227
|
-
this.searchEngine
|
|
278
|
+
this.searchEngine
|
|
279
|
+
.search(
|
|
280
|
+
this.searchConfigurationState.generateSearchText(this.searchText),
|
|
281
|
+
{
|
|
282
|
+
// NOTE: search for limit + 1 item so we can know if there are more search results
|
|
283
|
+
limit: DOCUMENTATION_SEARCH_RESULTS_LIMIT + 1,
|
|
284
|
+
},
|
|
285
|
+
)
|
|
286
|
+
.values(),
|
|
228
287
|
).map((result) => new VirtualAssistantDocumentationEntry(result.item));
|
|
288
|
+
|
|
289
|
+
// check if the search results exceed the limit
|
|
290
|
+
if (this.searchResults.length > DOCUMENTATION_SEARCH_RESULTS_LIMIT) {
|
|
291
|
+
this.isOverSearchLimit = true;
|
|
292
|
+
this.searchResults = this.searchResults.slice(
|
|
293
|
+
0,
|
|
294
|
+
DOCUMENTATION_SEARCH_RESULTS_LIMIT,
|
|
295
|
+
);
|
|
296
|
+
} else {
|
|
297
|
+
this.isOverSearchLimit = false;
|
|
298
|
+
}
|
|
299
|
+
|
|
229
300
|
this.searchState.complete();
|
|
230
301
|
}
|
|
302
|
+
|
|
303
|
+
setShowSearchConfigurationMenu(val: boolean): void {
|
|
304
|
+
this.showSearchConfigurationMenu = val;
|
|
305
|
+
}
|
|
231
306
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
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
|
+
export enum LEGEND_APPLICATION_DOCUMENTATION_KEY {
|
|
18
|
+
QUESTION_HOW_TO_USE_ADVANCED_SEARCH_SYNTAX = 'question.how-to-use-advanced-search-syntax',
|
|
19
|
+
}
|
|
@@ -124,10 +124,7 @@ const generateLanguageMonarch = (
|
|
|
124
124
|
PURE_ELEMENT_NAME.MEASURE,
|
|
125
125
|
PURE_ELEMENT_NAME.PROFILE,
|
|
126
126
|
PURE_ELEMENT_NAME.FUNCTION,
|
|
127
|
-
PURE_ELEMENT_NAME.FLAT_DATA,
|
|
128
|
-
PURE_ELEMENT_NAME.DATABASE,
|
|
129
127
|
PURE_ELEMENT_NAME.MAPPING,
|
|
130
|
-
PURE_ELEMENT_NAME.SERVICE,
|
|
131
128
|
PURE_ELEMENT_NAME.RUNTIME,
|
|
132
129
|
PURE_ELEMENT_NAME.CONNECTION,
|
|
133
130
|
PURE_ELEMENT_NAME.FILE_GENERATION,
|
|
@@ -148,6 +145,9 @@ const generateLanguageMonarch = (
|
|
|
148
145
|
* @modularize
|
|
149
146
|
* See https://github.com/finos/legend-studio/issues/65
|
|
150
147
|
*/
|
|
148
|
+
PURE_ELEMENT_NAME.SERVICE,
|
|
149
|
+
PURE_ELEMENT_NAME.FLAT_DATA,
|
|
150
|
+
PURE_ELEMENT_NAME.DATABASE,
|
|
151
151
|
PURE_CONNECTION_NAME.FLAT_DATA_CONNECTION,
|
|
152
152
|
PURE_CONNECTION_NAME.RELATIONAL_DATABASE_CONNECTION,
|
|
153
153
|
'Relational',
|
|
@@ -38,11 +38,13 @@ import {
|
|
|
38
38
|
import {
|
|
39
39
|
addUniqueEntry,
|
|
40
40
|
deleteEntry,
|
|
41
|
+
type Hashable,
|
|
42
|
+
hashArray,
|
|
41
43
|
IllegalStateError,
|
|
42
44
|
isNonNullable,
|
|
43
45
|
uuid,
|
|
44
46
|
} from '@finos/legend-shared';
|
|
45
|
-
import { makeObservable, observable, action } from 'mobx';
|
|
47
|
+
import { makeObservable, observable, action, computed } from 'mobx';
|
|
46
48
|
import {
|
|
47
49
|
genericType_setRawType,
|
|
48
50
|
multiplicity_setLowerBound,
|
|
@@ -54,6 +56,11 @@ export enum PARAMETER_SUBMIT_ACTION {
|
|
|
54
56
|
EXPORT = 'EXPORT',
|
|
55
57
|
}
|
|
56
58
|
|
|
59
|
+
enum LAMABA_PARAMETER_HASH_STRUCTURE {
|
|
60
|
+
LAMBDA_PARAMETER_STATE = 'LAMBDA_PARAMETER_STATE',
|
|
61
|
+
LAMBDA_PARAMETERS_STATE = 'LAMBDA_PARAMETERS_STATE',
|
|
62
|
+
}
|
|
63
|
+
|
|
57
64
|
export const buildParametersLetLambdaFunc = (
|
|
58
65
|
graph: PureModel,
|
|
59
66
|
lambdaParametersStates: LambdaParameterState[],
|
|
@@ -87,11 +94,13 @@ export const buildParametersLetLambdaFunc = (
|
|
|
87
94
|
.filter(isNonNullable);
|
|
88
95
|
return letlambdaFunction;
|
|
89
96
|
};
|
|
90
|
-
|
|
97
|
+
|
|
98
|
+
export class LambdaParameterState implements Hashable {
|
|
91
99
|
readonly uuid = uuid();
|
|
92
100
|
readonly parameter: VariableExpression;
|
|
93
101
|
readonly graph: PureModel;
|
|
94
|
-
observableContext: ObserverContext;
|
|
102
|
+
readonly observableContext: ObserverContext;
|
|
103
|
+
|
|
95
104
|
value: ValueSpecification | undefined;
|
|
96
105
|
|
|
97
106
|
constructor(
|
|
@@ -103,12 +112,20 @@ export class LambdaParameterState {
|
|
|
103
112
|
value: observable,
|
|
104
113
|
setValue: action,
|
|
105
114
|
mockParameterValue: action,
|
|
115
|
+
hashCode: computed,
|
|
106
116
|
});
|
|
107
117
|
this.observableContext = observableContext;
|
|
108
118
|
this.parameter = observe_VariableExpression(variableExpression);
|
|
109
119
|
this.graph = graph;
|
|
110
120
|
}
|
|
111
121
|
|
|
122
|
+
get hashCode(): string {
|
|
123
|
+
return hashArray([
|
|
124
|
+
LAMABA_PARAMETER_HASH_STRUCTURE.LAMBDA_PARAMETER_STATE,
|
|
125
|
+
this.parameter,
|
|
126
|
+
]);
|
|
127
|
+
}
|
|
128
|
+
|
|
112
129
|
mockParameterValue(): void {
|
|
113
130
|
this.setValue(
|
|
114
131
|
generateVariableExpressionMockValue(this.parameter, this.graph),
|
|
@@ -204,10 +221,24 @@ export class ParameterInstanceValuesEditorState {
|
|
|
204
221
|
this.setShowModal(false);
|
|
205
222
|
}
|
|
206
223
|
}
|
|
207
|
-
|
|
224
|
+
|
|
225
|
+
export class LambdaParametersState implements Hashable {
|
|
208
226
|
parameterStates: LambdaParameterState[] = [];
|
|
209
227
|
parameterValuesEditorState = new ParameterInstanceValuesEditorState();
|
|
210
228
|
|
|
229
|
+
constructor() {
|
|
230
|
+
makeObservable(this, {
|
|
231
|
+
hashCode: computed,
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
get hashCode(): string {
|
|
236
|
+
return hashArray([
|
|
237
|
+
LAMABA_PARAMETER_HASH_STRUCTURE.LAMBDA_PARAMETERS_STATE,
|
|
238
|
+
hashArray(this.parameterStates),
|
|
239
|
+
]);
|
|
240
|
+
}
|
|
241
|
+
|
|
211
242
|
addParameter(val: LambdaParameterState): void {
|
|
212
243
|
addUniqueEntry(this.parameterStates, val);
|
|
213
244
|
}
|
|
@@ -215,6 +246,7 @@ export class LambdaParametersState {
|
|
|
215
246
|
removeParameter(val: LambdaParameterState): void {
|
|
216
247
|
deleteEntry(this.parameterStates, val);
|
|
217
248
|
}
|
|
249
|
+
|
|
218
250
|
setParameters(val: LambdaParameterState[]): void {
|
|
219
251
|
this.parameterStates = val;
|
|
220
252
|
}
|
|
@@ -0,0 +1,65 @@
|
|
|
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 { action, computed, makeObservable, observable } from 'mobx';
|
|
18
|
+
|
|
19
|
+
export enum ADVANCED_TEXT_SEARCH_MODE {
|
|
20
|
+
STANDARD = 'standard',
|
|
21
|
+
INCLUDE = 'include match',
|
|
22
|
+
EXACT = 'exact match',
|
|
23
|
+
INVERSE = 'excludes exact match',
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export class TextSearchAdvancedConfigState {
|
|
27
|
+
currentMode = ADVANCED_TEXT_SEARCH_MODE.STANDARD;
|
|
28
|
+
onSearchModeChange: () => void;
|
|
29
|
+
|
|
30
|
+
constructor(onSearchModeChange: () => void) {
|
|
31
|
+
makeObservable(this, {
|
|
32
|
+
currentMode: observable,
|
|
33
|
+
isAdvancedSearchActive: computed,
|
|
34
|
+
setCurrentMode: action,
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
this.onSearchModeChange = onSearchModeChange;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get isAdvancedSearchActive(): boolean {
|
|
41
|
+
return this.currentMode !== ADVANCED_TEXT_SEARCH_MODE.STANDARD;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
generateSearchText(val: string): string {
|
|
45
|
+
switch (this.currentMode) {
|
|
46
|
+
case ADVANCED_TEXT_SEARCH_MODE.INCLUDE: {
|
|
47
|
+
return `'"${val}"`;
|
|
48
|
+
}
|
|
49
|
+
case ADVANCED_TEXT_SEARCH_MODE.EXACT: {
|
|
50
|
+
return `="${val}"`;
|
|
51
|
+
}
|
|
52
|
+
case ADVANCED_TEXT_SEARCH_MODE.INVERSE: {
|
|
53
|
+
return `!"${val}"`;
|
|
54
|
+
}
|
|
55
|
+
default: {
|
|
56
|
+
return val;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
setCurrentMode(val: ADVANCED_TEXT_SEARCH_MODE): void {
|
|
62
|
+
this.currentMode = val;
|
|
63
|
+
this.onSearchModeChange();
|
|
64
|
+
}
|
|
65
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -40,6 +40,7 @@
|
|
|
40
40
|
"./src/stores/AssistantService.ts",
|
|
41
41
|
"./src/stores/DocumentationService.ts",
|
|
42
42
|
"./src/stores/EventService.ts",
|
|
43
|
+
"./src/stores/LegendApplicationDocumentation.ts",
|
|
43
44
|
"./src/stores/LegendApplicationPlugin.ts",
|
|
44
45
|
"./src/stores/PureLanguageSupport.ts",
|
|
45
46
|
"./src/stores/WebApplicationNavigator.ts",
|
|
@@ -47,6 +48,7 @@
|
|
|
47
48
|
"./src/stores/shared/LambdaEditorState.ts",
|
|
48
49
|
"./src/stores/shared/LambdaParameterState.ts",
|
|
49
50
|
"./src/stores/shared/PackageableElementOption.ts",
|
|
51
|
+
"./src/stores/shared/TextSearchAdvancedConfigState.ts",
|
|
50
52
|
"./src/stores/shared/ValueSpecificationModifierHelper.ts",
|
|
51
53
|
"./src/application/LegendApplication.tsx",
|
|
52
54
|
"./src/application/LegendApplicationPluginManager.tsx",
|
|
@@ -67,6 +69,7 @@
|
|
|
67
69
|
"./src/components/shared/LambdaParameterValuesEditor.tsx",
|
|
68
70
|
"./src/components/shared/PackageableElementOptionRenderer.tsx",
|
|
69
71
|
"./src/components/shared/TextInputEditor.tsx",
|
|
72
|
+
"./src/components/shared/TextSearchAdvancedConfigMenu.tsx",
|
|
70
73
|
"./src/components/shared/execution-plan-viewer/ExecutionPlanViewer.tsx",
|
|
71
74
|
"./src/components/shared/execution-plan-viewer/SQLExecutionNodeViewer.tsx",
|
|
72
75
|
"./src/stores/CJS__Fuse.cts"
|