@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.
Files changed (22) hide show
  1. package/lib/components/editor/editor-group/function-activator/ActivatorFormComponents.d.ts +23 -0
  2. package/lib/components/editor/editor-group/function-activator/ActivatorFormComponents.d.ts.map +1 -0
  3. package/lib/components/editor/editor-group/function-activator/ActivatorFormComponents.js +34 -0
  4. package/lib/components/editor/editor-group/function-activator/ActivatorFormComponents.js.map +1 -0
  5. package/lib/components/editor/editor-group/function-activator/HostedServiceFunctionActivatorEditor.d.ts.map +1 -1
  6. package/lib/components/editor/editor-group/function-activator/HostedServiceFunctionActivatorEditor.js +76 -108
  7. package/lib/components/editor/editor-group/function-activator/HostedServiceFunctionActivatorEditor.js.map +1 -1
  8. package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.d.ts.map +1 -1
  9. package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.js +4 -13
  10. package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.js.map +1 -1
  11. package/lib/index.css +1 -1
  12. package/lib/package.json +1 -1
  13. package/lib/stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.d.ts +8 -3
  14. package/lib/stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.d.ts.map +1 -1
  15. package/lib/stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.js +15 -10
  16. package/lib/stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.js.map +1 -1
  17. package/package.json +6 -6
  18. package/src/components/editor/editor-group/function-activator/ActivatorFormComponents.tsx +97 -0
  19. package/src/components/editor/editor-group/function-activator/HostedServiceFunctionActivatorEditor.tsx +347 -482
  20. package/src/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.tsx +7 -42
  21. package/src/stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.ts +18 -11
  22. package/tsconfig.json +1 -0
@@ -25,14 +25,19 @@ import {
25
25
  PanelFormBooleanField,
26
26
  PanelFormValidatedTextField,
27
27
  TimesIcon,
28
- CustomSelectorInput,
29
- PencilIcon,
30
- ErrorIcon,
28
+ clsx,
29
+ PlusIcon,
31
30
  } from '@finos/legend-art';
32
31
  import {
33
- DeploymentOwner,
34
- UserList,
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
- OWNERSHIP_OPTIONS,
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 { useEffect, useMemo, useRef, useState } from 'react';
60
- import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js';
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
- type UserOption = { label: string; value: string };
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
- <PanelContent>
273
- <div className="hosted-service-function-activator-editor__header">
274
- <div className="hosted-service-function-activator-editor__header__label">
275
- Rest Service Activator
276
- </div>
277
- <div className="hosted-service-function-activator-editor__header__actions">
278
- <button
279
- className="hosted-service-function-activator-editor__header__actions__action hosted-service-function-activator-editor__header__actions__action--primary"
280
- onClick={validate}
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
- Validate
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
- <div className="service-editor__parameters__list">
331
- {!activator.patternParameters.length && (
332
- <div className="service-editor__parameters__list__empty">
333
- No parameter
334
- </div>
335
- )}
336
- {Boolean(activator.patternParameters.length) &&
337
- activator.patternParameters.map((parameter) => (
338
- <div key={parameter} className="service-editor__parameter">
339
- <div className="service-editor__parameter__text">
340
- {parameter}
341
- </div>
342
- <div className="service-editor__parameter__actions">
343
- <button
344
- className="service-editor__parameter__action"
345
- disabled={isReadOnly}
346
- onClick={removePatternParameter(parameter)}
347
- title="Remove parameter"
348
- tabIndex={-1}
349
- >
350
- <TimesIcon />
351
- </button>
352
- </div>
353
- </div>
354
- ))}
355
- </div>
356
- </div>
357
- </PanelForm>
358
- <PanelForm>
359
- <div className="panel__content__form__section">
360
- <div className="panel__content__form__section__header__label">
361
- Function
362
- </div>
363
- </div>
364
- <div className="hosted-service-function-activator-editor__configuration__items">
365
- <div className="hosted-service-function-activator-editor__configuration__item">
366
- <div className="btn--sm hosted-service-function-activator-editor__configuration__item__label">
367
- <PURE_FunctionIcon />
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
- <div className="panel__content__form__section__header__prompt">{`Provide a brief description of the service's functionalities and usage`}</div>
395
- <textarea
396
- className="panel__content__form__section__textarea service-editor__documentation__input"
397
- spellCheck={false}
398
- disabled={isReadOnly}
399
- value={activator.documentation}
400
- onChange={changeDocumentation}
401
- />
402
- </div>
403
- </PanelForm>
404
- <PanelForm>
405
- <PanelFormBooleanField
406
- isReadOnly={isReadOnly}
407
- value={activator.autoActivateUpdates}
408
- name="Auto Activate Updates"
409
- prompt="Specifies if the new generation should be automatically activated;
410
- only valid when latest revision is selected upon service
411
- registration"
412
- update={toggleAutoActivateUpdates}
413
- />
414
- </PanelForm>
415
- <PanelForm>
416
- <PanelFormBooleanField
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
- Ownership
335
+ Parameters
439
336
  </div>
440
337
  <div className="panel__content__form__section__header__prompt">
441
- The ownership model you want to use to control your service.
442
- </div>
443
- <CustomSelectorInput
444
- options={OWNERSHIP_OPTIONS}
445
- onChange={onOwnershipChange}
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
- {ownership instanceof UserList && (
470
- <div className="panel__content__form__section">
471
- <div>
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
- <div className="panel__content__form__section__list">
349
+ )}
350
+ {Boolean(activator.patternParameters.length) &&
351
+ activator.patternParameters.map((parameter) => (
476
352
  <div
477
- className="panel__content__form__section__list__items"
478
- data-testid={
479
- LEGEND_STUDIO_TEST_ID.PANEL_CONTENT_FORM_SECTION_LIST_ITEMS
480
- }
353
+ key={parameter}
354
+ className="service-editor__parameter"
481
355
  >
482
- {ownership.users.map((value, idx) => (
483
- <div
484
- key={value}
485
- className={
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="panel__content__form__section__list__new-item__add-btn btn btn--dark"
361
+ className="service-editor__parameter__action"
613
362
  disabled={isReadOnly}
614
- onClick={showAddOwnerInput}
363
+ onClick={removePatternParameter(parameter)}
364
+ title="Remove parameter"
615
365
  tabIndex={-1}
616
- title="Add owner"
617
366
  >
618
- Add Value
367
+ <TimesIcon />
619
368
  </button>
620
369
  </div>
621
- )}
622
- </div>
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
- </div>
627
- }
628
- </PanelForm>
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>