@finos/legend-application-studio 28.12.1 → 28.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (116) hide show
  1. package/lib/__lib__/LegendStudioTesting.d.ts +1 -0
  2. package/lib/__lib__/LegendStudioTesting.d.ts.map +1 -1
  3. package/lib/__lib__/LegendStudioTesting.js +1 -0
  4. package/lib/__lib__/LegendStudioTesting.js.map +1 -1
  5. package/lib/components/ElementIconUtils.d.ts.map +1 -1
  6. package/lib/components/ElementIconUtils.js +3 -1
  7. package/lib/components/ElementIconUtils.js.map +1 -1
  8. package/lib/components/editor/editor-group/EditorGroup.js +3 -3
  9. package/lib/components/editor/editor-group/EditorGroup.js.map +1 -1
  10. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.d.ts +7 -0
  11. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.d.ts.map +1 -1
  12. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js +8 -1
  13. package/lib/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.js.map +1 -1
  14. package/lib/components/editor/editor-group/function-activator/FunctionEditor.d.ts +26 -0
  15. package/lib/components/editor/editor-group/function-activator/FunctionEditor.d.ts.map +1 -0
  16. package/lib/components/editor/editor-group/{FunctionEditor.js → function-activator/FunctionEditor.js} +100 -18
  17. package/lib/components/editor/editor-group/function-activator/FunctionEditor.js.map +1 -0
  18. package/lib/components/editor/editor-group/function-activator/INTERNAL__UnknownFunctionActivatorEdtior.d.ts.map +1 -0
  19. package/lib/components/editor/editor-group/{INTERNAL__UnknownFunctionActivatorEdtior.js → function-activator/INTERNAL__UnknownFunctionActivatorEdtior.js} +3 -3
  20. package/lib/components/editor/editor-group/function-activator/INTERNAL__UnknownFunctionActivatorEdtior.js.map +1 -0
  21. package/lib/components/editor/editor-group/{FunctionEditor.d.ts → function-activator/SnowflakeAppFunctionActivatorEditor.d.ts} +2 -2
  22. package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.d.ts.map +1 -0
  23. package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.js +84 -0
  24. package/lib/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.js.map +1 -0
  25. package/lib/components/editor/editor-group/service-editor/ServiceEditor.js +1 -1
  26. package/lib/components/editor/editor-group/service-editor/ServiceEditor.js.map +1 -1
  27. package/lib/components/editor/editor-group/service-editor/ServiceExecutionEditor.d.ts.map +1 -1
  28. package/lib/components/editor/editor-group/service-editor/ServiceExecutionEditor.js +5 -6
  29. package/lib/components/editor/editor-group/service-editor/ServiceExecutionEditor.js.map +1 -1
  30. package/lib/components/editor/panel-group/SQLPlaygroundPanel.d.ts.map +1 -1
  31. package/lib/components/editor/panel-group/SQLPlaygroundPanel.js +2 -8
  32. package/lib/components/editor/panel-group/SQLPlaygroundPanel.js.map +1 -1
  33. package/lib/components/editor/side-bar/Explorer.d.ts.map +1 -1
  34. package/lib/components/editor/side-bar/Explorer.js +1 -3
  35. package/lib/components/editor/side-bar/Explorer.js.map +1 -1
  36. package/lib/index.css +2 -2
  37. package/lib/index.css.map +1 -1
  38. package/lib/index.d.ts +2 -0
  39. package/lib/index.d.ts.map +1 -1
  40. package/lib/index.js +2 -0
  41. package/lib/index.js.map +1 -1
  42. package/lib/package.json +1 -1
  43. package/lib/stores/editor/EditorGraphState.d.ts.map +1 -1
  44. package/lib/stores/editor/EditorGraphState.js +4 -1
  45. package/lib/stores/editor/EditorGraphState.js.map +1 -1
  46. package/lib/stores/editor/EditorTabManagerState.d.ts.map +1 -1
  47. package/lib/stores/editor/EditorTabManagerState.js +6 -2
  48. package/lib/stores/editor/EditorTabManagerState.js.map +1 -1
  49. package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorPromoteState.d.ts +35 -0
  50. package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorPromoteState.d.ts.map +1 -0
  51. package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorPromoteState.js +97 -0
  52. package/lib/stores/editor/editor-state/element-editor-state/FunctionActivatorPromoteState.js.map +1 -0
  53. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.d.ts +2 -0
  54. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.d.ts.map +1 -1
  55. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.js +4 -1
  56. package/lib/stores/editor/editor-state/element-editor-state/FunctionEditorState.js.map +1 -1
  57. package/lib/stores/editor/editor-state/element-editor-state/{INTERNAL__UnknownFunctionActivatorEditorState.d.ts → function-activator/INTERNAL__UnknownFunctionActivatorEditorState.d.ts} +3 -3
  58. package/lib/stores/editor/editor-state/element-editor-state/function-activator/INTERNAL__UnknownFunctionActivatorEditorState.d.ts.map +1 -0
  59. package/lib/stores/editor/editor-state/element-editor-state/{INTERNAL__UnknownFunctionActivatorEditorState.js → function-activator/INTERNAL__UnknownFunctionActivatorEditorState.js} +4 -4
  60. package/lib/stores/editor/editor-state/element-editor-state/function-activator/INTERNAL__UnknownFunctionActivatorEditorState.js.map +1 -0
  61. package/lib/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.d.ts +33 -0
  62. package/lib/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.d.ts.map +1 -0
  63. package/lib/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.js +84 -0
  64. package/lib/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.js.map +1 -0
  65. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceEditorState.d.ts.map +1 -1
  66. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceEditorState.js +2 -1
  67. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceEditorState.js.map +1 -1
  68. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.d.ts +1 -0
  69. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.d.ts.map +1 -1
  70. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.js +6 -3
  71. package/lib/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.js.map +1 -1
  72. package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestDataState.js +1 -1
  73. package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestDataState.js.map +1 -1
  74. package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestEditorState.js +1 -1
  75. package/lib/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestEditorState.js.map +1 -1
  76. package/lib/stores/editor/utils/ModelClassifierUtils.d.ts +1 -0
  77. package/lib/stores/editor/utils/ModelClassifierUtils.d.ts.map +1 -1
  78. package/lib/stores/editor/utils/ModelClassifierUtils.js +1 -0
  79. package/lib/stores/editor/utils/ModelClassifierUtils.js.map +1 -1
  80. package/lib/stores/graph-modifier/DSL_Service_GraphModifierHelper.d.ts +2 -2
  81. package/lib/stores/graph-modifier/DSL_Service_GraphModifierHelper.d.ts.map +1 -1
  82. package/lib/stores/graph-modifier/DSL_Service_GraphModifierHelper.js +4 -4
  83. package/lib/stores/graph-modifier/DSL_Service_GraphModifierHelper.js.map +1 -1
  84. package/package.json +6 -6
  85. package/src/__lib__/LegendStudioTesting.ts +2 -0
  86. package/src/components/ElementIconUtils.tsx +3 -0
  87. package/src/components/editor/editor-group/EditorGroup.tsx +3 -3
  88. package/src/components/editor/editor-group/connection-editor/RelationalDatabaseConnectionEditor.tsx +29 -0
  89. package/src/components/editor/editor-group/{FunctionEditor.tsx → function-activator/FunctionEditor.tsx} +249 -16
  90. package/src/components/editor/editor-group/{INTERNAL__UnknownFunctionActivatorEdtior.tsx → function-activator/INTERNAL__UnknownFunctionActivatorEdtior.tsx} +3 -3
  91. package/src/components/editor/editor-group/function-activator/SnowflakeAppFunctionActivatorEditor.tsx +260 -0
  92. package/src/components/editor/editor-group/service-editor/ServiceEditor.tsx +1 -1
  93. package/src/components/editor/editor-group/service-editor/ServiceExecutionEditor.tsx +17 -14
  94. package/src/components/editor/panel-group/SQLPlaygroundPanel.tsx +4 -27
  95. package/src/components/editor/side-bar/Explorer.tsx +3 -9
  96. package/src/index.ts +3 -0
  97. package/src/stores/editor/EditorGraphState.ts +9 -6
  98. package/src/stores/editor/EditorTabManagerState.ts +9 -2
  99. package/src/stores/editor/editor-state/element-editor-state/FunctionActivatorPromoteState.ts +127 -0
  100. package/src/stores/editor/editor-state/element-editor-state/FunctionEditorState.ts +4 -1
  101. package/src/stores/editor/editor-state/element-editor-state/{INTERNAL__UnknownFunctionActivatorEditorState.ts → function-activator/INTERNAL__UnknownFunctionActivatorEditorState.ts} +5 -5
  102. package/src/stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.ts +127 -0
  103. package/src/stores/editor/editor-state/element-editor-state/service/ServiceEditorState.ts +4 -1
  104. package/src/stores/editor/editor-state/element-editor-state/service/ServiceExecutionState.ts +10 -4
  105. package/src/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestDataState.ts +1 -1
  106. package/src/stores/editor/editor-state/element-editor-state/service/testable/ServiceTestEditorState.ts +1 -1
  107. package/src/stores/editor/utils/ModelClassifierUtils.ts +1 -0
  108. package/src/stores/graph-modifier/DSL_Service_GraphModifierHelper.ts +7 -4
  109. package/tsconfig.json +6 -3
  110. package/lib/components/editor/editor-group/FunctionEditor.d.ts.map +0 -1
  111. package/lib/components/editor/editor-group/FunctionEditor.js.map +0 -1
  112. package/lib/components/editor/editor-group/INTERNAL__UnknownFunctionActivatorEdtior.d.ts.map +0 -1
  113. package/lib/components/editor/editor-group/INTERNAL__UnknownFunctionActivatorEdtior.js.map +0 -1
  114. package/lib/stores/editor/editor-state/element-editor-state/INTERNAL__UnknownFunctionActivatorEditorState.d.ts.map +0 -1
  115. package/lib/stores/editor/editor-state/element-editor-state/INTERNAL__UnknownFunctionActivatorEditorState.js.map +0 -1
  116. /package/lib/components/editor/editor-group/{INTERNAL__UnknownFunctionActivatorEdtior.d.ts → function-activator/INTERNAL__UnknownFunctionActivatorEdtior.d.ts} +0 -0
@@ -19,12 +19,12 @@ import { observer } from 'mobx-react-lite';
19
19
  import {
20
20
  FunctionEditorState,
21
21
  FUNCTION_EDITOR_TAB,
22
- } from '../../../stores/editor/editor-state/element-editor-state/FunctionEditorState.js';
22
+ } from '../../../../stores/editor/editor-state/element-editor-state/FunctionEditorState.js';
23
23
  import {
24
24
  CORE_DND_TYPE,
25
25
  type UMLEditorElementDropTarget,
26
26
  type ElementDragSource,
27
- } from '../../../stores/editor/utils/DnDUtils.js';
27
+ } from '../../../../stores/editor/utils/DnDUtils.js';
28
28
  import {
29
29
  assertErrorThrown,
30
30
  assertTrue,
@@ -63,18 +63,23 @@ import {
63
63
  PlayIcon,
64
64
  PanelLoadingIndicator,
65
65
  PencilIcon,
66
+ RocketIcon,
67
+ ModalFooterButton,
68
+ BaseCard,
69
+ Snowflake_BrandIcon,
70
+ InputWithInlineValidation,
66
71
  } from '@finos/legend-art';
67
- import { LEGEND_STUDIO_TEST_ID } from '../../../__lib__/LegendStudioTesting.js';
72
+ import { LEGEND_STUDIO_TEST_ID } from '../../../../__lib__/LegendStudioTesting.js';
68
73
  import {
69
74
  StereotypeDragPreviewLayer,
70
75
  StereotypeSelector,
71
- } from './uml-editor/StereotypeSelector.js';
76
+ } from '../uml-editor/StereotypeSelector.js';
72
77
  import {
73
78
  TaggedValueDragPreviewLayer,
74
79
  TaggedValueEditor,
75
- } from './uml-editor/TaggedValueEditor.js';
80
+ } from '../uml-editor/TaggedValueEditor.js';
76
81
  import { flowResult } from 'mobx';
77
- import { useEditorStore } from '../EditorStoreProvider.js';
82
+ import { useEditorStore } from '../../EditorStoreProvider.js';
78
83
  import {
79
84
  type ConcreteFunctionDefinition,
80
85
  type StereotypeReference,
@@ -101,6 +106,8 @@ import {
101
106
  RawExecutionResult,
102
107
  extractExecutionResultValues,
103
108
  RawLambda,
109
+ DatabaseType,
110
+ RelationalDatabaseConnection,
104
111
  } from '@finos/legend-graph';
105
112
  import {
106
113
  type ApplicationStore,
@@ -115,7 +122,7 @@ import {
115
122
  type PackageableElementOption,
116
123
  buildElementOption,
117
124
  } from '@finos/legend-lego/graph-editor';
118
- import { getElementIcon } from '../../ElementIconUtils.js';
125
+ import { getElementIcon } from '../../../ElementIconUtils.js';
119
126
  import {
120
127
  function_setReturnType,
121
128
  function_setReturnMultiplicity,
@@ -126,13 +133,13 @@ import {
126
133
  annotatedElement_deleteStereotype,
127
134
  annotatedElement_deleteTaggedValue,
128
135
  function_swapParameters,
129
- } from '../../../stores/graph-modifier/DomainGraphModifierHelper.js';
136
+ } from '../../../../stores/graph-modifier/DomainGraphModifierHelper.js';
130
137
  import {
131
138
  rawVariableExpression_setMultiplicity,
132
139
  rawVariableExpression_setName,
133
140
  rawVariableExpression_setType,
134
- } from '../../../stores/graph-modifier/RawValueSpecificationGraphModifierHelper.js';
135
- import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../__lib__/LegendStudioApplicationNavigationContext.js';
141
+ } from '../../../../stores/graph-modifier/RawValueSpecificationGraphModifierHelper.js';
142
+ import { LEGEND_STUDIO_APPLICATION_NAVIGATION_CONTEXT_KEY } from '../../../../__lib__/LegendStudioApplicationNavigationContext.js';
136
143
  import {
137
144
  type QueryBuilderState,
138
145
  ExecutionPlanViewer,
@@ -140,15 +147,16 @@ import {
140
147
  LambdaEditor,
141
148
  LambdaParameterValuesEditor,
142
149
  } from '@finos/legend-query-builder';
143
- import type { EditorStore } from '../../../stores/editor/EditorStore.js';
144
- import { graph_renameElement } from '../../../stores/graph-modifier/GraphModifierHelper.js';
145
- import { ProtocolValueBuilder } from './ProtocolValueBuilder.js';
146
- import type { ProtocolValueBuilderState } from '../../../stores/editor/editor-state/element-editor-state/ProtocolValueBuilderState.js';
150
+ import type { EditorStore } from '../../../../stores/editor/EditorStore.js';
151
+ import { graph_renameElement } from '../../../../stores/graph-modifier/GraphModifierHelper.js';
152
+ import { ProtocolValueBuilder } from '../ProtocolValueBuilder.js';
153
+ import type { ProtocolValueBuilderState } from '../../../../stores/editor/editor-state/element-editor-state/ProtocolValueBuilderState.js';
147
154
  import {
148
155
  CODE_EDITOR_LANGUAGE,
149
156
  CodeEditor,
150
157
  } from '@finos/legend-lego/code-editor';
151
- import { PanelGroupItemExperimentalBadge } from '../panel-group/PanelGroup.js';
158
+ import { PanelGroupItemExperimentalBadge } from '../../panel-group/PanelGroup.js';
159
+ import type { FunctionActivatorPromoteState } from '../../../../stores/editor/editor-state/element-editor-state/FunctionActivatorPromoteState.js';
152
160
 
153
161
  enum FUNCTION_PARAMETER_TYPE {
154
162
  CLASS = 'CLASS',
@@ -156,6 +164,14 @@ enum FUNCTION_PARAMETER_TYPE {
156
164
  PRIMITIVE = 'PRIMITIVE',
157
165
  }
158
166
 
167
+ export enum FUNCTION_PROMOTE_TYPE {
168
+ SNOWFLAKE_NATIVE_APP = 'Snowflake Native App',
169
+ REST_SERVICE = 'REST Service',
170
+ SERVICE_JAR = 'Service JAR',
171
+ REFINER = 'Refiner',
172
+ BIG_QUERY_NATIVE_APP = 'BigQuery Native App',
173
+ }
174
+
159
175
  const getFunctionParameterType = (type: Type): FUNCTION_PARAMETER_TYPE => {
160
176
  if (type instanceof PrimitiveType) {
161
177
  return FUNCTION_PARAMETER_TYPE.PRIMITIVE;
@@ -661,6 +677,199 @@ const ReturnTypeEditor = observer(
661
677
  },
662
678
  );
663
679
 
680
+ const FunctionPromoteEditor = observer(
681
+ (props: {
682
+ functionElement: ConcreteFunctionDefinition;
683
+ activatorPromoteState: FunctionActivatorPromoteState;
684
+ }) => {
685
+ const { functionElement, activatorPromoteState } = props;
686
+ const applicationStore = useApplicationStore();
687
+ const elementAlreadyExistsMessage =
688
+ activatorPromoteState.functionEditorState.editorStore.graphManagerState.graph.allElements
689
+ .map((s) => s.path)
690
+ .includes(activatorPromoteState.activatorPath)
691
+ ? 'Element with same path already exists'
692
+ : undefined;
693
+ let validationMessage = '';
694
+ const closeModal = (): void => {
695
+ activatorPromoteState.closeFunctionPromoteModal();
696
+ activatorPromoteState.setPromoteType(undefined);
697
+ };
698
+ const promoteFunction = (): void => {
699
+ flowResult(activatorPromoteState.promote(functionElement))
700
+ .then(() => {
701
+ activatorPromoteState.closeFunctionPromoteModal();
702
+ })
703
+ .catch(applicationStore.alertUnhandledError);
704
+ };
705
+ const onTargetPathChange: React.ChangeEventHandler<HTMLInputElement> = (
706
+ event,
707
+ ) => {
708
+ activatorPromoteState.updateActivatorPath(event.target.value);
709
+ };
710
+ const validateFunctionActivator = (type: string): boolean => {
711
+ switch (type) {
712
+ case FUNCTION_PROMOTE_TYPE.SNOWFLAKE_NATIVE_APP: {
713
+ const availableConnections =
714
+ activatorPromoteState.functionEditorState.editorStore.graphManagerState.usableConnections.filter(
715
+ (connection) =>
716
+ connection.connectionValue instanceof
717
+ RelationalDatabaseConnection &&
718
+ connection.connectionValue.type === DatabaseType.Snowflake,
719
+ );
720
+ if (availableConnections.length > 0) {
721
+ return true;
722
+ } else {
723
+ validationMessage =
724
+ 'There is no available connection of type Snowflake';
725
+ }
726
+ return false;
727
+ }
728
+ default:
729
+ return true;
730
+ }
731
+ };
732
+ const renderFunctionPromoteTypes = (type: string): React.ReactNode => {
733
+ switch (type) {
734
+ case FUNCTION_PROMOTE_TYPE.SNOWFLAKE_NATIVE_APP:
735
+ return (
736
+ <BaseCard
737
+ key={FUNCTION_PROMOTE_TYPE.SNOWFLAKE_NATIVE_APP}
738
+ cardMedia={
739
+ <Snowflake_BrandIcon className="function-promote-editor__type-icon" />
740
+ }
741
+ cardName={type}
742
+ cardContent="Deploy the function as a UDTF(user-defined table function) in snowflake"
743
+ isActive={
744
+ activatorPromoteState.promoteType ===
745
+ FUNCTION_PROMOTE_TYPE.SNOWFLAKE_NATIVE_APP
746
+ }
747
+ onClick={() => {
748
+ activatorPromoteState.setPromoteType(type);
749
+ }}
750
+ />
751
+ );
752
+ case FUNCTION_PROMOTE_TYPE.REST_SERVICE:
753
+ return (
754
+ <BaseCard
755
+ key={FUNCTION_PROMOTE_TYPE.REST_SERVICE}
756
+ cardMedia={<div className="coming-soon-label">Coming Soon</div>}
757
+ cardName={type}
758
+ cardContent="Create a HostedService that will be deployed to a server environment and executed with a pattern"
759
+ isDisable={true}
760
+ isActive={
761
+ activatorPromoteState.promoteType ===
762
+ FUNCTION_PROMOTE_TYPE.REST_SERVICE
763
+ }
764
+ />
765
+ );
766
+ case FUNCTION_PROMOTE_TYPE.SERVICE_JAR:
767
+ return (
768
+ <BaseCard
769
+ key={FUNCTION_PROMOTE_TYPE.SERVICE_JAR}
770
+ cardMedia={<div className="coming-soon-label">Coming Soon</div>}
771
+ cardName={type}
772
+ cardContent="Deploy the function in the definition of a Store persistence"
773
+ isDisable={true}
774
+ isActive={
775
+ activatorPromoteState.promoteType ===
776
+ FUNCTION_PROMOTE_TYPE.SERVICE_JAR
777
+ }
778
+ />
779
+ );
780
+ case FUNCTION_PROMOTE_TYPE.REFINER:
781
+ return (
782
+ <BaseCard
783
+ key={FUNCTION_PROMOTE_TYPE.REFINER}
784
+ cardMedia={<div className="coming-soon-label">Coming Soon</div>}
785
+ cardName={type}
786
+ cardContent="Use the service in a refiner context"
787
+ isDisable={true}
788
+ isActive={
789
+ activatorPromoteState.promoteType ===
790
+ FUNCTION_PROMOTE_TYPE.REFINER
791
+ }
792
+ />
793
+ );
794
+ case FUNCTION_PROMOTE_TYPE.BIG_QUERY_NATIVE_APP:
795
+ return (
796
+ <BaseCard
797
+ key={FUNCTION_PROMOTE_TYPE.BIG_QUERY_NATIVE_APP}
798
+ cardMedia={<div className="coming-soon-label">Coming Soon</div>}
799
+ cardName={type}
800
+ cardContent="Deploy the function as a UDTF(user-defined table function) in BigQuery"
801
+ isDisable={true}
802
+ isActive={
803
+ activatorPromoteState.promoteType ===
804
+ FUNCTION_PROMOTE_TYPE.BIG_QUERY_NATIVE_APP
805
+ }
806
+ />
807
+ );
808
+ default:
809
+ return <></>;
810
+ }
811
+ };
812
+
813
+ return (
814
+ <Dialog
815
+ open={activatorPromoteState.isPromotingFunction}
816
+ onClose={closeModal}
817
+ classes={{ container: 'search-modal__container' }}
818
+ PaperProps={{ classes: { root: 'search-modal__inner-container' } }}
819
+ >
820
+ <Modal darkMode={true} className="function-promote-editor">
821
+ <ModalBody className="function-promote-editor__content">
822
+ <div className="function-promote-editor__content__prompt">
823
+ Select any one of the following activator type to continue
824
+ </div>
825
+ <div className="function-promote-editor__content__activator-types">
826
+ {Object.values(FUNCTION_PROMOTE_TYPE).map((type) =>
827
+ renderFunctionPromoteTypes(type),
828
+ )}
829
+ </div>
830
+ <div className="function-promote-editor__content__prompt">
831
+ Target Path
832
+ </div>
833
+ <InputWithInlineValidation
834
+ className="panel__content__form__section__input"
835
+ spellCheck={false}
836
+ onChange={onTargetPathChange}
837
+ value={activatorPromoteState.activatorPath}
838
+ error={elementAlreadyExistsMessage}
839
+ showEditableIcon={true}
840
+ />
841
+ </ModalBody>
842
+ <ModalFooter>
843
+ <ModalFooterButton
844
+ className="function-promote-editor__action-btn"
845
+ onClick={closeModal}
846
+ title="Close"
847
+ >
848
+ Cancel
849
+ </ModalFooterButton>
850
+ <ModalFooterButton
851
+ className=" function-promote-editor__action-btn function-promote-editor__action-btn--primitive"
852
+ disabled={
853
+ !activatorPromoteState.promoteType ||
854
+ !validateFunctionActivator(activatorPromoteState.promoteType)
855
+ }
856
+ title={
857
+ activatorPromoteState.promoteType &&
858
+ validateFunctionActivator(activatorPromoteState.promoteType)
859
+ ? ''
860
+ : validationMessage
861
+ }
862
+ onClick={promoteFunction}
863
+ >
864
+ Promote
865
+ </ModalFooterButton>
866
+ </ModalFooter>
867
+ </Modal>
868
+ </Dialog>
869
+ );
870
+ },
871
+ );
872
+
664
873
  const FunctionDefinitionEditor = observer(
665
874
  (props: {
666
875
  functionEditorState: FunctionEditorState;
@@ -1159,8 +1368,15 @@ export const FunctionEditor = observer(() => {
1159
1368
  }
1160
1369
  });
1161
1370
 
1371
+ const openFunctionPromoteModal = (): void => {
1372
+ functionEditorState.activatorPromoteState.showFunctionPromoteModal();
1373
+ };
1374
+
1162
1375
  return (
1163
- <div className="function-editor uml-editor uml-editor--dark">
1376
+ <div
1377
+ data-testid={LEGEND_STUDIO_TEST_ID.FUNCTION_EDITOR}
1378
+ className="function-editor uml-editor uml-editor--dark"
1379
+ >
1164
1380
  <Panel>
1165
1381
  <div className="panel__header">
1166
1382
  <div className="panel__header__title">
@@ -1262,6 +1478,17 @@ export const FunctionEditor = observer(() => {
1262
1478
  </>
1263
1479
  )}
1264
1480
  </div>
1481
+ <div className="btn__dropdown-combo btn__dropdown-combo--primary">
1482
+ <button
1483
+ className="btn__dropdown-combo__label"
1484
+ onClick={openFunctionPromoteModal}
1485
+ title="Promote function"
1486
+ tabIndex={-1}
1487
+ >
1488
+ <RocketIcon className="btn__dropdown-combo__label__icon" />
1489
+ <div className="btn__dropdown-combo__label__title">Promote</div>
1490
+ </button>
1491
+ </div>
1265
1492
  {editorStore.applicationStore.config.options
1266
1493
  .TEMPORARY__enableFunctionActivatorSupport && (
1267
1494
  <>
@@ -1472,6 +1699,12 @@ export const FunctionEditor = observer(() => {
1472
1699
  />
1473
1700
  )}
1474
1701
  </PanelContent>
1702
+ {functionEditorState.activatorPromoteState.isPromotingFunction && (
1703
+ <FunctionPromoteEditor
1704
+ functionElement={functionElement}
1705
+ activatorPromoteState={functionEditorState.activatorPromoteState}
1706
+ />
1707
+ )}
1475
1708
  </Panel>
1476
1709
  </div>
1477
1710
  );
@@ -15,8 +15,8 @@
15
15
  */
16
16
 
17
17
  import { observer } from 'mobx-react-lite';
18
- import { useEditorStore } from '../EditorStoreProvider.js';
19
- import { INTERNAL__UnknownFunctionActivatorEdtiorState } from '../../../stores/editor/editor-state/element-editor-state/INTERNAL__UnknownFunctionActivatorEditorState.js';
18
+ import { useEditorStore } from '../../EditorStoreProvider.js';
19
+ import { INTERNAL__UnknownFunctionActivatorEdtiorState } from '../../../../stores/editor/editor-state/element-editor-state/function-activator/INTERNAL__UnknownFunctionActivatorEditorState.js';
20
20
  import {
21
21
  ArrowRightIcon,
22
22
  BlankPanelContent,
@@ -26,7 +26,7 @@ import {
26
26
  } from '@finos/legend-art';
27
27
  import { useApplicationStore } from '@finos/legend-application';
28
28
  import { flowResult } from 'mobx';
29
- import { ProtocolValueBuilder } from './ProtocolValueBuilder.js';
29
+ import { ProtocolValueBuilder } from '../ProtocolValueBuilder.js';
30
30
  import {
31
31
  extractAnnotatedElementDocumentation,
32
32
  generateFunctionPrettyName,
@@ -0,0 +1,260 @@
1
+ /**
2
+ * Copyright (c) 2020-present, Goldman Sachs
3
+ *
4
+ * Licensed under the Apache License, Version 2.0 (the "License");
5
+ * you may not use this file except in compliance with the License.
6
+ * You may obtain a copy of the License at
7
+ *
8
+ * http://www.apache.org/licenses/LICENSE-2.0
9
+ *
10
+ * Unless required by applicable law or agreed to in writing, software
11
+ * distributed under the License is distributed on an "AS IS" BASIS,
12
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ * See the License for the specific language governing permissions and
14
+ * limitations under the License.
15
+ */
16
+
17
+ import {
18
+ Panel,
19
+ PanelHeader,
20
+ PanelContent,
21
+ PanelForm,
22
+ PanelFormTextField,
23
+ PURE_FunctionIcon,
24
+ LongArrowRightIcon,
25
+ PanelLoadingIndicator,
26
+ PURE_ConnectionIcon,
27
+ CustomSelectorInput,
28
+ createFilter,
29
+ type SelectComponent,
30
+ QuestionCircleIcon,
31
+ } from '@finos/legend-art';
32
+ import {
33
+ type PackageableConnection,
34
+ generateFunctionPrettyName,
35
+ RelationalDatabaseConnection,
36
+ DatabaseType,
37
+ } from '@finos/legend-graph';
38
+ import { observer } from 'mobx-react-lite';
39
+ import { useApplicationStore } from '@finos/legend-application';
40
+ import { useEditorStore } from '../../EditorStoreProvider.js';
41
+ import { SnowflakeAppFunctionActivatorEdtiorState } from '../../../../stores/editor/editor-state/element-editor-state/function-activator/SnowflakeAppFunctionActivatorEditorState.js';
42
+ import { flowResult } from 'mobx';
43
+ import { useRef } from 'react';
44
+ import {
45
+ buildRelationalDatabaseConnectionOption,
46
+ type RelationalDatabaseConnectionOption,
47
+ } from '../connection-editor/RelationalDatabaseConnectionEditor.js';
48
+
49
+ export const SnowflakeAppFunctionActivatorEditor = observer(() => {
50
+ const editorStore = useEditorStore();
51
+ const applicationStore = useApplicationStore();
52
+ const editorState = editorStore.tabManagerState.getCurrentEditorState(
53
+ SnowflakeAppFunctionActivatorEdtiorState,
54
+ );
55
+ const activator = editorState.activator;
56
+ const connectionSelectorRef = useRef<SelectComponent>(null);
57
+ const connectionFilterOption = createFilter({
58
+ ignoreCase: true,
59
+ ignoreAccents: false,
60
+ stringify: (option: RelationalDatabaseConnectionOption): string =>
61
+ option.value.path,
62
+ });
63
+ const connectionOptions = editorStore.graphManagerState.usableConnections
64
+ .filter(
65
+ (connection) =>
66
+ connection.connectionValue instanceof RelationalDatabaseConnection &&
67
+ connection.connectionValue.type === DatabaseType.Snowflake,
68
+ )
69
+ .map(buildRelationalDatabaseConnectionOption);
70
+
71
+ const initializeActivationConnection = (
72
+ val: PackageableConnection | undefined,
73
+ ): PackageableConnection | undefined => {
74
+ if (val) {
75
+ editorState.updateConnection(val);
76
+ }
77
+ return !val
78
+ ? undefined
79
+ : activator.activationConfiguration.activationConnection
80
+ ?.packageableConnection.value;
81
+ };
82
+
83
+ const activationConnection = activator.activationConfiguration
84
+ .activationConnection
85
+ ? activator.activationConfiguration.activationConnection
86
+ .packageableConnection.value
87
+ : initializeActivationConnection(connectionOptions.at(0)?.value);
88
+
89
+ const changeConnection = (val: RelationalDatabaseConnectionOption): void => {
90
+ if (val.value === activationConnection) {
91
+ return;
92
+ }
93
+ editorState.updateConnection(val.value);
94
+ };
95
+ const changeDescription: React.ChangeEventHandler<HTMLTextAreaElement> = (
96
+ event,
97
+ ) => {
98
+ editorState.updateAppDescription(event.target.value);
99
+ };
100
+ const visitFunction = (): void =>
101
+ editorState.editorStore.graphEditorMode.openElement(
102
+ activator.function.value,
103
+ );
104
+ const visitConnection = (): void => {
105
+ if (activationConnection) {
106
+ editorState.editorStore.graphEditorMode.openElement(activationConnection);
107
+ }
108
+ };
109
+ const validate = (): void => {
110
+ flowResult(editorState.validate()).catch(
111
+ applicationStore.alertUnhandledError,
112
+ );
113
+ };
114
+ const deploy = (): void => {
115
+ flowResult(editorState.deploy()).catch(
116
+ applicationStore.alertUnhandledError,
117
+ );
118
+ };
119
+
120
+ return (
121
+ <div className="snowflake-app-function-activator-editor">
122
+ <Panel>
123
+ <PanelHeader title="Snowflake Application" />
124
+ <PanelLoadingIndicator
125
+ isLoading={Boolean(
126
+ editorState.validateState.isInProgress ||
127
+ editorState.deployState.isInProgress,
128
+ )}
129
+ />
130
+ <PanelContent>
131
+ <div className="snowflake-app-function-activator-editor__header">
132
+ <div className="snowflake-app-function-activator-editor__header__label">
133
+ Snowflake Activator Metadata
134
+ </div>
135
+ <div className="snowflake-app-function-activator-editor__header__actions">
136
+ <button
137
+ className="snowflake-app-function-activator-editor__header__actions__action"
138
+ onClick={validate}
139
+ disabled={editorState.validateState.isInProgress}
140
+ tabIndex={-1}
141
+ title="Click Validate to verify your activator before deployment"
142
+ >
143
+ Validate
144
+ <QuestionCircleIcon
145
+ title="Click Validate to verify your activator before deployment"
146
+ className={
147
+ 'snowflake-app-function-activator-editor__header__actions__action__icon'
148
+ }
149
+ />
150
+ </button>
151
+ <button
152
+ className="snowflake-app-function-activator-editor__header__actions__action snowflake-app-function-activator-editor__header__actions__action--primary"
153
+ onClick={deploy}
154
+ disabled={editorState.deployState.isInProgress}
155
+ title="Publish to sandbox"
156
+ tabIndex={-1}
157
+ >
158
+ Deploy
159
+ </button>
160
+ </div>
161
+ </div>
162
+ <PanelForm>
163
+ <div className="panel__content__form__section">
164
+ <div className="panel__content__form__section__header__label">
165
+ Function
166
+ </div>
167
+ </div>
168
+ <div className="snowflake-app-function-activator-editor__configuration__items">
169
+ <div className="snowflake-app-function-activator-editor__configuration__item">
170
+ <div className="btn--sm snowflake-app-function-activator-editor__configuration__item__label">
171
+ <PURE_FunctionIcon />
172
+ </div>
173
+ <input
174
+ className="panel__content__form__section__input"
175
+ spellCheck={false}
176
+ disabled={true}
177
+ value={generateFunctionPrettyName(activator.function.value, {
178
+ fullPath: true,
179
+ spacing: false,
180
+ })}
181
+ />
182
+ <button
183
+ className="btn--dark btn--sm snowflake-app-function-activator-editor__configuration__item__btn"
184
+ onClick={visitFunction}
185
+ tabIndex={-1}
186
+ title="See Function"
187
+ >
188
+ <LongArrowRightIcon />
189
+ </button>
190
+ </div>
191
+ </div>
192
+ </PanelForm>
193
+ <PanelForm>
194
+ <div className="panel__content__form__section">
195
+ <div className="panel__content__form__section__header__label">
196
+ Connection
197
+ </div>
198
+ </div>
199
+ <div className="snowflake-app-function-activator-editor__configuration__items">
200
+ <div className="snowflake-app-function-activator-editor__configuration__item">
201
+ <div className="btn--sm snowflake-app-function-activator-editor__configuration__item__label">
202
+ <PURE_ConnectionIcon />
203
+ </div>
204
+ <CustomSelectorInput
205
+ ref={connectionSelectorRef}
206
+ className="snowflake-app-function-activator-editor__config__connection-selector__input"
207
+ options={connectionOptions}
208
+ onChange={changeConnection}
209
+ value={
210
+ activationConnection
211
+ ? buildRelationalDatabaseConnectionOption(
212
+ activationConnection,
213
+ )
214
+ : undefined
215
+ }
216
+ darkMode={true}
217
+ placeholder="Choose a connection"
218
+ filterOption={connectionFilterOption}
219
+ />
220
+ <button
221
+ className="btn--dark btn--sm snowflake-app-function-activator-editor__configuration__item__btn"
222
+ onClick={visitConnection}
223
+ disabled={!activationConnection}
224
+ tabIndex={-1}
225
+ title="See Connection"
226
+ >
227
+ <LongArrowRightIcon />
228
+ </button>
229
+ </div>
230
+ </div>
231
+ </PanelForm>
232
+ <PanelForm>
233
+ <PanelFormTextField
234
+ value={activator.applicationName}
235
+ name="Activator Identifer"
236
+ placeholder="Specify the name of the UDTF for this activator..."
237
+ update={(value: string | undefined): void =>
238
+ editorState.updateApplicationName(value ?? '')
239
+ }
240
+ />
241
+ </PanelForm>
242
+ <PanelForm>
243
+ <div className="panel__content__form__section">
244
+ <div className="panel__content__form__section__header__label">
245
+ Description
246
+ </div>
247
+ <div className="panel__content__form__section__header__prompt">{`Provide a brief description of Snowflake App`}</div>
248
+ <textarea
249
+ className="panel__content__form__section__textarea service-editor__documentation__input"
250
+ spellCheck={false}
251
+ value={activator.description}
252
+ onChange={changeDescription}
253
+ />
254
+ </div>
255
+ </PanelForm>
256
+ </PanelContent>
257
+ </Panel>
258
+ </div>
259
+ );
260
+ });
@@ -337,7 +337,7 @@ const ServiceGeneralEditor = observer(() => {
337
337
  <div className="panel__content__form__section__header__label">
338
338
  Documentation
339
339
  </div>
340
- <div className="panel__content__form__section__header__prompt">{`Provides a brief description of the service's functionalities and usage`}</div>
340
+ <div className="panel__content__form__section__header__prompt">{`Provide a brief description of the service's functionalities and usage`}</div>
341
341
  <textarea
342
342
  className="panel__content__form__section__textarea service-editor__documentation__input"
343
343
  spellCheck={false}