@finos/legend-application 4.0.3 → 5.1.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 +9 -1
- package/lib/application/LegendApplication.d.ts.map +1 -1
- package/lib/application/LegendApplication.js +54 -1
- package/lib/application/LegendApplication.js.map +1 -1
- package/lib/components/VirtualAssistant.d.ts.map +1 -1
- package/lib/components/VirtualAssistant.js +91 -11
- package/lib/components/VirtualAssistant.js.map +1 -1
- package/lib/components/{BasicValueSpecificationEditor.d.ts → shared/BasicValueSpecificationEditor.d.ts} +2 -2
- package/lib/components/shared/BasicValueSpecificationEditor.d.ts.map +1 -0
- package/lib/components/{BasicValueSpecificationEditor.js → shared/BasicValueSpecificationEditor.js} +29 -20
- package/lib/components/shared/BasicValueSpecificationEditor.js.map +1 -0
- package/lib/components/{CustomDatePicker.d.ts → shared/CustomDatePicker.d.ts} +1 -1
- package/lib/components/shared/CustomDatePicker.d.ts.map +1 -0
- package/lib/components/{CustomDatePicker.js → shared/CustomDatePicker.js} +20 -20
- package/lib/components/shared/CustomDatePicker.js.map +1 -0
- package/lib/components/{DocumentationLink.d.ts → shared/DocumentationLink.d.ts} +0 -0
- package/lib/components/shared/DocumentationLink.d.ts.map +1 -0
- package/lib/components/{DocumentationLink.js → shared/DocumentationLink.js} +1 -1
- package/lib/components/shared/DocumentationLink.js.map +1 -0
- package/lib/components/{LambdaEditor.d.ts → shared/LambdaEditor.d.ts} +1 -1
- package/lib/components/shared/LambdaEditor.d.ts.map +1 -0
- package/lib/components/{LambdaEditor.js → shared/LambdaEditor.js} +3 -3
- package/lib/components/shared/LambdaEditor.js.map +1 -0
- package/lib/components/{LambdaParameterValuesEditor.d.ts → shared/LambdaParameterValuesEditor.d.ts} +1 -1
- package/lib/components/shared/LambdaParameterValuesEditor.d.ts.map +1 -0
- package/lib/components/{LambdaParameterValuesEditor.js → shared/LambdaParameterValuesEditor.js} +2 -2
- package/lib/components/shared/LambdaParameterValuesEditor.js.map +1 -0
- package/lib/components/shared/PackageableElementOptionRenderer.d.ts +21 -0
- package/lib/components/shared/PackageableElementOptionRenderer.d.ts.map +1 -0
- package/lib/components/shared/PackageableElementOptionRenderer.js +8 -0
- package/lib/components/shared/PackageableElementOptionRenderer.js.map +1 -0
- package/lib/components/{TextInputEditor.d.ts → shared/TextInputEditor.d.ts} +1 -1
- package/lib/components/shared/TextInputEditor.d.ts.map +1 -0
- package/lib/components/{TextInputEditor.js → shared/TextInputEditor.js} +2 -2
- package/lib/components/shared/TextInputEditor.js.map +1 -0
- package/lib/components/shared/execution-plan-viewer/ExecutionPlanViewer.d.ts +28 -0
- package/lib/components/shared/execution-plan-viewer/ExecutionPlanViewer.d.ts.map +1 -0
- package/lib/components/shared/execution-plan-viewer/ExecutionPlanViewer.js +182 -0
- package/lib/components/shared/execution-plan-viewer/ExecutionPlanViewer.js.map +1 -0
- package/lib/components/shared/execution-plan-viewer/SQLExecutionNodeViewer.d.ts +31 -0
- package/lib/components/shared/execution-plan-viewer/SQLExecutionNodeViewer.d.ts.map +1 -0
- package/lib/components/shared/execution-plan-viewer/SQLExecutionNodeViewer.js +32 -0
- package/lib/components/shared/execution-plan-viewer/SQLExecutionNodeViewer.js.map +1 -0
- package/lib/const.d.ts +0 -3
- package/lib/const.d.ts.map +1 -1
- package/lib/const.js +0 -3
- 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 +12 -9
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +13 -9
- package/lib/index.js.map +1 -1
- package/lib/stores/ApplicationEvent.d.ts +4 -2
- package/lib/stores/ApplicationEvent.d.ts.map +1 -1
- package/lib/stores/ApplicationEvent.js +4 -2
- package/lib/stores/ApplicationEvent.js.map +1 -1
- package/lib/stores/ApplicationStore.d.ts.map +1 -1
- package/lib/stores/ApplicationStore.js +2 -1
- package/lib/stores/ApplicationStore.js.map +1 -1
- package/lib/stores/LegendApplicationAssistantService.d.ts +7 -2
- package/lib/stores/LegendApplicationAssistantService.d.ts.map +1 -1
- package/lib/stores/LegendApplicationAssistantService.js +22 -10
- package/lib/stores/LegendApplicationAssistantService.js.map +1 -1
- package/lib/stores/LegendApplicationConfig.d.ts +8 -5
- package/lib/stores/LegendApplicationConfig.d.ts.map +1 -1
- package/lib/stores/LegendApplicationConfig.js +15 -13
- package/lib/stores/LegendApplicationConfig.js.map +1 -1
- package/lib/stores/LegendApplicationDocumentationService.d.ts +34 -24
- package/lib/stores/LegendApplicationDocumentationService.d.ts.map +1 -1
- package/lib/stores/LegendApplicationDocumentationService.js +64 -60
- package/lib/stores/LegendApplicationDocumentationService.js.map +1 -1
- package/lib/stores/LegendApplicationPlugin.d.ts +14 -3
- 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 -3
- package/lib/stores/PureLanguageSupport.js.map +1 -1
- package/lib/stores/shared/ExecutionPlanState.d.ts +62 -0
- package/lib/stores/shared/ExecutionPlanState.d.ts.map +1 -0
- package/lib/stores/shared/ExecutionPlanState.js +118 -0
- package/lib/stores/shared/ExecutionPlanState.js.map +1 -0
- package/lib/stores/{LambdaEditorState.d.ts → shared/LambdaEditorState.d.ts} +0 -0
- package/lib/stores/shared/LambdaEditorState.d.ts.map +1 -0
- package/lib/stores/{LambdaEditorState.js → shared/LambdaEditorState.js} +0 -0
- package/lib/stores/shared/LambdaEditorState.js.map +1 -0
- package/lib/stores/{LambdaParameterState.d.ts → shared/LambdaParameterState.d.ts} +1 -3
- package/lib/stores/shared/LambdaParameterState.d.ts.map +1 -0
- package/lib/stores/{LambdaParameterState.js → shared/LambdaParameterState.js} +3 -52
- package/lib/stores/shared/LambdaParameterState.js.map +1 -0
- package/lib/stores/{PackageableElementOption.d.ts → shared/PackageableElementOption.d.ts} +0 -0
- package/lib/stores/shared/PackageableElementOption.d.ts.map +1 -0
- package/lib/stores/{PackageableElementOption.js → shared/PackageableElementOption.js} +0 -0
- package/lib/stores/shared/PackageableElementOption.js.map +1 -0
- package/lib/stores/{ValueSpecificationModifierHelper.d.ts → shared/ValueSpecificationModifierHelper.d.ts} +0 -0
- package/lib/stores/shared/ValueSpecificationModifierHelper.d.ts.map +1 -0
- package/lib/stores/{ValueSpecificationModifierHelper.js → shared/ValueSpecificationModifierHelper.js} +0 -0
- package/lib/stores/shared/ValueSpecificationModifierHelper.js.map +1 -0
- package/package.json +13 -12
- package/src/application/LegendApplication.tsx +100 -4
- package/src/components/VirtualAssistant.tsx +106 -16
- package/src/components/{BasicValueSpecificationEditor.tsx → shared/BasicValueSpecificationEditor.tsx} +50 -19
- package/src/components/{CustomDatePicker.tsx → shared/CustomDatePicker.tsx} +44 -27
- package/src/components/{DocumentationLink.tsx → shared/DocumentationLink.tsx} +1 -1
- package/src/components/{LambdaEditor.tsx → shared/LambdaEditor.tsx} +4 -4
- package/src/components/{LambdaParameterValuesEditor.tsx → shared/LambdaParameterValuesEditor.tsx} +5 -3
- package/src/components/shared/PackageableElementOptionRenderer.tsx +40 -0
- package/src/components/{TextInputEditor.tsx → shared/TextInputEditor.tsx} +2 -2
- package/src/components/shared/execution-plan-viewer/ExecutionPlanViewer.tsx +550 -0
- package/src/components/shared/execution-plan-viewer/SQLExecutionNodeViewer.tsx +46 -0
- package/src/const.ts +0 -5
- package/src/index.ts +16 -13
- package/src/stores/ApplicationEvent.ts +4 -2
- package/src/stores/ApplicationStore.ts +3 -1
- package/src/stores/LegendApplicationAssistantService.ts +30 -16
- package/src/stores/LegendApplicationConfig.ts +28 -27
- package/src/stores/LegendApplicationDocumentationService.ts +128 -124
- package/src/stores/LegendApplicationPlugin.ts +17 -3
- package/src/stores/PureLanguageSupport.ts +8 -3
- package/src/stores/shared/ExecutionPlanState.ts +154 -0
- package/src/stores/{LambdaEditorState.ts → shared/LambdaEditorState.ts} +0 -0
- package/src/stores/{LambdaParameterState.ts → shared/LambdaParameterState.ts} +2 -100
- package/src/stores/{PackageableElementOption.ts → shared/PackageableElementOption.ts} +0 -0
- package/src/stores/{ValueSpecificationModifierHelper.ts → shared/ValueSpecificationModifierHelper.ts} +0 -0
- package/tsconfig.json +14 -10
- package/lib/components/BasicValueSpecificationEditor.d.ts.map +0 -1
- package/lib/components/BasicValueSpecificationEditor.js.map +0 -1
- package/lib/components/CustomDatePicker.d.ts.map +0 -1
- package/lib/components/CustomDatePicker.js.map +0 -1
- package/lib/components/DocumentationLink.d.ts.map +0 -1
- package/lib/components/DocumentationLink.js.map +0 -1
- package/lib/components/LambdaEditor.d.ts.map +0 -1
- package/lib/components/LambdaEditor.js.map +0 -1
- package/lib/components/LambdaParameterValuesEditor.d.ts.map +0 -1
- package/lib/components/LambdaParameterValuesEditor.js.map +0 -1
- package/lib/components/TextInputEditor.d.ts.map +0 -1
- package/lib/components/TextInputEditor.js.map +0 -1
- package/lib/stores/LambdaEditorState.d.ts.map +0 -1
- package/lib/stores/LambdaEditorState.js.map +0 -1
- package/lib/stores/LambdaParameterState.d.ts.map +0 -1
- package/lib/stores/LambdaParameterState.js.map +0 -1
- package/lib/stores/PackageableElementOption.d.ts.map +0 -1
- package/lib/stores/PackageableElementOption.js.map +0 -1
- package/lib/stores/ValueSpecificationModifierHelper.d.ts.map +0 -1
- package/lib/stores/ValueSpecificationModifierHelper.js.map +0 -1
|
@@ -15,10 +15,7 @@
|
|
|
15
15
|
*/
|
|
16
16
|
|
|
17
17
|
import { action, makeObservable, observable, computed } from 'mobx';
|
|
18
|
-
import type {
|
|
19
|
-
LegendApplicationContextualDocumentationEntry,
|
|
20
|
-
LegendApplicationDocumentationEntry,
|
|
21
|
-
} from './LegendApplicationDocumentationService.js';
|
|
18
|
+
import type { LegendApplicationDocumentationEntry } from './LegendApplicationDocumentationService.js';
|
|
22
19
|
import type { LegendApplicationConfig } from './LegendApplicationConfig.js';
|
|
23
20
|
import type { ApplicationStore } from './ApplicationStore.js';
|
|
24
21
|
import { Fuse } from './CJS__Fuse.cjs';
|
|
@@ -69,13 +66,14 @@ export class VirtualAssistantContextualDocumentationEntry {
|
|
|
69
66
|
related: VirtualAssistantDocumentationEntry[];
|
|
70
67
|
|
|
71
68
|
constructor(
|
|
72
|
-
|
|
69
|
+
context: string,
|
|
70
|
+
docEntry: LegendApplicationDocumentationEntry,
|
|
73
71
|
related: VirtualAssistantDocumentationEntry[],
|
|
74
72
|
) {
|
|
75
|
-
this.context =
|
|
76
|
-
this.title =
|
|
77
|
-
this.content =
|
|
78
|
-
this.url =
|
|
73
|
+
this.context = context;
|
|
74
|
+
this.title = docEntry.title;
|
|
75
|
+
this.content = docEntry.markdownText ?? docEntry.text;
|
|
76
|
+
this.url = docEntry.url;
|
|
79
77
|
this.related = related;
|
|
80
78
|
}
|
|
81
79
|
}
|
|
@@ -83,6 +81,10 @@ export class VirtualAssistantContextualDocumentationEntry {
|
|
|
83
81
|
export class LegendApplicationAssistantService {
|
|
84
82
|
readonly applicationStore: ApplicationStore<LegendApplicationConfig>;
|
|
85
83
|
private readonly searchEngine: Fuse<LegendApplicationDocumentationEntry>;
|
|
84
|
+
/**
|
|
85
|
+
* This key is used to allow programmatic re-rendering of the assistant panel
|
|
86
|
+
*/
|
|
87
|
+
panelRenderingKey = uuid();
|
|
86
88
|
isHidden = false;
|
|
87
89
|
isOpen = false;
|
|
88
90
|
selectedTab = VIRTUAL_ASSISTANT_TAB.SEARCH;
|
|
@@ -95,6 +97,7 @@ export class LegendApplicationAssistantService {
|
|
|
95
97
|
makeObservable(this, {
|
|
96
98
|
isHidden: observable,
|
|
97
99
|
isOpen: observable,
|
|
100
|
+
panelRenderingKey: observable,
|
|
98
101
|
selectedTab: observable,
|
|
99
102
|
searchText: observable,
|
|
100
103
|
searchResults: observable,
|
|
@@ -105,6 +108,7 @@ export class LegendApplicationAssistantService {
|
|
|
105
108
|
setSearchText: action,
|
|
106
109
|
resetSearch: action,
|
|
107
110
|
search: action,
|
|
111
|
+
refreshPanelRendering: action,
|
|
108
112
|
});
|
|
109
113
|
|
|
110
114
|
this.applicationStore = applicationStore;
|
|
@@ -147,16 +151,20 @@ export class LegendApplicationAssistantService {
|
|
|
147
151
|
get currentContextualDocumentationEntry():
|
|
148
152
|
| VirtualAssistantContextualDocumentationEntry
|
|
149
153
|
| undefined {
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
if (!this.applicationStore.navigationContextService.currentContext) {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
const currentContext =
|
|
158
|
+
this.applicationStore.navigationContextService.currentContext.value;
|
|
159
|
+
const currentContextualDocumentationEntry =
|
|
160
|
+
this.applicationStore.documentationService.getContextualDocEntry(
|
|
161
|
+
currentContext,
|
|
162
|
+
);
|
|
156
163
|
return currentContextualDocumentationEntry
|
|
157
164
|
? new VirtualAssistantContextualDocumentationEntry(
|
|
165
|
+
currentContext,
|
|
158
166
|
currentContextualDocumentationEntry,
|
|
159
|
-
currentContextualDocumentationEntry.related
|
|
167
|
+
(currentContextualDocumentationEntry.related ?? [])
|
|
160
168
|
.map((entry) =>
|
|
161
169
|
this.applicationStore.documentationService.getDocEntry(entry),
|
|
162
170
|
)
|
|
@@ -165,6 +173,8 @@ export class LegendApplicationAssistantService {
|
|
|
165
173
|
(entry) =>
|
|
166
174
|
// NOTE: since we're searching for user-friendly docs, we will discard anything that
|
|
167
175
|
// doesn't come with a title, or does not have any content/url
|
|
176
|
+
//
|
|
177
|
+
// We could also consider having a flag in each documentation entry to be hidden from users
|
|
168
178
|
entry.title && (entry.url ?? entry.text ?? entry.markdownText),
|
|
169
179
|
)
|
|
170
180
|
.map((entry) => new VirtualAssistantDocumentationEntry(entry)),
|
|
@@ -198,6 +208,10 @@ export class LegendApplicationAssistantService {
|
|
|
198
208
|
this.selectedTab = val;
|
|
199
209
|
}
|
|
200
210
|
|
|
211
|
+
refreshPanelRendering(): void {
|
|
212
|
+
this.panelRenderingKey = uuid();
|
|
213
|
+
}
|
|
214
|
+
|
|
201
215
|
setSearchText(val: string): void {
|
|
202
216
|
this.searchText = val;
|
|
203
217
|
}
|
|
@@ -18,13 +18,15 @@ import {
|
|
|
18
18
|
guaranteeNonEmptyString,
|
|
19
19
|
guaranteeNonNullable,
|
|
20
20
|
} from '@finos/legend-shared';
|
|
21
|
+
import type { LegendApplicationConfigurationInput } from '../index.js';
|
|
21
22
|
import {
|
|
22
|
-
type LegendApplicationKeyedDocumentationEntry,
|
|
23
|
-
type LegendApplicationDocumentationEntryConfig,
|
|
24
|
-
type LegendApplicationKeyedContextualDocumentationEntry,
|
|
25
|
-
type LegendApplicationContextualDocumentationEntryConfig,
|
|
26
23
|
collectKeyedDocumnetationEntriesFromConfig,
|
|
27
|
-
|
|
24
|
+
collectContextualDocumnetationEntry,
|
|
25
|
+
type LegendApplicationKeyedDocumentationEntry,
|
|
26
|
+
type LegendApplicationDocumentationConfigEntry,
|
|
27
|
+
type LegendApplicationContextualDocumentationMapConfig,
|
|
28
|
+
type LegendApplicationContextualDocumentationEntry,
|
|
29
|
+
type LegendApplicationDocumentationRegistryEntry,
|
|
28
30
|
} from './LegendApplicationDocumentationService.js';
|
|
29
31
|
|
|
30
32
|
export interface LegendApplicationVersionData {
|
|
@@ -38,13 +40,11 @@ export interface LegendApplicationConfigurationData {
|
|
|
38
40
|
env: string;
|
|
39
41
|
documentation?: {
|
|
40
42
|
url: string;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
LegendApplicationContextualDocumentationEntryConfig
|
|
45
|
-
>;
|
|
43
|
+
registry?: LegendApplicationDocumentationRegistryEntry[];
|
|
44
|
+
entries?: Record<string, LegendApplicationDocumentationConfigEntry>;
|
|
45
|
+
contextualDocMap?: LegendApplicationContextualDocumentationMapConfig;
|
|
46
46
|
};
|
|
47
|
-
// TODO: when we support vault-like settings
|
|
47
|
+
// TODO: when we support vault-like settings, we could support `settingOverrides`
|
|
48
48
|
// See https://github.com/finos/legend-studio/issues/407
|
|
49
49
|
// settingOverrides
|
|
50
50
|
extensions?: Record<PropertyKey, unknown>;
|
|
@@ -57,9 +57,11 @@ export abstract class LegendApplicationConfig {
|
|
|
57
57
|
|
|
58
58
|
// documentation
|
|
59
59
|
readonly documentationUrl: string | undefined;
|
|
60
|
+
readonly documentationRegistryEntries: LegendApplicationDocumentationRegistryEntry[] =
|
|
61
|
+
[];
|
|
60
62
|
readonly keyedDocumentationEntries: LegendApplicationKeyedDocumentationEntry[] =
|
|
61
63
|
[];
|
|
62
|
-
readonly
|
|
64
|
+
readonly contextualDocEntries: LegendApplicationContextualDocumentationEntry[] =
|
|
63
65
|
[];
|
|
64
66
|
|
|
65
67
|
// version
|
|
@@ -68,41 +70,40 @@ export abstract class LegendApplicationConfig {
|
|
|
68
70
|
readonly appVersionCommitId: string;
|
|
69
71
|
|
|
70
72
|
constructor(
|
|
71
|
-
|
|
72
|
-
versionData: LegendApplicationVersionData,
|
|
73
|
-
baseUrl: string,
|
|
73
|
+
input: LegendApplicationConfigurationInput<LegendApplicationConfigurationData>,
|
|
74
74
|
) {
|
|
75
|
-
this.baseUrl = baseUrl;
|
|
75
|
+
this.baseUrl = input.baseUrl;
|
|
76
76
|
this.appName = guaranteeNonEmptyString(
|
|
77
|
-
configData.appName,
|
|
77
|
+
input.configData.appName,
|
|
78
78
|
`Can't configure application: 'appName' field is missing or empty`,
|
|
79
79
|
);
|
|
80
80
|
this.env = guaranteeNonEmptyString(
|
|
81
|
-
configData.env,
|
|
81
|
+
input.configData.env,
|
|
82
82
|
`Can't configure application: 'env' field is missing or empty`,
|
|
83
83
|
);
|
|
84
84
|
|
|
85
85
|
// Documentation
|
|
86
|
-
this.documentationUrl = configData.documentation?.url;
|
|
86
|
+
this.documentationUrl = input.configData.documentation?.url;
|
|
87
|
+
this.documentationRegistryEntries =
|
|
88
|
+
input.configData.documentation?.registry ?? [];
|
|
87
89
|
this.keyedDocumentationEntries = collectKeyedDocumnetationEntriesFromConfig(
|
|
88
|
-
configData.documentation?.entries ?? {},
|
|
90
|
+
input.configData.documentation?.entries ?? {},
|
|
91
|
+
);
|
|
92
|
+
this.contextualDocEntries = collectContextualDocumnetationEntry(
|
|
93
|
+
input.configData.documentation?.contextualDocMap ?? {},
|
|
89
94
|
);
|
|
90
|
-
this.keyedContextualDocumentationEntries =
|
|
91
|
-
collectKeyedContextualDocumentationEntriesFromConfig(
|
|
92
|
-
configData.documentation?.contextualEntries ?? {},
|
|
93
|
-
);
|
|
94
95
|
|
|
95
96
|
// Version
|
|
96
97
|
this.appVersion = guaranteeNonNullable(
|
|
97
|
-
versionData.version,
|
|
98
|
+
input.versionData.version,
|
|
98
99
|
`Can't collect application version: 'version' field is missing`,
|
|
99
100
|
);
|
|
100
101
|
this.appVersionBuildTime = guaranteeNonNullable(
|
|
101
|
-
versionData.buildTime,
|
|
102
|
+
input.versionData.buildTime,
|
|
102
103
|
`Can't collect application version: 'buildTime' field is missing`,
|
|
103
104
|
);
|
|
104
105
|
this.appVersionCommitId = guaranteeNonNullable(
|
|
105
|
-
versionData.commitSHA,
|
|
106
|
+
input.versionData.commitSHA,
|
|
106
107
|
`Can't collect application version: 'commitSHA' field is missing`,
|
|
107
108
|
);
|
|
108
109
|
}
|
|
@@ -21,7 +21,6 @@ import {
|
|
|
21
21
|
SerializationFactory,
|
|
22
22
|
LogEvent,
|
|
23
23
|
uniq,
|
|
24
|
-
guaranteeNonNullable,
|
|
25
24
|
} from '@finos/legend-shared';
|
|
26
25
|
import {
|
|
27
26
|
createModelSchema,
|
|
@@ -34,11 +33,34 @@ import { APPLICATION_EVENT } from './ApplicationEvent.js';
|
|
|
34
33
|
import type { ApplicationStore } from './ApplicationStore.js';
|
|
35
34
|
import type { LegendApplicationConfig } from './LegendApplicationConfig.js';
|
|
36
35
|
|
|
37
|
-
export type
|
|
36
|
+
export type LegendApplicationDocumentationRegistryEntry = {
|
|
37
|
+
url: string;
|
|
38
|
+
/**
|
|
39
|
+
* Sometimes, we don't need to expose an endpoint to get the documentation data
|
|
40
|
+
* we support the `simple` mode where the endpoint is really just a JSON
|
|
41
|
+
*
|
|
42
|
+
* The caveat about this mode is that the endpoint must have CORS enabled
|
|
43
|
+
* ideally, the CORS-enabled endpoint should be setup with "Access-Control-Allow-Origin", "*"
|
|
44
|
+
* (e.g. Github Pages - See https://stackoverflow.com/questions/26416727/cross-origin-resource-sharing-on-github-pages)
|
|
45
|
+
* With that, the network client used to fetch this request must also be simplified to not include credential
|
|
46
|
+
* See https://stackoverflow.com/questions/19743396/cors-cannot-use-wildcard-in-access-control-allow-origin-when-credentials-flag-i
|
|
47
|
+
*
|
|
48
|
+
* During development, an option is to use our mock-server or some sort of CORS proxies, for example `cors-anywhere`
|
|
49
|
+
* See https://cors-anywhere.herokuapp.com/
|
|
50
|
+
*/
|
|
51
|
+
simple?: boolean | undefined;
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
export type LegendApplicationDocumentationRegistryData = {
|
|
55
|
+
entries: Record<string, LegendApplicationDocumentationConfigEntry>;
|
|
56
|
+
};
|
|
57
|
+
|
|
58
|
+
export type LegendApplicationDocumentationConfigEntry = {
|
|
38
59
|
markdownText?: MarkdownText | undefined;
|
|
39
60
|
title?: string | undefined;
|
|
40
61
|
text?: string | undefined;
|
|
41
62
|
url?: string | undefined;
|
|
63
|
+
related?: string[] | undefined;
|
|
42
64
|
};
|
|
43
65
|
|
|
44
66
|
export class LegendApplicationDocumentationEntry {
|
|
@@ -48,6 +70,7 @@ export class LegendApplicationDocumentationEntry {
|
|
|
48
70
|
title?: string | undefined;
|
|
49
71
|
text?: string | undefined;
|
|
50
72
|
url?: string | undefined;
|
|
73
|
+
related?: string[] | undefined;
|
|
51
74
|
|
|
52
75
|
static readonly serialization = new SerializationFactory(
|
|
53
76
|
createModelSchema(LegendApplicationDocumentationEntry, {
|
|
@@ -55,6 +78,7 @@ export class LegendApplicationDocumentationEntry {
|
|
|
55
78
|
(val) => val,
|
|
56
79
|
(val) => (val.value ? val : undefined),
|
|
57
80
|
),
|
|
81
|
+
related: optional(list(primitive())),
|
|
58
82
|
title: optional(primitive()),
|
|
59
83
|
text: optional(primitive()),
|
|
60
84
|
url: optional(primitive()),
|
|
@@ -73,100 +97,70 @@ export class LegendApplicationDocumentationEntry {
|
|
|
73
97
|
}
|
|
74
98
|
}
|
|
75
99
|
|
|
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
100
|
export interface LegendApplicationKeyedDocumentationEntry {
|
|
138
101
|
key: string;
|
|
139
102
|
content: LegendApplicationDocumentationEntry;
|
|
140
103
|
}
|
|
141
104
|
|
|
142
105
|
export const collectKeyedDocumnetationEntriesFromConfig = (
|
|
143
|
-
rawEntries: Record<string,
|
|
106
|
+
rawEntries: Record<string, LegendApplicationDocumentationConfigEntry>,
|
|
144
107
|
): LegendApplicationKeyedDocumentationEntry[] =>
|
|
145
108
|
Object.entries(rawEntries).map((entry) => ({
|
|
146
109
|
key: entry[0],
|
|
147
110
|
content: LegendApplicationDocumentationEntry.create(entry[1], entry[0]),
|
|
148
111
|
}));
|
|
149
112
|
|
|
113
|
+
export type LegendApplicationContextualDocumentationMapConfig = Record<
|
|
114
|
+
string,
|
|
115
|
+
string
|
|
116
|
+
>;
|
|
117
|
+
export type LegendApplicationContextualDocumentationEntry = {
|
|
118
|
+
context: string;
|
|
119
|
+
documentationKey: string;
|
|
120
|
+
};
|
|
121
|
+
export const collectContextualDocumnetationEntry = (
|
|
122
|
+
contextualDocMap: LegendApplicationContextualDocumentationMapConfig,
|
|
123
|
+
): LegendApplicationContextualDocumentationEntry[] =>
|
|
124
|
+
Object.entries(contextualDocMap).map((entry) => ({
|
|
125
|
+
context: entry[0],
|
|
126
|
+
documentationKey: entry[1],
|
|
127
|
+
}));
|
|
128
|
+
|
|
150
129
|
export class LegendApplicationDocumentationService {
|
|
151
130
|
url?: string | undefined;
|
|
152
131
|
|
|
153
132
|
private docRegistry = new Map<string, LegendApplicationDocumentationEntry>();
|
|
154
|
-
private
|
|
133
|
+
private contextualDocMap = new Map<
|
|
155
134
|
string,
|
|
156
|
-
|
|
135
|
+
LegendApplicationDocumentationEntry
|
|
157
136
|
>();
|
|
158
137
|
|
|
159
138
|
constructor(applicationStore: ApplicationStore<LegendApplicationConfig>) {
|
|
139
|
+
// set the main documenation site url
|
|
140
|
+
this.url = applicationStore.config.documentationUrl;
|
|
141
|
+
|
|
142
|
+
/**
|
|
143
|
+
* NOTE: the order of documentation entry overidding is (the later override the former):
|
|
144
|
+
* 1. Natively specified: specified in the codebase (no overriding allowed within this group of documentation entries):
|
|
145
|
+
* since we have extension mechanism, the order of plugins matter,
|
|
146
|
+
* we do not allow overriding, i.e. so the first specification for a documentation key wins
|
|
147
|
+
* 2. Fetched from documentation registries (no overriding allowed within this group of documentation entries):
|
|
148
|
+
* since we have extension mechanism and allow specifying multiple registry URLS,
|
|
149
|
+
* we do not allow overriding, i.e. so the first specification for a documentation key wins
|
|
150
|
+
* 3. Configured in application config (overiding allowed within this group)
|
|
151
|
+
*/
|
|
152
|
+
|
|
153
|
+
// build doc registry
|
|
160
154
|
applicationStore.pluginManager
|
|
161
155
|
.getApplicationPlugins()
|
|
162
156
|
.flatMap((plugin) => plugin.getExtraKeyedDocumentationEntries?.() ?? [])
|
|
163
157
|
.forEach((entry) => {
|
|
164
|
-
// Entries specified natively will not override each other. This is to prevent entries from extensions
|
|
165
|
-
//
|
|
158
|
+
// NOTE: Entries specified natively will not override each other. This is to prevent entries from extensions
|
|
159
|
+
// accidentally overide entries from core.
|
|
166
160
|
if (this.hasDocEntry(entry.key)) {
|
|
167
161
|
applicationStore.log.warn(
|
|
168
162
|
LogEvent.create(
|
|
169
|
-
APPLICATION_EVENT.
|
|
163
|
+
APPLICATION_EVENT.APPLICATION_DOCUMENTATION_LOAD_SKIPPED,
|
|
170
164
|
),
|
|
171
165
|
entry.key,
|
|
172
166
|
);
|
|
@@ -174,55 +168,71 @@ export class LegendApplicationDocumentationService {
|
|
|
174
168
|
this.docRegistry.set(entry.key, entry.content);
|
|
175
169
|
}
|
|
176
170
|
});
|
|
171
|
+
|
|
177
172
|
// entries from config will override entries specified natively
|
|
178
173
|
applicationStore.config.keyedDocumentationEntries.forEach((entry) =>
|
|
179
174
|
this.docRegistry.set(entry.key, entry.content),
|
|
180
175
|
);
|
|
181
176
|
|
|
182
|
-
|
|
183
|
-
applicationStore.pluginManager
|
|
177
|
+
const contextualDocEntries = applicationStore.pluginManager
|
|
184
178
|
.getApplicationPlugins()
|
|
185
179
|
.flatMap(
|
|
186
|
-
(plugin) =>
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
180
|
+
(plugin) => plugin.getExtraContextualDocumentationEntries?.() ?? [],
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
// verify that required documentations are available
|
|
184
|
+
const missingDocumentationEntries: string[] = [];
|
|
185
|
+
uniq(
|
|
186
|
+
applicationStore.pluginManager
|
|
187
|
+
.getApplicationPlugins()
|
|
188
|
+
.flatMap((plugin) => plugin.getExtraRequiredDocumentationKeys?.() ?? [])
|
|
189
|
+
.concat(contextualDocEntries.map((entry) => entry.documentationKey)),
|
|
190
|
+
).forEach((key) => {
|
|
191
|
+
if (!this.docRegistry.has(key)) {
|
|
192
|
+
missingDocumentationEntries.push(key);
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
if (missingDocumentationEntries.length) {
|
|
196
|
+
applicationStore.log.warn(
|
|
197
|
+
LogEvent.create(
|
|
198
|
+
APPLICATION_EVENT.APPLICATION_DOCUMENTATION_REQUIREMENT_CHECK_FAILURE,
|
|
199
|
+
),
|
|
200
|
+
`Can't find corresponding documentation entry for keys:\n${missingDocumentationEntries
|
|
201
|
+
.map((key) => `- ${key}`)
|
|
202
|
+
.join('\n')}`,
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// Contextual Documentation
|
|
207
|
+
contextualDocEntries.forEach((entry) => {
|
|
208
|
+
// NOTE: Entries specified natively will not override each other. This is to prevent entries from extensions
|
|
209
|
+
// overriding entries from core.
|
|
210
|
+
//
|
|
211
|
+
// However, it might be useful to allow extending the list of related doc entries.
|
|
212
|
+
// This allows extensions to broaden related doc entries for contextual docs
|
|
213
|
+
// If we need to support this behavior, we could create a dedicated extension method
|
|
214
|
+
if (this.hasContextualDocEntry(entry.context)) {
|
|
215
|
+
applicationStore.log.warn(
|
|
216
|
+
LogEvent.create(
|
|
217
|
+
APPLICATION_EVENT.APPLICATION_CONTEXTUAL_DOCUMENTATION_LOAD_SKIPPED,
|
|
218
|
+
),
|
|
219
|
+
entry.context,
|
|
220
|
+
);
|
|
221
|
+
} else {
|
|
222
|
+
const existingDocEntry = this.getDocEntry(entry.documentationKey);
|
|
223
|
+
if (existingDocEntry) {
|
|
224
|
+
this.contextualDocMap.set(entry.context, existingDocEntry);
|
|
209
225
|
}
|
|
210
|
-
}
|
|
226
|
+
}
|
|
227
|
+
});
|
|
228
|
+
|
|
211
229
|
// entries from config will override entries specified natively
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
(
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
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;
|
|
230
|
+
applicationStore.config.contextualDocEntries.forEach((entry) => {
|
|
231
|
+
const existingDocEntry = this.getDocEntry(entry.documentationKey);
|
|
232
|
+
if (existingDocEntry) {
|
|
233
|
+
this.contextualDocMap.set(entry.context, existingDocEntry);
|
|
234
|
+
}
|
|
235
|
+
});
|
|
226
236
|
}
|
|
227
237
|
|
|
228
238
|
getDocEntry(key: string): LegendApplicationDocumentationEntry | undefined {
|
|
@@ -235,12 +245,12 @@ export class LegendApplicationDocumentationService {
|
|
|
235
245
|
|
|
236
246
|
getContextualDocEntry(
|
|
237
247
|
key: string,
|
|
238
|
-
):
|
|
239
|
-
return this.
|
|
248
|
+
): LegendApplicationDocumentationEntry | undefined {
|
|
249
|
+
return this.contextualDocMap.get(key);
|
|
240
250
|
}
|
|
241
251
|
|
|
242
252
|
hasContextualDocEntry(key: string): boolean {
|
|
243
|
-
return this.
|
|
253
|
+
return this.contextualDocMap.has(key);
|
|
244
254
|
}
|
|
245
255
|
|
|
246
256
|
getAllDocEntries(): LegendApplicationDocumentationEntry[] {
|
|
@@ -249,9 +259,9 @@ export class LegendApplicationDocumentationService {
|
|
|
249
259
|
|
|
250
260
|
publishDocRegistry(): Record<
|
|
251
261
|
string,
|
|
252
|
-
|
|
262
|
+
LegendApplicationDocumentationConfigEntry
|
|
253
263
|
> {
|
|
254
|
-
const result: Record<string,
|
|
264
|
+
const result: Record<string, LegendApplicationDocumentationConfigEntry> =
|
|
255
265
|
{};
|
|
256
266
|
this.docRegistry.forEach((value, key) => {
|
|
257
267
|
result[key] =
|
|
@@ -260,16 +270,10 @@ export class LegendApplicationDocumentationService {
|
|
|
260
270
|
return result;
|
|
261
271
|
}
|
|
262
272
|
|
|
263
|
-
|
|
264
|
-
const result:
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
> = {};
|
|
268
|
-
this.contextualDocRegistry.forEach((value, key) => {
|
|
269
|
-
result[key] =
|
|
270
|
-
LegendApplicationContextualDocumentationEntry.serialization.toJson(
|
|
271
|
-
value,
|
|
272
|
-
);
|
|
273
|
+
publishContextualDocMap(): LegendApplicationContextualDocumentationMapConfig {
|
|
274
|
+
const result: LegendApplicationContextualDocumentationMapConfig = {};
|
|
275
|
+
this.contextualDocMap.forEach((value, key) => {
|
|
276
|
+
result[key] = value._documentationKey;
|
|
273
277
|
});
|
|
274
278
|
return result;
|
|
275
279
|
}
|
|
@@ -16,18 +16,32 @@
|
|
|
16
16
|
|
|
17
17
|
import { AbstractPlugin } from '@finos/legend-shared';
|
|
18
18
|
import type {
|
|
19
|
-
|
|
19
|
+
LegendApplicationContextualDocumentationEntry,
|
|
20
|
+
LegendApplicationDocumentationRegistryEntry,
|
|
20
21
|
LegendApplicationKeyedDocumentationEntry,
|
|
21
22
|
} from './LegendApplicationDocumentationService.js';
|
|
22
23
|
|
|
23
24
|
export abstract class LegendApplicationPlugin extends AbstractPlugin {
|
|
25
|
+
/**
|
|
26
|
+
* Get the list of documentation registry entries from which the application can fetch
|
|
27
|
+
* documentation config data and load the documentation registry
|
|
28
|
+
*/
|
|
29
|
+
getExtraDocumentationRegistryEntries?(): LegendApplicationDocumentationRegistryEntry[];
|
|
30
|
+
|
|
24
31
|
/**
|
|
25
32
|
* Get the list of keyed documentation entries to be registered with documentation service.
|
|
26
33
|
*/
|
|
27
34
|
getExtraKeyedDocumentationEntries?(): LegendApplicationKeyedDocumentationEntry[];
|
|
28
35
|
|
|
29
36
|
/**
|
|
30
|
-
* Get the list of
|
|
37
|
+
* Get the list of documentation keys whose corresponding documentation entry is required
|
|
38
|
+
* in the application. The documentation registry will be scanned for the presence of these,
|
|
39
|
+
* if they are not available, warnings will be issued.
|
|
40
|
+
*/
|
|
41
|
+
getExtraRequiredDocumentationKeys?(): string[];
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Get the list of contextual documentation entries to be registered with documentation service.
|
|
31
45
|
*/
|
|
32
|
-
|
|
46
|
+
getExtraContextualDocumentationEntries?(): LegendApplicationContextualDocumentationEntry[];
|
|
33
47
|
}
|
|
@@ -137,15 +137,20 @@ const generateLanguageMonarch = (
|
|
|
137
137
|
PURE_CONNECTION_NAME.JSON_MODEL_CONNECTION,
|
|
138
138
|
PURE_CONNECTION_NAME.MODEL_CHAIN_CONNECTION,
|
|
139
139
|
PURE_CONNECTION_NAME.XML_MODEL_CONNECTION,
|
|
140
|
-
PURE_CONNECTION_NAME.FLAT_DATA_CONNECTION,
|
|
141
|
-
PURE_CONNECTION_NAME.RELATIONAL_DATABASE_CONNECTION,
|
|
142
140
|
// mapping
|
|
141
|
+
'include',
|
|
143
142
|
'EnumerationMapping',
|
|
144
143
|
'Pure',
|
|
145
|
-
'Relational', // to be modularized
|
|
146
144
|
'AssociationMapping',
|
|
147
145
|
'XStore',
|
|
148
146
|
'AggregationAware',
|
|
147
|
+
/**
|
|
148
|
+
* @modularize
|
|
149
|
+
* See https://github.com/finos/legend-studio/issues/65
|
|
150
|
+
*/
|
|
151
|
+
PURE_CONNECTION_NAME.FLAT_DATA_CONNECTION,
|
|
152
|
+
PURE_CONNECTION_NAME.RELATIONAL_DATABASE_CONNECTION,
|
|
153
|
+
'Relational',
|
|
149
154
|
],
|
|
150
155
|
|
|
151
156
|
operators: [
|