@finos/legend-application 3.0.3 → 4.0.2
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 +2 -2
- package/lib/application/LegendApplication.d.ts.map +1 -1
- package/lib/application/LegendApplication.js +4 -4
- package/lib/application/LegendApplication.js.map +1 -1
- package/lib/application/LegendApplicationPluginManager.d.ts +3 -3
- package/lib/application/LegendApplicationPluginManager.d.ts.map +1 -1
- package/lib/components/ActionAlert.d.ts +1 -0
- package/lib/components/ActionAlert.d.ts.map +1 -1
- package/lib/components/ActionAlert.js +2 -2
- 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/ApplicationStoreProvider.js +2 -2
- package/lib/components/ApplicationStoreProvider.js.map +1 -1
- package/lib/components/ApplicationStoreProviderTestUtils.d.ts +5 -5
- package/lib/components/ApplicationStoreProviderTestUtils.d.ts.map +1 -1
- package/lib/components/ApplicationStoreProviderTestUtils.js +5 -4
- package/lib/components/ApplicationStoreProviderTestUtils.js.map +1 -1
- package/lib/components/ApplicationTestID.js +1 -1
- package/lib/components/ApplicationTestID.js.map +1 -1
- package/lib/components/BasicValueSpecificationEditor.d.ts +44 -0
- package/lib/components/BasicValueSpecificationEditor.d.ts.map +1 -0
- package/lib/components/BasicValueSpecificationEditor.js +276 -0
- package/lib/components/BasicValueSpecificationEditor.js.map +1 -0
- package/lib/components/BlockingAlert.d.ts +1 -0
- package/lib/components/BlockingAlert.d.ts.map +1 -1
- package/lib/components/BlockingAlert.js +1 -1
- package/lib/components/BlockingAlert.js.map +1 -1
- package/lib/components/CustomDatePicker.d.ts +38 -0
- package/lib/components/CustomDatePicker.d.ts.map +1 -0
- package/lib/components/CustomDatePicker.js +592 -0
- package/lib/components/CustomDatePicker.js.map +1 -0
- package/lib/components/DocumentationLink.d.ts +1 -1
- package/lib/components/DocumentationLink.js +2 -2
- package/lib/components/DocumentationLink.js.map +1 -1
- package/lib/components/LambdaEditor.d.ts +2 -1
- package/lib/components/LambdaEditor.d.ts.map +1 -1
- package/lib/components/LambdaEditor.js +3 -3
- package/lib/components/LambdaEditor.js.map +1 -1
- package/lib/components/LambdaParameterValuesEditor.d.ts +25 -0
- package/lib/components/LambdaParameterValuesEditor.d.ts.map +1 -0
- package/lib/components/LambdaParameterValuesEditor.js +52 -0
- package/lib/components/LambdaParameterValuesEditor.js.map +1 -0
- package/lib/components/LegendApplicationComponentFrameworkProvider.d.ts +1 -1
- package/lib/components/LegendApplicationComponentFrameworkProvider.js +3 -3
- package/lib/components/LegendApplicationComponentFrameworkProvider.js.map +1 -1
- package/lib/components/LegendApplicationNavigationContextServiceUtils.d.ts +32 -0
- package/lib/components/LegendApplicationNavigationContextServiceUtils.d.ts.map +1 -0
- package/lib/components/LegendApplicationNavigationContextServiceUtils.js +57 -0
- package/lib/components/LegendApplicationNavigationContextServiceUtils.js.map +1 -0
- package/lib/components/NotificationManager.d.ts +1 -0
- package/lib/components/NotificationManager.d.ts.map +1 -1
- package/lib/components/NotificationManager.js +2 -2
- package/lib/components/NotificationManager.js.map +1 -1
- package/lib/components/TextInputEditor.d.ts +2 -2
- package/lib/components/TextInputEditor.d.ts.map +1 -1
- package/lib/components/TextInputEditor.js +2 -2
- package/lib/components/TextInputEditor.js.map +1 -1
- package/lib/components/{AppHeader.d.ts → VirtualAssistant.d.ts} +5 -5
- package/lib/components/VirtualAssistant.d.ts.map +1 -0
- package/lib/components/VirtualAssistant.js +171 -0
- package/lib/components/VirtualAssistant.js.map +1 -0
- package/lib/components/WebApplicationNavigatorProvider.d.ts +2 -2
- package/lib/components/WebApplicationNavigatorProvider.d.ts.map +1 -1
- package/lib/components/WebApplicationNavigatorProvider.js +1 -1
- package/lib/components/WebApplicationNavigatorProvider.js.map +1 -1
- package/lib/components/WebApplicationNavigatorProviderTestUtils.d.ts +2 -2
- package/lib/components/WebApplicationNavigatorProviderTestUtils.d.ts.map +1 -1
- package/lib/components/WebApplicationNavigatorProviderTestUtils.js +3 -2
- package/lib/components/WebApplicationNavigatorProviderTestUtils.js.map +1 -1
- package/lib/const.js +2 -2
- 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 +30 -22
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +32 -22
- package/lib/index.js.map +1 -1
- package/lib/stores/ApplicationEvent.d.ts +9 -7
- package/lib/stores/ApplicationEvent.d.ts.map +1 -1
- package/lib/stores/ApplicationEvent.js +10 -8
- package/lib/stores/ApplicationEvent.js.map +1 -1
- package/lib/stores/ApplicationStore.d.ts +15 -9
- package/lib/stores/ApplicationStore.d.ts.map +1 -1
- package/lib/stores/ApplicationStore.js +26 -21
- package/lib/stores/ApplicationStore.js.map +1 -1
- package/lib/stores/ApplicationStoreTestUtils.d.ts +3 -3
- package/lib/stores/ApplicationStoreTestUtils.d.ts.map +1 -1
- package/lib/stores/ApplicationStoreTestUtils.js +2 -2
- package/lib/stores/ApplicationStoreTestUtils.js.map +1 -1
- package/lib/stores/ApplicationTelemetry.d.ts +1 -1
- package/lib/stores/ApplicationTelemetry.d.ts.map +1 -1
- package/lib/stores/ApplicationTelemetry.js +2 -2
- package/lib/stores/ApplicationTelemetry.js.map +1 -1
- package/lib/stores/CJS__Fuse.cjs +35 -0
- package/lib/stores/CJS__Fuse.cjs.map +1 -0
- package/lib/stores/CJS__Fuse.d.cts +28 -0
- package/lib/stores/CJS__Fuse.d.cts.map +1 -0
- package/lib/stores/LambdaParameterState.d.ts +59 -0
- package/lib/stores/LambdaParameterState.d.ts.map +1 -0
- package/lib/stores/LambdaParameterState.js +184 -0
- package/lib/stores/LambdaParameterState.js.map +1 -0
- package/lib/stores/LegendApplicationAssistantService.d.ts +63 -0
- package/lib/stores/LegendApplicationAssistantService.d.ts.map +1 -0
- package/lib/stores/LegendApplicationAssistantService.js +167 -0
- package/lib/stores/LegendApplicationAssistantService.js.map +1 -0
- package/lib/stores/LegendApplicationConfig.d.ts +5 -4
- package/lib/stores/LegendApplicationConfig.d.ts.map +1 -1
- package/lib/stores/LegendApplicationConfig.js +8 -3
- package/lib/stores/LegendApplicationConfig.js.map +1 -1
- package/lib/stores/LegendApplicationDocumentationService.d.ts +70 -0
- package/lib/stores/LegendApplicationDocumentationService.d.ts.map +1 -0
- package/lib/stores/LegendApplicationDocumentationService.js +152 -0
- package/lib/stores/LegendApplicationDocumentationService.js.map +1 -0
- package/lib/stores/LegendApplicationEventService.d.ts +22 -0
- package/lib/stores/LegendApplicationEventService.d.ts.map +1 -0
- package/lib/stores/LegendApplicationEventService.js +25 -0
- package/lib/stores/LegendApplicationEventService.js.map +1 -0
- package/lib/stores/LegendApplicationNavigationContextService.d.ts +74 -0
- package/lib/stores/LegendApplicationNavigationContextService.d.ts.map +1 -0
- package/lib/stores/LegendApplicationNavigationContextService.js +118 -0
- package/lib/stores/LegendApplicationNavigationContextService.js.map +1 -0
- package/lib/stores/LegendApplicationPlugin.d.ts +6 -2
- 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 +8 -2
- package/lib/stores/PureLanguageSupport.js.map +1 -1
- package/lib/stores/ValueSpecificationModifierHelper.d.ts +27 -0
- package/lib/stores/ValueSpecificationModifierHelper.d.ts.map +1 -0
- package/lib/stores/ValueSpecificationModifierHelper.js +49 -0
- package/lib/stores/ValueSpecificationModifierHelper.js.map +1 -0
- package/package.json +24 -18
- package/src/application/LegendApplication.tsx +6 -6
- package/src/application/LegendApplicationPluginManager.tsx +3 -3
- package/src/components/ActionAlert.tsx +2 -2
- package/src/components/ApplicationStoreProvider.tsx +4 -4
- package/src/components/ApplicationStoreProviderTestUtils.tsx +7 -6
- package/src/components/BasicValueSpecificationEditor.tsx +703 -0
- package/src/components/BlockingAlert.tsx +1 -1
- package/src/components/CustomDatePicker.tsx +1235 -0
- package/src/components/DocumentationLink.tsx +2 -2
- package/src/components/LambdaEditor.tsx +4 -4
- package/src/components/LambdaParameterValuesEditor.tsx +114 -0
- package/src/components/LegendApplicationComponentFrameworkProvider.tsx +3 -3
- package/src/components/LegendApplicationNavigationContextServiceUtils.tsx +63 -0
- package/src/components/NotificationManager.tsx +2 -2
- package/src/components/TextInputEditor.tsx +2 -2
- package/src/components/VirtualAssistant.tsx +600 -0
- package/src/components/WebApplicationNavigatorProvider.tsx +1 -1
- package/src/components/WebApplicationNavigatorProviderTestUtils.tsx +3 -2
- package/src/index.ts +39 -28
- package/src/stores/ApplicationEvent.ts +11 -7
- package/src/stores/ApplicationStore.ts +29 -27
- package/src/stores/ApplicationStoreTestUtils.ts +4 -4
- package/src/stores/ApplicationTelemetry.ts +2 -2
- package/src/stores/CJS__Fuse.cts +28 -0
- package/src/stores/LambdaParameterState.ts +314 -0
- package/src/stores/LegendApplicationAssistantService.ts +218 -0
- package/src/stores/LegendApplicationConfig.ts +20 -6
- package/src/stores/LegendApplicationDocumentationService.ts +276 -0
- package/src/stores/LegendApplicationEventService.ts +32 -0
- package/src/stores/LegendApplicationNavigationContextService.ts +131 -0
- package/src/stores/LegendApplicationPlugin.ts +10 -2
- package/src/stores/PureLanguageSupport.ts +8 -2
- package/src/stores/ValueSpecificationModifierHelper.ts +104 -0
- package/tsconfig.json +18 -12
- package/lib/components/AppHeader.d.ts.map +0 -1
- package/lib/components/AppHeader.js +0 -26
- package/lib/components/AppHeader.js.map +0 -1
- package/lib/stores/LegendApplicationDocumentationRegistry.d.ts +0 -36
- package/lib/stores/LegendApplicationDocumentationRegistry.d.ts.map +0 -1
- package/lib/stores/LegendApplicationDocumentationRegistry.js +0 -47
- package/lib/stores/LegendApplicationDocumentationRegistry.js.map +0 -1
- package/src/components/AppHeader.tsx +0 -49
- package/src/stores/LegendApplicationDocumentationRegistry.ts +0 -81
|
@@ -0,0 +1,218 @@
|
|
|
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, makeObservable, observable, computed } from 'mobx';
|
|
18
|
+
import type {
|
|
19
|
+
LegendApplicationContextualDocumentationEntry,
|
|
20
|
+
LegendApplicationDocumentationEntry,
|
|
21
|
+
} from './LegendApplicationDocumentationService.js';
|
|
22
|
+
import type { LegendApplicationConfig } from './LegendApplicationConfig.js';
|
|
23
|
+
import type { ApplicationStore } from './ApplicationStore.js';
|
|
24
|
+
import { Fuse } from './CJS__Fuse.cjs';
|
|
25
|
+
import {
|
|
26
|
+
type MarkdownText,
|
|
27
|
+
guaranteeNonEmptyString,
|
|
28
|
+
uuid,
|
|
29
|
+
isNonNullable,
|
|
30
|
+
ActionState,
|
|
31
|
+
} from '@finos/legend-shared';
|
|
32
|
+
|
|
33
|
+
export enum VIRTUAL_ASSISTANT_TAB {
|
|
34
|
+
SEARCH = 'SEARCH',
|
|
35
|
+
CONTEXTUAL_SUPPORT = 'CONTEXTUAL_SUPPORT',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
export class VirtualAssistantDocumentationEntry {
|
|
39
|
+
uuid = uuid();
|
|
40
|
+
documentationKey: string;
|
|
41
|
+
title: string;
|
|
42
|
+
content?: string | MarkdownText | undefined;
|
|
43
|
+
url?: string | undefined;
|
|
44
|
+
isOpen = false;
|
|
45
|
+
|
|
46
|
+
constructor(docEntry: LegendApplicationDocumentationEntry) {
|
|
47
|
+
makeObservable(this, {
|
|
48
|
+
isOpen: observable,
|
|
49
|
+
setIsOpen: action,
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
this.documentationKey = docEntry._documentationKey;
|
|
53
|
+
this.title = guaranteeNonEmptyString(docEntry.title);
|
|
54
|
+
this.content = docEntry.markdownText ?? docEntry.text;
|
|
55
|
+
this.url = docEntry.url;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
setIsOpen(val: boolean): void {
|
|
59
|
+
this.isOpen = val;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export class VirtualAssistantContextualDocumentationEntry {
|
|
64
|
+
uuid = uuid();
|
|
65
|
+
context: string;
|
|
66
|
+
title?: string | undefined;
|
|
67
|
+
content?: string | MarkdownText | undefined;
|
|
68
|
+
url?: string | undefined;
|
|
69
|
+
related: VirtualAssistantDocumentationEntry[];
|
|
70
|
+
|
|
71
|
+
constructor(
|
|
72
|
+
contextualDocEntry: LegendApplicationContextualDocumentationEntry,
|
|
73
|
+
related: VirtualAssistantDocumentationEntry[],
|
|
74
|
+
) {
|
|
75
|
+
this.context = contextualDocEntry._context;
|
|
76
|
+
this.title = contextualDocEntry.title;
|
|
77
|
+
this.content = contextualDocEntry.markdownText ?? contextualDocEntry.text;
|
|
78
|
+
this.url = contextualDocEntry.url;
|
|
79
|
+
this.related = related;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
export class LegendApplicationAssistantService {
|
|
84
|
+
readonly applicationStore: ApplicationStore<LegendApplicationConfig>;
|
|
85
|
+
private readonly searchEngine: Fuse<LegendApplicationDocumentationEntry>;
|
|
86
|
+
isHidden = false;
|
|
87
|
+
isOpen = false;
|
|
88
|
+
selectedTab = VIRTUAL_ASSISTANT_TAB.SEARCH;
|
|
89
|
+
|
|
90
|
+
searchResults: VirtualAssistantDocumentationEntry[] = [];
|
|
91
|
+
searchState = ActionState.create().pass();
|
|
92
|
+
searchText = '';
|
|
93
|
+
|
|
94
|
+
constructor(applicationStore: ApplicationStore<LegendApplicationConfig>) {
|
|
95
|
+
makeObservable(this, {
|
|
96
|
+
isHidden: observable,
|
|
97
|
+
isOpen: observable,
|
|
98
|
+
selectedTab: observable,
|
|
99
|
+
searchText: observable,
|
|
100
|
+
searchResults: observable,
|
|
101
|
+
currentContextualDocumentationEntry: computed,
|
|
102
|
+
setIsHidden: action,
|
|
103
|
+
setIsOpen: action,
|
|
104
|
+
setSelectedTab: action,
|
|
105
|
+
setSearchText: action,
|
|
106
|
+
resetSearch: action,
|
|
107
|
+
search: action,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
this.applicationStore = applicationStore;
|
|
111
|
+
this.searchEngine = new Fuse(
|
|
112
|
+
this.applicationStore.documentationService.getAllDocEntries().filter(
|
|
113
|
+
(entry) =>
|
|
114
|
+
// NOTE: since we're searching for user-friendly docs, we will discard anything that
|
|
115
|
+
// doesn't come with a title, or does not have any content/url
|
|
116
|
+
entry.title && (entry.url ?? entry.text ?? entry.markdownText),
|
|
117
|
+
),
|
|
118
|
+
{
|
|
119
|
+
includeScore: true,
|
|
120
|
+
shouldSort: true,
|
|
121
|
+
// Ignore location when computing the search score
|
|
122
|
+
// See https://fusejs.io/concepts/scoring-theory.html
|
|
123
|
+
ignoreLocation: true,
|
|
124
|
+
// This specifies the point the search gives up
|
|
125
|
+
// `0.0` means exact match where `1.0` would match anything
|
|
126
|
+
// We set a relatively low threshold to filter out irrelevant results
|
|
127
|
+
threshold: 0.2,
|
|
128
|
+
keys: [
|
|
129
|
+
{
|
|
130
|
+
// NOTE: for now, we would weight title the most
|
|
131
|
+
name: 'title',
|
|
132
|
+
weight: 4,
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
name: 'text',
|
|
136
|
+
weight: 1,
|
|
137
|
+
},
|
|
138
|
+
{
|
|
139
|
+
name: 'markdownText.value',
|
|
140
|
+
weight: 1,
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
get currentContextualDocumentationEntry():
|
|
148
|
+
| VirtualAssistantContextualDocumentationEntry
|
|
149
|
+
| undefined {
|
|
150
|
+
const currentContextualDocumentationEntry = this.applicationStore
|
|
151
|
+
.navigationContextService.currentContext
|
|
152
|
+
? this.applicationStore.documentationService.getContextualDocEntry(
|
|
153
|
+
this.applicationStore.navigationContextService.currentContext.value,
|
|
154
|
+
)
|
|
155
|
+
: undefined;
|
|
156
|
+
return currentContextualDocumentationEntry
|
|
157
|
+
? new VirtualAssistantContextualDocumentationEntry(
|
|
158
|
+
currentContextualDocumentationEntry,
|
|
159
|
+
currentContextualDocumentationEntry.related
|
|
160
|
+
.map((entry) =>
|
|
161
|
+
this.applicationStore.documentationService.getDocEntry(entry),
|
|
162
|
+
)
|
|
163
|
+
.filter(isNonNullable)
|
|
164
|
+
.filter(
|
|
165
|
+
(entry) =>
|
|
166
|
+
// NOTE: since we're searching for user-friendly docs, we will discard anything that
|
|
167
|
+
// doesn't come with a title, or does not have any content/url
|
|
168
|
+
entry.title && (entry.url ?? entry.text ?? entry.markdownText),
|
|
169
|
+
)
|
|
170
|
+
.map((entry) => new VirtualAssistantDocumentationEntry(entry)),
|
|
171
|
+
)
|
|
172
|
+
: undefined;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
setIsHidden(val: boolean): void {
|
|
176
|
+
this.isHidden = val;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
hideAssistant(): void {
|
|
180
|
+
this.setIsHidden(true);
|
|
181
|
+
this.setIsOpen(false);
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
toggleAssistant(): void {
|
|
185
|
+
const newVal = !this.isHidden;
|
|
186
|
+
if (newVal) {
|
|
187
|
+
this.hideAssistant();
|
|
188
|
+
} else {
|
|
189
|
+
this.setIsHidden(false);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
setIsOpen(val: boolean): void {
|
|
194
|
+
this.isOpen = val;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
setSelectedTab(val: VIRTUAL_ASSISTANT_TAB): void {
|
|
198
|
+
this.selectedTab = val;
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
setSearchText(val: string): void {
|
|
202
|
+
this.searchText = val;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
resetSearch(): void {
|
|
206
|
+
this.searchText = '';
|
|
207
|
+
this.searchResults = [];
|
|
208
|
+
this.searchState.complete();
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
search(): void {
|
|
212
|
+
this.searchState.inProgress();
|
|
213
|
+
this.searchResults = Array.from(
|
|
214
|
+
this.searchEngine.search(this.searchText).values(),
|
|
215
|
+
).map((result) => new VirtualAssistantDocumentationEntry(result.item));
|
|
216
|
+
this.searchState.complete();
|
|
217
|
+
}
|
|
218
|
+
}
|
|
@@ -17,13 +17,15 @@
|
|
|
17
17
|
import {
|
|
18
18
|
guaranteeNonEmptyString,
|
|
19
19
|
guaranteeNonNullable,
|
|
20
|
-
type PlainObject,
|
|
21
20
|
} from '@finos/legend-shared';
|
|
22
21
|
import {
|
|
23
22
|
type LegendApplicationKeyedDocumentationEntry,
|
|
24
|
-
type
|
|
23
|
+
type LegendApplicationDocumentationEntryConfig,
|
|
24
|
+
type LegendApplicationKeyedContextualDocumentationEntry,
|
|
25
|
+
type LegendApplicationContextualDocumentationEntryConfig,
|
|
25
26
|
collectKeyedDocumnetationEntriesFromConfig,
|
|
26
|
-
|
|
27
|
+
collectKeyedContextualDocumentationEntriesFromConfig,
|
|
28
|
+
} from './LegendApplicationDocumentationService.js';
|
|
27
29
|
|
|
28
30
|
export interface LegendApplicationVersionData {
|
|
29
31
|
buildTime: string;
|
|
@@ -36,7 +38,11 @@ export interface LegendApplicationConfigurationData {
|
|
|
36
38
|
env: string;
|
|
37
39
|
documentation?: {
|
|
38
40
|
url: string;
|
|
39
|
-
entries?: Record<string,
|
|
41
|
+
entries?: Record<string, LegendApplicationDocumentationEntryConfig>;
|
|
42
|
+
contextualEntries?: Record<
|
|
43
|
+
string,
|
|
44
|
+
LegendApplicationContextualDocumentationEntryConfig
|
|
45
|
+
>;
|
|
40
46
|
};
|
|
41
47
|
// TODO: when we support vault-like settings
|
|
42
48
|
// See https://github.com/finos/legend-studio/issues/407
|
|
@@ -49,10 +55,14 @@ export abstract class LegendApplicationConfig {
|
|
|
49
55
|
readonly baseUrl: string;
|
|
50
56
|
readonly env: string;
|
|
51
57
|
|
|
58
|
+
// documentation
|
|
52
59
|
readonly documentationUrl: string | undefined;
|
|
53
|
-
readonly
|
|
60
|
+
readonly keyedDocumentationEntries: LegendApplicationKeyedDocumentationEntry[] =
|
|
61
|
+
[];
|
|
62
|
+
readonly keyedContextualDocumentationEntries: LegendApplicationKeyedContextualDocumentationEntry[] =
|
|
54
63
|
[];
|
|
55
64
|
|
|
65
|
+
// version
|
|
56
66
|
readonly appVersion: string;
|
|
57
67
|
readonly appVersionBuildTime: string;
|
|
58
68
|
readonly appVersionCommitId: string;
|
|
@@ -74,9 +84,13 @@ export abstract class LegendApplicationConfig {
|
|
|
74
84
|
|
|
75
85
|
// Documentation
|
|
76
86
|
this.documentationUrl = configData.documentation?.url;
|
|
77
|
-
this.
|
|
87
|
+
this.keyedDocumentationEntries = collectKeyedDocumnetationEntriesFromConfig(
|
|
78
88
|
configData.documentation?.entries ?? {},
|
|
79
89
|
);
|
|
90
|
+
this.keyedContextualDocumentationEntries =
|
|
91
|
+
collectKeyedContextualDocumentationEntriesFromConfig(
|
|
92
|
+
configData.documentation?.contextualEntries ?? {},
|
|
93
|
+
);
|
|
80
94
|
|
|
81
95
|
// Version
|
|
82
96
|
this.appVersion = guaranteeNonNullable(
|
|
@@ -0,0 +1,276 @@
|
|
|
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 {
|
|
18
|
+
type MarkdownText,
|
|
19
|
+
type PlainObject,
|
|
20
|
+
type Writable,
|
|
21
|
+
SerializationFactory,
|
|
22
|
+
LogEvent,
|
|
23
|
+
uniq,
|
|
24
|
+
guaranteeNonNullable,
|
|
25
|
+
} from '@finos/legend-shared';
|
|
26
|
+
import {
|
|
27
|
+
createModelSchema,
|
|
28
|
+
custom,
|
|
29
|
+
list,
|
|
30
|
+
optional,
|
|
31
|
+
primitive,
|
|
32
|
+
} from 'serializr';
|
|
33
|
+
import { APPLICATION_EVENT } from './ApplicationEvent.js';
|
|
34
|
+
import type { ApplicationStore } from './ApplicationStore.js';
|
|
35
|
+
import type { LegendApplicationConfig } from './LegendApplicationConfig.js';
|
|
36
|
+
|
|
37
|
+
export type LegendApplicationDocumentationEntryConfig = {
|
|
38
|
+
markdownText?: MarkdownText | undefined;
|
|
39
|
+
title?: string | undefined;
|
|
40
|
+
text?: string | undefined;
|
|
41
|
+
url?: string | undefined;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export class LegendApplicationDocumentationEntry {
|
|
45
|
+
readonly _documentationKey!: string;
|
|
46
|
+
|
|
47
|
+
markdownText?: MarkdownText | undefined;
|
|
48
|
+
title?: string | undefined;
|
|
49
|
+
text?: string | undefined;
|
|
50
|
+
url?: string | undefined;
|
|
51
|
+
|
|
52
|
+
static readonly serialization = new SerializationFactory(
|
|
53
|
+
createModelSchema(LegendApplicationDocumentationEntry, {
|
|
54
|
+
markdownText: custom(
|
|
55
|
+
(val) => val,
|
|
56
|
+
(val) => (val.value ? val : undefined),
|
|
57
|
+
),
|
|
58
|
+
title: optional(primitive()),
|
|
59
|
+
text: optional(primitive()),
|
|
60
|
+
url: optional(primitive()),
|
|
61
|
+
}),
|
|
62
|
+
);
|
|
63
|
+
|
|
64
|
+
static create(
|
|
65
|
+
json: PlainObject<LegendApplicationDocumentationEntry>,
|
|
66
|
+
documentationKey: string,
|
|
67
|
+
): LegendApplicationDocumentationEntry {
|
|
68
|
+
const entry =
|
|
69
|
+
LegendApplicationDocumentationEntry.serialization.fromJson(json);
|
|
70
|
+
(entry as Writable<LegendApplicationDocumentationEntry>)._documentationKey =
|
|
71
|
+
documentationKey;
|
|
72
|
+
return entry;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export type LegendApplicationContextualDocumentationEntryConfig =
|
|
77
|
+
LegendApplicationDocumentationEntryConfig & {
|
|
78
|
+
related?: string[];
|
|
79
|
+
};
|
|
80
|
+
|
|
81
|
+
export class LegendApplicationContextualDocumentationEntry {
|
|
82
|
+
readonly _context!: string;
|
|
83
|
+
|
|
84
|
+
markdownText?: MarkdownText | undefined;
|
|
85
|
+
title?: string | undefined;
|
|
86
|
+
text?: string | undefined;
|
|
87
|
+
url?: string | undefined;
|
|
88
|
+
related: string[] = [];
|
|
89
|
+
|
|
90
|
+
static readonly serialization = new SerializationFactory(
|
|
91
|
+
createModelSchema(LegendApplicationContextualDocumentationEntry, {
|
|
92
|
+
markdownText: custom(
|
|
93
|
+
(val) => val,
|
|
94
|
+
(val) => (val.value ? val : undefined),
|
|
95
|
+
),
|
|
96
|
+
title: optional(primitive()),
|
|
97
|
+
text: optional(primitive()),
|
|
98
|
+
url: optional(primitive()),
|
|
99
|
+
related: list(primitive()),
|
|
100
|
+
}),
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
static create(
|
|
104
|
+
json: PlainObject<LegendApplicationContextualDocumentationEntry>,
|
|
105
|
+
context: string,
|
|
106
|
+
): LegendApplicationContextualDocumentationEntry {
|
|
107
|
+
const entry =
|
|
108
|
+
LegendApplicationContextualDocumentationEntry.serialization.fromJson(
|
|
109
|
+
json,
|
|
110
|
+
);
|
|
111
|
+
(
|
|
112
|
+
entry as Writable<LegendApplicationContextualDocumentationEntry>
|
|
113
|
+
)._context = context;
|
|
114
|
+
return entry;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
export interface LegendApplicationKeyedContextualDocumentationEntry {
|
|
119
|
+
key: string;
|
|
120
|
+
content: LegendApplicationContextualDocumentationEntry;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export const collectKeyedContextualDocumentationEntriesFromConfig = (
|
|
124
|
+
rawEntries: Record<
|
|
125
|
+
string,
|
|
126
|
+
LegendApplicationContextualDocumentationEntryConfig
|
|
127
|
+
>,
|
|
128
|
+
): LegendApplicationKeyedContextualDocumentationEntry[] =>
|
|
129
|
+
Object.entries(rawEntries).map((entry) => ({
|
|
130
|
+
key: entry[0],
|
|
131
|
+
content: LegendApplicationContextualDocumentationEntry.create(
|
|
132
|
+
entry[1],
|
|
133
|
+
entry[0],
|
|
134
|
+
),
|
|
135
|
+
}));
|
|
136
|
+
|
|
137
|
+
export interface LegendApplicationKeyedDocumentationEntry {
|
|
138
|
+
key: string;
|
|
139
|
+
content: LegendApplicationDocumentationEntry;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export const collectKeyedDocumnetationEntriesFromConfig = (
|
|
143
|
+
rawEntries: Record<string, LegendApplicationDocumentationEntryConfig>,
|
|
144
|
+
): LegendApplicationKeyedDocumentationEntry[] =>
|
|
145
|
+
Object.entries(rawEntries).map((entry) => ({
|
|
146
|
+
key: entry[0],
|
|
147
|
+
content: LegendApplicationDocumentationEntry.create(entry[1], entry[0]),
|
|
148
|
+
}));
|
|
149
|
+
|
|
150
|
+
export class LegendApplicationDocumentationService {
|
|
151
|
+
url?: string | undefined;
|
|
152
|
+
|
|
153
|
+
private docRegistry = new Map<string, LegendApplicationDocumentationEntry>();
|
|
154
|
+
private contextualDocRegistry = new Map<
|
|
155
|
+
string,
|
|
156
|
+
LegendApplicationContextualDocumentationEntry
|
|
157
|
+
>();
|
|
158
|
+
|
|
159
|
+
constructor(applicationStore: ApplicationStore<LegendApplicationConfig>) {
|
|
160
|
+
applicationStore.pluginManager
|
|
161
|
+
.getApplicationPlugins()
|
|
162
|
+
.flatMap((plugin) => plugin.getExtraKeyedDocumentationEntries?.() ?? [])
|
|
163
|
+
.forEach((entry) => {
|
|
164
|
+
// Entries specified natively will not override each other. This is to prevent entries from extensions
|
|
165
|
+
// overriding entries from core.
|
|
166
|
+
if (this.hasDocEntry(entry.key)) {
|
|
167
|
+
applicationStore.log.warn(
|
|
168
|
+
LogEvent.create(
|
|
169
|
+
APPLICATION_EVENT.APPLICATION_DOCUMTENTION_LOAD_SKIPPED,
|
|
170
|
+
),
|
|
171
|
+
entry.key,
|
|
172
|
+
);
|
|
173
|
+
} else {
|
|
174
|
+
this.docRegistry.set(entry.key, entry.content);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
// entries from config will override entries specified natively
|
|
178
|
+
applicationStore.config.keyedDocumentationEntries.forEach((entry) =>
|
|
179
|
+
this.docRegistry.set(entry.key, entry.content),
|
|
180
|
+
);
|
|
181
|
+
|
|
182
|
+
// Contextual Documentation
|
|
183
|
+
applicationStore.pluginManager
|
|
184
|
+
.getApplicationPlugins()
|
|
185
|
+
.flatMap(
|
|
186
|
+
(plugin) =>
|
|
187
|
+
plugin.getExtraKeyedContextualDocumentationEntries?.() ?? [],
|
|
188
|
+
)
|
|
189
|
+
.forEach((entry) => {
|
|
190
|
+
// Entries specified natively will not override each other. This is to prevent entries from extensions
|
|
191
|
+
// overriding entries from core. However, we will merge the list of related doc entries. This allows
|
|
192
|
+
// extensions to broaden related doc entries for certain contexts
|
|
193
|
+
if (this.hasContextualDocEntry(entry.key)) {
|
|
194
|
+
applicationStore.log.warn(
|
|
195
|
+
LogEvent.create(
|
|
196
|
+
APPLICATION_EVENT.APPLICATION_CONTEXTUAL_DOCUMTENTION_LOAD_SKIPPED,
|
|
197
|
+
),
|
|
198
|
+
entry.key,
|
|
199
|
+
);
|
|
200
|
+
const existingEntry = guaranteeNonNullable(
|
|
201
|
+
this.getContextualDocEntry(entry.key),
|
|
202
|
+
);
|
|
203
|
+
existingEntry.related = uniq([
|
|
204
|
+
...existingEntry.related,
|
|
205
|
+
...entry.content.related,
|
|
206
|
+
]);
|
|
207
|
+
} else {
|
|
208
|
+
this.contextualDocRegistry.set(entry.key, entry.content);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
// entries from config will override entries specified natively
|
|
212
|
+
// however, we will keep merging related doc entries list
|
|
213
|
+
applicationStore.config.keyedContextualDocumentationEntries.forEach(
|
|
214
|
+
(entry) => {
|
|
215
|
+
const existingEntry = this.getContextualDocEntry(entry.key);
|
|
216
|
+
if (existingEntry) {
|
|
217
|
+
entry.content.related = uniq([
|
|
218
|
+
...existingEntry.related,
|
|
219
|
+
...entry.content.related,
|
|
220
|
+
]);
|
|
221
|
+
}
|
|
222
|
+
this.contextualDocRegistry.set(entry.key, entry.content);
|
|
223
|
+
},
|
|
224
|
+
);
|
|
225
|
+
this.url = applicationStore.config.documentationUrl;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
getDocEntry(key: string): LegendApplicationDocumentationEntry | undefined {
|
|
229
|
+
return this.docRegistry.get(key);
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
hasDocEntry(key: string): boolean {
|
|
233
|
+
return this.docRegistry.has(key);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
getContextualDocEntry(
|
|
237
|
+
key: string,
|
|
238
|
+
): LegendApplicationContextualDocumentationEntry | undefined {
|
|
239
|
+
return this.contextualDocRegistry.get(key);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
hasContextualDocEntry(key: string): boolean {
|
|
243
|
+
return this.contextualDocRegistry.has(key);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
getAllDocEntries(): LegendApplicationDocumentationEntry[] {
|
|
247
|
+
return Array.from(this.docRegistry.values());
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
publishDocRegistry(): Record<
|
|
251
|
+
string,
|
|
252
|
+
LegendApplicationDocumentationEntryConfig
|
|
253
|
+
> {
|
|
254
|
+
const result: Record<string, LegendApplicationDocumentationEntryConfig> =
|
|
255
|
+
{};
|
|
256
|
+
this.docRegistry.forEach((value, key) => {
|
|
257
|
+
result[key] =
|
|
258
|
+
LegendApplicationDocumentationEntry.serialization.toJson(value);
|
|
259
|
+
});
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
publishContextualDocRegistry(): object {
|
|
264
|
+
const result: Record<
|
|
265
|
+
string,
|
|
266
|
+
LegendApplicationContextualDocumentationEntryConfig
|
|
267
|
+
> = {};
|
|
268
|
+
this.contextualDocRegistry.forEach((value, key) => {
|
|
269
|
+
result[key] =
|
|
270
|
+
LegendApplicationContextualDocumentationEntry.serialization.toJson(
|
|
271
|
+
value,
|
|
272
|
+
);
|
|
273
|
+
});
|
|
274
|
+
return result;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
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 type {
|
|
18
|
+
NotificationEventData,
|
|
19
|
+
EventNotifierPlugin,
|
|
20
|
+
} from '@finos/legend-shared';
|
|
21
|
+
|
|
22
|
+
export class LegendApplicationEventService {
|
|
23
|
+
private notifierPlugins: EventNotifierPlugin[] = [];
|
|
24
|
+
|
|
25
|
+
registerEventNotifierPlugins(plugins: EventNotifierPlugin[]): void {
|
|
26
|
+
this.notifierPlugins = plugins;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
notify(event: string, data: NotificationEventData): void {
|
|
30
|
+
this.notifierPlugins.forEach((plugin) => plugin.notify(event, data));
|
|
31
|
+
}
|
|
32
|
+
}
|