@finos/legend-application-studio 24.2.0 → 25.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/components/editor/ActivityBar.d.ts +0 -7
- package/lib/components/editor/ActivityBar.d.ts.map +1 -1
- package/lib/components/editor/ActivityBar.js +15 -16
- package/lib/components/editor/ActivityBar.js.map +1 -1
- package/lib/components/editor/__test-utils__/EditorComponentTestUtils.d.ts +2 -2
- package/lib/components/editor/__test-utils__/EditorComponentTestUtils.d.ts.map +1 -1
- package/lib/components/editor/__test-utils__/EditorComponentTestUtils.js +3 -3
- package/lib/components/editor/__test-utils__/EditorComponentTestUtils.js.map +1 -1
- package/lib/components/editor/edit-panel/mapping-editor/testable/MappingTestableEditor.js +2 -2
- package/lib/components/editor/edit-panel/mapping-editor/testable/MappingTestableEditor.js.map +1 -1
- package/lib/components/editor/editor-group/GrammarTextEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/GrammarTextEditor.js +3 -9
- package/lib/components/editor/editor-group/GrammarTextEditor.js.map +1 -1
- package/lib/components/editor/editor-group/ModelImporter.d.ts.map +1 -1
- package/lib/components/editor/editor-group/ModelImporter.js +1 -1
- package/lib/components/editor/editor-group/ModelImporter.js.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js +15 -16
- package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js.map +1 -1
- package/lib/components/editor/editor-group/diff-editor/EntityChangeConflictEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/diff-editor/EntityChangeConflictEditor.js +3 -9
- package/lib/components/editor/editor-group/diff-editor/EntityChangeConflictEditor.js.map +1 -1
- package/lib/components/editor/editor-group/mapping-editor/DEPRECATED__MappingTestEditor.js +1 -1
- package/lib/components/editor/editor-group/mapping-editor/DEPRECATED__MappingTestEditor.js.map +1 -1
- package/lib/components/editor/editor-group/mapping-editor/MappingExecutionBuilder.js +1 -1
- package/lib/components/editor/editor-group/mapping-editor/MappingExecutionBuilder.js.map +1 -1
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.js +4 -2
- package/lib/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.js.map +1 -1
- package/lib/components/editor/editor-group/service-editor/ServiceEditor.js +1 -1
- package/lib/components/editor/editor-group/service-editor/ServiceEditor.js.map +1 -1
- package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.js +2 -2
- package/lib/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.js.map +1 -1
- package/lib/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.js +1 -1
- package/lib/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.js.map +1 -1
- package/lib/components/editor/editor-group/uml-editor/ClassQueryBuilder.d.ts +12 -0
- package/lib/components/editor/editor-group/uml-editor/ClassQueryBuilder.d.ts.map +1 -1
- package/lib/components/editor/editor-group/uml-editor/ClassQueryBuilder.js +106 -12
- package/lib/components/editor/editor-group/uml-editor/ClassQueryBuilder.js.map +1 -1
- package/lib/components/editor/side-bar/WorkflowManager.d.ts.map +1 -1
- package/lib/components/editor/side-bar/WorkflowManager.js +1 -1
- package/lib/components/editor/side-bar/WorkflowManager.js.map +1 -1
- package/lib/components/editor/side-bar/testable/GlobalTestRunner.d.ts.map +1 -1
- package/lib/components/editor/side-bar/testable/GlobalTestRunner.js +8 -7
- package/lib/components/editor/side-bar/testable/GlobalTestRunner.js.map +1 -1
- package/lib/components/project-view/ProjectViewer.d.ts.map +1 -1
- package/lib/components/project-view/ProjectViewer.js +2 -2
- package/lib/components/project-view/ProjectViewer.js.map +1 -1
- package/lib/index.css +2 -2
- package/lib/index.css.map +1 -1
- package/lib/index.d.ts +0 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +0 -1
- package/lib/index.js.map +1 -1
- package/lib/package.json +2 -2
- package/lib/stores/LegendStudioApplicationPlugin.d.ts +9 -0
- package/lib/stores/LegendStudioApplicationPlugin.d.ts.map +1 -1
- package/lib/stores/LegendStudioApplicationPlugin.js.map +1 -1
- package/lib/stores/editor/EditorStore.d.ts +3 -3
- package/lib/stores/editor/EditorStore.d.ts.map +1 -1
- package/lib/stores/editor/EditorStore.js.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/ConnectionEditorState.d.ts +23 -23
- package/lib/stores/editor/editor-state/element-editor-state/connection/ConnectionEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/connection/ConnectionEditorState.js +23 -23
- package/lib/stores/editor/editor-state/element-editor-state/connection/ConnectionEditorState.js.map +1 -1
- package/package.json +12 -12
- package/src/components/editor/ActivityBar.tsx +100 -96
- package/src/components/editor/__test-utils__/EditorComponentTestUtils.tsx +5 -5
- package/src/components/editor/edit-panel/mapping-editor/testable/MappingTestableEditor.tsx +2 -2
- package/src/components/editor/editor-group/GrammarTextEditor.tsx +2 -11
- package/src/components/editor/editor-group/ModelImporter.tsx +0 -1
- package/src/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.tsx +15 -17
- package/src/components/editor/editor-group/diff-editor/EntityChangeConflictEditor.tsx +2 -11
- package/src/components/editor/editor-group/mapping-editor/DEPRECATED__MappingTestEditor.tsx +1 -1
- package/src/components/editor/editor-group/mapping-editor/MappingExecutionBuilder.tsx +1 -1
- package/src/components/editor/editor-group/project-configuration-editor/ProjectConfigurationEditor.tsx +6 -6
- package/src/components/editor/editor-group/service-editor/ServiceEditor.tsx +1 -1
- package/src/components/editor/editor-group/service-editor/ServiceExecutionQueryEditor.tsx +0 -2
- package/src/components/editor/editor-group/service-editor/testable/ServiceTestsEditor.tsx +1 -1
- package/src/components/editor/editor-group/uml-editor/ClassQueryBuilder.tsx +267 -31
- package/src/components/editor/side-bar/WorkflowManager.tsx +0 -1
- package/src/components/editor/side-bar/testable/GlobalTestRunner.tsx +11 -22
- package/src/components/project-view/ProjectViewer.tsx +27 -29
- package/src/index.ts +0 -1
- package/src/stores/LegendStudioApplicationPlugin.ts +15 -0
- package/src/stores/editor/EditorStore.ts +2 -2
- package/src/stores/editor/editor-state/element-editor-state/connection/ConnectionEditorState.ts +23 -23
- package/tsconfig.json +0 -1
- package/lib/stores/extensions/STO_ProjectOverview_LegendStudioApplicationPlugin_Extension.d.ts +0 -31
- package/lib/stores/extensions/STO_ProjectOverview_LegendStudioApplicationPlugin_Extension.d.ts.map +0 -1
- package/lib/stores/extensions/STO_ProjectOverview_LegendStudioApplicationPlugin_Extension.js +0 -17
- package/lib/stores/extensions/STO_ProjectOverview_LegendStudioApplicationPlugin_Extension.js.map +0 -1
- package/src/stores/extensions/STO_ProjectOverview_LegendStudioApplicationPlugin_Extension.ts +0 -40
@@ -517,12 +517,12 @@ export const ProjectConfigurationEditor = observer(() => {
|
|
517
517
|
selectedTab === CONFIGURATION_EDITOR_TAB.PROJECT_DEPENDENCIES &&
|
518
518
|
!configState.associatedProjectsAndVersionsFetched
|
519
519
|
) {
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
).catch(applicationStore.alertUnhandledError);
|
520
|
+
Promise.all([
|
521
|
+
flowResult(configState.fectchAssociatedProjectsAndVersions()),
|
522
|
+
flowResult(
|
523
|
+
configState.projectDependencyEditorState.fetchDependencyReport(),
|
524
|
+
),
|
525
|
+
]).catch(applicationStore.alertUnhandledError);
|
526
526
|
}
|
527
527
|
}, [applicationStore, configState, selectedTab]);
|
528
528
|
|
@@ -370,7 +370,7 @@ const ServiceGeneralEditor = observer(() => {
|
|
370
370
|
<div className="panel__content__form__section__list__new-item">
|
371
371
|
<CustomSelectorInput
|
372
372
|
className="service-editor__owner__selector"
|
373
|
-
placeholder=
|
373
|
+
placeholder="Enter an owner..."
|
374
374
|
spellCheck={false}
|
375
375
|
inputValue={searchText}
|
376
376
|
options={userOptions}
|
@@ -84,7 +84,6 @@ const ServiceExecutionResultViewer = observer(
|
|
84
84
|
inputValue={executionResultText ?? ''}
|
85
85
|
isReadOnly={true}
|
86
86
|
language={CODE_EDITOR_LANGUAGE.JSON}
|
87
|
-
showMiniMap={true}
|
88
87
|
/>
|
89
88
|
</ModalBody>
|
90
89
|
<ModalFooter>
|
@@ -456,7 +455,6 @@ export const ServiceExecutionQueryEditor = observer(
|
|
456
455
|
inputValue={queryState.lambdaString}
|
457
456
|
isReadOnly={true}
|
458
457
|
language={CODE_EDITOR_LANGUAGE.PURE}
|
459
|
-
showMiniMap={true}
|
460
458
|
/>
|
461
459
|
</div>
|
462
460
|
<ExecutionPlanViewer
|
@@ -19,15 +19,24 @@ import {
|
|
19
19
|
PackageableElementExplicitReference,
|
20
20
|
PureSingleExecution,
|
21
21
|
Service,
|
22
|
+
ConcreteFunctionDefinition,
|
23
|
+
Multiplicity,
|
24
|
+
resolvePackagePathAndElementName,
|
25
|
+
ELEMENT_PATH_DELIMITER,
|
26
|
+
RawVariableExpression,
|
22
27
|
} from '@finos/legend-graph';
|
23
28
|
import {
|
24
29
|
type QueryBuilderState,
|
25
30
|
ClassQueryBuilderState,
|
26
31
|
} from '@finos/legend-query-builder';
|
27
|
-
import {
|
32
|
+
import {
|
33
|
+
assertErrorThrown,
|
34
|
+
guaranteeNonNullable,
|
35
|
+
prettyCONSTName,
|
36
|
+
} from '@finos/legend-shared';
|
28
37
|
import { flowResult } from 'mobx';
|
29
38
|
import { observer } from 'mobx-react-lite';
|
30
|
-
import { useState } from 'react';
|
39
|
+
import { useRef, useState } from 'react';
|
31
40
|
import type { EditorStore } from '../../../../stores/editor/EditorStore.js';
|
32
41
|
import type { EmbeddedQueryBuilderState } from '../../../../stores/editor/EmbeddedQueryBuilderState.js';
|
33
42
|
import {
|
@@ -36,6 +45,18 @@ import {
|
|
36
45
|
} from '../../../../stores/graph-modifier/DSL_Service_GraphModifierHelper.js';
|
37
46
|
import { useEditorStore } from '../../EditorStoreProvider.js';
|
38
47
|
import { NewServiceModal } from '../service-editor/NewServiceModal.js';
|
48
|
+
import {
|
49
|
+
CaretDownIcon,
|
50
|
+
Dialog,
|
51
|
+
DropdownMenu,
|
52
|
+
MenuContent,
|
53
|
+
MenuContentItem,
|
54
|
+
MenuContentItemLabel,
|
55
|
+
ModalTitle,
|
56
|
+
PanelDivider,
|
57
|
+
PanelFormSection,
|
58
|
+
PanelFormValidatedTextField,
|
59
|
+
} from '@finos/legend-art';
|
39
60
|
|
40
61
|
const promoteQueryToService = async (
|
41
62
|
packagePath: string,
|
@@ -82,48 +103,263 @@ const promoteQueryToService = async (
|
|
82
103
|
}
|
83
104
|
};
|
84
105
|
|
106
|
+
export const promoteQueryToFunction = async (
|
107
|
+
packagePath: string,
|
108
|
+
functionName: string,
|
109
|
+
embeddedQueryBuilderState: EmbeddedQueryBuilderState,
|
110
|
+
queryBuilderState: QueryBuilderState,
|
111
|
+
): Promise<void> => {
|
112
|
+
const editorStore = embeddedQueryBuilderState.editorStore;
|
113
|
+
const applicationStore = editorStore.applicationStore;
|
114
|
+
try {
|
115
|
+
const query = queryBuilderState.buildFromQuery();
|
116
|
+
const returnType = queryBuilderState.getQueryReturnType();
|
117
|
+
const _function = new ConcreteFunctionDefinition(
|
118
|
+
functionName,
|
119
|
+
PackageableElementExplicitReference.create(returnType),
|
120
|
+
Multiplicity.ONE,
|
121
|
+
);
|
122
|
+
// we will copy the body of the query to the body of the function and extract the parameters out
|
123
|
+
// to the function parameters
|
124
|
+
_function.expressionSequence = query.body as object[];
|
125
|
+
_function.parameters =
|
126
|
+
queryBuilderState.parametersState.parameterStates.map(
|
127
|
+
(e) =>
|
128
|
+
new RawVariableExpression(
|
129
|
+
e.parameter.name,
|
130
|
+
e.parameter.multiplicity,
|
131
|
+
PackageableElementExplicitReference.create(
|
132
|
+
guaranteeNonNullable(e.parameter.genericType?.value.rawType),
|
133
|
+
),
|
134
|
+
),
|
135
|
+
);
|
136
|
+
await flowResult(
|
137
|
+
editorStore.graphEditorMode.addElement(_function, packagePath, true),
|
138
|
+
);
|
139
|
+
await flowResult(
|
140
|
+
embeddedQueryBuilderState.setEmbeddedQueryBuilderConfiguration(undefined),
|
141
|
+
).catch(applicationStore.alertUnhandledError);
|
142
|
+
applicationStore.notificationService.notifySuccess(
|
143
|
+
`Function '${_function.name}' created`,
|
144
|
+
);
|
145
|
+
} catch (error) {
|
146
|
+
assertErrorThrown(error);
|
147
|
+
applicationStore.notificationService.notifyError(error);
|
148
|
+
}
|
149
|
+
};
|
150
|
+
|
151
|
+
enum PROMOTE_QUERY_TYPE {
|
152
|
+
FUNCTION = 'FUNCTION',
|
153
|
+
SERVICE = 'SERVICE',
|
154
|
+
}
|
155
|
+
|
156
|
+
export const NewFunctionModal = observer(
|
157
|
+
(props: {
|
158
|
+
_class: Class | undefined;
|
159
|
+
close: () => void;
|
160
|
+
showModal: boolean;
|
161
|
+
promoteToFunction: (
|
162
|
+
packagePath: string,
|
163
|
+
functionName: string,
|
164
|
+
) => Promise<void>;
|
165
|
+
isReadOnly?: boolean;
|
166
|
+
}) => {
|
167
|
+
const { isReadOnly, close, _class, showModal, promoteToFunction } = props;
|
168
|
+
const editorStore = useEditorStore();
|
169
|
+
const applicationStore = editorStore.applicationStore;
|
170
|
+
const nameRef = useRef<HTMLInputElement>(null);
|
171
|
+
const defaultFunctionname = _class
|
172
|
+
? `${_class.name}_QueryFunction`
|
173
|
+
: `QueryFunction`;
|
174
|
+
const [functionPath, setFunctionPath] =
|
175
|
+
useState<string>(defaultFunctionname);
|
176
|
+
const [packagePath, funcName] = resolvePackagePathAndElementName(
|
177
|
+
functionPath,
|
178
|
+
_class?.package?.path ?? 'model::functions',
|
179
|
+
);
|
180
|
+
const [isValid, setIsValid] = useState(true);
|
181
|
+
|
182
|
+
const handleEnter = (): void => nameRef.current?.focus();
|
183
|
+
const create = (): void => {
|
184
|
+
if (functionPath && !isReadOnly && isValid) {
|
185
|
+
promoteToFunction(packagePath, funcName)
|
186
|
+
.then(() => close())
|
187
|
+
.catch(applicationStore.alertUnhandledError);
|
188
|
+
}
|
189
|
+
};
|
190
|
+
|
191
|
+
const validateElementDoesNotAlreadyExist = (
|
192
|
+
myFunctionName: string,
|
193
|
+
): string | undefined => {
|
194
|
+
const elementAlreadyExists =
|
195
|
+
editorStore.graphManagerState.graph.allOwnElements
|
196
|
+
.map((s) => s.path)
|
197
|
+
.includes(packagePath + ELEMENT_PATH_DELIMITER + myFunctionName);
|
198
|
+
|
199
|
+
if (!elementAlreadyExists) {
|
200
|
+
return undefined;
|
201
|
+
} else {
|
202
|
+
return 'Element with same path already exists';
|
203
|
+
}
|
204
|
+
};
|
205
|
+
|
206
|
+
const changeValue = (value: string): void => {
|
207
|
+
setFunctionPath(value);
|
208
|
+
};
|
209
|
+
|
210
|
+
return (
|
211
|
+
<Dialog
|
212
|
+
open={showModal}
|
213
|
+
onClose={close}
|
214
|
+
TransitionProps={{
|
215
|
+
onEnter: handleEnter,
|
216
|
+
}}
|
217
|
+
PaperProps={{
|
218
|
+
classes: {
|
219
|
+
root: 'search-modal__inner-container',
|
220
|
+
},
|
221
|
+
}}
|
222
|
+
>
|
223
|
+
<form
|
224
|
+
onSubmit={(event) => {
|
225
|
+
event.preventDefault();
|
226
|
+
create();
|
227
|
+
}}
|
228
|
+
className="modal search-modal modal--dark"
|
229
|
+
>
|
230
|
+
<ModalTitle title="Promote to Function" />
|
231
|
+
<PanelFormValidatedTextField
|
232
|
+
ref={nameRef}
|
233
|
+
isReadOnly={isReadOnly ?? false}
|
234
|
+
update={(value: string | undefined): void => {
|
235
|
+
changeValue(value ?? '');
|
236
|
+
}}
|
237
|
+
validate={validateElementDoesNotAlreadyExist}
|
238
|
+
onValidate={(issue: string | undefined) => setIsValid(!issue)}
|
239
|
+
value={functionPath}
|
240
|
+
placeholder={`Enter a name, use ${ELEMENT_PATH_DELIMITER} to create new package(s) for the function`}
|
241
|
+
/>
|
242
|
+
<PanelDivider />
|
243
|
+
<PanelFormSection>
|
244
|
+
<div className="search-modal__actions">
|
245
|
+
<button
|
246
|
+
className="btn btn--dark"
|
247
|
+
disabled={Boolean(isReadOnly) || !isValid}
|
248
|
+
onClick={create}
|
249
|
+
>
|
250
|
+
Create
|
251
|
+
</button>
|
252
|
+
</div>
|
253
|
+
</PanelFormSection>
|
254
|
+
</form>
|
255
|
+
</Dialog>
|
256
|
+
);
|
257
|
+
},
|
258
|
+
);
|
259
|
+
|
85
260
|
const PromoteToServiceQueryBuilderAction = observer(
|
86
261
|
(props: { queryBuilderState: QueryBuilderState }) => {
|
87
262
|
const { queryBuilderState } = props;
|
88
263
|
const editorStore = useEditorStore();
|
89
264
|
const queryBuilderExtension = editorStore.embeddedQueryBuilderState;
|
90
|
-
const [
|
91
|
-
|
92
|
-
|
93
|
-
const
|
94
|
-
|
265
|
+
const [promoteQueryModal, setPromoteQueryType] = useState<
|
266
|
+
PROMOTE_QUERY_TYPE | undefined
|
267
|
+
>(undefined);
|
268
|
+
const showPromoteQueryModal = (type: PROMOTE_QUERY_TYPE): void =>
|
269
|
+
setPromoteQueryType(type);
|
270
|
+
const closeNewServiceModal = (): void => setPromoteQueryType(undefined);
|
271
|
+
const allowPromotion = Boolean(
|
272
|
+
queryBuilderState.mapping &&
|
273
|
+
queryBuilderState.runtimeValue &&
|
274
|
+
!queryBuilderState.allValidationIssues.length,
|
95
275
|
);
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
276
|
+
|
277
|
+
const renderPromoteModal = (): React.ReactNode => {
|
278
|
+
if (
|
279
|
+
promoteQueryModal === PROMOTE_QUERY_TYPE.SERVICE &&
|
280
|
+
queryBuilderState.mapping
|
281
|
+
) {
|
282
|
+
const promoteToService = async (
|
283
|
+
packagePath: string,
|
284
|
+
serviceName: string,
|
285
|
+
): Promise<void> => {
|
286
|
+
if (allowPromotion) {
|
287
|
+
await promoteQueryToService(
|
288
|
+
packagePath,
|
289
|
+
serviceName,
|
290
|
+
queryBuilderExtension,
|
291
|
+
queryBuilderState,
|
292
|
+
);
|
293
|
+
}
|
294
|
+
};
|
295
|
+
|
296
|
+
return (
|
297
|
+
<NewServiceModal
|
298
|
+
mapping={queryBuilderState.mapping}
|
299
|
+
close={closeNewServiceModal}
|
300
|
+
showModal={true}
|
301
|
+
promoteToService={promoteToService}
|
302
|
+
/>
|
303
|
+
);
|
304
|
+
} else if (promoteQueryModal === PROMOTE_QUERY_TYPE.FUNCTION) {
|
305
|
+
const promoteToFunction = async (
|
306
|
+
packagePath: string,
|
307
|
+
serviceName: string,
|
308
|
+
): Promise<void> => {
|
309
|
+
if (allowPromotion) {
|
310
|
+
await promoteQueryToFunction(
|
311
|
+
packagePath,
|
312
|
+
serviceName,
|
313
|
+
queryBuilderExtension,
|
314
|
+
queryBuilderState,
|
315
|
+
);
|
316
|
+
}
|
317
|
+
};
|
318
|
+
|
319
|
+
return (
|
320
|
+
<NewFunctionModal
|
321
|
+
_class={queryBuilderState.class}
|
322
|
+
close={closeNewServiceModal}
|
323
|
+
showModal={true}
|
324
|
+
promoteToFunction={promoteToFunction}
|
325
|
+
/>
|
106
326
|
);
|
107
327
|
}
|
328
|
+
return null;
|
108
329
|
};
|
330
|
+
|
109
331
|
return (
|
110
332
|
<>
|
111
|
-
<
|
333
|
+
<DropdownMenu
|
112
334
|
className="query-builder__dialog__header__custom-action"
|
113
|
-
|
114
|
-
|
115
|
-
|
335
|
+
title="Promote Query..."
|
336
|
+
content={
|
337
|
+
<MenuContent>
|
338
|
+
{Object.values(PROMOTE_QUERY_TYPE).map((type) => (
|
339
|
+
<MenuContentItem
|
340
|
+
key={type}
|
341
|
+
disabled={!allowPromotion}
|
342
|
+
onClick={(): void => showPromoteQueryModal(type)}
|
343
|
+
>
|
344
|
+
<MenuContentItemLabel className="query-builder__sub-header__menu-content">
|
345
|
+
{prettyCONSTName(type)}
|
346
|
+
</MenuContentItemLabel>
|
347
|
+
</MenuContentItem>
|
348
|
+
))}
|
349
|
+
</MenuContent>
|
350
|
+
}
|
351
|
+
menuProps={{
|
352
|
+
anchorOrigin: { vertical: 'bottom', horizontal: 'right' },
|
353
|
+
transformOrigin: { vertical: 'top', horizontal: 'right' },
|
354
|
+
elevation: 7,
|
355
|
+
}}
|
116
356
|
>
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
<
|
121
|
-
|
122
|
-
|
123
|
-
showModal={openNewServiceModal}
|
124
|
-
promoteToService={promoteToService}
|
125
|
-
/>
|
126
|
-
)}
|
357
|
+
<div className="query-builder__sub-header__custom-action__label">
|
358
|
+
Promote To...
|
359
|
+
</div>
|
360
|
+
<CaretDownIcon className="query-builder__sub-header__custom-action__icon" />
|
361
|
+
</DropdownMenu>
|
362
|
+
{renderPromoteModal()}
|
127
363
|
</>
|
128
364
|
);
|
129
365
|
},
|
@@ -72,7 +72,6 @@ import {
|
|
72
72
|
getAtomicTest_TestResult,
|
73
73
|
getAssertionStatus,
|
74
74
|
} from '../../../../stores/editor/sidebar-state/testable/GlobalTestRunnerState.js';
|
75
|
-
import type { STO_ProjectOverview_LegendStudioApplicationPlugin_Extension } from '../../../../stores/extensions/STO_ProjectOverview_LegendStudioApplicationPlugin_Extension.js';
|
76
75
|
import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js';
|
77
76
|
import { getElementTypeIcon } from '../../../ElementIconUtils.js';
|
78
77
|
import { UnsupportedEditorPanel } from '../../editor-group/UnsupportedElementEditor.js';
|
@@ -206,7 +205,6 @@ const TestFailViewer = observer(
|
|
206
205
|
inputValue={failure.error}
|
207
206
|
isReadOnly={true}
|
208
207
|
language={CODE_EDITOR_LANGUAGE.TEXT}
|
209
|
-
showMiniMap={true}
|
210
208
|
/>
|
211
209
|
)}
|
212
210
|
{failure instanceof EqualToJsonAssertFail && (
|
@@ -431,17 +429,13 @@ export const GlobalTestRunner = observer(
|
|
431
429
|
const editorStore = useEditorStore();
|
432
430
|
const globalTestRunnerState = props.globalTestRunnerState;
|
433
431
|
const isDispatchingAction = globalTestRunnerState.isDispatchingAction;
|
434
|
-
const sdlcState = editorStore.sdlcState;
|
435
|
-
const currentWorkspace = sdlcState.currentWorkspace;
|
436
|
-
const plugins = editorStore.pluginManager.getApplicationPlugins();
|
437
432
|
const testRunnerTabs = (Object.values(GLOBAL_TEST_RUNNER_TABS) as string[])
|
438
433
|
.concat(
|
439
|
-
|
440
|
-
(
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
),
|
434
|
+
editorStore.pluginManager
|
435
|
+
.getApplicationPlugins()
|
436
|
+
.flatMap(
|
437
|
+
(plugin) => plugin.getExtraTestRunnerTabClassifiers?.() ?? [],
|
438
|
+
),
|
445
439
|
)
|
446
440
|
.map((e) => ({
|
447
441
|
value: e,
|
@@ -573,18 +567,13 @@ export const GlobalTestRunner = observer(
|
|
573
567
|
</div>
|
574
568
|
);
|
575
569
|
} else {
|
576
|
-
const extraTestRunnerTabEditorRenderers =
|
577
|
-
(
|
578
|
-
|
579
|
-
|
580
|
-
).getExtraTestRunnerTabsEditorRenderers?.() ?? [],
|
581
|
-
);
|
582
|
-
for (const editorRenderer of extraTestRunnerTabEditorRenderers) {
|
583
|
-
const editor = editorRenderer(
|
584
|
-
selectedTab,
|
585
|
-
editorStore,
|
586
|
-
currentWorkspace,
|
570
|
+
const extraTestRunnerTabEditorRenderers = editorStore.pluginManager
|
571
|
+
.getApplicationPlugins()
|
572
|
+
.flatMap(
|
573
|
+
(plugin) => plugin.getExtraTestRunnerTabEditorRenderers?.() ?? [],
|
587
574
|
);
|
575
|
+
for (const editorRenderer of extraTestRunnerTabEditorRenderers) {
|
576
|
+
const editor = editorRenderer(selectedTab, editorStore);
|
588
577
|
if (editor) {
|
589
578
|
return editor;
|
590
579
|
}
|
@@ -55,10 +55,6 @@ import {
|
|
55
55
|
} from '../editor/EditorStoreProvider.js';
|
56
56
|
import { useApplicationStore, useCommands } from '@finos/legend-application';
|
57
57
|
import { useParams } from '@finos/legend-application/browser';
|
58
|
-
import {
|
59
|
-
ActivityBarMenu,
|
60
|
-
type ActivityDisplay,
|
61
|
-
} from '../editor/ActivityBar.js';
|
62
58
|
import { Explorer } from '../editor/side-bar/Explorer.js';
|
63
59
|
import { ProjectOverview } from '../editor/side-bar/ProjectOverview.js';
|
64
60
|
import { WorkflowManager } from '../editor/side-bar/WorkflowManager.js';
|
@@ -67,6 +63,8 @@ import {
|
|
67
63
|
useLegendStudioBaseStore,
|
68
64
|
} from '../LegendStudioFrameworkProvider.js';
|
69
65
|
import { EmbeddedQueryBuilder } from '../EmbeddedQueryBuilder.js';
|
66
|
+
import type { ActivityBarItemConfig } from '@finos/legend-lego/application';
|
67
|
+
import { ActivityBarMenu } from '../editor/ActivityBar.js';
|
70
68
|
|
71
69
|
const ProjectViewerStatusBar = observer(() => {
|
72
70
|
const params = useParams<ProjectViewerPathParams>();
|
@@ -204,31 +202,33 @@ const ProjectViewerActivityBar = observer(() => {
|
|
204
202
|
const editorStore = useEditorStore();
|
205
203
|
|
206
204
|
const changeActivity =
|
207
|
-
(activity:
|
205
|
+
(activity: string): (() => void) =>
|
208
206
|
(): void =>
|
209
207
|
editorStore.setActiveActivity(activity);
|
210
208
|
// tabs
|
211
|
-
const activities:
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
<
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
209
|
+
const activities: ActivityBarItemConfig[] = (
|
210
|
+
[
|
211
|
+
{
|
212
|
+
mode: ACTIVITY_MODE.EXPLORER,
|
213
|
+
title: 'Explorer (Ctrl + Shift + X)',
|
214
|
+
icon: <FileTrayIcon />,
|
215
|
+
},
|
216
|
+
baseStore.isSDLCAuthorized !== undefined && {
|
217
|
+
mode: ACTIVITY_MODE.PROJECT_OVERVIEW,
|
218
|
+
title: 'Project',
|
219
|
+
icon: (
|
220
|
+
<div className="activity-bar__project-overview-icon">
|
221
|
+
<RepoIcon />
|
222
|
+
</div>
|
223
|
+
),
|
224
|
+
},
|
225
|
+
viewerStore.workflowManagerState && {
|
226
|
+
mode: ACTIVITY_MODE.WORKFLOW_MANAGER,
|
227
|
+
title: 'WORKFLOW MANAGER',
|
228
|
+
icon: <WrenchIcon />,
|
229
|
+
},
|
230
|
+
] as (ActivityBarItemConfig | boolean)[]
|
231
|
+
).filter((activity): activity is ActivityBarItemConfig => Boolean(activity));
|
232
232
|
|
233
233
|
return (
|
234
234
|
<div className="activity-bar">
|
@@ -244,9 +244,7 @@ const ProjectViewerActivityBar = observer(() => {
|
|
244
244
|
})}
|
245
245
|
onClick={changeActivity(activity.mode)}
|
246
246
|
tabIndex={-1}
|
247
|
-
title={
|
248
|
-
activity.info ? ` - ${activity.info}` : ''
|
249
|
-
}`}
|
247
|
+
title={activity.title}
|
250
248
|
>
|
251
249
|
{activity.icon}
|
252
250
|
</button>
|
package/src/index.ts
CHANGED
@@ -91,7 +91,6 @@ export { getElementIcon } from './components/ElementIconUtils.js';
|
|
91
91
|
*/
|
92
92
|
|
93
93
|
export * from './stores/extensions/DSL_Generation_LegendStudioApplicationPlugin_Extension.js';
|
94
|
-
export * from './stores/extensions/STO_ProjectOverview_LegendStudioApplicationPlugin_Extension.js';
|
95
94
|
export * from './stores/extensions/STO_Relational_LegendStudioApplicationPlugin_Extension.js';
|
96
95
|
|
97
96
|
export { MINIMUM_SERVICE_OWNERS } from './stores/editor/editor-state/element-editor-state/service/ServiceEditorState.js';
|
@@ -77,6 +77,11 @@ export type TestableMetadataGetter = (
|
|
77
77
|
editorStore: EditorStore,
|
78
78
|
) => TestableMetadata | undefined;
|
79
79
|
|
80
|
+
export type TestRunnerTabRenderer = (
|
81
|
+
selectedTab: string,
|
82
|
+
editorStore: EditorStore,
|
83
|
+
) => React.ReactNode | undefined;
|
84
|
+
|
80
85
|
export abstract class LegendStudioApplicationPlugin extends LegendApplicationPlugin {
|
81
86
|
/**
|
82
87
|
* This helps to better type-check for this empty abtract type
|
@@ -119,6 +124,16 @@ export abstract class LegendStudioApplicationPlugin extends LegendApplicationPlu
|
|
119
124
|
* Get the list of extension for testables
|
120
125
|
*/
|
121
126
|
getExtraTestableMetadata?(): TestableMetadataGetter[];
|
127
|
+
|
128
|
+
/**
|
129
|
+
* Get the list of the supported classifers for test runner tabs.
|
130
|
+
*/
|
131
|
+
getExtraTestRunnerTabClassifiers?(): string[];
|
132
|
+
|
133
|
+
/**
|
134
|
+
* Get the list of renderers for the editor for a test runner tab.
|
135
|
+
*/
|
136
|
+
getExtraTestRunnerTabEditorRenderers?(): TestRunnerTabRenderer[];
|
122
137
|
}
|
123
138
|
|
124
139
|
export type PureGrammarElementLabeler = (
|
@@ -159,7 +159,7 @@ export class EditorStore implements CommandRegistrar {
|
|
159
159
|
default: 300,
|
160
160
|
snap: 100,
|
161
161
|
});
|
162
|
-
activeActivity?:
|
162
|
+
activeActivity?: string = ACTIVITY_MODE.EXPLORER;
|
163
163
|
readonly sideBarDisplayState = new PanelDisplayState({
|
164
164
|
initial: 300,
|
165
165
|
default: 300,
|
@@ -839,7 +839,7 @@ export class EditorStore implements CommandRegistrar {
|
|
839
839
|
}
|
840
840
|
|
841
841
|
setActiveActivity(
|
842
|
-
activity:
|
842
|
+
activity: string,
|
843
843
|
options?: { keepShowingIfMatchedCurrent?: boolean },
|
844
844
|
): void {
|
845
845
|
if (!this.sideBarDisplayState.isOpen) {
|