@finos/legend-application-studio 28.18.42 → 28.18.44
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/editor-group/function-activator/ActivatorFormComponents.d.ts +23 -0
- package/lib/components/editor/editor-group/function-activator/ActivatorFormComponents.d.ts.map +1 -0
- package/lib/components/editor/editor-group/function-activator/ActivatorFormComponents.js +34 -0
- package/lib/components/editor/editor-group/function-activator/ActivatorFormComponents.js.map +1 -0
- package/lib/components/editor/editor-group/function-activator/HostedServiceFunctionActivatorEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/function-activator/HostedServiceFunctionActivatorEditor.js +76 -108
- package/lib/components/editor/editor-group/function-activator/HostedServiceFunctionActivatorEditor.js.map +1 -1
- package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.d.ts.map +1 -1
- package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.js +4 -13
- package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.js.map +1 -1
- package/lib/index.css +1 -1
- package/lib/package.json +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.d.ts +8 -3
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.d.ts.map +1 -1
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.js +15 -10
- package/lib/stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.js.map +1 -1
- package/package.json +6 -6
- package/src/components/editor/editor-group/function-activator/ActivatorFormComponents.tsx +97 -0
- package/src/components/editor/editor-group/function-activator/HostedServiceFunctionActivatorEditor.tsx +347 -482
- package/src/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.tsx +7 -42
- package/src/stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.ts +18 -11
- package/tsconfig.json +1 -0
|
@@ -25,14 +25,19 @@ import {
|
|
|
25
25
|
PanelFormBooleanField,
|
|
26
26
|
PanelFormValidatedTextField,
|
|
27
27
|
TimesIcon,
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
ErrorIcon,
|
|
28
|
+
clsx,
|
|
29
|
+
PlusIcon,
|
|
31
30
|
} from '@finos/legend-art';
|
|
32
31
|
import {
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
Profile,
|
|
33
|
+
StereotypeExplicitReference,
|
|
34
|
+
type StereotypeReference,
|
|
35
|
+
type TaggedValue,
|
|
35
36
|
generateFunctionPrettyName,
|
|
37
|
+
stub_Profile,
|
|
38
|
+
stub_Stereotype,
|
|
39
|
+
stub_Tag,
|
|
40
|
+
stub_TaggedValue,
|
|
36
41
|
validate_ServicePattern,
|
|
37
42
|
} from '@finos/legend-graph';
|
|
38
43
|
import { observer } from 'mobx-react-lite';
|
|
@@ -40,9 +45,7 @@ import { useApplicationStore } from '@finos/legend-application';
|
|
|
40
45
|
import { useEditorStore } from '../../EditorStoreProvider.js';
|
|
41
46
|
import {
|
|
42
47
|
HostedServiceFunctionActivatorEditorState,
|
|
43
|
-
|
|
44
|
-
type HostedServiceOwnerOption,
|
|
45
|
-
MINIMUM_HOSTED_SERVICE_OWNERS,
|
|
48
|
+
ACTIVATOR_EDITOR_TAB,
|
|
46
49
|
} from '../../../../stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.js';
|
|
47
50
|
import {
|
|
48
51
|
hostedService_setAutoActivateUpdates,
|
|
@@ -50,18 +53,31 @@ import {
|
|
|
50
53
|
hostedService_setPattern,
|
|
51
54
|
hostedService_removePatternParameter,
|
|
52
55
|
hostedService_setStoreModel,
|
|
53
|
-
hostedService_setGenerateLineage,
|
|
54
|
-
activator_setDeploymentOwner,
|
|
55
|
-
activator_updateUserOwnership,
|
|
56
|
-
activator_deleteValueFromUserOwnership,
|
|
57
|
-
activator_addUserOwner,
|
|
58
56
|
} from '../../../../stores/graph-modifier/DSL_FunctionActivator_GraphModifierHelper.js';
|
|
59
|
-
import {
|
|
60
|
-
import {
|
|
61
|
-
import { debounce } from '@finos/legend-shared';
|
|
57
|
+
import { useCallback, useEffect, useRef, useState } from 'react';
|
|
58
|
+
import { prettyCONSTName } from '@finos/legend-shared';
|
|
62
59
|
import { flowResult } from 'mobx';
|
|
63
|
-
|
|
64
|
-
|
|
60
|
+
import { ActivatorOwnershipForm } from './ActivatorFormComponents.js';
|
|
61
|
+
import {
|
|
62
|
+
annotatedElement_addStereotype,
|
|
63
|
+
annotatedElement_addTaggedValue,
|
|
64
|
+
annotatedElement_deleteStereotype,
|
|
65
|
+
annotatedElement_deleteTaggedValue,
|
|
66
|
+
} from '../../../../stores/graph-modifier/DomainGraphModifierHelper.js';
|
|
67
|
+
import {
|
|
68
|
+
CORE_DND_TYPE,
|
|
69
|
+
type ElementDragSource,
|
|
70
|
+
type UMLEditorElementDropTarget,
|
|
71
|
+
} from '../../../../stores/editor/utils/DnDUtils.js';
|
|
72
|
+
import { useDrop } from 'react-dnd';
|
|
73
|
+
import {
|
|
74
|
+
TaggedValueDragPreviewLayer,
|
|
75
|
+
TaggedValueEditor,
|
|
76
|
+
} from '../uml-editor/TaggedValueEditor.js';
|
|
77
|
+
import {
|
|
78
|
+
StereotypeDragPreviewLayer,
|
|
79
|
+
StereotypeSelector,
|
|
80
|
+
} from '../uml-editor/StereotypeSelector.js';
|
|
65
81
|
|
|
66
82
|
export const HostedServiceFunctionActivatorEditor = observer(() => {
|
|
67
83
|
const editorStore = useEditorStore();
|
|
@@ -69,9 +85,103 @@ export const HostedServiceFunctionActivatorEditor = observer(() => {
|
|
|
69
85
|
const editorState = editorStore.tabManagerState.getCurrentEditorState(
|
|
70
86
|
HostedServiceFunctionActivatorEditorState,
|
|
71
87
|
);
|
|
88
|
+
const activatorElement = editorState.element;
|
|
72
89
|
const isReadOnly = editorState.isReadOnly;
|
|
90
|
+
const selectedTab = editorState.selectedTab;
|
|
91
|
+
let addButtonTitle = '';
|
|
92
|
+
switch (selectedTab) {
|
|
93
|
+
case ACTIVATOR_EDITOR_TAB.TAGGED_VALUES:
|
|
94
|
+
addButtonTitle = 'Add tagged value';
|
|
95
|
+
break;
|
|
96
|
+
case ACTIVATOR_EDITOR_TAB.STEREOTYPES:
|
|
97
|
+
addButtonTitle = 'Add stereotype';
|
|
98
|
+
break;
|
|
99
|
+
default:
|
|
100
|
+
break;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Tagged Values and Stereotype
|
|
104
|
+
const add = (): void => {
|
|
105
|
+
if (!isReadOnly) {
|
|
106
|
+
if (selectedTab === ACTIVATOR_EDITOR_TAB.TAGGED_VALUES) {
|
|
107
|
+
annotatedElement_addTaggedValue(
|
|
108
|
+
activatorElement,
|
|
109
|
+
stub_TaggedValue(stub_Tag(stub_Profile())),
|
|
110
|
+
);
|
|
111
|
+
} else if (selectedTab === ACTIVATOR_EDITOR_TAB.STEREOTYPES) {
|
|
112
|
+
annotatedElement_addStereotype(
|
|
113
|
+
activatorElement,
|
|
114
|
+
StereotypeExplicitReference.create(stub_Stereotype(stub_Profile())),
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
const handleDropTaggedValue = useCallback(
|
|
120
|
+
(item: UMLEditorElementDropTarget): void => {
|
|
121
|
+
if (!isReadOnly && item.data.packageableElement instanceof Profile) {
|
|
122
|
+
annotatedElement_addTaggedValue(
|
|
123
|
+
activatorElement,
|
|
124
|
+
stub_TaggedValue(stub_Tag(item.data.packageableElement)),
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
},
|
|
128
|
+
[activatorElement, isReadOnly],
|
|
129
|
+
);
|
|
130
|
+
const [{ isTaggedValueDragOver }, dropTaggedValueRef] = useDrop<
|
|
131
|
+
ElementDragSource,
|
|
132
|
+
void,
|
|
133
|
+
{ isTaggedValueDragOver: boolean }
|
|
134
|
+
>(
|
|
135
|
+
() => ({
|
|
136
|
+
accept: [CORE_DND_TYPE.PROJECT_EXPLORER_PROFILE],
|
|
137
|
+
drop: (item) => handleDropTaggedValue(item),
|
|
138
|
+
collect: (monitor) => ({
|
|
139
|
+
isTaggedValueDragOver: monitor.isOver({ shallow: true }),
|
|
140
|
+
}),
|
|
141
|
+
}),
|
|
142
|
+
[handleDropTaggedValue],
|
|
143
|
+
);
|
|
144
|
+
const handleDropStereotype = useCallback(
|
|
145
|
+
(item: UMLEditorElementDropTarget): void => {
|
|
146
|
+
if (!isReadOnly && item.data.packageableElement instanceof Profile) {
|
|
147
|
+
annotatedElement_addStereotype(
|
|
148
|
+
activatorElement,
|
|
149
|
+
StereotypeExplicitReference.create(
|
|
150
|
+
stub_Stereotype(item.data.packageableElement),
|
|
151
|
+
),
|
|
152
|
+
);
|
|
153
|
+
}
|
|
154
|
+
},
|
|
155
|
+
[activatorElement, isReadOnly],
|
|
156
|
+
);
|
|
157
|
+
const [{ isStereotypeDragOver }, dropStereotypeRef] = useDrop<
|
|
158
|
+
ElementDragSource,
|
|
159
|
+
void,
|
|
160
|
+
{ isStereotypeDragOver: boolean }
|
|
161
|
+
>(
|
|
162
|
+
() => ({
|
|
163
|
+
accept: [CORE_DND_TYPE.PROJECT_EXPLORER_PROFILE],
|
|
164
|
+
drop: (item) => handleDropStereotype(item),
|
|
165
|
+
collect: (monitor) => ({
|
|
166
|
+
isStereotypeDragOver: monitor.isOver({ shallow: true }),
|
|
167
|
+
}),
|
|
168
|
+
}),
|
|
169
|
+
[handleDropStereotype],
|
|
170
|
+
);
|
|
171
|
+
const _deleteStereotype =
|
|
172
|
+
(val: StereotypeReference): (() => void) =>
|
|
173
|
+
(): void =>
|
|
174
|
+
annotatedElement_deleteStereotype(activatorElement, val);
|
|
175
|
+
const _deleteTaggedValue =
|
|
176
|
+
(val: TaggedValue): (() => void) =>
|
|
177
|
+
(): void =>
|
|
178
|
+
annotatedElement_deleteTaggedValue(activatorElement, val);
|
|
179
|
+
const changeTab =
|
|
180
|
+
(tab: ACTIVATOR_EDITOR_TAB): (() => void) =>
|
|
181
|
+
(): void =>
|
|
182
|
+
editorState.setSelectedTab(tab);
|
|
183
|
+
|
|
73
184
|
const activator = editorState.activator;
|
|
74
|
-
const ownership = activator.ownership;
|
|
75
185
|
const visitFunction = (): void =>
|
|
76
186
|
editorState.editorStore.graphEditorMode.openElement(
|
|
77
187
|
activator.function.value,
|
|
@@ -99,10 +209,6 @@ export const HostedServiceFunctionActivatorEditor = observer(() => {
|
|
|
99
209
|
hostedService_setStoreModel(activator, !activator.storeModel);
|
|
100
210
|
};
|
|
101
211
|
|
|
102
|
-
const toggleGenerateLineage = (): void => {
|
|
103
|
-
hostedService_setGenerateLineage(activator, !activator.generateLineage);
|
|
104
|
-
};
|
|
105
|
-
|
|
106
212
|
const toggleAutoActivateUpdates = (): void => {
|
|
107
213
|
hostedService_setAutoActivateUpdates(
|
|
108
214
|
activator,
|
|
@@ -117,127 +223,6 @@ export const HostedServiceFunctionActivatorEditor = observer(() => {
|
|
|
117
223
|
: undefined;
|
|
118
224
|
};
|
|
119
225
|
|
|
120
|
-
//Ownership
|
|
121
|
-
const [showOwnerEditInput, setShowOwnerEditInput] = useState<
|
|
122
|
-
boolean | number
|
|
123
|
-
>(false);
|
|
124
|
-
const [ownerInputValue, setOwnerInputValue] = useState<string>('');
|
|
125
|
-
const [searchText, setSearchText] = useState('');
|
|
126
|
-
const [userOptions, setUserOptions] = useState<UserOption[]>([]);
|
|
127
|
-
const [isLoadingUsers, setIsLoadingUsers] = useState<boolean>(false);
|
|
128
|
-
const [ownerInputs, setOwnerInputs] = useState<string[]>([]);
|
|
129
|
-
const showAddOwnerInput = (): void => setShowOwnerEditInput(true);
|
|
130
|
-
|
|
131
|
-
const onOwnershipChange = (
|
|
132
|
-
val: HostedServiceOwnerOption | undefined,
|
|
133
|
-
): void => {
|
|
134
|
-
if (val) {
|
|
135
|
-
editorState.setSelectedOwnership(val);
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
const updateDeploymentIdentifier: React.ChangeEventHandler<
|
|
140
|
-
HTMLInputElement
|
|
141
|
-
> = (event) => {
|
|
142
|
-
if (!isReadOnly && ownership instanceof DeploymentOwner) {
|
|
143
|
-
activator_setDeploymentOwner(ownership, event.target.value);
|
|
144
|
-
}
|
|
145
|
-
};
|
|
146
|
-
|
|
147
|
-
const changeUserOwnerInputValue: React.ChangeEventHandler<
|
|
148
|
-
HTMLInputElement
|
|
149
|
-
> = (event) => setOwnerInputValue(event.target.value);
|
|
150
|
-
|
|
151
|
-
const updateUser =
|
|
152
|
-
(idx: number): (() => void) =>
|
|
153
|
-
(): void => {
|
|
154
|
-
if (
|
|
155
|
-
ownerInputValue &&
|
|
156
|
-
ownership instanceof UserList &&
|
|
157
|
-
!ownership.users.includes(ownerInputValue)
|
|
158
|
-
) {
|
|
159
|
-
activator_updateUserOwnership(ownership, ownerInputValue, idx);
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
|
|
163
|
-
const showEditOwnerInput =
|
|
164
|
-
(value: string, idx: number): (() => void) =>
|
|
165
|
-
(): void => {
|
|
166
|
-
setOwnerInputValue(value);
|
|
167
|
-
setShowOwnerEditInput(idx);
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
const hideAddOrEditOwnerInput = (): void => {
|
|
171
|
-
setShowOwnerEditInput(false);
|
|
172
|
-
setOwnerInputValue('');
|
|
173
|
-
};
|
|
174
|
-
|
|
175
|
-
const deleteUser =
|
|
176
|
-
(idx: number): (() => void) =>
|
|
177
|
-
(): void => {
|
|
178
|
-
if (!isReadOnly && ownership instanceof UserList) {
|
|
179
|
-
activator_deleteValueFromUserOwnership(ownership, idx);
|
|
180
|
-
if (
|
|
181
|
-
typeof showOwnerEditInput === 'number' &&
|
|
182
|
-
showOwnerEditInput > idx
|
|
183
|
-
) {
|
|
184
|
-
setShowOwnerEditInput(showOwnerEditInput - 1);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
const debouncedSearchUsers = useMemo(
|
|
190
|
-
() =>
|
|
191
|
-
debounce((input: string): void => {
|
|
192
|
-
setIsLoadingUsers(true);
|
|
193
|
-
flowResult(editorState.searchUsers(input))
|
|
194
|
-
.then((users) =>
|
|
195
|
-
setUserOptions(
|
|
196
|
-
users.map((u) => ({
|
|
197
|
-
value: u.userId,
|
|
198
|
-
label: u.userId,
|
|
199
|
-
})),
|
|
200
|
-
),
|
|
201
|
-
)
|
|
202
|
-
.then(() => setIsLoadingUsers(false))
|
|
203
|
-
.catch(editorState.editorStore.applicationStore.alertUnhandledError);
|
|
204
|
-
}, 500),
|
|
205
|
-
[editorState],
|
|
206
|
-
);
|
|
207
|
-
|
|
208
|
-
const onSearchTextChange = (value: string): void => {
|
|
209
|
-
if (value !== searchText) {
|
|
210
|
-
setSearchText(value);
|
|
211
|
-
debouncedSearchUsers.cancel();
|
|
212
|
-
if (value.length >= 3) {
|
|
213
|
-
debouncedSearchUsers(value);
|
|
214
|
-
} else if (value.length === 0) {
|
|
215
|
-
setUserOptions([]);
|
|
216
|
-
setIsLoadingUsers(false);
|
|
217
|
-
}
|
|
218
|
-
}
|
|
219
|
-
};
|
|
220
|
-
|
|
221
|
-
const onUserOptionChange = (options: UserOption[]): void => {
|
|
222
|
-
setOwnerInputs(options.map((op) => op.label));
|
|
223
|
-
setUserOptions([]);
|
|
224
|
-
debouncedSearchUsers.cancel();
|
|
225
|
-
setIsLoadingUsers(false);
|
|
226
|
-
};
|
|
227
|
-
|
|
228
|
-
const addUser = (): void => {
|
|
229
|
-
ownerInputs.forEach((value) => {
|
|
230
|
-
if (
|
|
231
|
-
value &&
|
|
232
|
-
ownership instanceof UserList &&
|
|
233
|
-
!ownership.users.includes(value)
|
|
234
|
-
) {
|
|
235
|
-
activator_addUserOwner(ownership, value);
|
|
236
|
-
}
|
|
237
|
-
});
|
|
238
|
-
hideAddOrEditOwnerInput();
|
|
239
|
-
};
|
|
240
|
-
|
|
241
226
|
//Pattern
|
|
242
227
|
const patternRef = useRef<HTMLInputElement>(null);
|
|
243
228
|
const [pattern, setPattern] = useState(activator.pattern);
|
|
@@ -269,363 +254,243 @@ export const HostedServiceFunctionActivatorEditor = observer(() => {
|
|
|
269
254
|
editorState.deployState.isInProgress,
|
|
270
255
|
)}
|
|
271
256
|
/>
|
|
272
|
-
<
|
|
273
|
-
<div className="
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
disabled={editorState.validateState.isInProgress}
|
|
282
|
-
tabIndex={-1}
|
|
283
|
-
title="Click Validate to verify your activator before deployment"
|
|
257
|
+
<div className="panel__header function-editor__tabs__header">
|
|
258
|
+
<div className="function-editor__tabs">
|
|
259
|
+
{Object.values(ACTIVATOR_EDITOR_TAB).map((tab) => (
|
|
260
|
+
<div
|
|
261
|
+
key={tab}
|
|
262
|
+
onClick={changeTab(tab)}
|
|
263
|
+
className={clsx('function-editor__tab', {
|
|
264
|
+
'function-editor__tab--active': tab === selectedTab,
|
|
265
|
+
})}
|
|
284
266
|
>
|
|
285
|
-
|
|
286
|
-
</button>
|
|
287
|
-
<button
|
|
288
|
-
className="hosted-service-function-activator-editor__header__actions__action hosted-service-function-activator-editor__header__actions__action--primary"
|
|
289
|
-
onClick={deploy}
|
|
290
|
-
disabled={editorState.deployState.isInProgress}
|
|
291
|
-
title="Deploy to sandbox"
|
|
292
|
-
tabIndex={-1}
|
|
293
|
-
>
|
|
294
|
-
Deploy to Sandbox
|
|
295
|
-
</button>
|
|
296
|
-
</div>
|
|
297
|
-
</div>
|
|
298
|
-
<PanelForm>
|
|
299
|
-
<PanelFormValidatedTextField
|
|
300
|
-
ref={patternRef}
|
|
301
|
-
name="URL Pattern"
|
|
302
|
-
isReadOnly={isReadOnly}
|
|
303
|
-
className="service-editor__pattern__input"
|
|
304
|
-
errorMessageClassName="service-editor__pattern__input"
|
|
305
|
-
prompt={
|
|
306
|
-
<>
|
|
307
|
-
Specifies the URL pattern of the service (e.g. /myService/
|
|
308
|
-
<span className="service-editor__pattern__example__param">{`{param}`}</span>
|
|
309
|
-
)
|
|
310
|
-
</>
|
|
311
|
-
}
|
|
312
|
-
update={(value: string | undefined): void => {
|
|
313
|
-
updatePattern(value ?? '');
|
|
314
|
-
}}
|
|
315
|
-
validate={getValidationMessage}
|
|
316
|
-
value={pattern}
|
|
317
|
-
/>
|
|
318
|
-
</PanelForm>
|
|
319
|
-
<PanelForm>
|
|
320
|
-
<div className="panel__content__form__section service-editor__parameters">
|
|
321
|
-
<div className="panel__content__form__section__header__label">
|
|
322
|
-
Parameters
|
|
323
|
-
</div>
|
|
324
|
-
<div className="panel__content__form__section__header__prompt">
|
|
325
|
-
URL parameters (each must be surrounded by curly braces) will be
|
|
326
|
-
passed as arguments for the execution query. Note that if the
|
|
327
|
-
service is configured to use multi-execution, one of the URL
|
|
328
|
-
parameters must be chosen as the execution key.
|
|
267
|
+
{prettyCONSTName(tab)}
|
|
329
268
|
</div>
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
269
|
+
))}
|
|
270
|
+
</div>
|
|
271
|
+
{selectedTab !== ACTIVATOR_EDITOR_TAB.DEFINITION && (
|
|
272
|
+
<button
|
|
273
|
+
className="panel__header__action"
|
|
274
|
+
disabled={isReadOnly}
|
|
275
|
+
onClick={add}
|
|
276
|
+
tabIndex={-1}
|
|
277
|
+
title={addButtonTitle}
|
|
278
|
+
>
|
|
279
|
+
<PlusIcon />
|
|
280
|
+
</button>
|
|
281
|
+
)}
|
|
282
|
+
</div>
|
|
283
|
+
<PanelContent>
|
|
284
|
+
{selectedTab === ACTIVATOR_EDITOR_TAB.DEFINITION && (
|
|
285
|
+
<div>
|
|
286
|
+
<div className="hosted-service-function-activator-editor__header">
|
|
287
|
+
<div className="hosted-service-function-activator-editor__header__label">
|
|
288
|
+
Rest Service Activator
|
|
289
|
+
</div>
|
|
290
|
+
<div className="hosted-service-function-activator-editor__header__actions">
|
|
291
|
+
<button
|
|
292
|
+
className="hosted-service-function-activator-editor__header__actions__action hosted-service-function-activator-editor__header__actions__action--primary"
|
|
293
|
+
onClick={validate}
|
|
294
|
+
disabled={editorState.validateState.isInProgress}
|
|
295
|
+
tabIndex={-1}
|
|
296
|
+
title="Click Validate to verify your activator before deployment"
|
|
297
|
+
>
|
|
298
|
+
Validate
|
|
299
|
+
</button>
|
|
300
|
+
<button
|
|
301
|
+
className="hosted-service-function-activator-editor__header__actions__action hosted-service-function-activator-editor__header__actions__action--primary"
|
|
302
|
+
onClick={deploy}
|
|
303
|
+
disabled={editorState.deployState.isInProgress}
|
|
304
|
+
title="Deploy to sandbox"
|
|
305
|
+
tabIndex={-1}
|
|
306
|
+
>
|
|
307
|
+
Deploy to Sandbox
|
|
308
|
+
</button>
|
|
368
309
|
</div>
|
|
369
|
-
<input
|
|
370
|
-
className="panel__content__form__section__input"
|
|
371
|
-
spellCheck={false}
|
|
372
|
-
disabled={true}
|
|
373
|
-
value={generateFunctionPrettyName(activator.function.value, {
|
|
374
|
-
fullPath: true,
|
|
375
|
-
spacing: false,
|
|
376
|
-
})}
|
|
377
|
-
/>
|
|
378
|
-
<button
|
|
379
|
-
className="btn--dark btn--sm hosted-service-function-activator-editor__configuration__item__btn"
|
|
380
|
-
onClick={visitFunction}
|
|
381
|
-
tabIndex={-1}
|
|
382
|
-
title="See Function"
|
|
383
|
-
>
|
|
384
|
-
<LongArrowRightIcon />
|
|
385
|
-
</button>
|
|
386
|
-
</div>
|
|
387
|
-
</div>
|
|
388
|
-
</PanelForm>
|
|
389
|
-
<PanelForm>
|
|
390
|
-
<div className="panel__content__form__section">
|
|
391
|
-
<div className="panel__content__form__section__header__label">
|
|
392
|
-
Documentation
|
|
393
310
|
</div>
|
|
394
|
-
<
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
isReadOnly={isReadOnly}
|
|
418
|
-
value={activator.storeModel}
|
|
419
|
-
name="Store Model"
|
|
420
|
-
prompt="Use Store Model (slower)"
|
|
421
|
-
update={toggleUseStoreModel}
|
|
422
|
-
/>
|
|
423
|
-
</PanelForm>
|
|
424
|
-
<PanelForm>
|
|
425
|
-
<PanelFormBooleanField
|
|
426
|
-
isReadOnly={isReadOnly}
|
|
427
|
-
value={activator.generateLineage}
|
|
428
|
-
name="Generate Lineage"
|
|
429
|
-
prompt="Generate Lineage (slower)"
|
|
430
|
-
update={toggleGenerateLineage}
|
|
431
|
-
/>
|
|
432
|
-
</PanelForm>
|
|
433
|
-
<PanelForm>
|
|
434
|
-
{
|
|
435
|
-
<div>
|
|
436
|
-
<div className="panel__content__form__section">
|
|
311
|
+
<PanelForm>
|
|
312
|
+
<PanelFormValidatedTextField
|
|
313
|
+
ref={patternRef}
|
|
314
|
+
name="URL Pattern"
|
|
315
|
+
isReadOnly={isReadOnly}
|
|
316
|
+
className="service-editor__pattern__input"
|
|
317
|
+
errorMessageClassName="service-editor__pattern__input"
|
|
318
|
+
prompt={
|
|
319
|
+
<>
|
|
320
|
+
Specifies the URL pattern of the service (e.g. /myService/
|
|
321
|
+
<span className="service-editor__pattern__example__param">{`{param}`}</span>
|
|
322
|
+
)
|
|
323
|
+
</>
|
|
324
|
+
}
|
|
325
|
+
update={(value: string | undefined): void => {
|
|
326
|
+
updatePattern(value ?? '');
|
|
327
|
+
}}
|
|
328
|
+
validate={getValidationMessage}
|
|
329
|
+
value={pattern}
|
|
330
|
+
/>
|
|
331
|
+
</PanelForm>
|
|
332
|
+
<PanelForm>
|
|
333
|
+
<div className="panel__content__form__section service-editor__parameters">
|
|
437
334
|
<div className="panel__content__form__section__header__label">
|
|
438
|
-
|
|
335
|
+
Parameters
|
|
439
336
|
</div>
|
|
440
337
|
<div className="panel__content__form__section__header__prompt">
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
value={editorState.selectedOwnership}
|
|
447
|
-
darkMode={
|
|
448
|
-
!applicationStore.layoutService
|
|
449
|
-
.TEMPORARY__isLightColorThemeEnabled
|
|
450
|
-
}
|
|
451
|
-
/>
|
|
452
|
-
</div>
|
|
453
|
-
{ownership instanceof DeploymentOwner && (
|
|
454
|
-
<div className="panel__content__form__section">
|
|
455
|
-
<div>
|
|
456
|
-
<div className="panel__content__form__section__header__label">
|
|
457
|
-
Deployment Identifier :
|
|
458
|
-
</div>
|
|
459
|
-
<input
|
|
460
|
-
className="panel__content__form__section__input"
|
|
461
|
-
spellCheck={false}
|
|
462
|
-
disabled={isReadOnly}
|
|
463
|
-
value={ownership.id}
|
|
464
|
-
onChange={updateDeploymentIdentifier}
|
|
465
|
-
/>
|
|
466
|
-
</div>
|
|
338
|
+
URL parameters (each must be surrounded by curly braces)
|
|
339
|
+
will be passed as arguments for the execution query. Note
|
|
340
|
+
that if the service is configured to use multi-execution,
|
|
341
|
+
one of the URL parameters must be chosen as the execution
|
|
342
|
+
key.
|
|
467
343
|
</div>
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
<div className="panel__content__form__section__header__label">
|
|
473
|
-
Users :
|
|
344
|
+
<div className="service-editor__parameters__list">
|
|
345
|
+
{!activator.patternParameters.length && (
|
|
346
|
+
<div className="service-editor__parameters__list__empty">
|
|
347
|
+
No parameter
|
|
474
348
|
</div>
|
|
475
|
-
|
|
349
|
+
)}
|
|
350
|
+
{Boolean(activator.patternParameters.length) &&
|
|
351
|
+
activator.patternParameters.map((parameter) => (
|
|
476
352
|
<div
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
LEGEND_STUDIO_TEST_ID.PANEL_CONTENT_FORM_SECTION_LIST_ITEMS
|
|
480
|
-
}
|
|
353
|
+
key={parameter}
|
|
354
|
+
className="service-editor__parameter"
|
|
481
355
|
>
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
showOwnerEditInput === idx
|
|
487
|
-
? 'panel__content__form__section__list__new-item'
|
|
488
|
-
: 'panel__content__form__section__list__item'
|
|
489
|
-
}
|
|
490
|
-
>
|
|
491
|
-
{showOwnerEditInput === idx ? (
|
|
492
|
-
<>
|
|
493
|
-
<input
|
|
494
|
-
className="panel__content__form__section__input panel__content__form__section__list__new-item__input"
|
|
495
|
-
spellCheck={false}
|
|
496
|
-
disabled={isReadOnly}
|
|
497
|
-
value={ownerInputValue}
|
|
498
|
-
onChange={changeUserOwnerInputValue}
|
|
499
|
-
/>
|
|
500
|
-
<div className="panel__content__form__section__list__new-item__actions">
|
|
501
|
-
<button
|
|
502
|
-
className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
|
|
503
|
-
disabled={
|
|
504
|
-
isReadOnly ||
|
|
505
|
-
ownership.users.includes(
|
|
506
|
-
ownerInputValue,
|
|
507
|
-
)
|
|
508
|
-
}
|
|
509
|
-
onClick={updateUser(idx)}
|
|
510
|
-
tabIndex={-1}
|
|
511
|
-
>
|
|
512
|
-
Save
|
|
513
|
-
</button>
|
|
514
|
-
<button
|
|
515
|
-
className="panel__content__form__section__list__new-item__cancel-btn btn btn--dark"
|
|
516
|
-
disabled={isReadOnly}
|
|
517
|
-
onClick={hideAddOrEditOwnerInput}
|
|
518
|
-
tabIndex={-1}
|
|
519
|
-
>
|
|
520
|
-
Cancel
|
|
521
|
-
</button>
|
|
522
|
-
</div>
|
|
523
|
-
</>
|
|
524
|
-
) : (
|
|
525
|
-
<>
|
|
526
|
-
<div className="panel__content__form__section__list__item__value">
|
|
527
|
-
{value}
|
|
528
|
-
</div>
|
|
529
|
-
<div className="panel__content__form__section__list__item__actions">
|
|
530
|
-
<button
|
|
531
|
-
className="panel__content__form__section__list__item__edit-btn"
|
|
532
|
-
disabled={isReadOnly}
|
|
533
|
-
onClick={showEditOwnerInput(value, idx)}
|
|
534
|
-
tabIndex={-1}
|
|
535
|
-
>
|
|
536
|
-
<PencilIcon />
|
|
537
|
-
</button>
|
|
538
|
-
<button
|
|
539
|
-
className="panel__content__form__section__list__item__remove-btn"
|
|
540
|
-
disabled={isReadOnly}
|
|
541
|
-
onClick={deleteUser(idx)}
|
|
542
|
-
tabIndex={-1}
|
|
543
|
-
>
|
|
544
|
-
<TimesIcon />
|
|
545
|
-
</button>
|
|
546
|
-
</div>
|
|
547
|
-
</>
|
|
548
|
-
)}
|
|
549
|
-
</div>
|
|
550
|
-
))}
|
|
551
|
-
{showOwnerEditInput === true && (
|
|
552
|
-
<div className="panel__content__form__section__list__new-item">
|
|
553
|
-
<CustomSelectorInput
|
|
554
|
-
className="service-editor__owner__selector"
|
|
555
|
-
placeholder="Enter an owner..."
|
|
556
|
-
inputValue={searchText}
|
|
557
|
-
options={userOptions}
|
|
558
|
-
allowCreating={true}
|
|
559
|
-
isLoading={isLoadingUsers}
|
|
560
|
-
disabled={isReadOnly}
|
|
561
|
-
darkMode={
|
|
562
|
-
!applicationStore.layoutService
|
|
563
|
-
.TEMPORARY__isLightColorThemeEnabled
|
|
564
|
-
}
|
|
565
|
-
onInputChange={onSearchTextChange}
|
|
566
|
-
onChange={onUserOptionChange}
|
|
567
|
-
isMulti={true}
|
|
568
|
-
/>
|
|
569
|
-
<div className="panel__content__form__section__list__new-item__actions">
|
|
570
|
-
<button
|
|
571
|
-
className="panel__content__form__section__list__new-item__add-btn btn btn--dark service-editor__owner__action"
|
|
572
|
-
disabled={
|
|
573
|
-
isReadOnly ||
|
|
574
|
-
ownerInputs.some((i) =>
|
|
575
|
-
ownership.users.includes(i),
|
|
576
|
-
)
|
|
577
|
-
}
|
|
578
|
-
onClick={addUser}
|
|
579
|
-
tabIndex={-1}
|
|
580
|
-
>
|
|
581
|
-
Save
|
|
582
|
-
</button>
|
|
583
|
-
<button
|
|
584
|
-
className="panel__content__form__section__list__new-item__cancel-btn btn btn--dark service-editor__owner__action"
|
|
585
|
-
disabled={isReadOnly}
|
|
586
|
-
onClick={hideAddOrEditOwnerInput}
|
|
587
|
-
tabIndex={-1}
|
|
588
|
-
>
|
|
589
|
-
Cancel
|
|
590
|
-
</button>
|
|
591
|
-
</div>
|
|
592
|
-
</div>
|
|
593
|
-
)}
|
|
594
|
-
</div>
|
|
595
|
-
{ownership.users.length <
|
|
596
|
-
MINIMUM_HOSTED_SERVICE_OWNERS &&
|
|
597
|
-
showOwnerEditInput !== true && (
|
|
598
|
-
<div
|
|
599
|
-
className="service-editor__owner__validation"
|
|
600
|
-
title={`${MINIMUM_HOSTED_SERVICE_OWNERS} owners required`}
|
|
601
|
-
>
|
|
602
|
-
<ErrorIcon />
|
|
603
|
-
<div className="service-editor__owner__validation-label">
|
|
604
|
-
Service requires at least{' '}
|
|
605
|
-
{MINIMUM_HOSTED_SERVICE_OWNERS} owners
|
|
606
|
-
</div>
|
|
607
|
-
</div>
|
|
608
|
-
)}
|
|
609
|
-
{showOwnerEditInput !== true && (
|
|
610
|
-
<div className="panel__content__form__section__list__new-item__add">
|
|
356
|
+
<div className="service-editor__parameter__text">
|
|
357
|
+
{parameter}
|
|
358
|
+
</div>
|
|
359
|
+
<div className="service-editor__parameter__actions">
|
|
611
360
|
<button
|
|
612
|
-
className="
|
|
361
|
+
className="service-editor__parameter__action"
|
|
613
362
|
disabled={isReadOnly}
|
|
614
|
-
onClick={
|
|
363
|
+
onClick={removePatternParameter(parameter)}
|
|
364
|
+
title="Remove parameter"
|
|
615
365
|
tabIndex={-1}
|
|
616
|
-
title="Add owner"
|
|
617
366
|
>
|
|
618
|
-
|
|
367
|
+
<TimesIcon />
|
|
619
368
|
</button>
|
|
620
369
|
</div>
|
|
621
|
-
|
|
622
|
-
|
|
370
|
+
</div>
|
|
371
|
+
))}
|
|
372
|
+
</div>
|
|
373
|
+
</div>
|
|
374
|
+
</PanelForm>
|
|
375
|
+
<PanelForm>
|
|
376
|
+
<div className="panel__content__form__section">
|
|
377
|
+
<div className="panel__content__form__section__header__label">
|
|
378
|
+
Function
|
|
379
|
+
</div>
|
|
380
|
+
</div>
|
|
381
|
+
<div className="hosted-service-function-activator-editor__configuration__items">
|
|
382
|
+
<div className="hosted-service-function-activator-editor__configuration__item">
|
|
383
|
+
<div className="btn--sm hosted-service-function-activator-editor__configuration__item__label">
|
|
384
|
+
<PURE_FunctionIcon />
|
|
623
385
|
</div>
|
|
386
|
+
<input
|
|
387
|
+
className="panel__content__form__section__input"
|
|
388
|
+
spellCheck={false}
|
|
389
|
+
disabled={true}
|
|
390
|
+
value={generateFunctionPrettyName(
|
|
391
|
+
activator.function.value,
|
|
392
|
+
{
|
|
393
|
+
fullPath: true,
|
|
394
|
+
spacing: false,
|
|
395
|
+
},
|
|
396
|
+
)}
|
|
397
|
+
/>
|
|
398
|
+
<button
|
|
399
|
+
className="btn--dark btn--sm hosted-service-function-activator-editor__configuration__item__btn"
|
|
400
|
+
onClick={visitFunction}
|
|
401
|
+
tabIndex={-1}
|
|
402
|
+
title="See Function"
|
|
403
|
+
>
|
|
404
|
+
<LongArrowRightIcon />
|
|
405
|
+
</button>
|
|
624
406
|
</div>
|
|
625
|
-
|
|
626
|
-
</
|
|
627
|
-
|
|
628
|
-
|
|
407
|
+
</div>
|
|
408
|
+
</PanelForm>
|
|
409
|
+
<PanelForm>
|
|
410
|
+
<div className="panel__content__form__section">
|
|
411
|
+
<div className="panel__content__form__section__header__label">
|
|
412
|
+
Documentation
|
|
413
|
+
</div>
|
|
414
|
+
<div className="panel__content__form__section__header__prompt">{`Provide a brief description of the service's functionalities and usage`}</div>
|
|
415
|
+
<textarea
|
|
416
|
+
className="panel__content__form__section__textarea service-editor__documentation__input"
|
|
417
|
+
spellCheck={false}
|
|
418
|
+
disabled={isReadOnly}
|
|
419
|
+
value={activator.documentation}
|
|
420
|
+
onChange={changeDocumentation}
|
|
421
|
+
/>
|
|
422
|
+
</div>
|
|
423
|
+
</PanelForm>
|
|
424
|
+
<PanelForm>
|
|
425
|
+
<PanelFormBooleanField
|
|
426
|
+
isReadOnly={isReadOnly}
|
|
427
|
+
value={activator.autoActivateUpdates}
|
|
428
|
+
name="Auto Activate Updates"
|
|
429
|
+
prompt="Specifies if the new generation should be automatically activated;
|
|
430
|
+
only valid when latest revision is selected upon service
|
|
431
|
+
registration"
|
|
432
|
+
update={toggleAutoActivateUpdates}
|
|
433
|
+
/>
|
|
434
|
+
</PanelForm>
|
|
435
|
+
<PanelForm>
|
|
436
|
+
<PanelFormBooleanField
|
|
437
|
+
isReadOnly={isReadOnly}
|
|
438
|
+
value={activator.storeModel}
|
|
439
|
+
name="Store Model"
|
|
440
|
+
prompt="Use Store Model (slower)"
|
|
441
|
+
update={toggleUseStoreModel}
|
|
442
|
+
/>
|
|
443
|
+
</PanelForm>
|
|
444
|
+
<PanelForm>
|
|
445
|
+
<ActivatorOwnershipForm
|
|
446
|
+
activator={activator}
|
|
447
|
+
isReadOnly={isReadOnly}
|
|
448
|
+
/>
|
|
449
|
+
</PanelForm>
|
|
450
|
+
</div>
|
|
451
|
+
)}
|
|
452
|
+
{selectedTab === ACTIVATOR_EDITOR_TAB.TAGGED_VALUES && (
|
|
453
|
+
<div
|
|
454
|
+
ref={dropTaggedValueRef}
|
|
455
|
+
className={clsx('panel__content__lists', {
|
|
456
|
+
'panel__content__lists--dnd-over':
|
|
457
|
+
isTaggedValueDragOver && !isReadOnly,
|
|
458
|
+
})}
|
|
459
|
+
>
|
|
460
|
+
<TaggedValueDragPreviewLayer />
|
|
461
|
+
{activatorElement.taggedValues.map((taggedValue) => (
|
|
462
|
+
<TaggedValueEditor
|
|
463
|
+
annotatedElement={activatorElement}
|
|
464
|
+
key={taggedValue._UUID}
|
|
465
|
+
taggedValue={taggedValue}
|
|
466
|
+
deleteValue={_deleteTaggedValue(taggedValue)}
|
|
467
|
+
isReadOnly={isReadOnly}
|
|
468
|
+
darkTheme={true}
|
|
469
|
+
/>
|
|
470
|
+
))}
|
|
471
|
+
</div>
|
|
472
|
+
)}
|
|
473
|
+
{selectedTab === ACTIVATOR_EDITOR_TAB.STEREOTYPES && (
|
|
474
|
+
<div
|
|
475
|
+
ref={dropStereotypeRef}
|
|
476
|
+
className={clsx('panel__content__lists', {
|
|
477
|
+
'panel__content__lists--dnd-over':
|
|
478
|
+
isStereotypeDragOver && !isReadOnly,
|
|
479
|
+
})}
|
|
480
|
+
>
|
|
481
|
+
<StereotypeDragPreviewLayer />
|
|
482
|
+
{activatorElement.stereotypes.map((stereotype) => (
|
|
483
|
+
<StereotypeSelector
|
|
484
|
+
key={stereotype.value._UUID}
|
|
485
|
+
annotatedElement={activatorElement}
|
|
486
|
+
stereotype={stereotype}
|
|
487
|
+
deleteStereotype={_deleteStereotype(stereotype)}
|
|
488
|
+
isReadOnly={isReadOnly}
|
|
489
|
+
darkTheme={true}
|
|
490
|
+
/>
|
|
491
|
+
))}
|
|
492
|
+
</div>
|
|
493
|
+
)}
|
|
629
494
|
</PanelContent>
|
|
630
495
|
</Panel>
|
|
631
496
|
</div>
|