@finos/legend-application-studio 22.5.0 → 22.6.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/components/editor/ActivityBar.d.ts.map +1 -1
- package/lib/components/editor/ActivityBar.js +6 -1
- package/lib/components/editor/ActivityBar.js.map +1 -1
- package/lib/components/editor/edit-panel/service-editor/BulkServiceRegistrationEditor.d.ts +20 -0
- package/lib/components/editor/edit-panel/service-editor/BulkServiceRegistrationEditor.d.ts.map +1 -0
- package/lib/components/editor/edit-panel/service-editor/BulkServiceRegistrationEditor.js +98 -0
- package/lib/components/editor/edit-panel/service-editor/BulkServiceRegistrationEditor.js.map +1 -0
- package/lib/components/editor/side-bar/RegisterService.d.ts +8 -0
- package/lib/components/editor/side-bar/RegisterService.d.ts.map +1 -0
- package/lib/components/editor/side-bar/RegisterService.js +35 -0
- package/lib/components/editor/side-bar/RegisterService.js.map +1 -0
- package/lib/components/editor/side-bar/SideBar.d.ts.map +1 -1
- package/lib/components/editor/side-bar/SideBar.js +3 -0
- package/lib/components/editor/side-bar/SideBar.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/EditorConfig.d.ts +2 -1
- package/lib/stores/EditorConfig.d.ts.map +1 -1
- package/lib/stores/EditorConfig.js +1 -0
- package/lib/stores/EditorConfig.js.map +1 -1
- package/lib/stores/EditorStore.d.ts +2 -0
- package/lib/stores/EditorStore.d.ts.map +1 -1
- package/lib/stores/EditorStore.js +3 -0
- package/lib/stores/EditorStore.js.map +1 -1
- package/lib/stores/sidebar-state/BulkServiceRegistrationState.d.ts +51 -0
- package/lib/stores/sidebar-state/BulkServiceRegistrationState.d.ts.map +1 -0
- package/lib/stores/sidebar-state/BulkServiceRegistrationState.js +237 -0
- package/lib/stores/sidebar-state/BulkServiceRegistrationState.js.map +1 -0
- package/package.json +5 -5
- package/src/components/editor/ActivityBar.tsx +6 -0
- package/src/components/editor/edit-panel/service-editor/BulkServiceRegistrationEditor.tsx +283 -0
- package/src/components/editor/side-bar/RegisterService.tsx +139 -0
- package/src/components/editor/side-bar/SideBar.tsx +9 -0
- package/src/stores/EditorConfig.ts +1 -0
- package/src/stores/EditorStore.ts +6 -0
- package/src/stores/sidebar-state/BulkServiceRegistrationState.ts +370 -0
- package/tsconfig.json +3 -0
|
@@ -0,0 +1,139 @@
|
|
|
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
|
+
import { useState } from 'react';
|
|
17
|
+
import { observer } from 'mobx-react-lite';
|
|
18
|
+
import { LEGEND_STUDIO_TEST_ID } from '../../LegendStudioTestID.js';
|
|
19
|
+
import { useEditorStore } from '../EditorStoreProvider.js';
|
|
20
|
+
import {
|
|
21
|
+
ContextMenu,
|
|
22
|
+
PanelContent,
|
|
23
|
+
PURE_ServiceIcon,
|
|
24
|
+
clsx,
|
|
25
|
+
PlayIcon,
|
|
26
|
+
Dialog,
|
|
27
|
+
Modal,
|
|
28
|
+
TimesIcon,
|
|
29
|
+
EmptyWindowRestoreIcon,
|
|
30
|
+
WindowMaximizeIcon,
|
|
31
|
+
} from '@finos/legend-art';
|
|
32
|
+
import type { BulkServiceRegistrationState } from '../../../stores/sidebar-state/BulkServiceRegistrationState.js';
|
|
33
|
+
import { BulkServiceRegistrationEditor } from '../edit-panel/service-editor/BulkServiceRegistrationEditor.js';
|
|
34
|
+
import { noop } from '@finos/legend-shared';
|
|
35
|
+
|
|
36
|
+
export const RegisterService = observer(
|
|
37
|
+
(props: { bulkServiceRegistrationState: BulkServiceRegistrationState }) => {
|
|
38
|
+
const editorStore = useEditorStore();
|
|
39
|
+
const services = editorStore.graphManagerState.graph.ownServices;
|
|
40
|
+
const [open, setOpen] = useState(false);
|
|
41
|
+
|
|
42
|
+
const [isMaximized, setIsMaximized] = useState(false);
|
|
43
|
+
const toggleMaximize = (): void => setIsMaximized(!isMaximized);
|
|
44
|
+
|
|
45
|
+
const renderTestables = (): React.ReactNode => (
|
|
46
|
+
<>
|
|
47
|
+
{services.map((service) => (
|
|
48
|
+
<ContextMenu key={service._UUID}>
|
|
49
|
+
<div
|
|
50
|
+
className={clsx(
|
|
51
|
+
'tree-view__node__container global-test-runner__explorer__testable-tree__node__container',
|
|
52
|
+
)}
|
|
53
|
+
>
|
|
54
|
+
<div className="global-test-runner__explorer__testable-tree__node__result__icon__type">
|
|
55
|
+
<PURE_ServiceIcon />
|
|
56
|
+
</div>
|
|
57
|
+
<div className="global-test-runner__item__link__content">
|
|
58
|
+
<span className="global-test-runner__item__link__content__id">
|
|
59
|
+
{service.name}
|
|
60
|
+
</span>
|
|
61
|
+
</div>
|
|
62
|
+
</div>
|
|
63
|
+
</ContextMenu>
|
|
64
|
+
))}
|
|
65
|
+
</>
|
|
66
|
+
);
|
|
67
|
+
|
|
68
|
+
return (
|
|
69
|
+
<div
|
|
70
|
+
data-testid={LEGEND_STUDIO_TEST_ID.GLOBAL_TEST_RUNNER}
|
|
71
|
+
className="panel global-test-runner"
|
|
72
|
+
>
|
|
73
|
+
<div className="panel__header side-bar__header">
|
|
74
|
+
<div className="panel__header__title global-test-runner__header__title">
|
|
75
|
+
<div className="panel__header__title__content side-bar__header__title__content">
|
|
76
|
+
REGISTER SERVICES
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
<div className="panel__header__actions side-bar__header__actions"></div>
|
|
80
|
+
<button
|
|
81
|
+
className="panel__header__action side-bar__header__action global-test-runner__refresh-btn"
|
|
82
|
+
onClick={() => setOpen(true)}
|
|
83
|
+
tabIndex={-1}
|
|
84
|
+
title="Register All Services"
|
|
85
|
+
>
|
|
86
|
+
<PlayIcon />
|
|
87
|
+
</button>
|
|
88
|
+
<Dialog onClose={noop} open={open}>
|
|
89
|
+
<Modal
|
|
90
|
+
darkMode={true}
|
|
91
|
+
className={clsx('editor-modal query-builder__dialog', {
|
|
92
|
+
'query-builder__dialog--expanded': isMaximized,
|
|
93
|
+
})}
|
|
94
|
+
>
|
|
95
|
+
<div className="query-builder__dialog__header">
|
|
96
|
+
<div className="query-builder__dialog__header__actions"></div>
|
|
97
|
+
<button
|
|
98
|
+
className="query-builder__dialog__header__action"
|
|
99
|
+
tabIndex={-1}
|
|
100
|
+
onClick={toggleMaximize}
|
|
101
|
+
>
|
|
102
|
+
{isMaximized ? (
|
|
103
|
+
<EmptyWindowRestoreIcon />
|
|
104
|
+
) : (
|
|
105
|
+
<WindowMaximizeIcon />
|
|
106
|
+
)}
|
|
107
|
+
</button>
|
|
108
|
+
<button
|
|
109
|
+
className="query-builder__dialog__header__action"
|
|
110
|
+
tabIndex={-1}
|
|
111
|
+
onClick={() => setOpen(false)}
|
|
112
|
+
>
|
|
113
|
+
<TimesIcon />
|
|
114
|
+
</button>
|
|
115
|
+
</div>
|
|
116
|
+
<BulkServiceRegistrationEditor />;
|
|
117
|
+
</Modal>
|
|
118
|
+
</Dialog>
|
|
119
|
+
</div>
|
|
120
|
+
<div className="panel__content side-bar__content">
|
|
121
|
+
<div className="panel side-bar__panel">
|
|
122
|
+
<div className="panel__header">
|
|
123
|
+
<div className="panel__header__title">
|
|
124
|
+
<div className="panel__header__title__content">SERVICES</div>
|
|
125
|
+
</div>
|
|
126
|
+
<div
|
|
127
|
+
className="side-bar__panel__header__changes-count"
|
|
128
|
+
data-testid={
|
|
129
|
+
LEGEND_STUDIO_TEST_ID.SIDEBAR_PANEL_HEADER__CHANGES_COUNT
|
|
130
|
+
}
|
|
131
|
+
></div>
|
|
132
|
+
</div>
|
|
133
|
+
<PanelContent>{renderTestables()}</PanelContent>
|
|
134
|
+
</div>
|
|
135
|
+
</div>
|
|
136
|
+
</div>
|
|
137
|
+
);
|
|
138
|
+
},
|
|
139
|
+
);
|
|
@@ -25,6 +25,7 @@ import { ProjectOverview } from './ProjectOverview.js';
|
|
|
25
25
|
import { WorkflowManager } from './WorkflowManager.js';
|
|
26
26
|
import { useEditorStore } from '../EditorStoreProvider.js';
|
|
27
27
|
import { GlobalTestRunner } from './testable/GlobalTestRunner.js';
|
|
28
|
+
import { RegisterService } from './RegisterService.js';
|
|
28
29
|
|
|
29
30
|
/**
|
|
30
31
|
* Wrapper component around different implementations of sidebar, such as to view domain, to manage SDLC, etc.
|
|
@@ -58,6 +59,14 @@ export const SideBar = observer(() => {
|
|
|
58
59
|
globalTestRunnerState={editorStore.globalTestRunnerState}
|
|
59
60
|
/>
|
|
60
61
|
);
|
|
62
|
+
case ACTIVITY_MODE.REGISTER_SERVICES:
|
|
63
|
+
return (
|
|
64
|
+
<RegisterService
|
|
65
|
+
bulkServiceRegistrationState={
|
|
66
|
+
editorStore.bulkServiceRegistrationState
|
|
67
|
+
}
|
|
68
|
+
/>
|
|
69
|
+
);
|
|
61
70
|
default:
|
|
62
71
|
return null;
|
|
63
72
|
}
|
|
@@ -138,6 +138,7 @@ import { EmbeddedQueryBuilderState } from './EmbeddedQueryBuilderState.js';
|
|
|
138
138
|
import { LEGEND_STUDIO_COMMAND_KEY } from './LegendStudioCommand.js';
|
|
139
139
|
import { EditorTabManagerState } from './EditorTabManagerState.js';
|
|
140
140
|
import type { ProjectViewerEditorMode } from './project-viewer/ProjectViewerEditorMode.js';
|
|
141
|
+
import { BulkServiceRegistrationState } from './sidebar-state/BulkServiceRegistrationState.js';
|
|
141
142
|
|
|
142
143
|
export abstract class EditorExtensionState {
|
|
143
144
|
/**
|
|
@@ -183,6 +184,7 @@ export class EditorStore implements CommandRegistrar {
|
|
|
183
184
|
devToolState: DevToolState;
|
|
184
185
|
embeddedQueryBuilderState: EmbeddedQueryBuilderState;
|
|
185
186
|
newElementState: NewElementState;
|
|
187
|
+
bulkServiceRegistrationState: BulkServiceRegistrationState;
|
|
186
188
|
/**
|
|
187
189
|
* Since we want to share element generation state across all element in the editor, we will create 1 element generate state
|
|
188
190
|
* per file generation configuration type.
|
|
@@ -281,6 +283,10 @@ export class EditorStore implements CommandRegistrar {
|
|
|
281
283
|
this.sdlcState,
|
|
282
284
|
);
|
|
283
285
|
this.newElementState = new NewElementState(this);
|
|
286
|
+
this.bulkServiceRegistrationState = new BulkServiceRegistrationState(
|
|
287
|
+
this,
|
|
288
|
+
this.sdlcState,
|
|
289
|
+
);
|
|
284
290
|
// special (singleton) editors
|
|
285
291
|
this.grammarTextEditorState = new GrammarTextEditorState(this);
|
|
286
292
|
this.modelImporterState = new ModelImporterState(this);
|
|
@@ -0,0 +1,370 @@
|
|
|
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
|
+
import { action, computed, makeObservable, observable, flow } from 'mobx';
|
|
17
|
+
import type { EditorSDLCState } from '../EditorSDLCState.js';
|
|
18
|
+
import type { EditorStore } from '../EditorStore.js';
|
|
19
|
+
import {
|
|
20
|
+
type PureExecution,
|
|
21
|
+
areMultiplicitiesEqual,
|
|
22
|
+
buildLambdaVariableExpressions,
|
|
23
|
+
generateMultiplicityString,
|
|
24
|
+
Multiplicity,
|
|
25
|
+
VariableExpression,
|
|
26
|
+
ServiceExecutionMode,
|
|
27
|
+
type BulkRegistrationResultFail,
|
|
28
|
+
BulkRegistrationResultSuccess,
|
|
29
|
+
type BulkServiceRegistrationResult,
|
|
30
|
+
} from '@finos/legend-graph';
|
|
31
|
+
import {
|
|
32
|
+
type GeneratorFn,
|
|
33
|
+
ActionState,
|
|
34
|
+
assertNonEmptyString,
|
|
35
|
+
assertTrue,
|
|
36
|
+
filterByType,
|
|
37
|
+
getNullableFirstElement,
|
|
38
|
+
guaranteeNonNullable,
|
|
39
|
+
prettyCONSTName,
|
|
40
|
+
UnsupportedOperationError,
|
|
41
|
+
assertErrorThrown,
|
|
42
|
+
LogEvent,
|
|
43
|
+
} from '@finos/legend-shared';
|
|
44
|
+
import { Version } from '@finos/legend-server-sdlc';
|
|
45
|
+
import { MINIMUM_SERVICE_OWNERS } from '../editor-state/element-editor-state/service/ServiceEditorState.js';
|
|
46
|
+
import { ServiceRegistrationEnvironmentConfig } from '../../application/LegendStudioApplicationConfig.js';
|
|
47
|
+
import { LEGEND_STUDIO_APP_EVENT } from '../LegendStudioAppEvent.js';
|
|
48
|
+
import { generateServiceManagementUrl } from '../editor-state/element-editor-state/service/ServiceRegistrationState.js';
|
|
49
|
+
|
|
50
|
+
export const LATEST_PROJECT_REVISION = 'Latest Project Revision';
|
|
51
|
+
const getServiceExecutionMode = (mode: string): ServiceExecutionMode => {
|
|
52
|
+
switch (mode) {
|
|
53
|
+
case ServiceExecutionMode.FULL_INTERACTIVE:
|
|
54
|
+
return ServiceExecutionMode.FULL_INTERACTIVE;
|
|
55
|
+
case ServiceExecutionMode.SEMI_INTERACTIVE:
|
|
56
|
+
return ServiceExecutionMode.SEMI_INTERACTIVE;
|
|
57
|
+
case ServiceExecutionMode.PROD:
|
|
58
|
+
return ServiceExecutionMode.PROD;
|
|
59
|
+
default:
|
|
60
|
+
throw new UnsupportedOperationError(
|
|
61
|
+
`Encountered unsupported service execution mode '${mode}'`,
|
|
62
|
+
);
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
interface ServiceVersionOption {
|
|
66
|
+
label: string;
|
|
67
|
+
value: Version | string;
|
|
68
|
+
}
|
|
69
|
+
interface ServiceRegistrationResult {
|
|
70
|
+
successfulServices: string[];
|
|
71
|
+
failedServices: string[];
|
|
72
|
+
serviceLinks: string[];
|
|
73
|
+
}
|
|
74
|
+
export class ServiceConfigState {
|
|
75
|
+
readonly editorStore: EditorStore;
|
|
76
|
+
readonly registrationOptions: ServiceRegistrationEnvironmentConfig[] = [];
|
|
77
|
+
readonly registrationState = ActionState.create();
|
|
78
|
+
registrationResult: ServiceRegistrationResult | undefined;
|
|
79
|
+
serviceEnv?: string | undefined;
|
|
80
|
+
serviceExecutionMode?: ServiceExecutionMode | undefined;
|
|
81
|
+
projectVersion?: Version | string | undefined;
|
|
82
|
+
enableModesWithVersioning: boolean;
|
|
83
|
+
TEMPORARY__useStoreModel = false;
|
|
84
|
+
|
|
85
|
+
constructor(
|
|
86
|
+
editorStore: EditorStore,
|
|
87
|
+
registrationOptions: ServiceRegistrationEnvironmentConfig[],
|
|
88
|
+
enableModesWithVersioning: boolean,
|
|
89
|
+
) {
|
|
90
|
+
makeObservable(this, {
|
|
91
|
+
serviceEnv: observable,
|
|
92
|
+
serviceExecutionMode: observable,
|
|
93
|
+
projectVersion: observable,
|
|
94
|
+
enableModesWithVersioning: observable,
|
|
95
|
+
TEMPORARY__useStoreModel: observable,
|
|
96
|
+
executionModes: computed,
|
|
97
|
+
options: computed,
|
|
98
|
+
versionOptions: computed,
|
|
99
|
+
setServiceEnv: action,
|
|
100
|
+
setServiceExecutionMode: action,
|
|
101
|
+
setProjectVersion: action,
|
|
102
|
+
|
|
103
|
+
setUseStoreModelWithFullInteractive: action,
|
|
104
|
+
initialize: action,
|
|
105
|
+
|
|
106
|
+
updateVersion: action,
|
|
107
|
+
updateType: action,
|
|
108
|
+
updateEnv: action,
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
this.editorStore = editorStore;
|
|
112
|
+
this.registrationOptions = registrationOptions;
|
|
113
|
+
this.enableModesWithVersioning = enableModesWithVersioning;
|
|
114
|
+
this.initialize();
|
|
115
|
+
this.registrationState.setMessageFormatter(prettyCONSTName);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
get options(): ServiceRegistrationEnvironmentConfig[] {
|
|
119
|
+
if (this.enableModesWithVersioning) {
|
|
120
|
+
return this.registrationOptions;
|
|
121
|
+
}
|
|
122
|
+
return this.registrationOptions
|
|
123
|
+
.map((_envConfig) => {
|
|
124
|
+
const envConfig = new ServiceRegistrationEnvironmentConfig();
|
|
125
|
+
envConfig.env = _envConfig.env;
|
|
126
|
+
envConfig.executionUrl = _envConfig.executionUrl;
|
|
127
|
+
envConfig.managementUrl = _envConfig.managementUrl;
|
|
128
|
+
// NOTE: For projects that we cannot create a version for, only fully-interactive mode is supported
|
|
129
|
+
envConfig.modes = _envConfig.modes.filter(
|
|
130
|
+
(mode) => mode === ServiceExecutionMode.FULL_INTERACTIVE,
|
|
131
|
+
);
|
|
132
|
+
return envConfig;
|
|
133
|
+
})
|
|
134
|
+
.filter((envConfig) => envConfig.modes.length);
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
get executionModes(): ServiceExecutionMode[] {
|
|
138
|
+
return (
|
|
139
|
+
this.options.find((e) => e.env === this.serviceEnv)?.modes ?? []
|
|
140
|
+
).map(getServiceExecutionMode);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
get versionOptions(): ServiceVersionOption[] | undefined {
|
|
144
|
+
if (
|
|
145
|
+
this.enableModesWithVersioning &&
|
|
146
|
+
this.serviceExecutionMode !== ServiceExecutionMode.FULL_INTERACTIVE
|
|
147
|
+
) {
|
|
148
|
+
const options: ServiceVersionOption[] =
|
|
149
|
+
this.editorStore.sdlcState.projectVersions.map((version) => ({
|
|
150
|
+
label: version.id.id,
|
|
151
|
+
value: version,
|
|
152
|
+
}));
|
|
153
|
+
if (this.serviceExecutionMode !== ServiceExecutionMode.PROD) {
|
|
154
|
+
return [
|
|
155
|
+
{
|
|
156
|
+
label: prettyCONSTName(LATEST_PROJECT_REVISION),
|
|
157
|
+
value: LATEST_PROJECT_REVISION,
|
|
158
|
+
},
|
|
159
|
+
...options,
|
|
160
|
+
];
|
|
161
|
+
}
|
|
162
|
+
return options;
|
|
163
|
+
}
|
|
164
|
+
return undefined;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
setServiceEnv(val: string | undefined): void {
|
|
168
|
+
this.serviceEnv = val;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
setServiceExecutionMode(val: ServiceExecutionMode | undefined): void {
|
|
172
|
+
this.serviceExecutionMode = val;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
setProjectVersion(val: Version | string | undefined): void {
|
|
176
|
+
this.projectVersion = val;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
setUseStoreModelWithFullInteractive(val: boolean): void {
|
|
180
|
+
this.TEMPORARY__useStoreModel = val;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
initialize(): void {
|
|
184
|
+
this.serviceEnv = getNullableFirstElement(this.registrationOptions)?.env;
|
|
185
|
+
this.serviceExecutionMode = this.executionModes[0];
|
|
186
|
+
this.updateVersion();
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
updateVersion(): void {
|
|
190
|
+
if (this.serviceExecutionMode === ServiceExecutionMode.SEMI_INTERACTIVE) {
|
|
191
|
+
this.projectVersion = LATEST_PROJECT_REVISION;
|
|
192
|
+
} else if (this.serviceExecutionMode === ServiceExecutionMode.PROD) {
|
|
193
|
+
this.projectVersion = this.editorStore.sdlcState.projectVersions[0];
|
|
194
|
+
} else {
|
|
195
|
+
this.projectVersion = undefined;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
updateType(val: ServiceExecutionMode | undefined): void {
|
|
200
|
+
this.setServiceExecutionMode(val);
|
|
201
|
+
this.updateVersion();
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
updateEnv(val: string | undefined): void {
|
|
205
|
+
this.setServiceEnv(val);
|
|
206
|
+
this.setServiceExecutionMode(this.executionModes[0]);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
export class BulkServiceRegistrationState {
|
|
211
|
+
editorStore: EditorStore;
|
|
212
|
+
sdlcState: EditorSDLCState;
|
|
213
|
+
serviceConfigState: ServiceConfigState;
|
|
214
|
+
showSuccessModel = false;
|
|
215
|
+
|
|
216
|
+
constructor(editorStore: EditorStore, sdlcState: EditorSDLCState) {
|
|
217
|
+
makeObservable(this, {
|
|
218
|
+
showSuccessModel: observable,
|
|
219
|
+
editorStore: false,
|
|
220
|
+
sdlcState: false,
|
|
221
|
+
registerServices: flow,
|
|
222
|
+
setSuccessModal: action,
|
|
223
|
+
});
|
|
224
|
+
this.editorStore = editorStore;
|
|
225
|
+
this.sdlcState = sdlcState;
|
|
226
|
+
this.serviceConfigState = new ServiceConfigState(
|
|
227
|
+
editorStore,
|
|
228
|
+
editorStore.applicationStore.config.options.TEMPORARY__serviceRegistrationConfig,
|
|
229
|
+
editorStore.sdlcServerClient.featuresConfigHasBeenFetched &&
|
|
230
|
+
editorStore.sdlcServerClient.features.canCreateVersion,
|
|
231
|
+
);
|
|
232
|
+
}
|
|
233
|
+
setSuccessModal(val: boolean): void {
|
|
234
|
+
this.showSuccessModel = val;
|
|
235
|
+
}
|
|
236
|
+
*registerServices(): GeneratorFn<void> {
|
|
237
|
+
const successfulServices: string[] = [];
|
|
238
|
+
const failedServices: string[] = [];
|
|
239
|
+
const serviceManagementURL: string[] = [];
|
|
240
|
+
|
|
241
|
+
this.serviceConfigState.registrationState.inProgress();
|
|
242
|
+
this.validateServiceForRegistration();
|
|
243
|
+
try {
|
|
244
|
+
const projectConfig = guaranteeNonNullable(
|
|
245
|
+
this.editorStore.projectConfigurationEditorState.projectConfiguration,
|
|
246
|
+
);
|
|
247
|
+
|
|
248
|
+
const versionInput =
|
|
249
|
+
this.serviceConfigState.projectVersion instanceof Version
|
|
250
|
+
? this.serviceConfigState.projectVersion.id.id
|
|
251
|
+
: undefined;
|
|
252
|
+
|
|
253
|
+
const config = guaranteeNonNullable(
|
|
254
|
+
this.serviceConfigState.options.find(
|
|
255
|
+
(info) => info.env === this.serviceConfigState.serviceEnv,
|
|
256
|
+
),
|
|
257
|
+
);
|
|
258
|
+
const serviceRegistrationResult =
|
|
259
|
+
(yield this.editorStore.graphManagerState.graphManager.bulkServiceRegistration(
|
|
260
|
+
this.editorStore.graphManagerState.graph.ownServices,
|
|
261
|
+
this.editorStore.graphManagerState.graph,
|
|
262
|
+
projectConfig.groupId,
|
|
263
|
+
projectConfig.artifactId,
|
|
264
|
+
versionInput,
|
|
265
|
+
config.executionUrl,
|
|
266
|
+
guaranteeNonNullable(this.serviceConfigState.serviceExecutionMode),
|
|
267
|
+
{
|
|
268
|
+
TEMPORARY__useStoreModel:
|
|
269
|
+
this.serviceConfigState.TEMPORARY__useStoreModel,
|
|
270
|
+
},
|
|
271
|
+
)) as BulkServiceRegistrationResult[];
|
|
272
|
+
|
|
273
|
+
serviceRegistrationResult.forEach((result) => {
|
|
274
|
+
if (result instanceof BulkRegistrationResultSuccess) {
|
|
275
|
+
const serviceURL = generateServiceManagementUrl(
|
|
276
|
+
config.managementUrl,
|
|
277
|
+
result.pattern,
|
|
278
|
+
);
|
|
279
|
+
serviceManagementURL.push(serviceURL);
|
|
280
|
+
successfulServices.push(result.pattern);
|
|
281
|
+
} else {
|
|
282
|
+
failedServices.push(
|
|
283
|
+
`${result.servicePath} ERROR: ${
|
|
284
|
+
(result as BulkRegistrationResultFail).errorMessage
|
|
285
|
+
}`,
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
this.serviceConfigState.registrationResult = {
|
|
290
|
+
successfulServices: successfulServices,
|
|
291
|
+
serviceLinks: serviceManagementURL,
|
|
292
|
+
failedServices: failedServices,
|
|
293
|
+
};
|
|
294
|
+
this.showSuccessModel = true;
|
|
295
|
+
} catch (error) {
|
|
296
|
+
assertErrorThrown(error);
|
|
297
|
+
this.editorStore.applicationStore.logService.error(
|
|
298
|
+
LogEvent.create(LEGEND_STUDIO_APP_EVENT.SERVICE_REGISTRATION_FAILURE),
|
|
299
|
+
error,
|
|
300
|
+
);
|
|
301
|
+
this.editorStore.applicationStore.notificationService.notifyError(error);
|
|
302
|
+
} finally {
|
|
303
|
+
this.serviceConfigState.registrationState.reset();
|
|
304
|
+
this.serviceConfigState.registrationState.setMessage(undefined);
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
validateServiceForRegistration(): void {
|
|
309
|
+
const services = this.editorStore.graphManagerState.graph.ownServices;
|
|
310
|
+
|
|
311
|
+
services.forEach((service) => {
|
|
312
|
+
service.owners.forEach((owner) =>
|
|
313
|
+
assertNonEmptyString(owner, `Service can't have an empty owner name`),
|
|
314
|
+
);
|
|
315
|
+
assertTrue(
|
|
316
|
+
service.owners.length >= MINIMUM_SERVICE_OWNERS,
|
|
317
|
+
`Service needs to have at least 2 owners in order to be registered`,
|
|
318
|
+
);
|
|
319
|
+
guaranteeNonNullable(
|
|
320
|
+
this.serviceConfigState.serviceEnv,
|
|
321
|
+
'Service registration environment can not be empty',
|
|
322
|
+
);
|
|
323
|
+
guaranteeNonNullable(
|
|
324
|
+
this.serviceConfigState.serviceExecutionMode,
|
|
325
|
+
'Service type can not be empty',
|
|
326
|
+
);
|
|
327
|
+
if (
|
|
328
|
+
this.serviceConfigState.serviceExecutionMode ===
|
|
329
|
+
ServiceExecutionMode.PROD ||
|
|
330
|
+
this.serviceConfigState.serviceExecutionMode ===
|
|
331
|
+
ServiceExecutionMode.SEMI_INTERACTIVE
|
|
332
|
+
) {
|
|
333
|
+
guaranteeNonNullable(
|
|
334
|
+
this.serviceConfigState.projectVersion,
|
|
335
|
+
'Service version can not be empty in Semi-interactive and Prod service type',
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
// validate service parameter multiplicities
|
|
340
|
+
const SUPPORTED_SERVICE_PARAMETER_MULTIPLICITIES = [
|
|
341
|
+
Multiplicity.ONE,
|
|
342
|
+
Multiplicity.ZERO_MANY,
|
|
343
|
+
Multiplicity.ZERO_ONE,
|
|
344
|
+
];
|
|
345
|
+
const invalidParams = buildLambdaVariableExpressions(
|
|
346
|
+
(service.execution as PureExecution).func,
|
|
347
|
+
this.editorStore.graphManagerState,
|
|
348
|
+
)
|
|
349
|
+
.filter(filterByType(VariableExpression))
|
|
350
|
+
.filter(
|
|
351
|
+
(p) =>
|
|
352
|
+
!SUPPORTED_SERVICE_PARAMETER_MULTIPLICITIES.some((m) =>
|
|
353
|
+
areMultiplicitiesEqual(m, p.multiplicity),
|
|
354
|
+
),
|
|
355
|
+
);
|
|
356
|
+
assertTrue(
|
|
357
|
+
invalidParams.length === 0,
|
|
358
|
+
`Parameter(s)${invalidParams.map(
|
|
359
|
+
(p) =>
|
|
360
|
+
` ${p.name}: [${generateMultiplicityString(
|
|
361
|
+
p.multiplicity.lowerBound,
|
|
362
|
+
p.multiplicity.upperBound,
|
|
363
|
+
)}]`,
|
|
364
|
+
)} has/have unsupported multiplicity. Supported multiplicities include ${SUPPORTED_SERVICE_PARAMETER_MULTIPLICITIES.map(
|
|
365
|
+
(m) => ` [${generateMultiplicityString(m.lowerBound, m.upperBound)}]`,
|
|
366
|
+
)}.`,
|
|
367
|
+
);
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
}
|
package/tsconfig.json
CHANGED
|
@@ -143,6 +143,7 @@
|
|
|
143
143
|
"./src/stores/shared/modifier/STO_Relational_GraphModifierHelper.ts",
|
|
144
144
|
"./src/stores/shared/modifier/Testable_GraphModifierHelper.ts",
|
|
145
145
|
"./src/stores/shared/testable/TestableUtils.ts",
|
|
146
|
+
"./src/stores/sidebar-state/BulkServiceRegistrationState.ts",
|
|
146
147
|
"./src/stores/sidebar-state/LocalChangesState.ts",
|
|
147
148
|
"./src/stores/sidebar-state/ProjectDependantEditorState.ts",
|
|
148
149
|
"./src/stores/sidebar-state/ProjectOverviewState.ts",
|
|
@@ -221,6 +222,7 @@
|
|
|
221
222
|
"./src/components/editor/edit-panel/mapping-editor/relational/TableOrViewSourceTree.tsx",
|
|
222
223
|
"./src/components/editor/edit-panel/project-configuration-editor/ProjectConfigurationEditor.tsx",
|
|
223
224
|
"./src/components/editor/edit-panel/project-configuration-editor/ProjectDependencyEditor.tsx",
|
|
225
|
+
"./src/components/editor/edit-panel/service-editor/BulkServiceRegistrationEditor.tsx",
|
|
224
226
|
"./src/components/editor/edit-panel/service-editor/NewServiceModal.tsx",
|
|
225
227
|
"./src/components/editor/edit-panel/service-editor/ServiceEditor.tsx",
|
|
226
228
|
"./src/components/editor/edit-panel/service-editor/ServiceExecutionEditor.tsx",
|
|
@@ -244,6 +246,7 @@
|
|
|
244
246
|
"./src/components/editor/side-bar/LocalChanges.tsx",
|
|
245
247
|
"./src/components/editor/side-bar/ProjectDependantsEditor.tsx",
|
|
246
248
|
"./src/components/editor/side-bar/ProjectOverview.tsx",
|
|
249
|
+
"./src/components/editor/side-bar/RegisterService.tsx",
|
|
247
250
|
"./src/components/editor/side-bar/SideBar.tsx",
|
|
248
251
|
"./src/components/editor/side-bar/WorkflowManager.tsx",
|
|
249
252
|
"./src/components/editor/side-bar/WorkspaceReview.tsx",
|