@finos/legend-application-studio 28.18.41 → 28.18.43

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.
@@ -28,11 +28,21 @@ import {
28
28
  CustomSelectorInput,
29
29
  PencilIcon,
30
30
  ErrorIcon,
31
+ clsx,
32
+ PlusIcon,
31
33
  } from '@finos/legend-art';
32
34
  import {
33
35
  DeploymentOwner,
36
+ Profile,
37
+ StereotypeExplicitReference,
38
+ type StereotypeReference,
39
+ type TaggedValue,
34
40
  UserList,
35
41
  generateFunctionPrettyName,
42
+ stub_Profile,
43
+ stub_Stereotype,
44
+ stub_Tag,
45
+ stub_TaggedValue,
36
46
  validate_ServicePattern,
37
47
  } from '@finos/legend-graph';
38
48
  import { observer } from 'mobx-react-lite';
@@ -43,6 +53,7 @@ import {
43
53
  OWNERSHIP_OPTIONS,
44
54
  type HostedServiceOwnerOption,
45
55
  MINIMUM_HOSTED_SERVICE_OWNERS,
56
+ ACTIVATOR_EDITOR_TAB,
46
57
  } from '../../../../stores/editor/editor-state/element-editor-state/function-activator/HostedServiceFunctionActivatorEditorState.js';
47
58
  import {
48
59
  hostedService_setAutoActivateUpdates,
@@ -56,10 +67,30 @@ import {
56
67
  activator_deleteValueFromUserOwnership,
57
68
  activator_addUserOwner,
58
69
  } from '../../../../stores/graph-modifier/DSL_FunctionActivator_GraphModifierHelper.js';
59
- import { useEffect, useMemo, useRef, useState } from 'react';
70
+ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
60
71
  import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js';
61
- import { debounce } from '@finos/legend-shared';
72
+ import { debounce, prettyCONSTName } from '@finos/legend-shared';
62
73
  import { flowResult } from 'mobx';
74
+ import {
75
+ annotatedElement_addStereotype,
76
+ annotatedElement_addTaggedValue,
77
+ annotatedElement_deleteStereotype,
78
+ annotatedElement_deleteTaggedValue,
79
+ } from '../../../../stores/graph-modifier/DomainGraphModifierHelper.js';
80
+ import {
81
+ CORE_DND_TYPE,
82
+ type ElementDragSource,
83
+ type UMLEditorElementDropTarget,
84
+ } from '../../../../stores/editor/utils/DnDUtils.js';
85
+ import { useDrop } from 'react-dnd';
86
+ import {
87
+ TaggedValueDragPreviewLayer,
88
+ TaggedValueEditor,
89
+ } from '../uml-editor/TaggedValueEditor.js';
90
+ import {
91
+ StereotypeDragPreviewLayer,
92
+ StereotypeSelector,
93
+ } from '../uml-editor/StereotypeSelector.js';
63
94
 
64
95
  type UserOption = { label: string; value: string };
65
96
 
@@ -69,7 +100,102 @@ export const HostedServiceFunctionActivatorEditor = observer(() => {
69
100
  const editorState = editorStore.tabManagerState.getCurrentEditorState(
70
101
  HostedServiceFunctionActivatorEditorState,
71
102
  );
103
+ const activatorElement = editorState.element;
72
104
  const isReadOnly = editorState.isReadOnly;
105
+ const selectedTab = editorState.selectedTab;
106
+ let addButtonTitle = '';
107
+ switch (selectedTab) {
108
+ case ACTIVATOR_EDITOR_TAB.TAGGED_VALUES:
109
+ addButtonTitle = 'Add tagged value';
110
+ break;
111
+ case ACTIVATOR_EDITOR_TAB.STEREOTYPES:
112
+ addButtonTitle = 'Add stereotype';
113
+ break;
114
+ default:
115
+ break;
116
+ }
117
+
118
+ // Tagged Values and Stereotype
119
+ const add = (): void => {
120
+ if (!isReadOnly) {
121
+ if (selectedTab === ACTIVATOR_EDITOR_TAB.TAGGED_VALUES) {
122
+ annotatedElement_addTaggedValue(
123
+ activatorElement,
124
+ stub_TaggedValue(stub_Tag(stub_Profile())),
125
+ );
126
+ } else if (selectedTab === ACTIVATOR_EDITOR_TAB.STEREOTYPES) {
127
+ annotatedElement_addStereotype(
128
+ activatorElement,
129
+ StereotypeExplicitReference.create(stub_Stereotype(stub_Profile())),
130
+ );
131
+ }
132
+ }
133
+ };
134
+ const handleDropTaggedValue = useCallback(
135
+ (item: UMLEditorElementDropTarget): void => {
136
+ if (!isReadOnly && item.data.packageableElement instanceof Profile) {
137
+ annotatedElement_addTaggedValue(
138
+ activatorElement,
139
+ stub_TaggedValue(stub_Tag(item.data.packageableElement)),
140
+ );
141
+ }
142
+ },
143
+ [activatorElement, isReadOnly],
144
+ );
145
+ const [{ isTaggedValueDragOver }, dropTaggedValueRef] = useDrop<
146
+ ElementDragSource,
147
+ void,
148
+ { isTaggedValueDragOver: boolean }
149
+ >(
150
+ () => ({
151
+ accept: [CORE_DND_TYPE.PROJECT_EXPLORER_PROFILE],
152
+ drop: (item) => handleDropTaggedValue(item),
153
+ collect: (monitor) => ({
154
+ isTaggedValueDragOver: monitor.isOver({ shallow: true }),
155
+ }),
156
+ }),
157
+ [handleDropTaggedValue],
158
+ );
159
+ const handleDropStereotype = useCallback(
160
+ (item: UMLEditorElementDropTarget): void => {
161
+ if (!isReadOnly && item.data.packageableElement instanceof Profile) {
162
+ annotatedElement_addStereotype(
163
+ activatorElement,
164
+ StereotypeExplicitReference.create(
165
+ stub_Stereotype(item.data.packageableElement),
166
+ ),
167
+ );
168
+ }
169
+ },
170
+ [activatorElement, isReadOnly],
171
+ );
172
+ const [{ isStereotypeDragOver }, dropStereotypeRef] = useDrop<
173
+ ElementDragSource,
174
+ void,
175
+ { isStereotypeDragOver: boolean }
176
+ >(
177
+ () => ({
178
+ accept: [CORE_DND_TYPE.PROJECT_EXPLORER_PROFILE],
179
+ drop: (item) => handleDropStereotype(item),
180
+ collect: (monitor) => ({
181
+ isStereotypeDragOver: monitor.isOver({ shallow: true }),
182
+ }),
183
+ }),
184
+ [handleDropStereotype],
185
+ );
186
+ const _deleteStereotype =
187
+ (val: StereotypeReference): (() => void) =>
188
+ (): void =>
189
+ annotatedElement_deleteStereotype(activatorElement, val);
190
+ const _deleteTaggedValue =
191
+ (val: TaggedValue): (() => void) =>
192
+ (): void =>
193
+ annotatedElement_deleteTaggedValue(activatorElement, val);
194
+ const changeTab =
195
+ (tab: ACTIVATOR_EDITOR_TAB): (() => void) =>
196
+ (): void =>
197
+ editorState.setSelectedTab(tab);
198
+
73
199
  const activator = editorState.activator;
74
200
  const ownership = activator.ownership;
75
201
  const visitFunction = (): void =>
@@ -269,250 +395,358 @@ export const HostedServiceFunctionActivatorEditor = observer(() => {
269
395
  editorState.deployState.isInProgress,
270
396
  )}
271
397
  />
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"
284
- >
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}
398
+ <div className="panel__header function-editor__tabs__header">
399
+ <div className="function-editor__tabs">
400
+ {Object.values(ACTIVATOR_EDITOR_TAB).map((tab) => (
401
+ <div
402
+ key={tab}
403
+ onClick={changeTab(tab)}
404
+ className={clsx('function-editor__tab', {
405
+ 'function-editor__tab--active': tab === selectedTab,
406
+ })}
293
407
  >
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
408
+ {prettyCONSTName(tab)}
323
409
  </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.
410
+ ))}
411
+ </div>
412
+ {selectedTab !== ACTIVATOR_EDITOR_TAB.DEFINITION && (
413
+ <button
414
+ className="panel__header__action"
415
+ disabled={isReadOnly}
416
+ onClick={add}
417
+ tabIndex={-1}
418
+ title={addButtonTitle}
419
+ >
420
+ <PlusIcon />
421
+ </button>
422
+ )}
423
+ </div>
424
+ <PanelContent>
425
+ {selectedTab === ACTIVATOR_EDITOR_TAB.DEFINITION && (
426
+ <div>
427
+ <div className="hosted-service-function-activator-editor__header">
428
+ <div className="hosted-service-function-activator-editor__header__label">
429
+ Rest Service Activator
430
+ </div>
431
+ <div className="hosted-service-function-activator-editor__header__actions">
432
+ <button
433
+ className="hosted-service-function-activator-editor__header__actions__action hosted-service-function-activator-editor__header__actions__action--primary"
434
+ onClick={validate}
435
+ disabled={editorState.validateState.isInProgress}
436
+ tabIndex={-1}
437
+ title="Click Validate to verify your activator before deployment"
438
+ >
439
+ Validate
440
+ </button>
441
+ <button
442
+ className="hosted-service-function-activator-editor__header__actions__action hosted-service-function-activator-editor__header__actions__action--primary"
443
+ onClick={deploy}
444
+ disabled={editorState.deployState.isInProgress}
445
+ title="Deploy to sandbox"
446
+ tabIndex={-1}
447
+ >
448
+ Deploy to Sandbox
449
+ </button>
450
+ </div>
329
451
  </div>
330
- <div className="service-editor__parameters__list">
331
- {!activator.patternParameters.length && (
332
- <div className="service-editor__parameters__list__empty">
333
- No parameter
452
+ <PanelForm>
453
+ <PanelFormValidatedTextField
454
+ ref={patternRef}
455
+ name="URL Pattern"
456
+ isReadOnly={isReadOnly}
457
+ className="service-editor__pattern__input"
458
+ errorMessageClassName="service-editor__pattern__input"
459
+ prompt={
460
+ <>
461
+ Specifies the URL pattern of the service (e.g. /myService/
462
+ <span className="service-editor__pattern__example__param">{`{param}`}</span>
463
+ )
464
+ </>
465
+ }
466
+ update={(value: string | undefined): void => {
467
+ updatePattern(value ?? '');
468
+ }}
469
+ validate={getValidationMessage}
470
+ value={pattern}
471
+ />
472
+ </PanelForm>
473
+ <PanelForm>
474
+ <div className="panel__content__form__section service-editor__parameters">
475
+ <div className="panel__content__form__section__header__label">
476
+ Parameters
477
+ </div>
478
+ <div className="panel__content__form__section__header__prompt">
479
+ URL parameters (each must be surrounded by curly braces)
480
+ will be passed as arguments for the execution query. Note
481
+ that if the service is configured to use multi-execution,
482
+ one of the URL parameters must be chosen as the execution
483
+ key.
334
484
  </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}
485
+ <div className="service-editor__parameters__list">
486
+ {!activator.patternParameters.length && (
487
+ <div className="service-editor__parameters__list__empty">
488
+ No parameter
341
489
  </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}
490
+ )}
491
+ {Boolean(activator.patternParameters.length) &&
492
+ activator.patternParameters.map((parameter) => (
493
+ <div
494
+ key={parameter}
495
+ className="service-editor__parameter"
349
496
  >
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 />
497
+ <div className="service-editor__parameter__text">
498
+ {parameter}
499
+ </div>
500
+ <div className="service-editor__parameter__actions">
501
+ <button
502
+ className="service-editor__parameter__action"
503
+ disabled={isReadOnly}
504
+ onClick={removePatternParameter(parameter)}
505
+ title="Remove parameter"
506
+ tabIndex={-1}
507
+ >
508
+ <TimesIcon />
509
+ </button>
510
+ </div>
511
+ </div>
512
+ ))}
513
+ </div>
368
514
  </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
- </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>
515
+ </PanelForm>
516
+ <PanelForm>
436
517
  <div className="panel__content__form__section">
437
518
  <div className="panel__content__form__section__header__label">
438
- Ownership
519
+ Function
439
520
  </div>
440
- <div className="panel__content__form__section__header__prompt">
441
- The ownership model you want to use to control your service.
521
+ </div>
522
+ <div className="hosted-service-function-activator-editor__configuration__items">
523
+ <div className="hosted-service-function-activator-editor__configuration__item">
524
+ <div className="btn--sm hosted-service-function-activator-editor__configuration__item__label">
525
+ <PURE_FunctionIcon />
526
+ </div>
527
+ <input
528
+ className="panel__content__form__section__input"
529
+ spellCheck={false}
530
+ disabled={true}
531
+ value={generateFunctionPrettyName(
532
+ activator.function.value,
533
+ {
534
+ fullPath: true,
535
+ spacing: false,
536
+ },
537
+ )}
538
+ />
539
+ <button
540
+ className="btn--dark btn--sm hosted-service-function-activator-editor__configuration__item__btn"
541
+ onClick={visitFunction}
542
+ tabIndex={-1}
543
+ title="See Function"
544
+ >
545
+ <LongArrowRightIcon />
546
+ </button>
442
547
  </div>
443
- <CustomSelectorInput
444
- options={OWNERSHIP_OPTIONS}
445
- onChange={onOwnershipChange}
446
- value={editorState.selectedOwnership}
447
- darkMode={
448
- !applicationStore.layoutService
449
- .TEMPORARY__isLightColorThemeEnabled
450
- }
548
+ </div>
549
+ </PanelForm>
550
+ <PanelForm>
551
+ <div className="panel__content__form__section">
552
+ <div className="panel__content__form__section__header__label">
553
+ Documentation
554
+ </div>
555
+ <div className="panel__content__form__section__header__prompt">{`Provide a brief description of the service's functionalities and usage`}</div>
556
+ <textarea
557
+ className="panel__content__form__section__textarea service-editor__documentation__input"
558
+ spellCheck={false}
559
+ disabled={isReadOnly}
560
+ value={activator.documentation}
561
+ onChange={changeDocumentation}
451
562
  />
452
563
  </div>
453
- {ownership instanceof DeploymentOwner && (
454
- <div className="panel__content__form__section">
455
- <div>
564
+ </PanelForm>
565
+ <PanelForm>
566
+ <PanelFormBooleanField
567
+ isReadOnly={isReadOnly}
568
+ value={activator.autoActivateUpdates}
569
+ name="Auto Activate Updates"
570
+ prompt="Specifies if the new generation should be automatically activated;
571
+ only valid when latest revision is selected upon service
572
+ registration"
573
+ update={toggleAutoActivateUpdates}
574
+ />
575
+ </PanelForm>
576
+ <PanelForm>
577
+ <PanelFormBooleanField
578
+ isReadOnly={isReadOnly}
579
+ value={activator.storeModel}
580
+ name="Store Model"
581
+ prompt="Use Store Model (slower)"
582
+ update={toggleUseStoreModel}
583
+ />
584
+ </PanelForm>
585
+ <PanelForm>
586
+ <PanelFormBooleanField
587
+ isReadOnly={isReadOnly}
588
+ value={activator.generateLineage}
589
+ name="Generate Lineage"
590
+ prompt="Generate Lineage (slower)"
591
+ update={toggleGenerateLineage}
592
+ />
593
+ </PanelForm>
594
+ <PanelForm>
595
+ {
596
+ <div>
597
+ <div className="panel__content__form__section">
456
598
  <div className="panel__content__form__section__header__label">
457
- Deployment Identifier :
599
+ Ownership
600
+ </div>
601
+ <div className="panel__content__form__section__header__prompt">
602
+ The ownership model you want to use to control your
603
+ service.
458
604
  </div>
459
- <input
460
- className="panel__content__form__section__input"
461
- spellCheck={false}
462
- disabled={isReadOnly}
463
- value={ownership.id}
464
- onChange={updateDeploymentIdentifier}
605
+ <CustomSelectorInput
606
+ options={OWNERSHIP_OPTIONS}
607
+ onChange={onOwnershipChange}
608
+ value={editorState.selectedOwnership}
609
+ darkMode={
610
+ !applicationStore.layoutService
611
+ .TEMPORARY__isLightColorThemeEnabled
612
+ }
465
613
  />
466
614
  </div>
467
- </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 :
615
+ {ownership instanceof DeploymentOwner && (
616
+ <div className="panel__content__form__section">
617
+ <div>
618
+ <div className="panel__content__form__section__header__label">
619
+ Deployment Identifier :
620
+ </div>
621
+ <input
622
+ className="panel__content__form__section__input"
623
+ spellCheck={false}
624
+ disabled={isReadOnly}
625
+ value={ownership.id}
626
+ onChange={updateDeploymentIdentifier}
627
+ />
628
+ </div>
474
629
  </div>
475
- <div className="panel__content__form__section__list">
476
- <div
477
- className="panel__content__form__section__list__items"
478
- data-testid={
479
- LEGEND_STUDIO_TEST_ID.PANEL_CONTENT_FORM_SECTION_LIST_ITEMS
480
- }
481
- >
482
- {ownership.users.map((value, idx) => (
630
+ )}
631
+ {ownership instanceof UserList && (
632
+ <div className="panel__content__form__section">
633
+ <div>
634
+ <div className="panel__content__form__section__header__label">
635
+ Users :
636
+ </div>
637
+ <div className="panel__content__form__section__list">
483
638
  <div
484
- key={value}
485
- className={
486
- showOwnerEditInput === idx
487
- ? 'panel__content__form__section__list__new-item'
488
- : 'panel__content__form__section__list__item'
639
+ className="panel__content__form__section__list__items"
640
+ data-testid={
641
+ LEGEND_STUDIO_TEST_ID.PANEL_CONTENT_FORM_SECTION_LIST_ITEMS
489
642
  }
490
643
  >
491
- {showOwnerEditInput === idx ? (
492
- <>
493
- <input
494
- className="panel__content__form__section__input panel__content__form__section__list__new-item__input"
495
- spellCheck={false}
644
+ {ownership.users.map((value, idx) => (
645
+ <div
646
+ key={value}
647
+ className={
648
+ showOwnerEditInput === idx
649
+ ? 'panel__content__form__section__list__new-item'
650
+ : 'panel__content__form__section__list__item'
651
+ }
652
+ >
653
+ {showOwnerEditInput === idx ? (
654
+ <>
655
+ <input
656
+ className="panel__content__form__section__input panel__content__form__section__list__new-item__input"
657
+ spellCheck={false}
658
+ disabled={isReadOnly}
659
+ value={ownerInputValue}
660
+ onChange={changeUserOwnerInputValue}
661
+ />
662
+ <div className="panel__content__form__section__list__new-item__actions">
663
+ <button
664
+ className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
665
+ disabled={
666
+ isReadOnly ||
667
+ ownership.users.includes(
668
+ ownerInputValue,
669
+ )
670
+ }
671
+ onClick={updateUser(idx)}
672
+ tabIndex={-1}
673
+ >
674
+ Save
675
+ </button>
676
+ <button
677
+ className="panel__content__form__section__list__new-item__cancel-btn btn btn--dark"
678
+ disabled={isReadOnly}
679
+ onClick={hideAddOrEditOwnerInput}
680
+ tabIndex={-1}
681
+ >
682
+ Cancel
683
+ </button>
684
+ </div>
685
+ </>
686
+ ) : (
687
+ <>
688
+ <div className="panel__content__form__section__list__item__value">
689
+ {value}
690
+ </div>
691
+ <div className="panel__content__form__section__list__item__actions">
692
+ <button
693
+ className="panel__content__form__section__list__item__edit-btn"
694
+ disabled={isReadOnly}
695
+ onClick={showEditOwnerInput(
696
+ value,
697
+ idx,
698
+ )}
699
+ tabIndex={-1}
700
+ >
701
+ <PencilIcon />
702
+ </button>
703
+ <button
704
+ className="panel__content__form__section__list__item__remove-btn"
705
+ disabled={isReadOnly}
706
+ onClick={deleteUser(idx)}
707
+ tabIndex={-1}
708
+ >
709
+ <TimesIcon />
710
+ </button>
711
+ </div>
712
+ </>
713
+ )}
714
+ </div>
715
+ ))}
716
+ {showOwnerEditInput === true && (
717
+ <div className="panel__content__form__section__list__new-item">
718
+ <CustomSelectorInput
719
+ className="service-editor__owner__selector"
720
+ placeholder="Enter an owner..."
721
+ inputValue={searchText}
722
+ options={userOptions}
723
+ allowCreating={true}
724
+ isLoading={isLoadingUsers}
496
725
  disabled={isReadOnly}
497
- value={ownerInputValue}
498
- onChange={changeUserOwnerInputValue}
726
+ darkMode={
727
+ !applicationStore.layoutService
728
+ .TEMPORARY__isLightColorThemeEnabled
729
+ }
730
+ onInputChange={onSearchTextChange}
731
+ onChange={onUserOptionChange}
732
+ isMulti={true}
499
733
  />
500
734
  <div className="panel__content__form__section__list__new-item__actions">
501
735
  <button
502
- className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
736
+ className="panel__content__form__section__list__new-item__add-btn btn btn--dark service-editor__owner__action"
503
737
  disabled={
504
738
  isReadOnly ||
505
- ownership.users.includes(
506
- ownerInputValue,
739
+ ownerInputs.some((i) =>
740
+ ownership.users.includes(i),
507
741
  )
508
742
  }
509
- onClick={updateUser(idx)}
743
+ onClick={addUser}
510
744
  tabIndex={-1}
511
745
  >
512
746
  Save
513
747
  </button>
514
748
  <button
515
- className="panel__content__form__section__list__new-item__cancel-btn btn btn--dark"
749
+ className="panel__content__form__section__list__new-item__cancel-btn btn btn--dark service-editor__owner__action"
516
750
  disabled={isReadOnly}
517
751
  onClick={hideAddOrEditOwnerInput}
518
752
  tabIndex={-1}
@@ -520,112 +754,87 @@ export const HostedServiceFunctionActivatorEditor = observer(() => {
520
754
  Cancel
521
755
  </button>
522
756
  </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
- </>
757
+ </div>
548
758
  )}
549
759
  </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}
760
+ {ownership.users.length <
761
+ MINIMUM_HOSTED_SERVICE_OWNERS &&
762
+ showOwnerEditInput !== true && (
763
+ <div
764
+ className="service-editor__owner__validation"
765
+ title={`${MINIMUM_HOSTED_SERVICE_OWNERS} owners required`}
580
766
  >
581
- Save
582
- </button>
767
+ <ErrorIcon />
768
+ <div className="service-editor__owner__validation-label">
769
+ Service requires at least{' '}
770
+ {MINIMUM_HOSTED_SERVICE_OWNERS} owners
771
+ </div>
772
+ </div>
773
+ )}
774
+ {showOwnerEditInput !== true && (
775
+ <div className="panel__content__form__section__list__new-item__add">
583
776
  <button
584
- className="panel__content__form__section__list__new-item__cancel-btn btn btn--dark service-editor__owner__action"
777
+ className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
585
778
  disabled={isReadOnly}
586
- onClick={hideAddOrEditOwnerInput}
779
+ onClick={showAddOwnerInput}
587
780
  tabIndex={-1}
781
+ title="Add owner"
588
782
  >
589
- Cancel
783
+ Add Value
590
784
  </button>
591
785
  </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">
611
- <button
612
- className="panel__content__form__section__list__new-item__add-btn btn btn--dark"
613
- disabled={isReadOnly}
614
- onClick={showAddOwnerInput}
615
- tabIndex={-1}
616
- title="Add owner"
617
- >
618
- Add Value
619
- </button>
786
+ )}
620
787
  </div>
621
- )}
788
+ </div>
622
789
  </div>
623
- </div>
790
+ )}
624
791
  </div>
625
- )}
626
- </div>
627
- }
628
- </PanelForm>
792
+ }
793
+ </PanelForm>
794
+ </div>
795
+ )}
796
+ {selectedTab === ACTIVATOR_EDITOR_TAB.TAGGED_VALUES && (
797
+ <div
798
+ ref={dropTaggedValueRef}
799
+ className={clsx('panel__content__lists', {
800
+ 'panel__content__lists--dnd-over':
801
+ isTaggedValueDragOver && !isReadOnly,
802
+ })}
803
+ >
804
+ <TaggedValueDragPreviewLayer />
805
+ {activatorElement.taggedValues.map((taggedValue) => (
806
+ <TaggedValueEditor
807
+ annotatedElement={activatorElement}
808
+ key={taggedValue._UUID}
809
+ taggedValue={taggedValue}
810
+ deleteValue={_deleteTaggedValue(taggedValue)}
811
+ isReadOnly={isReadOnly}
812
+ darkTheme={true}
813
+ />
814
+ ))}
815
+ </div>
816
+ )}
817
+ {selectedTab === ACTIVATOR_EDITOR_TAB.STEREOTYPES && (
818
+ <div
819
+ ref={dropStereotypeRef}
820
+ className={clsx('panel__content__lists', {
821
+ 'panel__content__lists--dnd-over':
822
+ isStereotypeDragOver && !isReadOnly,
823
+ })}
824
+ >
825
+ <StereotypeDragPreviewLayer />
826
+ {activatorElement.stereotypes.map((stereotype) => (
827
+ <StereotypeSelector
828
+ key={stereotype.value._UUID}
829
+ annotatedElement={activatorElement}
830
+ stereotype={stereotype}
831
+ deleteStereotype={_deleteStereotype(stereotype)}
832
+ isReadOnly={isReadOnly}
833
+ darkTheme={true}
834
+ />
835
+ ))}
836
+ </div>
837
+ )}
629
838
  </PanelContent>
630
839
  </Panel>
631
840
  </div>