@elyx-code/editor-ui 0.0.2

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 (452) hide show
  1. package/README.md +2 -0
  2. package/package.json +109 -0
  3. package/src/App.tsx +31 -0
  4. package/src/Router.tsx +115 -0
  5. package/src/__mocks__/defaultModuleMock.ts +1 -0
  6. package/src/__mocks__/fileMock.ts +1 -0
  7. package/src/__mocks__/styleMock.ts +1 -0
  8. package/src/assets/Clock-11.1s-18px.svg +16 -0
  9. package/src/assets/Clock-11.1s-28px.svg +16 -0
  10. package/src/assets/authentication.svg +1 -0
  11. package/src/assets/canvas-backdrop-0.png +0 -0
  12. package/src/assets/canvas-backdrop-1.png +0 -0
  13. package/src/assets/canvas-backdrop-2.png +0 -0
  14. package/src/assets/canvas-backdrop-3.png +0 -0
  15. package/src/assets/canvas-backdrop-4.png +0 -0
  16. package/src/assets/canvas-backdrop-5.png +0 -0
  17. package/src/assets/canvas-backdrop.png +0 -0
  18. package/src/assets/checkmark-animation.gif +0 -0
  19. package/src/assets/checkmark-animation.mp4 +0 -0
  20. package/src/assets/code-formatting/format-black.svg +6 -0
  21. package/src/assets/code-formatting/format-dark-grey.svg +6 -0
  22. package/src/assets/code-formatting/format-light-grey.svg +6 -0
  23. package/src/assets/code-formatting/format-white.svg +6 -0
  24. package/src/assets/code-formatting/inline-black.svg +5 -0
  25. package/src/assets/code-formatting/inline-dark-grey.svg +5 -0
  26. package/src/assets/code-formatting/inline-light-grey.svg +5 -0
  27. package/src/assets/code-formatting/inline-white.svg +5 -0
  28. package/src/assets/contained-logo-full-word.png +0 -0
  29. package/src/assets/cron-job-color.png +0 -0
  30. package/src/assets/cron-job.png +0 -0
  31. package/src/assets/database-table-color.png +0 -0
  32. package/src/assets/database-table.png +0 -0
  33. package/src/assets/datatype-icons/black/any.svg +1 -0
  34. package/src/assets/datatype-icons/black/binary.svg +1 -0
  35. package/src/assets/datatype-icons/black/boolean.svg +3 -0
  36. package/src/assets/datatype-icons/black/date-time.svg +3 -0
  37. package/src/assets/datatype-icons/black/definition-entity.svg +6 -0
  38. package/src/assets/datatype-icons/black/key-file.svg +1 -0
  39. package/src/assets/datatype-icons/black/list.svg +3 -0
  40. package/src/assets/datatype-icons/black/null.svg +3 -0
  41. package/src/assets/datatype-icons/black/number.svg +13 -0
  42. package/src/assets/datatype-icons/black/project.svg +12 -0
  43. package/src/assets/datatype-icons/black/sql-program.svg +2 -0
  44. package/src/assets/datatype-icons/black/text.svg +3 -0
  45. package/src/assets/datatype-icons/black/unknown.svg +3 -0
  46. package/src/assets/datatype-icons/black/uuid.svg +4 -0
  47. package/src/assets/datatype-icons/black/void.svg +1 -0
  48. package/src/assets/datatype-icons/dark-grey/any.svg +1 -0
  49. package/src/assets/datatype-icons/dark-grey/boolean.svg +3 -0
  50. package/src/assets/datatype-icons/dark-grey/date-time.svg +3 -0
  51. package/src/assets/datatype-icons/dark-grey/definition-entity.svg +6 -0
  52. package/src/assets/datatype-icons/dark-grey/list.svg +3 -0
  53. package/src/assets/datatype-icons/dark-grey/null.svg +3 -0
  54. package/src/assets/datatype-icons/dark-grey/number.svg +13 -0
  55. package/src/assets/datatype-icons/dark-grey/project.svg +12 -0
  56. package/src/assets/datatype-icons/dark-grey/sql-program.svg +2 -0
  57. package/src/assets/datatype-icons/dark-grey/text.svg +3 -0
  58. package/src/assets/datatype-icons/dark-grey/unknown.svg +3 -0
  59. package/src/assets/datatype-icons/dark-grey/uuid.svg +4 -0
  60. package/src/assets/datatype-icons/dark-grey/void.svg +1 -0
  61. package/src/assets/datatype-icons/light-grey/any.svg +1 -0
  62. package/src/assets/datatype-icons/light-grey/boolean.svg +3 -0
  63. package/src/assets/datatype-icons/light-grey/date-time.svg +3 -0
  64. package/src/assets/datatype-icons/light-grey/definition-entity.svg +6 -0
  65. package/src/assets/datatype-icons/light-grey/list.svg +3 -0
  66. package/src/assets/datatype-icons/light-grey/null.svg +3 -0
  67. package/src/assets/datatype-icons/light-grey/number.svg +13 -0
  68. package/src/assets/datatype-icons/light-grey/project.svg +12 -0
  69. package/src/assets/datatype-icons/light-grey/sql-program.svg +2 -0
  70. package/src/assets/datatype-icons/light-grey/text.svg +3 -0
  71. package/src/assets/datatype-icons/light-grey/unknown.svg +3 -0
  72. package/src/assets/datatype-icons/light-grey/uuid.svg +4 -0
  73. package/src/assets/datatype-icons/light-grey/void.svg +1 -0
  74. package/src/assets/edit.png +0 -0
  75. package/src/assets/execution.svg +13 -0
  76. package/src/assets/favicon.svg +14 -0
  77. package/src/assets/file-search.svg +1 -0
  78. package/src/assets/http-endpoint.png +0 -0
  79. package/src/assets/image-input-placeholder.png +0 -0
  80. package/src/assets/logo-full-word-white.png +0 -0
  81. package/src/assets/logo-full-word.png +0 -0
  82. package/src/assets/password.svg +85 -0
  83. package/src/assets/pencil.png +0 -0
  84. package/src/assets/publish-project-rich-icon-2.svg +1 -0
  85. package/src/assets/publish-project-rich-icon.svg +1 -0
  86. package/src/assets/relational-database.png +0 -0
  87. package/src/assets/resources.svg +3 -0
  88. package/src/assets/resume-icon-14px.png +0 -0
  89. package/src/assets/server.png +0 -0
  90. package/src/assets/small-status/checkmark.svg +4 -0
  91. package/src/assets/small-status/error.svg +4 -0
  92. package/src/assets/small-status/loading.svg +4 -0
  93. package/src/assets/small-status/skipped.svg +11 -0
  94. package/src/assets/sql-connection-config.svg +1 -0
  95. package/src/assets/sql-row-transformer.svg +1 -0
  96. package/src/assets/ssl-certificate-config.svg +1 -0
  97. package/src/assets/sync.svg +1 -0
  98. package/src/assets/testing-logic-icon.svg +1 -0
  99. package/src/assets/versions.svg +25 -0
  100. package/src/assets/visual-programming-icon.svg +1 -0
  101. package/src/assets/warning-sign-24px.png +0 -0
  102. package/src/auth/index.ts +318 -0
  103. package/src/components/DialogLoader.tsx +94 -0
  104. package/src/components/EntityDialogHeader.tsx +110 -0
  105. package/src/components/EntityDialogSectionHeader.tsx +214 -0
  106. package/src/components/GalleryAddExternalIntegrationInfoDialog.tsx +87 -0
  107. package/src/components/GenerateProjectStartingLogicPromptDialog.tsx +281 -0
  108. package/src/components/LegacyRouteRedirector.tsx +55 -0
  109. package/src/components/ProPlanChip.tsx +23 -0
  110. package/src/components/ReportBugDialog.tsx +412 -0
  111. package/src/components/RequestIntegrationAccessDialog.tsx +261 -0
  112. package/src/components/UseTemplateProjectDialog.tsx +193 -0
  113. package/src/components/WorkspaceLayout.tsx +152 -0
  114. package/src/components/animated-svg/AnimatedCheckmark.tsx +41 -0
  115. package/src/components/animated-svg/AnimatedCrossmark.tsx +51 -0
  116. package/src/components/animated-svg/AnimatedEmailSending.tsx +38 -0
  117. package/src/components/animated-svg/AnimatedLoading.tsx +72 -0
  118. package/src/components/animated-svg/animated-svg.css +239 -0
  119. package/src/components/canvas/Canvas.tsx +16 -0
  120. package/src/components/canvas/CreateEntityMenu.tsx +2020 -0
  121. package/src/components/canvas/canvas.css +10 -0
  122. package/src/components/canvas/create-entity-menu.css +579 -0
  123. package/src/components/canvas-search/CanvasSearch.tsx +501 -0
  124. package/src/components/canvas-search/canvas-search.css +126 -0
  125. package/src/components/canvas-settings-menu/CanvasSettingsMenuButton.tsx +515 -0
  126. package/src/components/canvas-settings-menu/canvas-settings-menu.css +96 -0
  127. package/src/components/circular-image-upload/CircularImageUpload.tsx +113 -0
  128. package/src/components/circular-image-upload/circular-image-upload.css +69 -0
  129. package/src/components/costs/CostsDialog.tsx +459 -0
  130. package/src/components/data-type/DataTypeBuilder.tsx +3127 -0
  131. package/src/components/data-type/data-type-builder.css +45 -0
  132. package/src/components/dialogs/BetaAcknowledgeDialog.tsx +43 -0
  133. package/src/components/dialogs/ComplexDataDialog.tsx +458 -0
  134. package/src/components/dialogs/CronBuilderDialog.tsx +2145 -0
  135. package/src/components/dialogs/ExternalIntegrationConnections.tsx +565 -0
  136. package/src/components/dialogs/JsonEditorDialog.tsx +1392 -0
  137. package/src/components/dialogs/StringEditorDialog.tsx +268 -0
  138. package/src/components/dialogs/argument-declaration/ArgumentDeclaration.tsx +1167 -0
  139. package/src/components/dialogs/argument-declaration/ArgumentDeclarationDialogContent.tsx +128 -0
  140. package/src/components/dialogs/beta-dialog.css +165 -0
  141. package/src/components/dialogs/condition/Condition.tsx +431 -0
  142. package/src/components/dialogs/condition/ConditionDialogContent.tsx +126 -0
  143. package/src/components/dialogs/definition-entity/DefinitionEntityDialogContent.tsx +973 -0
  144. package/src/components/dialogs/function-call/FunctionCall.tsx +442 -0
  145. package/src/components/dialogs/function-call/FunctionCallDialogContent.tsx +126 -0
  146. package/src/components/dialogs/function-declaration/FunctionDeclaration.tsx +926 -0
  147. package/src/components/dialogs/function-declaration/FunctionDeclarationDialogContent.tsx +124 -0
  148. package/src/components/dialogs/generating-project-starting-logic-overlay/GeneratingProjectStartingLogicOverlay.tsx +176 -0
  149. package/src/components/dialogs/generating-project-starting-logic-overlay/generating-project-starting-logic-overlay.css +13 -0
  150. package/src/components/dialogs/global-event/GlobalEvent.tsx +475 -0
  151. package/src/components/dialogs/global-event/GlobalEventDialogContent.tsx +126 -0
  152. package/src/components/dialogs/help/HelpDialog.tsx +217 -0
  153. package/src/components/dialogs/help/HelpDilalogHomeContent.tsx +178 -0
  154. package/src/components/dialogs/help/help-dialog.css +116 -0
  155. package/src/components/dialogs/help/help-icon/HelpIconButton.tsx +41 -0
  156. package/src/components/dialogs/help/help-icon/help-icon.css +9 -0
  157. package/src/components/dialogs/input-map/InputMap.tsx +635 -0
  158. package/src/components/dialogs/input-map/InputMapDialogContent.tsx +126 -0
  159. package/src/components/dialogs/json-editor-dialog.css +4 -0
  160. package/src/components/dialogs/loop/Loop.tsx +650 -0
  161. package/src/components/dialogs/loop/LoopDialogContent.tsx +122 -0
  162. package/src/components/dialogs/operation/Operation.tsx +440 -0
  163. package/src/components/dialogs/operation/OperationDialogContent.tsx +126 -0
  164. package/src/components/dialogs/output-map/OutputMap.tsx +536 -0
  165. package/src/components/dialogs/output-map/OutputMapDialogContent.tsx +126 -0
  166. package/src/components/dialogs/property/Property.tsx +1490 -0
  167. package/src/components/dialogs/property/PropertyDialogContent.tsx +106 -0
  168. package/src/components/dialogs/search-statement/ColumnSelector.tsx +334 -0
  169. package/src/components/dialogs/search-statement/ConditionBuilder.tsx +750 -0
  170. package/src/components/dialogs/search-statement/DataAggregationSection.tsx +621 -0
  171. package/src/components/dialogs/search-statement/DataSourceSelection.tsx +734 -0
  172. package/src/components/dialogs/search-statement/EntityMetadataSection.tsx +135 -0
  173. package/src/components/dialogs/search-statement/FilterConditionsSection.tsx +151 -0
  174. package/src/components/dialogs/search-statement/InlineInputMap.tsx +153 -0
  175. package/src/components/dialogs/search-statement/LiteralValue.tsx +616 -0
  176. package/src/components/dialogs/search-statement/MainSourceAndInputsSection.tsx +271 -0
  177. package/src/components/dialogs/search-statement/NestedSearchStatementBuilder.tsx +170 -0
  178. package/src/components/dialogs/search-statement/OutputFormatSection.tsx +1779 -0
  179. package/src/components/dialogs/search-statement/ResultsSection.tsx +344 -0
  180. package/src/components/dialogs/search-statement/SearchStatementBuilder.tsx +251 -0
  181. package/src/components/dialogs/search-statement/SearchStatementDialogContent.tsx +398 -0
  182. package/src/components/dialogs/search-statement/ValueSelector.tsx +766 -0
  183. package/src/components/dialogs/search-statement/search-statement-context.tsx +1630 -0
  184. package/src/components/dialogs/search-statement/search-statement-dialog.css +56 -0
  185. package/src/components/dialogs/search-statement/test.sql +111 -0
  186. package/src/components/dialogs/value-descriptor/ValueDescriptor.tsx +824 -0
  187. package/src/components/dialogs/value-descriptor/ValueDescriptorDialogContent.tsx +124 -0
  188. package/src/components/dialogs/variable-declaration/VariableDeclaration.tsx +836 -0
  189. package/src/components/dialogs/variable-declaration/VariableDeclarationDialogContent.tsx +106 -0
  190. package/src/components/dialogs/variable-instance/VariableInstance.tsx +443 -0
  191. package/src/components/dialogs/variable-instance/VariableInstanceDialogContent.tsx +124 -0
  192. package/src/components/draggable-entity-card/ArgumentDeclaration.tsx +736 -0
  193. package/src/components/draggable-entity-card/CollapseEntityButton.tsx +170 -0
  194. package/src/components/draggable-entity-card/ConditionCard.tsx +1062 -0
  195. package/src/components/draggable-entity-card/ConnectionDeleteButton.tsx +309 -0
  196. package/src/components/draggable-entity-card/DataTypeIcon.tsx +624 -0
  197. package/src/components/draggable-entity-card/DraggableEntityCard.tsx +617 -0
  198. package/src/components/draggable-entity-card/ErrorMapProperty.tsx +464 -0
  199. package/src/components/draggable-entity-card/EventCard.tsx +700 -0
  200. package/src/components/draggable-entity-card/ExecutionInProgressValue.tsx +327 -0
  201. package/src/components/draggable-entity-card/FunctionDeclarationCard.tsx +819 -0
  202. package/src/components/draggable-entity-card/InputMapProperty.tsx +1067 -0
  203. package/src/components/draggable-entity-card/InternalCall.tsx +978 -0
  204. package/src/components/draggable-entity-card/InternalCallExecutionNode.tsx +643 -0
  205. package/src/components/draggable-entity-card/LogicScopeCallerNode.tsx +262 -0
  206. package/src/components/draggable-entity-card/LoopCard.tsx +791 -0
  207. package/src/components/draggable-entity-card/MainValueInput.tsx +523 -0
  208. package/src/components/draggable-entity-card/MainValueOutput.tsx +458 -0
  209. package/src/components/draggable-entity-card/MethodDeclaration.tsx +1088 -0
  210. package/src/components/draggable-entity-card/NestedCondition.tsx +1025 -0
  211. package/src/components/draggable-entity-card/OutputMapProperty.tsx +843 -0
  212. package/src/components/draggable-entity-card/PassthroughEntityCard.tsx +1247 -0
  213. package/src/components/draggable-entity-card/ReturnedError.tsx +549 -0
  214. package/src/components/draggable-entity-card/SmallSuccessFailureNodes.tsx +523 -0
  215. package/src/components/draggable-entity-card/SuccessFailureNodes.tsx +509 -0
  216. package/src/components/draggable-entity-card/TestEntityButton.tsx +946 -0
  217. package/src/components/draggable-entity-card/TestMenu.tsx +523 -0
  218. package/src/components/draggable-entity-card/TestMenuValidationDropdown.tsx +84 -0
  219. package/src/components/draggable-entity-card/UnreachableMarker.tsx +114 -0
  220. package/src/components/draggable-entity-card/VariableCard.tsx +1577 -0
  221. package/src/components/draggable-entity-card/VariableScopeMarker.tsx +117 -0
  222. package/src/components/draggable-entity-card/collapse-entity-button.css +44 -0
  223. package/src/components/draggable-entity-card/definition-entity/DefinitionEntityCard.tsx +1181 -0
  224. package/src/components/draggable-entity-card/definition-entity/DefinitionEntityIcon.tsx +36 -0
  225. package/src/components/draggable-entity-card/definition-entity/DefinitionEntityProperty.tsx +478 -0
  226. package/src/components/draggable-entity-card/definition-entity/DynamicFooterActions.tsx +112 -0
  227. package/src/components/draggable-entity-card/definition-entity/actions/external-integration-connection/ExportCredentialsFooterAction.tsx +461 -0
  228. package/src/components/draggable-entity-card/definition-entity/actions/external-integration-connection/RestablishConnectionFooterAction.tsx +199 -0
  229. package/src/components/draggable-entity-card/definition-entity/actions/external-integration-connection/restablish-connection-footer-action.css +85 -0
  230. package/src/components/draggable-entity-card/definition-entity/actions/google-drive/GoogleDriveFilePickerAPIFooterAction.tsx +277 -0
  231. package/src/components/draggable-entity-card/definition-entity/actions/google-drive/google-drive-file-picker-api-footer-action.css +107 -0
  232. package/src/components/draggable-entity-card/definition-entity/actions/persisted-entity/DatabaseFooterAction.tsx +452 -0
  233. package/src/components/draggable-entity-card/definition-entity/actions/persisted-entity/database-footer-action.css +86 -0
  234. package/src/components/draggable-entity-card/definition-entity/definition-entity-card.css +17 -0
  235. package/src/components/draggable-entity-card/draggable-entity-card.css +1140 -0
  236. package/src/components/draggable-entity-card/entity-locked-icon/EntityLockedIcon.tsx +133 -0
  237. package/src/components/draggable-entity-card/entity-locked-icon/entity-locked.css +8 -0
  238. package/src/components/draggable-entity-card/expand-properties-icon-button/ExpandPropertiesIconButton.tsx +84 -0
  239. package/src/components/draggable-entity-card/expand-properties-icon-button/expand-properties-icon-button.css +21 -0
  240. package/src/components/draggable-entity-card/implement-entity-icon/ImplementEntityIcon.tsx +74 -0
  241. package/src/components/draggable-entity-card/implement-entity-icon/implement-entity-icon.css +13 -0
  242. package/src/components/draggable-entity-card/logic-error/LogicErrorIconMenu.tsx +424 -0
  243. package/src/components/draggable-entity-card/logic-error/logic-error.css +23 -0
  244. package/src/components/draggable-entity-card/new-card-input-button/NewCardInputButton.tsx +193 -0
  245. package/src/components/draggable-entity-card/new-card-input-button/NewDynamicInputButton.tsx +214 -0
  246. package/src/components/draggable-entity-card/new-card-input-button/new-card-input-button.css +71 -0
  247. package/src/components/draggable-entity-card/new-card-output-button/NewCardOutputButton.tsx +192 -0
  248. package/src/components/draggable-entity-card/new-card-output-button/new-card-output-button.css +71 -0
  249. package/src/components/draggable-entity-card/termination-statement/TerminationStatementCard.tsx +1543 -0
  250. package/src/components/draggable-entity-card/termination-statement/termination-statement-card.css +17 -0
  251. package/src/components/draggable-entity-card/test-entity-button.css +55 -0
  252. package/src/components/draggable-entity-card/test-menu.css +181 -0
  253. package/src/components/draggable-entity-card/unreachable-marker.css +43 -0
  254. package/src/components/draggable-entity-card/variable-scope-marker.css +22 -0
  255. package/src/components/dynamic-value/DynamicValue.tsx +2395 -0
  256. package/src/components/dynamic-value/DynamicValueEntry.tsx +1957 -0
  257. package/src/components/dynamic-value/dynamic-value.css +230 -0
  258. package/src/components/editor/ElyxMonacoEditor.tsx +38 -0
  259. package/src/components/entity-error/EntityErrorListItem.tsx +47 -0
  260. package/src/components/entity-error/entity-error.css +198 -0
  261. package/src/components/entity-icon/EntityIcon.tsx +292 -0
  262. package/src/components/entity-icon/entity-icon.css +39 -0
  263. package/src/components/gallery-card/CreateNewProject.tsx +222 -0
  264. package/src/components/gallery-card/GalleryCard.tsx +171 -0
  265. package/src/components/gallery-card/MarketplaceCard.tsx +87 -0
  266. package/src/components/gallery-card/ProjectDuplicationCard.tsx +575 -0
  267. package/src/components/gallery-card/gallery-card.css +25 -0
  268. package/src/components/notifications/NotificationsIconButton.tsx +124 -0
  269. package/src/components/notifications/NotificationsPanel.tsx +385 -0
  270. package/src/components/notifications/notifications.css +189 -0
  271. package/src/components/online-users/LocalOnlineUsers.tsx +175 -0
  272. package/src/components/online-users/PageOnlineUsers.tsx +297 -0
  273. package/src/components/online-users/online-users.css +72 -0
  274. package/src/components/page-backdrop/PageBackdrop.tsx +8 -0
  275. package/src/components/page-backdrop/page-backdrop.css +7 -0
  276. package/src/components/project-configuration/DeleteProjectConfirmationDialog.tsx +134 -0
  277. package/src/components/project-configuration/ProjectConfigurationDialog.tsx +972 -0
  278. package/src/components/project-configuration/ProjectDataForm.tsx +121 -0
  279. package/src/components/project-configuration/UnpublishProjectConfirmationDialog.tsx +162 -0
  280. package/src/components/project-configuration/project-configuration-content.css +209 -0
  281. package/src/components/project-name/ProjectName.tsx +2025 -0
  282. package/src/components/project-name/project-name.css +599 -0
  283. package/src/components/publishing/Publication.tsx +133 -0
  284. package/src/components/publishing/history/PublicationHistoryContent.tsx +414 -0
  285. package/src/components/publishing/history/PublicationHistoryDialog.tsx +234 -0
  286. package/src/components/publishing/preview/PublicationPreviewDialog.tsx +1158 -0
  287. package/src/components/publishing/preview/PublishingPriceForecast.tsx +160 -0
  288. package/src/components/publishing/preview/PublishingResourcesDetails.tsx +91 -0
  289. package/src/components/publishing/publication-sequence/PublishingSequenceContent.tsx +375 -0
  290. package/src/components/publishing/publication-sequence/PublishingSequenceDialog.tsx +344 -0
  291. package/src/components/publishing/publishing-dialog.css +142 -0
  292. package/src/components/publishing/utils.ts +227 -0
  293. package/src/components/resources/ResourcesDialog.tsx +591 -0
  294. package/src/components/resources/UpgradeBanner.tsx +102 -0
  295. package/src/components/resources/codebase/CodebaseDetails.tsx +156 -0
  296. package/src/components/resources/cron-job/CronJobsList.tsx +532 -0
  297. package/src/components/resources/functions/FunctionsList.tsx +454 -0
  298. package/src/components/resources/http-api/HttpAPI.tsx +566 -0
  299. package/src/components/resources/http-api/HttpAPIClientModule.tsx +37 -0
  300. package/src/components/resources/logs/LogsViewer.tsx +768 -0
  301. package/src/components/resources/query.ts +74 -0
  302. package/src/components/resources/relational-database/DatabaseTable.tsx +905 -0
  303. package/src/components/resources/relational-database/RelationalDatabase.tsx +83 -0
  304. package/src/components/resources/relational-database/RelationalDatabaseSecrets.tsx +361 -0
  305. package/src/components/resources/resources-dialog.css +74 -0
  306. package/src/components/test-relational-database/DatabaseTable.tsx +913 -0
  307. package/src/components/test-relational-database/TestDatabaseDialogContent.tsx +670 -0
  308. package/src/components/test-relational-database/query.ts +74 -0
  309. package/src/components/toolbar/ToolBar.tsx +236 -0
  310. package/src/components/toolbar/toolbar.css +78 -0
  311. package/src/components/transaction-history/TransactionHistoryDialog.tsx +268 -0
  312. package/src/components/user/CurrentUserAvatar.tsx +65 -0
  313. package/src/components/user/UserChip.tsx +62 -0
  314. package/src/components/user/user.css +39 -0
  315. package/src/components/user-profile/ChangePasswordForm.tsx +67 -0
  316. package/src/components/user-profile/OwnUserProfileContent.tsx +665 -0
  317. package/src/components/user-profile/PublicUserProfileContent.tsx +99 -0
  318. package/src/components/user-profile/UserDataForm.tsx +75 -0
  319. package/src/components/user-profile/UserProfileDialog.tsx +110 -0
  320. package/src/components/user-profile/user-profile-content.css +25 -0
  321. package/src/config.ts +130 -0
  322. package/src/globals.d.ts +13 -0
  323. package/src/index.html +27 -0
  324. package/src/index.tsx +23 -0
  325. package/src/lib/badge/Badge.tsx +35 -0
  326. package/src/lib/badge/badge.css +32 -0
  327. package/src/lib/button/Button.tsx +129 -0
  328. package/src/lib/button/button.css +145 -0
  329. package/src/lib/canvas/canvas-undo-redo.ts +263 -0
  330. package/src/lib/canvas/defs.ts +170 -0
  331. package/src/lib/canvas/index.test.ts +189 -0
  332. package/src/lib/canvas/index.ts +6999 -0
  333. package/src/lib/canvas/utils.ts +59 -0
  334. package/src/lib/card/Card.tsx +62 -0
  335. package/src/lib/card/LoadingCard.tsx +82 -0
  336. package/src/lib/card/card.css +259 -0
  337. package/src/lib/chip/Chip.tsx +79 -0
  338. package/src/lib/chip/chip.css +0 -0
  339. package/src/lib/dialog/Dialog.tsx +122 -0
  340. package/src/lib/dialog/SmallDialog.tsx +61 -0
  341. package/src/lib/dialog/dialog.css +40 -0
  342. package/src/lib/display-data-structure/index.tsx +21 -0
  343. package/src/lib/dropdown/CanvasDropdownMenuCard.tsx +68 -0
  344. package/src/lib/dropdown/CanvasDropdownMenuCardOption.tsx +136 -0
  345. package/src/lib/dropdown/DropdownButton.tsx +104 -0
  346. package/src/lib/dropdown/DropdownMenuCard.tsx +324 -0
  347. package/src/lib/dropdown/DropdownMenuPopup.tsx +27 -0
  348. package/src/lib/dropdown/dropdown-button.css +76 -0
  349. package/src/lib/dropdown/dropdown-menu.css +151 -0
  350. package/src/lib/json-editor/RawJsonEditor.tsx +137 -0
  351. package/src/lib/json-editor/json-editor.css +35 -0
  352. package/src/lib/loader/Loader.tsx +120 -0
  353. package/src/lib/loader/loader.css +38 -0
  354. package/src/lib/pagination/Pagination.tsx +64 -0
  355. package/src/lib/popup/CanvasPopupBaseComponent.tsx +103 -0
  356. package/src/lib/popup/Popup.tsx +243 -0
  357. package/src/lib/popup/popup.css +16 -0
  358. package/src/lib/table/RowForm.tsx +301 -0
  359. package/src/lib/table/Table.tsx +1069 -0
  360. package/src/lib/table/table.css +249 -0
  361. package/src/lib/table/types.ts +108 -0
  362. package/src/lib/text-area/TextArea.tsx +183 -0
  363. package/src/lib/text-area/text-area.css +156 -0
  364. package/src/lib/text-field/TextField.tsx +218 -0
  365. package/src/lib/text-field/index.ts +8 -0
  366. package/src/lib/text-field/text-field.css +201 -0
  367. package/src/lib/tooltip/Tooltip.tsx +24 -0
  368. package/src/lib/tooltip/tooltip.css +17 -0
  369. package/src/localization/index.ts +47 -0
  370. package/src/main.css +343 -0
  371. package/src/pages/Auth.tsx +848 -0
  372. package/src/pages/Editor.tsx +883 -0
  373. package/src/pages/ErrorPage.tsx +179 -0
  374. package/src/pages/Gallery.tsx +1693 -0
  375. package/src/pages/NewPaymentMethodCallback.tsx +53 -0
  376. package/src/pages/NotFoundPage.tsx +126 -0
  377. package/src/pages/PricingPlans.tsx +155 -0
  378. package/src/pages/auth.css +304 -0
  379. package/src/pages/gallery.css +421 -0
  380. package/src/payments/index.ts +187 -0
  381. package/src/popup-notification/index.ts +90 -0
  382. package/src/services/database/index.ts +1 -0
  383. package/src/services/database/utils.ts +1301 -0
  384. package/src/services/editor/CanvasElement.tsx +2934 -0
  385. package/src/services/editor/CanvasElementConnectionDeleteButton.ts +204 -0
  386. package/src/services/editor/CanvasPopup.tsx +749 -0
  387. package/src/services/editor/EditorService.ts +8157 -0
  388. package/src/services/editor/area.ts +1312 -0
  389. package/src/services/editor/connections.ts +1019 -0
  390. package/src/services/editor/create/condition.ts +25 -0
  391. package/src/services/editor/create/definition-entity.ts +29 -0
  392. package/src/services/editor/create/function-call.ts +25 -0
  393. package/src/services/editor/create/global-event.ts +33 -0
  394. package/src/services/editor/create/loop.ts +25 -0
  395. package/src/services/editor/create/operation.ts +30 -0
  396. package/src/services/editor/create/utils.ts +140 -0
  397. package/src/services/editor/create/variable-declaration.ts +135 -0
  398. package/src/services/editor/create/variable-instance.ts +100 -0
  399. package/src/services/editor/editor-ui-extensions-context.ts +43 -0
  400. package/src/services/editor/entities-metadata.json +9310 -0
  401. package/src/services/editor/icons.ts +1093 -0
  402. package/src/services/editor/index.ts +1 -0
  403. package/src/services/editor/layout.ts +102 -0
  404. package/src/services/editor/modules/built-in-function-implementations/base.ts +14 -0
  405. package/src/services/editor/modules/built-in-function-implementations/create-persisted-entity/index.ts +56 -0
  406. package/src/services/editor/modules/built-in-function-implementations/delete-persisted-entity/index.ts +55 -0
  407. package/src/services/editor/modules/built-in-function-implementations/index.ts +4 -0
  408. package/src/services/editor/modules/built-in-function-implementations/update-persisted-entity/index.ts +56 -0
  409. package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/get-files.ts +183 -0
  410. package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/list-drives.ts +124 -0
  411. package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/list-root-folders.ts +125 -0
  412. package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/smart-fetch-document.ts +702 -0
  413. package/src/services/editor/modules/operations-implementations/external-integrations/google-drive/upload-document.ts +535 -0
  414. package/src/services/editor/modules/operations-implementations/external-integrations/google-gemini/generate-content.ts +193 -0
  415. package/src/services/editor/modules/operations-implementations/external-integrations/google-mail/get-emails.ts +586 -0
  416. package/src/services/editor/modules/operations-implementations/external-integrations/google-mail/send-email.ts +386 -0
  417. package/src/services/editor/modules/operations-implementations/external-integrations/index.ts +12 -0
  418. package/src/services/editor/modules/operations-implementations/external-integrations/slack/channels.ts +240 -0
  419. package/src/services/editor/modules/operations-implementations/external-integrations/slack/messages.ts +210 -0
  420. package/src/services/editor/modules/operations-implementations/external-integrations/slack/replies.ts +200 -0
  421. package/src/services/editor/modules/operations-implementations/external-integrations/slack/send-message.ts +177 -0
  422. package/src/services/editor/modules/operations-implementations/index.ts +1 -0
  423. package/src/services/editor/modules/search-node-implementation/index.ts +42 -0
  424. package/src/services/editor/modules/sql-migrations-generation.tsx +1054 -0
  425. package/src/services/editor/publication/publication.ts +578 -0
  426. package/src/services/editor/ui.ts +1348 -0
  427. package/src/services/editor/utils.ts +5868 -0
  428. package/src/services/editor/value-store.ts +619 -0
  429. package/src/services/execution/built-in-function-implementations.ts +422 -0
  430. package/src/services/execution/index.ts +4747 -0
  431. package/src/services/execution/logic.ts +121 -0
  432. package/src/services/execution/test-instance.tsx +2296 -0
  433. package/src/services/execution/utils.ts +33 -0
  434. package/src/services/execution/value-resolution.test.ts +424 -0
  435. package/src/services/execution/value-resolution.ts +4087 -0
  436. package/src/services/integrations/ExternalIntegrationsService.ts +439 -0
  437. package/src/services/integrations/api.ts +175 -0
  438. package/src/services/local-relational-database/idb_helper.ts +66 -0
  439. package/src/services/local-relational-database/index.ts +3308 -0
  440. package/src/services/local-relational-database/utils.ts +403 -0
  441. package/src/services/notifications/index.ts +525 -0
  442. package/src/services/user/index.ts +144 -0
  443. package/src/setupTests.ts +1 -0
  444. package/src/socket/socket.ts +248 -0
  445. package/src/socket/utils.ts +10 -0
  446. package/src/store/workspace.ts +12 -0
  447. package/src/theme.ts +19 -0
  448. package/src/utils/DOM.ts +39 -0
  449. package/src/utils/date.ts +169 -0
  450. package/src/utils/index.ts +158 -0
  451. package/src/utils/react.tsx +679 -0
  452. package/src/utils/testing.ts +103 -0
@@ -0,0 +1,1957 @@
1
+ import React, {
2
+ useCallback,
3
+ useEffect,
4
+ useMemo,
5
+ useRef,
6
+ useState
7
+ } from 'react';
8
+ import {
9
+ BaseEntityNames,
10
+ ChangeSet,
11
+ checkHasBaseEntity,
12
+ EntityError,
13
+ EntityType,
14
+ EntityWithValueState,
15
+ flattenDefinitionEntityExtensionAndImplementationTypes,
16
+ getExtendedDefinitionEntity,
17
+ PrimitiveTypes,
18
+ ProjectState,
19
+ ValueAsTypeState,
20
+ CanvasEntityDisabledReason,
21
+ VariableDeclarationState,
22
+ resolveEntityName,
23
+ uuidValueValidation,
24
+ translateLogicErrorCode,
25
+ InputMapState,
26
+ ValueDescriptorState,
27
+ ArgumentDeclarationState,
28
+ ValueReadingEntityState,
29
+ DefinitionEntityState,
30
+ BUILT_IN_BASE_ENTITY_IDS,
31
+ getParentCallableEntity,
32
+ OperationState,
33
+ checkIsEmptyValue,
34
+ EntityWithDefaultValueState,
35
+ DynamicValueTypes,
36
+ EntityInstanceErrorCode,
37
+ safeResolveEntityName,
38
+ flattenDataTypeAndGroup,
39
+ flattenDataTypesInOrGroup,
40
+ DataTypeState,
41
+ StateMutationAction
42
+ } from '@elyx-code/project-logic-tree';
43
+ import './dynamic-value.css';
44
+ import {
45
+ errorCodeToMessage,
46
+ getCanvasEntityDOMId
47
+ } from '../../services/editor/ui';
48
+ import DynamicValue from './DynamicValue';
49
+ import {
50
+ castHTMLInputValueToType,
51
+ castLiteralValueToHTMLInputValue,
52
+ getExternalIntegrationIdFromAction,
53
+ resolveInputTypeFromDataType,
54
+ resolvePersistedDefinitionEntityDatabaseDialogAbsolutePath
55
+ } from '../../services/editor/utils';
56
+ import { EditorService } from '../../services/editor';
57
+ import {
58
+ handleLiteralValueChange,
59
+ handleLiteralValueDelete,
60
+ handleValueAsTypeChange,
61
+ handleValueAsTypeDelete,
62
+ resolveValue
63
+ } from '../../services/execution/value-resolution';
64
+ import {
65
+ IDynamicValue,
66
+ IValueInheritanceLink,
67
+ IValueStoreClient
68
+ } from '../../services/editor/value-store';
69
+ import { CanvasEntityElement } from '../../services/editor/CanvasElement';
70
+ import { TestDatabaseDialogMode } from '../test-relational-database/TestDatabaseDialogContent';
71
+ import {
72
+ FormControl,
73
+ IconButton,
74
+ InputLabel,
75
+ Tooltip as MuiTooltip,
76
+ MenuItem,
77
+ Select,
78
+ OutlinedInput,
79
+ InputAdornment,
80
+ FormHelperText,
81
+ TextField,
82
+ Box,
83
+ Stack,
84
+ Autocomplete,
85
+ Checkbox,
86
+ Chip
87
+ } from '@mui/material';
88
+ import { onClickAway } from '../../utils/DOM';
89
+ import CheckIcon from '@mui/icons-material/Check';
90
+ import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';
91
+ import CheckBoxIcon from '@mui/icons-material/CheckBox';
92
+ import CancelIcon from '@mui/icons-material/Cancel';
93
+ import FullscreenIcon from '@mui/icons-material/Fullscreen';
94
+ import EntityIcon from '../entity-icon/EntityIcon';
95
+ import { popupNotification } from '../../popup-notification';
96
+
97
+ const icon = <CheckBoxOutlineBlankIcon fontSize="small" />;
98
+ const checkedIcon = <CheckBoxIcon fontSize="small" />;
99
+
100
+ export const SingleValueAsTypeAutocomplete = ({
101
+ id,
102
+ canvasElement,
103
+ options,
104
+ dynamicValue,
105
+ project,
106
+ popupPlacement,
107
+ onChange,
108
+ name
109
+ }: {
110
+ id?: string;
111
+ options: ValueAsTypeState[];
112
+ dynamicValue: IDynamicValue;
113
+ project: EditorService;
114
+ canvasElement?: CanvasEntityElement;
115
+ popupPlacement?:
116
+ | 'left'
117
+ | 'right'
118
+ | 'top'
119
+ | 'bottom'
120
+ | 'bottom-end'
121
+ | 'bottom-start'
122
+ | 'left-end'
123
+ | 'left-start'
124
+ | 'right-end'
125
+ | 'right-start'
126
+ | 'top-end'
127
+ | 'top-start';
128
+ onChange: (newValue: ValueAsTypeState | null) => void;
129
+ name: string;
130
+ }) => {
131
+ return (
132
+ <Autocomplete
133
+ id={id || 'value-as-type-single-autocomplete'}
134
+ fullWidth
135
+ options={options}
136
+ getOptionLabel={(option) =>
137
+ resolveEntityName(option, project.logic)
138
+ }
139
+ isOptionEqualToValue={(option, value) => option.id === value.id}
140
+ value={dynamicValue.value?.valueAsTypeSingle}
141
+ disableClearable={false}
142
+ getOptionDisabled={(option) => false}
143
+ renderOption={(fieldProps, option, { selected }) => {
144
+ const { key, ...optionProps } = fieldProps;
145
+ return (
146
+ <MuiTooltip
147
+ key={key}
148
+ title={''}
149
+ placement={popupPlacement || 'bottom'}
150
+ arrow
151
+ enterDelay={false ? 100 : 400}
152
+ leaveDelay={200}
153
+ >
154
+ <Box
155
+ component="li"
156
+ sx={{ '& > img': { mr: 2, flexShrink: 0 } }}
157
+ {...optionProps}
158
+ >
159
+ <Stack direction="row" gap={1} alignItems="center">
160
+ <EntityIcon
161
+ entity={option}
162
+ project={project}
163
+ parentCanvasObject={
164
+ canvasElement?.draggableObject
165
+ }
166
+ />
167
+ {resolveEntityName(option, project.logic)}
168
+ </Stack>
169
+ </Box>
170
+ </MuiTooltip>
171
+ );
172
+ }}
173
+ onChange={(e, newValue) => {
174
+ onChange(newValue);
175
+ }}
176
+ renderInput={(params) => (
177
+ <TextField
178
+ {...params}
179
+ label={name}
180
+ variant="outlined"
181
+ placeholder="Select value"
182
+ size="small"
183
+ />
184
+ )}
185
+ />
186
+ );
187
+ };
188
+
189
+ export const ListValueAsTypeAutocomplete = ({
190
+ id,
191
+ entity,
192
+ options,
193
+ dynamicValue,
194
+ project,
195
+ canvasElement,
196
+ popupPlacement,
197
+ onChange,
198
+ name
199
+ }: {
200
+ id?: string;
201
+ entity: EntityWithValueState;
202
+ options: ValueAsTypeState[];
203
+ dynamicValue: IDynamicValue;
204
+ canvasElement?: CanvasEntityElement;
205
+ project: EditorService;
206
+ popupPlacement?:
207
+ | 'left'
208
+ | 'right'
209
+ | 'top'
210
+ | 'bottom'
211
+ | 'bottom-end'
212
+ | 'bottom-start'
213
+ | 'left-end'
214
+ | 'left-start'
215
+ | 'right-end'
216
+ | 'right-start'
217
+ | 'top-end'
218
+ | 'top-start';
219
+ onChange: (newValue: ValueAsTypeState[]) => void;
220
+ name: string;
221
+ }) => {
222
+ return (
223
+ <Autocomplete
224
+ fullWidth
225
+ multiple
226
+ id={id || 'value-as-type-list-autocomplete'}
227
+ options={options}
228
+ disableCloseOnSelect
229
+ isOptionEqualToValue={(option, value) => option.id === value.id}
230
+ getOptionLabel={(option) => {
231
+ const ent = project.logic.get(option.id) as ValueAsTypeState;
232
+
233
+ return resolveEntityName(ent, project.logic);
234
+ }}
235
+ renderOption={(fieldProps, option, { selected }) => {
236
+ const { key, ...optionProps } = fieldProps;
237
+ const ent = project.logic.get(option.id) as ValueAsTypeState;
238
+
239
+ return (
240
+ <MuiTooltip
241
+ key={key}
242
+ title={''}
243
+ placement={popupPlacement || 'bottom'}
244
+ arrow
245
+ enterDelay={false ? 100 : 400}
246
+ leaveDelay={200}
247
+ >
248
+ <Box
249
+ component="li"
250
+ sx={{ '& > img': { mr: 2, flexShrink: 0 } }}
251
+ {...optionProps}
252
+ >
253
+ <Checkbox
254
+ icon={icon}
255
+ checkedIcon={checkedIcon}
256
+ style={{ marginRight: 8 }}
257
+ checked={
258
+ (
259
+ dynamicValue?.value?.valueAsTypeList ||
260
+ []
261
+ ).findIndex((v) => v.id === ent.id) > -1
262
+ }
263
+ />
264
+ <Stack direction="row" gap={1} alignItems="center">
265
+ <EntityIcon
266
+ entity={ent}
267
+ project={project}
268
+ parentCanvasObject={
269
+ canvasElement?.draggableObject
270
+ }
271
+ />
272
+ {resolveEntityName(ent, project.logic)}
273
+ </Stack>
274
+ </Box>
275
+ </MuiTooltip>
276
+ );
277
+ }}
278
+ renderTags={(selected) => (
279
+ <Stack gap={1} direction="row" flexWrap="wrap">
280
+ {selected.map((value) => {
281
+ const ent = project.logic.get(
282
+ value.id
283
+ ) as ValueAsTypeState;
284
+
285
+ return (
286
+ <Chip
287
+ avatar={
288
+ <EntityIcon
289
+ entity={ent}
290
+ project={project}
291
+ parentCanvasObject={
292
+ canvasElement?.draggableObject
293
+ }
294
+ style={{ marginLeft: 8 }}
295
+ />
296
+ }
297
+ key={value.id}
298
+ label={resolveEntityName(ent, project.logic)}
299
+ onDelete={() => {
300
+ onChange(
301
+ (
302
+ dynamicValue.value
303
+ ?.valueAsTypeList || []
304
+ ).filter((v) => v.id !== ent.id)
305
+ );
306
+ }}
307
+ deleteIcon={
308
+ <CancelIcon
309
+ onMouseDown={(event) =>
310
+ event.stopPropagation()
311
+ }
312
+ />
313
+ }
314
+ />
315
+ );
316
+ })}
317
+ </Stack>
318
+ )}
319
+ value={dynamicValue.value?.valueAsTypeList || []}
320
+ onChange={(_, newValue) => {
321
+ // const option = options.filter((opt) => opt.id === newValue.id)[0];
322
+ onChange(newValue);
323
+ }}
324
+ getOptionDisabled={
325
+ (option) => false
326
+ // !!validateCanImplementEntity(
327
+ // entity,
328
+ // project.logic.get(option.id) as
329
+ // | DefinitionEntityState
330
+ // | BuiltInBaseEntityState
331
+ // ).length
332
+ }
333
+ renderInput={(params) => (
334
+ <TextField
335
+ {...params}
336
+ variant="outlined"
337
+ label={name}
338
+ placeholder="Select values"
339
+ size="small"
340
+ />
341
+ )}
342
+ />
343
+ );
344
+ };
345
+
346
+ export interface IDynamicValueEntryProps {
347
+ entity: EntityWithDefaultValueState;
348
+ project: EditorService;
349
+ canvasElement?: CanvasEntityElement;
350
+ parentDisabledReasons: CanvasEntityDisabledReason[];
351
+ onlyDefault?: boolean;
352
+ children: (extraContent: React.ReactNode) => React.ReactNode;
353
+ popupPlacement?:
354
+ | 'left'
355
+ | 'right'
356
+ | 'top'
357
+ | 'bottom'
358
+ | 'bottom-end'
359
+ | 'bottom-start'
360
+ | 'left-end'
361
+ | 'left-start'
362
+ | 'right-end'
363
+ | 'right-start'
364
+ | 'top-end'
365
+ | 'top-start';
366
+ }
367
+
368
+ // This is an attempt to build a component which can be used generically to display a dynamic value
369
+ // The challenge is that dynamic values are often displayed among other elements, which often get hidden when the dynamic value is being edited
370
+ const DynamicValueEntry = (props: IDynamicValueEntryProps) => {
371
+ if (props.project.destroyed) {
372
+ return null;
373
+ }
374
+
375
+ const [updateKey, setValue] = useState(0);
376
+
377
+ const useForceUpdate = () => {
378
+ return () => setValue((value) => value + 1);
379
+ };
380
+ const forceUpdate = useForceUpdate(); // Update the component
381
+
382
+ const inputRef = useRef<HTMLInputElement>(null);
383
+
384
+ const onlyDefault = props.onlyDefault || false;
385
+
386
+ const entity = props.entity;
387
+ let dataType = entity.getDataType(null);
388
+
389
+ if (entity.type === EntityType.InputMap && (entity as any).declaration) {
390
+ dataType = (entity as any).declaration.getDataType(null);
391
+ }
392
+
393
+ const reducedDataTypes = flattenDataTypesInOrGroup(
394
+ flattenDataTypeAndGroup(dataType),
395
+ { removeDuplicates: true, removeNulls: true }
396
+ );
397
+
398
+ const allResolved = reducedDataTypes.filter((dt) => !!dt.isResolved);
399
+
400
+ let workingDataType: DataTypeState | null = null;
401
+
402
+ if (allResolved.length === 1) {
403
+ workingDataType = allResolved[0];
404
+ } else {
405
+ workingDataType = dataType;
406
+ }
407
+
408
+ // A foreign-key reference doesn't carry its own `entity` — the type of the
409
+ // value the user enters (uuid, number, …) lives on the referenced property.
410
+ // Without this step the `!workingDataType.entity` branch below would always
411
+ // open the raw JSON editor for any foreign-key field. Dereferencing here
412
+ // lets us render the matching primitive input instead.
413
+ if (workingDataType?.foreignKeyRef && !workingDataType.entity) {
414
+ const refDataType = workingDataType.foreignKeyRef.getDataType?.(null);
415
+
416
+ if (refDataType) {
417
+ const refResolved = flattenDataTypesInOrGroup(
418
+ flattenDataTypeAndGroup(refDataType),
419
+ { removeDuplicates: true, removeNulls: true }
420
+ ).filter((dt) => !!dt.isResolved);
421
+
422
+ if (refResolved.length === 1) {
423
+ workingDataType = refResolved[0];
424
+ }
425
+ }
426
+ }
427
+
428
+ const dynamicValue: IDynamicValue | null = useMemo(() => {
429
+ if (props.project.destroyed) {
430
+ return null;
431
+ }
432
+
433
+ const dynamicValueResolutionResult = !!entity
434
+ ? resolveValue(entity, props.project, onlyDefault)
435
+ : null;
436
+
437
+ return dynamicValueResolutionResult;
438
+ }, [entity, props.project, onlyDefault, updateKey]);
439
+
440
+ const [primitiveDefaultValueLocal, setPrimitiveDefaultValueLocal] =
441
+ useState<string | number | boolean | null>(
442
+ (dynamicValue?.value?.rawString as string) ??
443
+ (dynamicValue?.value?.value as string) ??
444
+ ''
445
+ );
446
+ const [
447
+ primitiveDefaultValueValidationErrors,
448
+ setPrimitiveDefaultValueValidationErrors
449
+ ] = useState<EntityError<string>[]>([]);
450
+
451
+ const [isEditingValue, setIsEditingValue] = useState<boolean>(false);
452
+ const [preferedLocalType, setPreferedLocalType] = useState<
453
+ DynamicValueTypes.DefaultValue | DynamicValueTypes.Testing | null
454
+ >(null);
455
+
456
+ const name = safeResolveEntityName(entity, props.project.logic);
457
+
458
+ const _handleLiteralValueDelete = (value: IDynamicValue) => {
459
+ const isValueAsType = dataType.asType || !!value?.value?.valueAsType;
460
+
461
+ let valueStore: IValueStoreClient = props.project.localTestValues;
462
+ let changeSet: ChangeSet | null = null;
463
+
464
+ if (
465
+ ![
466
+ DynamicValueTypes.Testing,
467
+ DynamicValueTypes.QueuedAutocalculation,
468
+ DynamicValueTypes.ExecutionResult,
469
+ DynamicValueTypes.AutoCalculated
470
+ ].includes(value.type)
471
+ ) {
472
+ changeSet = props.project.logic.addChangeSet(
473
+ new ChangeSet(
474
+ props.project.logic,
475
+ ProjectState.sessionAuthor,
476
+ new Date().toISOString(),
477
+ props.entity,
478
+ false,
479
+ StateMutationAction.RemoveLiteralValue
480
+ )
481
+ );
482
+ }
483
+
484
+ // Choose between deleting a literal value or a value as type
485
+ // based on the previous dynamic value data
486
+ if (isValueAsType) {
487
+ changeSet = handleValueAsTypeDelete(
488
+ props.entity,
489
+ props.project.logic,
490
+ changeSet || valueStore
491
+ );
492
+ } else {
493
+ changeSet = handleLiteralValueDelete(
494
+ props.entity,
495
+ props.project.logic,
496
+ changeSet || valueStore
497
+ );
498
+ }
499
+
500
+ if (!!changeSet) {
501
+ props.project.renderAndCloseChangeSet(changeSet);
502
+ } else {
503
+ props.project.emit(props.entity.id, {});
504
+ }
505
+
506
+ forceUpdate();
507
+ };
508
+
509
+ const _handleLiteralValueChange = (
510
+ newValue: string | number | boolean | string[],
511
+ localOnlyDefault?: boolean
512
+ ) => {
513
+ let finalValueToSave = newValue;
514
+ let finalRawString: string | null = null;
515
+ if (
516
+ workingDataType?.entity?.type === EntityType.PrimitiveEntity &&
517
+ workingDataType.entity.name === PrimitiveTypes.Number &&
518
+ typeof newValue === 'string' &&
519
+ newValue !== '' &&
520
+ newValue !== '-'
521
+ ) {
522
+ const num = Number(newValue);
523
+ if (!isNaN(num)) {
524
+ finalValueToSave = num;
525
+ }
526
+ } else if (
527
+ workingDataType?.entity?.type === EntityType.PrimitiveEntity &&
528
+ workingDataType.entity.name === PrimitiveTypes.String &&
529
+ typeof newValue === 'string'
530
+ ) {
531
+ finalRawString = newValue;
532
+ finalValueToSave = newValue.replace(
533
+ /\\(n|t|r|\\)/g,
534
+ (match, char) => {
535
+ switch (char) {
536
+ case 'n':
537
+ return '\n';
538
+ case 't':
539
+ return '\t';
540
+ case 'r':
541
+ return '\r';
542
+ case '\\':
543
+ return '\\';
544
+ default:
545
+ return match;
546
+ }
547
+ }
548
+ );
549
+ }
550
+
551
+ const primitiveDefaultValueValidationErrorsWithoutRequired =
552
+ primitiveDefaultValueValidationErrors.filter(
553
+ (err) =>
554
+ err.code !== EntityInstanceErrorCode.MissingRequiredValue
555
+ );
556
+
557
+ // Do a final check to prevent the values being saved if there are validation errors or it is required and empty
558
+ if (!!primitiveDefaultValueValidationErrorsWithoutRequired.length) {
559
+ return;
560
+ }
561
+
562
+ if (
563
+ ((entity as InputMapState).declaration?.required ||
564
+ (entity as ValueDescriptorState).required ||
565
+ (entity as ArgumentDeclarationState).implements?.some(
566
+ (impl) => impl.required
567
+ )) &&
568
+ !(entity as ValueReadingEntityState).readsValue &&
569
+ checkIsEmptyValue(finalValueToSave)
570
+ ) {
571
+ // We should be able to empty a value even if it is required, so we just ignore the change
572
+ // return;
573
+ }
574
+
575
+ let storage: ChangeSet | IValueStoreClient =
576
+ props.project.localTestValues;
577
+
578
+ if (localOnlyDefault ?? onlyDefault) {
579
+ storage = props.project.logic.addChangeSet(
580
+ new ChangeSet(
581
+ props.project.logic,
582
+ ProjectState.sessionAuthor,
583
+ new Date().toISOString(),
584
+ props.entity,
585
+ false,
586
+ StateMutationAction.ModifyLiteralValue
587
+ )
588
+ );
589
+ }
590
+
591
+ const changeSet = handleLiteralValueChange(
592
+ finalValueToSave,
593
+ props.entity,
594
+ props.project.logic,
595
+ storage,
596
+ undefined,
597
+ finalRawString
598
+ );
599
+
600
+ if (!!changeSet) {
601
+ props.project.renderAndCloseChangeSet(changeSet);
602
+ } else {
603
+ props.project.emit(props.entity.id, {});
604
+ }
605
+
606
+ forceUpdate();
607
+ };
608
+
609
+ const _handleValueAsTypeChange = (
610
+ newValue: ValueAsTypeState | ValueAsTypeState[] | null,
611
+ localOnlyDefault?: boolean
612
+ ) => {
613
+ let storage: ChangeSet | IValueStoreClient =
614
+ props.project.localTestValues;
615
+
616
+ if (localOnlyDefault ?? onlyDefault) {
617
+ storage = props.project.logic.addChangeSet(
618
+ new ChangeSet(
619
+ props.project.logic,
620
+ ProjectState.sessionAuthor,
621
+ new Date().toISOString(),
622
+ props.entity,
623
+ false,
624
+ StateMutationAction.ModifyLiteralValueAsType
625
+ )
626
+ );
627
+ }
628
+
629
+ const changeSet = handleValueAsTypeChange(
630
+ newValue,
631
+ props.entity,
632
+ props.project.logic,
633
+ storage
634
+ );
635
+
636
+ if (!!changeSet) {
637
+ props.project.renderAndCloseChangeSet(changeSet);
638
+ } else {
639
+ props.project.emit(props.entity.id, {});
640
+ }
641
+
642
+ forceUpdate();
643
+ };
644
+
645
+ // Recursively unfold the inheritance tree and resolve all dependencies so we subscribe them as events
646
+ const subscribeValueInheritanceUpdates = useCallback(
647
+ (inheritanceLink: IValueInheritanceLink): (() => void) => {
648
+ // Create a stable handler
649
+ const handleInheritanceUpdate = () => {
650
+ forceUpdate();
651
+ };
652
+
653
+ const cleanupFunctions: (() => void)[] = [];
654
+
655
+ // Use a recursive inner function to gather all listeners
656
+ const subscribeRecursive = (link: IValueInheritanceLink) => {
657
+ link.sources.forEach((valueInheritanceLink) => {
658
+ if (!valueInheritanceLink) {
659
+ return;
660
+ }
661
+
662
+ const ownerId = valueInheritanceLink.valueOwner.id;
663
+ props.project.on(ownerId, handleInheritanceUpdate);
664
+ cleanupFunctions.push(() => {
665
+ props.project.off(ownerId, handleInheritanceUpdate);
666
+ });
667
+
668
+ const dataType = (
669
+ valueInheritanceLink.valueOwner as VariableDeclarationState
670
+ ).dataType;
671
+ if (dataType) {
672
+ const dataTypeId = dataType.id;
673
+ props.project.on(dataTypeId, handleInheritanceUpdate);
674
+ cleanupFunctions.push(() => {
675
+ props.project.off(
676
+ dataTypeId,
677
+ handleInheritanceUpdate
678
+ );
679
+ });
680
+ }
681
+
682
+ if (valueInheritanceLink.inheritanceLink) {
683
+ subscribeRecursive(
684
+ valueInheritanceLink.inheritanceLink
685
+ );
686
+ }
687
+ });
688
+ };
689
+
690
+ // Start the recursion
691
+ subscribeRecursive(inheritanceLink);
692
+
693
+ // Return a single function that cleans up everything
694
+ return () => {
695
+ cleanupFunctions.forEach((cleanup) => cleanup());
696
+ };
697
+ },
698
+ [props.project, forceUpdate] // Dependencies for the useCallback
699
+ );
700
+
701
+ useEffect(() => {
702
+ const handleValueOwnerUpdate = () => {
703
+ forceUpdate();
704
+ };
705
+
706
+ const handleValueUpdate = () => {
707
+ forceUpdate();
708
+ };
709
+
710
+ const handleValueStoresinitialized = () => {
711
+ forceUpdate();
712
+ };
713
+
714
+ props.project.on(props.entity.id, handleValueOwnerUpdate);
715
+
716
+ if (props.entity.type === EntityType.InputMap) {
717
+ let relevantParent = props.entity.parent;
718
+
719
+ if (
720
+ relevantParent &&
721
+ relevantParent.type === EntityType.VariableInstance
722
+ ) {
723
+ relevantParent = relevantParent.declaration;
724
+ }
725
+
726
+ if (relevantParent) {
727
+ props.project.on(relevantParent.id, handleValueOwnerUpdate);
728
+ }
729
+ }
730
+
731
+ // Call the recursive subscription and store its cleanup function
732
+ let inheritanceCleanup: (() => void) | null = null;
733
+ if (dynamicValue?.inheritanceLink) {
734
+ inheritanceCleanup = subscribeValueInheritanceUpdates(
735
+ dynamicValue.inheritanceLink
736
+ );
737
+ }
738
+
739
+ props.project.on(
740
+ 'value-stores-initialized',
741
+ handleValueStoresinitialized
742
+ );
743
+
744
+ return () => {
745
+ props.project.off(props.entity.id, handleValueOwnerUpdate);
746
+
747
+ if (props.entity.type === EntityType.InputMap) {
748
+ let relevantParent = props.entity.parent;
749
+
750
+ if (
751
+ relevantParent &&
752
+ relevantParent.type === EntityType.VariableInstance
753
+ ) {
754
+ relevantParent = relevantParent.declaration;
755
+ }
756
+
757
+ if (relevantParent) {
758
+ props.project.off(
759
+ relevantParent.id,
760
+ handleValueOwnerUpdate
761
+ );
762
+ }
763
+ }
764
+
765
+ // Call the recursive cleanup function
766
+ if (inheritanceCleanup) {
767
+ inheritanceCleanup();
768
+ }
769
+
770
+ props.project.off(
771
+ 'value-stores-initialized',
772
+ handleValueStoresinitialized
773
+ );
774
+ };
775
+ }, [
776
+ props.project,
777
+ props.entity.id,
778
+ dynamicValue, // Rerun if the resolved dynamicValue changes
779
+ subscribeValueInheritanceUpdates, // The stable useCallback function
780
+ updateKey
781
+ ]);
782
+
783
+ useEffect(() => {
784
+ let cleanup: () => void;
785
+
786
+ if (inputRef.current) {
787
+ const dialog = document.getElementById('dialog-card');
788
+
789
+ cleanup = onClickAway(
790
+ inputRef.current,
791
+ () => {
792
+ setIsEditingValue(false);
793
+ setPreferedLocalType(null);
794
+
795
+ if (props.canvasElement) {
796
+ props.canvasElement.draggableObject.deletable = true;
797
+ props.canvasElement.draggableObject.selectable = true;
798
+ }
799
+
800
+ _handleLiteralValueChange(
801
+ primitiveDefaultValueLocal,
802
+ preferedLocalType === DynamicValueTypes.DefaultValue
803
+ );
804
+ },
805
+ document.body,
806
+ dialog
807
+ );
808
+ }
809
+
810
+ return () => {
811
+ if (cleanup) {
812
+ cleanup();
813
+ }
814
+
815
+ if (props.canvasElement) {
816
+ props.canvasElement.draggableObject.deletable = true;
817
+ props.canvasElement.draggableObject.selectable = true;
818
+ }
819
+ };
820
+ }, [inputRef.current, primitiveDefaultValueLocal, isEditingValue]);
821
+
822
+ useEffect(() => {
823
+ if (!isEditingValue) {
824
+ setPrimitiveDefaultValueLocal(
825
+ (dynamicValue?.value?.value as string) ?? ''
826
+ );
827
+ }
828
+ }, [dynamicValue?.value?.value, isEditingValue]);
829
+
830
+ useEffect(() => {
831
+ // listen to "enter" and "escape" key to save the value
832
+ const handleKeyDown = (e: KeyboardEvent) => {
833
+ if (e.key === 'Enter' && e.shiftKey) {
834
+ return;
835
+ }
836
+ if ((e.key === 'Enter' || e.key === 'Escape') && isEditingValue) {
837
+ setIsEditingValue(false);
838
+ setPreferedLocalType(null);
839
+
840
+ if (props.canvasElement) {
841
+ props.canvasElement.draggableObject.deletable = true;
842
+ props.canvasElement.draggableObject.selectable = true;
843
+ }
844
+
845
+ if (e.key === 'Enter' && inputRef.current) {
846
+ _handleLiteralValueChange(
847
+ primitiveDefaultValueLocal,
848
+ preferedLocalType === DynamicValueTypes.DefaultValue
849
+ );
850
+ } else if (e.key === 'Escape') {
851
+ setPrimitiveDefaultValueLocal(
852
+ (dynamicValue?.value?.value as string) ?? ''
853
+ );
854
+ }
855
+ }
856
+ };
857
+
858
+ if (isEditingValue) {
859
+ document.addEventListener('keydown', handleKeyDown);
860
+ }
861
+
862
+ return () => {
863
+ document.removeEventListener('keydown', handleKeyDown);
864
+
865
+ if (props.canvasElement) {
866
+ props.canvasElement.draggableObject.deletable = true;
867
+ props.canvasElement.draggableObject.selectable = true;
868
+ }
869
+ };
870
+ }, [isEditingValue, primitiveDefaultValueLocal]);
871
+
872
+ useEffect(() => {
873
+ if (inputRef.current && document.activeElement !== inputRef.current) {
874
+ inputRef.current.focus();
875
+ }
876
+
877
+ props.canvasElement?.draggableObject?.updateConnections();
878
+ });
879
+
880
+ // Set a flag on the event during the capture phase to prevent double clicks and drags from bubbling to canvas
881
+ useEffect(() => {
882
+ if (!isEditingValue) return;
883
+
884
+ const ids = [
885
+ getCanvasEntityDOMId(entity) + '--input',
886
+ getCanvasEntityDOMId(entity) + '--enum-select',
887
+ getCanvasEntityDOMId(entity) + '--enum-list-autocomplete',
888
+ getCanvasEntityDOMId(entity) +
889
+ '--value-as-type-single-autocomplete',
890
+ getCanvasEntityDOMId(entity) + '--value-as-type-list-autocomplete'
891
+ ];
892
+
893
+ let els: HTMLElement[] = [];
894
+
895
+ const flagEvent = (e: MouseEvent) => {
896
+ (e as any).__canvasIgnore = true;
897
+ };
898
+
899
+ // Elements should be available in the DOM when this effect runs
900
+ els = ids
901
+ .map((id) => document.getElementById(id))
902
+ .filter(Boolean) as HTMLElement[];
903
+
904
+ els.forEach((el) => {
905
+ el.addEventListener('dblclick', flagEvent, true);
906
+ el.addEventListener('mousedown', flagEvent, true);
907
+ });
908
+
909
+ return () => {
910
+ els.forEach((el) => {
911
+ el.removeEventListener('dblclick', flagEvent, true);
912
+ el.removeEventListener('mousedown', flagEvent, true);
913
+ });
914
+ };
915
+ }, [isEditingValue, entity]);
916
+
917
+ if (isEditingValue) {
918
+ if (workingDataType.asType) {
919
+ const options = [
920
+ ...props.project.logic.entities,
921
+ ...props.project.logic.getFunctionCalls(),
922
+ ...props.project.logic.getOperations(),
923
+ ...props.project.logic.functions,
924
+ ...props.project.logic.operationDeclarations,
925
+ ...props.project.logic.loopDeclarations,
926
+ ...props.project.logic.conditionDeclarations
927
+ ].filter((ent) => {
928
+ if (ent.id === workingDataType.entity?.id) {
929
+ return true;
930
+ }
931
+
932
+ if (
933
+ !!workingDataType.entity &&
934
+ ent.type !== EntityType.DefinitionEntity
935
+ ) {
936
+ return false;
937
+ }
938
+
939
+ if (
940
+ ent.type === EntityType.DefinitionEntity &&
941
+ workingDataType.entity?.type ===
942
+ EntityType.BuiltInBaseEntity &&
943
+ !checkHasBaseEntity(ent, workingDataType.entity.name)
944
+ ) {
945
+ return false;
946
+ }
947
+
948
+ if (workingDataType.staticEntities) {
949
+ if (
950
+ ent.type !== EntityType.DefinitionEntity ||
951
+ !ent.static
952
+ ) {
953
+ return false;
954
+ }
955
+ }
956
+
957
+ if (workingDataType.interactiveEntities) {
958
+ if (
959
+ ent.type !== EntityType.DefinitionEntity ||
960
+ !ent.interactive
961
+ ) {
962
+ return false;
963
+ }
964
+ }
965
+
966
+ if (workingDataType.actionEntities) {
967
+ if (ent.type === EntityType.DefinitionEntity) {
968
+ return false;
969
+ }
970
+ }
971
+
972
+ return true;
973
+ });
974
+
975
+ if (workingDataType.isList || workingDataType.isList === null) {
976
+ return (
977
+ <ListValueAsTypeAutocomplete
978
+ id={
979
+ getCanvasEntityDOMId(entity) +
980
+ '--value-as-type-list-autocomplete'
981
+ }
982
+ entity={entity}
983
+ options={options}
984
+ dynamicValue={dynamicValue}
985
+ popupPlacement={props.popupPlacement || 'bottom-end'}
986
+ project={props.project}
987
+ onChange={(newValue) => {
988
+ _handleValueAsTypeChange(
989
+ newValue,
990
+ preferedLocalType ===
991
+ DynamicValueTypes.DefaultValue
992
+ );
993
+ }}
994
+ name={name}
995
+ />
996
+ );
997
+ } else {
998
+ return (
999
+ <SingleValueAsTypeAutocomplete
1000
+ id={
1001
+ getCanvasEntityDOMId(entity) +
1002
+ '--value-as-type-single-autocomplete'
1003
+ }
1004
+ options={options}
1005
+ dynamicValue={dynamicValue}
1006
+ popupPlacement={props.popupPlacement || 'bottom-end'}
1007
+ project={props.project}
1008
+ onChange={(newValue) => {
1009
+ _handleValueAsTypeChange(
1010
+ newValue,
1011
+ preferedLocalType ===
1012
+ DynamicValueTypes.DefaultValue
1013
+ );
1014
+
1015
+ setIsEditingValue(false);
1016
+ setPreferedLocalType(null);
1017
+ }}
1018
+ name={name}
1019
+ />
1020
+ );
1021
+ }
1022
+ } else if (workingDataType.entity?.name === PrimitiveTypes.Enum) {
1023
+ if (workingDataType.isList) {
1024
+ // Multi-select
1025
+ return (
1026
+ <Autocomplete
1027
+ fullWidth
1028
+ multiple
1029
+ id={
1030
+ getCanvasEntityDOMId(entity) +
1031
+ '--enum-list-autocomplete'
1032
+ }
1033
+ options={workingDataType.options || []}
1034
+ disableCloseOnSelect
1035
+ value={(dynamicValue.value?.value as string[]) || []}
1036
+ isOptionEqualToValue={(option, value) =>
1037
+ option === value
1038
+ }
1039
+ getOptionLabel={(option) => option}
1040
+ renderOption={(fieldProps, option) => {
1041
+ const { key, ...optionProps } = fieldProps;
1042
+ const current =
1043
+ (dynamicValue.value?.value as string[]) || [];
1044
+ return (
1045
+ <Box
1046
+ component="li"
1047
+ sx={{ '& > img': { mr: 2, flexShrink: 0 } }}
1048
+ {...optionProps}
1049
+ key={key}
1050
+ >
1051
+ <Checkbox
1052
+ icon={icon}
1053
+ checkedIcon={checkedIcon}
1054
+ style={{ marginRight: 8 }}
1055
+ checked={current.includes(option)}
1056
+ />
1057
+ {option}
1058
+ </Box>
1059
+ );
1060
+ }}
1061
+ renderTags={(selected) => (
1062
+ <Stack gap={1} direction="row" flexWrap="wrap">
1063
+ {selected.map((value) => (
1064
+ <Chip
1065
+ key={value}
1066
+ label={value}
1067
+ onDelete={() => {
1068
+ const current =
1069
+ (dynamicValue.value
1070
+ ?.value as string[]) || [];
1071
+ _handleLiteralValueChange(
1072
+ current.filter(
1073
+ (v) => v !== value
1074
+ ),
1075
+ preferedLocalType ===
1076
+ DynamicValueTypes.DefaultValue
1077
+ );
1078
+ }}
1079
+ deleteIcon={
1080
+ <CancelIcon
1081
+ onMouseDown={(event) =>
1082
+ event.stopPropagation()
1083
+ }
1084
+ />
1085
+ }
1086
+ />
1087
+ ))}
1088
+ </Stack>
1089
+ )}
1090
+ onChange={(_, newValue) => {
1091
+ // de-dupe just in case
1092
+ const sanitized = newValue.filter(
1093
+ (v, i, a) => a.indexOf(v) === i
1094
+ );
1095
+ _handleLiteralValueChange(
1096
+ sanitized,
1097
+ preferedLocalType ===
1098
+ DynamicValueTypes.DefaultValue
1099
+ );
1100
+ }}
1101
+ renderInput={(params) => (
1102
+ <TextField
1103
+ {...params}
1104
+ variant="outlined"
1105
+ label={name}
1106
+ placeholder="Select values"
1107
+ size="small"
1108
+ />
1109
+ )}
1110
+ />
1111
+ );
1112
+ } else {
1113
+ return (
1114
+ <FormControl fullWidth>
1115
+ <InputLabel
1116
+ id={getCanvasEntityDOMId(entity) + '--enum-label'}
1117
+ >
1118
+ {name}
1119
+ </InputLabel>
1120
+ <Select
1121
+ size="small"
1122
+ // ref={inputRef}
1123
+ labelId={
1124
+ getCanvasEntityDOMId(entity) + '--enum-label'
1125
+ }
1126
+ id={getCanvasEntityDOMId(entity) + '--enum-select'}
1127
+ value={(dynamicValue?.value?.value as string) || ''}
1128
+ label={name}
1129
+ // Confirm value icon button
1130
+ inputProps={{
1131
+ endAdornment: (
1132
+ <InputAdornment position="end">
1133
+ <IconButton
1134
+ aria-label={'confirm value'}
1135
+ onClick={() => {
1136
+ setIsEditingValue(false);
1137
+ setPreferedLocalType(null);
1138
+ }}
1139
+ edge="end"
1140
+ className="dynamic-value-entry__confirm-value-button"
1141
+ style={{
1142
+ backgroundColor:
1143
+ 'var(--color-main-success)',
1144
+ width: 26,
1145
+ color: 'white',
1146
+ height: 26,
1147
+ marginRight: 2
1148
+ }}
1149
+ >
1150
+ <CheckIcon />
1151
+ </IconButton>
1152
+ </InputAdornment>
1153
+ )
1154
+ }}
1155
+ onChange={(e) => {
1156
+ _handleLiteralValueChange(
1157
+ e.target.value as string,
1158
+ preferedLocalType ===
1159
+ DynamicValueTypes.DefaultValue
1160
+ );
1161
+
1162
+ setIsEditingValue(false);
1163
+ setPreferedLocalType(null);
1164
+ }}
1165
+ onBlur={(e) => {
1166
+ setIsEditingValue(false);
1167
+ setPreferedLocalType(null);
1168
+ }}
1169
+ >
1170
+ {workingDataType.options.map((option) => (
1171
+ <MenuItem key={option} value={option}>
1172
+ {option}
1173
+ </MenuItem>
1174
+ ))}
1175
+ </Select>
1176
+ </FormControl>
1177
+ );
1178
+ }
1179
+ } else if (workingDataType.entity.name === PrimitiveTypes.UUID) {
1180
+ const hasHelperText =
1181
+ !!(
1182
+ ((entity as InputMapState).declaration?.required ||
1183
+ (entity as ValueDescriptorState).required ||
1184
+ (entity as ArgumentDeclarationState).implements?.some(
1185
+ (impl) => impl.required
1186
+ )) &&
1187
+ !(entity as ValueReadingEntityState).readsValue &&
1188
+ !checkIsEmptyValue(primitiveDefaultValueLocal)
1189
+ ) || !!primitiveDefaultValueValidationErrors.length;
1190
+
1191
+ return (
1192
+ <FormControl fullWidth>
1193
+ <InputLabel
1194
+ id={getCanvasEntityDOMId(entity) + '--input-label'}
1195
+ >
1196
+ {name}
1197
+ </InputLabel>
1198
+ <OutlinedInput
1199
+ maxRows={4}
1200
+ ref={inputRef}
1201
+ fullWidth
1202
+ autoFocus
1203
+ endAdornment={
1204
+ <InputAdornment position="end">
1205
+ <IconButton
1206
+ aria-label={'confirm value'}
1207
+ disabled={
1208
+ !!(
1209
+ false
1210
+ // ((entity as InputMapState).declaration?.required ||
1211
+ // (entity as ValueDescriptorState).required ||
1212
+ // (entity as ArgumentDeclarationState).implements?.some(
1213
+ // (impl) => impl.required
1214
+ // )) &&
1215
+ // !(entity as ValueReadingEntityState).readsValue &&
1216
+ // !checkIsEmptyValue(primitiveDefaultValueLocal)
1217
+ ) ||
1218
+ !!primitiveDefaultValueValidationErrors.filter(
1219
+ (err) =>
1220
+ err.code !==
1221
+ EntityInstanceErrorCode.MissingRequiredValue
1222
+ ).length
1223
+ }
1224
+ onClick={() => {
1225
+ _handleLiteralValueChange(
1226
+ primitiveDefaultValueLocal,
1227
+ preferedLocalType ===
1228
+ DynamicValueTypes.DefaultValue
1229
+ );
1230
+
1231
+ setIsEditingValue(false);
1232
+ setPreferedLocalType(null);
1233
+ }}
1234
+ edge="end"
1235
+ className="dynamic-value-entry__confirm-value-button"
1236
+ style={{
1237
+ backgroundColor:
1238
+ !!(
1239
+ false
1240
+ // ((entity as InputMapState).declaration?.required ||
1241
+ // (entity as ValueDescriptorState).required ||
1242
+ // (entity as ArgumentDeclarationState).implements?.some(
1243
+ // (impl) => impl.required
1244
+ // )) &&
1245
+ // !(entity as ValueReadingEntityState).readsValue &&
1246
+ // !checkIsEmptyValue(primitiveDefaultValueLocal)
1247
+ ) ||
1248
+ !!primitiveDefaultValueValidationErrors.filter(
1249
+ (err) =>
1250
+ err.code !==
1251
+ EntityInstanceErrorCode.MissingRequiredValue
1252
+ ).length
1253
+ ? 'rgba(0,0,0,0.12)'
1254
+ : 'var(--color-main-success)',
1255
+ cursor:
1256
+ !!(
1257
+ false
1258
+ // ((entity as InputMapState).declaration?.required ||
1259
+ // (entity as ValueDescriptorState).required ||
1260
+ // (entity as ArgumentDeclarationState).implements?.some(
1261
+ // (impl) => impl.required
1262
+ // )) &&
1263
+ // !(entity as ValueReadingEntityState).readsValue &&
1264
+ // !checkIsEmptyValue(primitiveDefaultValueLocal)
1265
+ ) ||
1266
+ !!primitiveDefaultValueValidationErrors.filter(
1267
+ (err) =>
1268
+ err.code !==
1269
+ EntityInstanceErrorCode.MissingRequiredValue
1270
+ ).length
1271
+ ? 'not-allowed'
1272
+ : 'pointer',
1273
+ width: 26,
1274
+ color: 'white',
1275
+ height: 26,
1276
+ marginRight: 2
1277
+ }}
1278
+ >
1279
+ <CheckIcon />
1280
+ </IconButton>
1281
+ </InputAdornment>
1282
+ }
1283
+ id={getCanvasEntityDOMId(entity) + '--input'}
1284
+ error={
1285
+ !!(
1286
+ ((entity as InputMapState).declaration
1287
+ ?.required ||
1288
+ (entity as ValueDescriptorState).required ||
1289
+ (
1290
+ entity as ArgumentDeclarationState
1291
+ ).implements?.some(
1292
+ (impl) => impl.required
1293
+ )) &&
1294
+ !(entity as ValueReadingEntityState)
1295
+ .readsValue &&
1296
+ !checkIsEmptyValue(primitiveDefaultValueLocal)
1297
+ ) || !!primitiveDefaultValueValidationErrors.length
1298
+ }
1299
+ value={primitiveDefaultValueLocal}
1300
+ onChange={(e) => {
1301
+ const sanitizedValue = castHTMLInputValueToType(
1302
+ e.target.value,
1303
+ workingDataType
1304
+ );
1305
+
1306
+ const validationResult = uuidValueValidation(
1307
+ entity,
1308
+ sanitizedValue
1309
+ ) || { errors: [], override: sanitizedValue };
1310
+
1311
+ setPrimitiveDefaultValueLocal(
1312
+ validationResult.override as string
1313
+ );
1314
+ setPrimitiveDefaultValueValidationErrors(
1315
+ validationResult.errors
1316
+ );
1317
+ }}
1318
+ size="small"
1319
+ type={resolveInputTypeFromDataType(workingDataType)}
1320
+ label={name}
1321
+ />
1322
+ <FormHelperText
1323
+ id="outlined-weight-helper-text"
1324
+ error={!!primitiveDefaultValueValidationErrors.length}
1325
+ // override parent’s `user-select: none` only when there is text to select
1326
+ sx={{
1327
+ userSelect: hasHelperText
1328
+ ? 'text !important'
1329
+ : 'none',
1330
+ cursor: hasHelperText ? 'text' : 'default'
1331
+ }}
1332
+ // prevent drag on mouse-down when helper text exists
1333
+ onMouseDown={(e) => {
1334
+ if (hasHelperText) {
1335
+ e.stopPropagation();
1336
+ }
1337
+ }}
1338
+ onClick={(e) => {
1339
+ if (hasHelperText) {
1340
+ e.stopPropagation();
1341
+ }
1342
+ }}
1343
+ onMouseMove={(e) => {
1344
+ if (hasHelperText) {
1345
+ e.stopPropagation();
1346
+ }
1347
+ }}
1348
+ >
1349
+ {!!(
1350
+ ((entity as InputMapState).declaration?.required ||
1351
+ (entity as ValueDescriptorState).required ||
1352
+ (
1353
+ entity as ArgumentDeclarationState
1354
+ ).implements?.some((impl) => impl.required)) &&
1355
+ !(entity as ValueReadingEntityState).readsValue &&
1356
+ checkIsEmptyValue(primitiveDefaultValueLocal)
1357
+ )
1358
+ ? 'This field is required'
1359
+ : ''}
1360
+ {!!primitiveDefaultValueValidationErrors.length
1361
+ ? primitiveDefaultValueValidationErrors
1362
+ .map((err) =>
1363
+ translateLogicErrorCode(err as any)
1364
+ )
1365
+ .join('. ')
1366
+ : ''}
1367
+ </FormHelperText>
1368
+ </FormControl>
1369
+ );
1370
+ }
1371
+
1372
+ const hasHelperText =
1373
+ !!(
1374
+ ((entity as InputMapState).declaration?.required ||
1375
+ (entity as ValueDescriptorState).required ||
1376
+ (entity as ArgumentDeclarationState).implements?.some(
1377
+ (impl) => impl.required
1378
+ )) &&
1379
+ !(entity as ValueReadingEntityState).readsValue &&
1380
+ checkIsEmptyValue(primitiveDefaultValueLocal)
1381
+ ) || !!primitiveDefaultValueValidationErrors.length;
1382
+
1383
+ return (
1384
+ <FormControl fullWidth>
1385
+ <InputLabel id={getCanvasEntityDOMId(entity) + '--input-label'}>
1386
+ {name}
1387
+ </InputLabel>
1388
+ <OutlinedInput
1389
+ multiline={
1390
+ workingDataType?.entity?.name === PrimitiveTypes.String
1391
+ }
1392
+ maxRows={4}
1393
+ ref={inputRef}
1394
+ fullWidth
1395
+ autoFocus
1396
+ endAdornment={
1397
+ <InputAdornment position="end">
1398
+ {workingDataType?.entity?.name ===
1399
+ PrimitiveTypes.String && (
1400
+ <IconButton
1401
+ aria-label={'expand string editor'}
1402
+ onClick={(e) => {
1403
+ e.stopPropagation();
1404
+ props.project.events.emit(
1405
+ 'string-editor-dialog-open',
1406
+ {
1407
+ value:
1408
+ dynamicValue?.value || null,
1409
+ valueOwner: entity,
1410
+ valueType: dynamicValue?.type,
1411
+ draggableObject:
1412
+ props.canvasElement
1413
+ ?.draggableObject,
1414
+ project: props.project,
1415
+ onlyDefault:
1416
+ preferedLocalType ===
1417
+ DynamicValueTypes.DefaultValue ||
1418
+ onlyDefault
1419
+ }
1420
+ );
1421
+ setIsEditingValue(false);
1422
+ setPreferedLocalType(null);
1423
+ }}
1424
+ >
1425
+ <FullscreenIcon />
1426
+ </IconButton>
1427
+ )}
1428
+ <IconButton
1429
+ aria-label={'confirm value'}
1430
+ disabled={
1431
+ !!(
1432
+ false
1433
+ // ((entity as InputMapState).declaration?.required ||
1434
+ // (entity as ValueDescriptorState).required ||
1435
+ // (entity as ArgumentDeclarationState).implements?.some(
1436
+ // (impl) => impl.required
1437
+ // )) &&
1438
+ // !(entity as ValueReadingEntityState).readsValue &&
1439
+ // checkIsEmptyValue(primitiveDefaultValueLocal)
1440
+ ) ||
1441
+ !!primitiveDefaultValueValidationErrors.filter(
1442
+ (err) =>
1443
+ err.code !==
1444
+ EntityInstanceErrorCode.MissingRequiredValue
1445
+ ).length
1446
+ }
1447
+ onClick={() => {
1448
+ _handleLiteralValueChange(
1449
+ primitiveDefaultValueLocal,
1450
+ preferedLocalType ===
1451
+ DynamicValueTypes.DefaultValue
1452
+ );
1453
+
1454
+ setIsEditingValue(false);
1455
+ setPreferedLocalType(null);
1456
+ }}
1457
+ edge="end"
1458
+ className="dynamic-value-entry__confirm-value-button"
1459
+ style={{
1460
+ backgroundColor:
1461
+ !!(
1462
+ false
1463
+ // ((entity as InputMapState).declaration?.required ||
1464
+ // (entity as ValueDescriptorState).required ||
1465
+ // (entity as ArgumentDeclarationState).implements?.some(
1466
+ // (impl) => impl.required
1467
+ // )) &&
1468
+ // !(entity as ValueReadingEntityState).readsValue &&
1469
+ // checkIsEmptyValue(primitiveDefaultValueLocal)
1470
+ ) ||
1471
+ !!primitiveDefaultValueValidationErrors.filter(
1472
+ (err) =>
1473
+ err.code !==
1474
+ EntityInstanceErrorCode.MissingRequiredValue
1475
+ ).length
1476
+ ? 'rgba(0,0,0,0.12)'
1477
+ : 'var(--color-main-success)',
1478
+ cursor:
1479
+ !!(
1480
+ false
1481
+ // ((entity as InputMapState).declaration?.required ||
1482
+ // (entity as ValueDescriptorState).required ||
1483
+ // (entity as ArgumentDeclarationState).implements?.some(
1484
+ // (impl) => impl.required
1485
+ // )) &&
1486
+ // !(entity as ValueReadingEntityState).readsValue &&
1487
+ // checkIsEmptyValue(primitiveDefaultValueLocal)
1488
+ ) ||
1489
+ !!primitiveDefaultValueValidationErrors.filter(
1490
+ (err) =>
1491
+ err.code !==
1492
+ EntityInstanceErrorCode.MissingRequiredValue
1493
+ ).length
1494
+ ? 'not-allowed'
1495
+ : 'pointer',
1496
+ width: 26,
1497
+ color: 'white',
1498
+ height: 26,
1499
+ marginRight: 2
1500
+ }}
1501
+ >
1502
+ <CheckIcon />
1503
+ </IconButton>
1504
+ </InputAdornment>
1505
+ }
1506
+ id={getCanvasEntityDOMId(entity) + '--input'}
1507
+ error={
1508
+ !!(
1509
+ ((entity as InputMapState).declaration?.required ||
1510
+ (entity as ValueDescriptorState).required ||
1511
+ (
1512
+ entity as ArgumentDeclarationState
1513
+ ).implements?.some((impl) => impl.required)) &&
1514
+ !(entity as ValueReadingEntityState).readsValue &&
1515
+ checkIsEmptyValue(primitiveDefaultValueLocal)
1516
+ ) || !!primitiveDefaultValueValidationErrors.length
1517
+ }
1518
+ value={castLiteralValueToHTMLInputValue(
1519
+ primitiveDefaultValueLocal,
1520
+ workingDataType
1521
+ )}
1522
+ onChange={(e) => {
1523
+ const sanitizedValue = castHTMLInputValueToType(
1524
+ e.target.value,
1525
+ workingDataType
1526
+ );
1527
+
1528
+ let valueForValidation = sanitizedValue;
1529
+ if (
1530
+ workingDataType?.entity?.type ===
1531
+ EntityType.PrimitiveEntity &&
1532
+ workingDataType.entity.name ===
1533
+ PrimitiveTypes.Number &&
1534
+ typeof sanitizedValue === 'string' &&
1535
+ sanitizedValue !== '' &&
1536
+ sanitizedValue !== '-'
1537
+ ) {
1538
+ const num = Number(sanitizedValue);
1539
+ if (!isNaN(num)) {
1540
+ valueForValidation = num;
1541
+ }
1542
+ }
1543
+
1544
+ // @ts-ignore
1545
+ const validationResult =
1546
+ entity.codeNativeValueValidation?.(
1547
+ entity,
1548
+ valueForValidation
1549
+ ) || { errors: [], override: valueForValidation };
1550
+
1551
+ setPrimitiveDefaultValueLocal(
1552
+ typeof sanitizedValue === 'string' &&
1553
+ typeof validationResult.override === 'number'
1554
+ ? sanitizedValue
1555
+ : (validationResult.override as string)
1556
+ );
1557
+ setPrimitiveDefaultValueValidationErrors(
1558
+ validationResult.errors
1559
+ );
1560
+ }}
1561
+ size="small"
1562
+ type={resolveInputTypeFromDataType(workingDataType)}
1563
+ label={name}
1564
+ />
1565
+ <FormHelperText
1566
+ id="outlined-weight-helper-text"
1567
+ error={
1568
+ !!(
1569
+ ((entity as InputMapState).declaration?.required ||
1570
+ (entity as ValueDescriptorState).required ||
1571
+ (
1572
+ entity as ArgumentDeclarationState
1573
+ ).implements?.some((impl) => impl.required)) &&
1574
+ !(entity as ValueReadingEntityState).readsValue &&
1575
+ checkIsEmptyValue(primitiveDefaultValueLocal)
1576
+ ) || !!primitiveDefaultValueValidationErrors.length
1577
+ }
1578
+ // override parent’s `user-select: none` only when there is text to select
1579
+ sx={{
1580
+ userSelect: hasHelperText ? 'text !important' : 'none',
1581
+ cursor: hasHelperText ? 'text' : 'default'
1582
+ }}
1583
+ // prevent drag on mouse-down when helper text exists
1584
+ onMouseDown={(e) => {
1585
+ if (hasHelperText) {
1586
+ e.stopPropagation();
1587
+ }
1588
+ }}
1589
+ onClick={(e) => {
1590
+ if (hasHelperText) {
1591
+ e.stopPropagation();
1592
+ }
1593
+ }}
1594
+ onMouseMove={(e) => {
1595
+ if (hasHelperText) {
1596
+ e.stopPropagation();
1597
+ }
1598
+ }}
1599
+ >
1600
+ {!!(
1601
+ ((entity as InputMapState).declaration?.required ||
1602
+ (entity as ValueDescriptorState).required ||
1603
+ (
1604
+ entity as ArgumentDeclarationState
1605
+ ).implements?.some((impl) => impl.required)) &&
1606
+ !(entity as ValueReadingEntityState).readsValue &&
1607
+ checkIsEmptyValue(primitiveDefaultValueLocal)
1608
+ )
1609
+ ? 'This field is required'
1610
+ : ''}
1611
+ {!!primitiveDefaultValueValidationErrors.length
1612
+ ? primitiveDefaultValueValidationErrors
1613
+ .map((err) => errorCodeToMessage(err.code))
1614
+ .join('. ')
1615
+ : ''}
1616
+ </FormHelperText>
1617
+ </FormControl>
1618
+ );
1619
+ }
1620
+
1621
+ const dynamicValueContent = (
1622
+ <DynamicValue
1623
+ valueOwner={entity}
1624
+ project={props.project}
1625
+ parentCanvasObject={props.canvasElement?.draggableObject}
1626
+ parentDisabledReasons={props.parentDisabledReasons}
1627
+ popupPlacement={props.popupPlacement || 'bottom'}
1628
+ onlyDefault={onlyDefault}
1629
+ onEdit={(e, type) => {
1630
+ if (props.parentDisabledReasons.length) {
1631
+ return;
1632
+ }
1633
+
1634
+ e.stopPropagation();
1635
+ e.preventDefault();
1636
+
1637
+ let localOnlyDefault =
1638
+ type === DynamicValueTypes.DefaultValue || onlyDefault;
1639
+
1640
+ if (
1641
+ entity.type === EntityType.Property &&
1642
+ (entity as any).implements?.find?.(
1643
+ (impl: any) =>
1644
+ impl.id ===
1645
+ BUILT_IN_BASE_ENTITY_IDS['built-in-base-entity']
1646
+ .BUILT_IN_CRON_JOB_ENTITY.properties.expression
1647
+ .id
1648
+ )
1649
+ ) {
1650
+ props.project.emit('cron-builder-dialog-open', {
1651
+ value: dynamicValue?.value || null,
1652
+ valueOwner: entity,
1653
+ valueType: dynamicValue?.type,
1654
+ draggableObject: props.canvasElement?.draggableObject,
1655
+ project: props.project,
1656
+ onlyDefault: localOnlyDefault
1657
+ });
1658
+ return;
1659
+ }
1660
+
1661
+ // If the value requires an inline input, like date, number, string, etc, then we should open the input
1662
+ // Otherwise we should open the value editor for the respective data type
1663
+ if (
1664
+ (!workingDataType ||
1665
+ !workingDataType.entity ||
1666
+ (workingDataType.isList &&
1667
+ workingDataType.entity?.name !==
1668
+ PrimitiveTypes.Enum) ||
1669
+ workingDataType?.entity?.name ===
1670
+ PrimitiveTypes.Untyped ||
1671
+ workingDataType?.entity?.name ===
1672
+ PrimitiveTypes.KeyValue) &&
1673
+ !workingDataType?.asType
1674
+ ) {
1675
+ // Open the value editor
1676
+ props.project.emit('json-editor-dialog-open', {
1677
+ value: dynamicValue?.value || null,
1678
+ valueOwner: entity,
1679
+ valueType: dynamicValue?.type,
1680
+ draggableObject: props.canvasElement?.draggableObject,
1681
+ project: props.project,
1682
+ onlyDefault: localOnlyDefault
1683
+ });
1684
+ return;
1685
+ } else if (
1686
+ workingDataType?.entity?.type ===
1687
+ EntityType.DefinitionEntity
1688
+ ) {
1689
+ // If it is a persisted entity, open the dialog with the database client
1690
+ const lowestDefinitionEntity =
1691
+ getExtendedDefinitionEntity(workingDataType?.entity) ||
1692
+ workingDataType?.entity;
1693
+ const baseTypes =
1694
+ flattenDefinitionEntityExtensionAndImplementationTypes(
1695
+ lowestDefinitionEntity
1696
+ );
1697
+
1698
+ if (
1699
+ !workingDataType?.asType &&
1700
+ checkHasBaseEntity(
1701
+ workingDataType?.entity,
1702
+ BaseEntityNames.PERSISTED_ENTITY
1703
+ )
1704
+ ) {
1705
+ if (localOnlyDefault) {
1706
+ popupNotification({
1707
+ text: 'You cannot edit the default value of a persisted entity.',
1708
+ color: 'warning',
1709
+ delay: 3000
1710
+ });
1711
+ return;
1712
+ } else {
1713
+ EditorService.navigate(
1714
+ resolvePersistedDefinitionEntityDatabaseDialogAbsolutePath(
1715
+ props.project,
1716
+ workingDataType?.entity,
1717
+ workingDataType.isList
1718
+ ? TestDatabaseDialogMode.SelectMultipleFromFixedTable
1719
+ : TestDatabaseDialogMode.SelectSingleFromFixedTable
1720
+ ) + `&valueOwner=${entity.id}`
1721
+ );
1722
+ return;
1723
+ }
1724
+ } else if (
1725
+ checkHasBaseEntity(
1726
+ workingDataType?.entity,
1727
+ BaseEntityNames.EXTERNAL_INTEGRATION_CONNECTION
1728
+ )
1729
+ ) {
1730
+ let integrationName: string | null = null;
1731
+
1732
+ // Resolve the integration name
1733
+ if (!!dynamicValue.value?.valueAsType) {
1734
+ const connectionConfigEntity = dynamicValue.value
1735
+ ?.valueAsType as DefinitionEntityState;
1736
+ const providerProperty =
1737
+ connectionConfigEntity.properties.find((p) =>
1738
+ p.implements.find(
1739
+ (impl) =>
1740
+ impl.id ===
1741
+ BUILT_IN_BASE_ENTITY_IDS[
1742
+ 'built-in-base-entity'
1743
+ ]
1744
+ .BUILT_IN_EXTERNAL_INTEGRATION_CONNECTION_ENTITY
1745
+ .properties.integration.id
1746
+ )
1747
+ );
1748
+
1749
+ const integrationNameValue =
1750
+ providerProperty?.getDefaultValue()?.value;
1751
+
1752
+ if (integrationNameValue) {
1753
+ integrationName =
1754
+ integrationNameValue as string;
1755
+ }
1756
+ }
1757
+
1758
+ if (
1759
+ !integrationName &&
1760
+ entity.type === EntityType.InputMap &&
1761
+ getParentCallableEntity(entity)?.type ===
1762
+ EntityType.Operation
1763
+ ) {
1764
+ // Get the integration name from the parent operation
1765
+ const externalIntegrationId =
1766
+ getExternalIntegrationIdFromAction(
1767
+ getParentCallableEntity(
1768
+ entity
1769
+ ) as OperationState
1770
+ );
1771
+
1772
+ if (externalIntegrationId) {
1773
+ integrationName = externalIntegrationId;
1774
+ }
1775
+ }
1776
+
1777
+ if (!integrationName) {
1778
+ popupNotification({
1779
+ text: 'No external integration could be found to edit this value.',
1780
+ color: 'warning',
1781
+ delay: 3000
1782
+ });
1783
+ return;
1784
+ }
1785
+
1786
+ if (integrationName) {
1787
+ // popupNotification({
1788
+ // text: 'External integration: ' + integrationName,
1789
+ // color: 'success',
1790
+ // delay: 3000,
1791
+ // });
1792
+
1793
+ // Open the external integrations' connection dialog
1794
+ // This will allow the user to connect to the external integration
1795
+ // Or choose an existing connection
1796
+ // The connection will set as the new value of the dynamic value
1797
+ // Navigate to external-integration-connections/:valueOwnerId
1798
+ EditorService.navigate(
1799
+ `external-integration-connections/${
1800
+ entity.id
1801
+ }?integrationName=${integrationName}${
1802
+ localOnlyDefault ? '&onlyDefault=true' : ''
1803
+ }`
1804
+ );
1805
+ // props.project.integrationsService.connect(integrationName);
1806
+
1807
+ return;
1808
+ }
1809
+ } else if (!baseTypes.length) {
1810
+ props.project.emit('json-editor-dialog-open', {
1811
+ value: dynamicValue?.value || null,
1812
+ valueOwner: entity,
1813
+ valueType: dynamicValue?.type,
1814
+ draggableObject:
1815
+ props.canvasElement?.draggableObject,
1816
+ project: props.project,
1817
+ onlyDefault: localOnlyDefault
1818
+ });
1819
+ return;
1820
+ }
1821
+ } else if (
1822
+ !!workingDataType?.asType &&
1823
+ workingDataType?.entity?.type ===
1824
+ EntityType.BuiltInBaseEntity
1825
+ ) {
1826
+ if (
1827
+ checkHasBaseEntity(
1828
+ workingDataType?.entity,
1829
+ BaseEntityNames.EXTERNAL_INTEGRATION_CONNECTION
1830
+ )
1831
+ ) {
1832
+ let integrationName: string | null = null;
1833
+
1834
+ // Resolve the integration name
1835
+ if (!!dynamicValue.value?.valueAsType) {
1836
+ const connectionConfigEntity = dynamicValue.value
1837
+ ?.valueAsType as DefinitionEntityState;
1838
+ const providerProperty =
1839
+ connectionConfigEntity.properties.find((p) =>
1840
+ p.implements.find(
1841
+ (impl) =>
1842
+ impl.id ===
1843
+ BUILT_IN_BASE_ENTITY_IDS[
1844
+ 'built-in-base-entity'
1845
+ ]
1846
+ .BUILT_IN_EXTERNAL_INTEGRATION_CONNECTION_ENTITY
1847
+ .properties.integration.id
1848
+ )
1849
+ );
1850
+
1851
+ const integrationNameValue =
1852
+ providerProperty?.getDefaultValue()?.value;
1853
+
1854
+ if (integrationNameValue) {
1855
+ integrationName =
1856
+ integrationNameValue as string;
1857
+ }
1858
+ }
1859
+
1860
+ if (
1861
+ !integrationName &&
1862
+ entity.type === EntityType.InputMap &&
1863
+ getParentCallableEntity(entity)?.type ===
1864
+ EntityType.Operation
1865
+ ) {
1866
+ // Get the integration name from the parent operation
1867
+ const externalIntegrationId =
1868
+ getExternalIntegrationIdFromAction(
1869
+ getParentCallableEntity(
1870
+ entity
1871
+ ) as OperationState
1872
+ );
1873
+
1874
+ if (externalIntegrationId) {
1875
+ integrationName = externalIntegrationId;
1876
+ }
1877
+ }
1878
+
1879
+ if (!integrationName) {
1880
+ popupNotification({
1881
+ text: 'No external integration could be found to edit this value.',
1882
+ color: 'warning',
1883
+ delay: 3000
1884
+ });
1885
+ return;
1886
+ }
1887
+
1888
+ if (integrationName) {
1889
+ // popupNotification({
1890
+ // text: 'External integration: ' + integrationName,
1891
+ // color: 'success',
1892
+ // delay: 3000,
1893
+ // });
1894
+
1895
+ // Open the external integrations' connection dialog
1896
+ // This will allow the user to connect to the external integration
1897
+ // Or choose an existing connection
1898
+ // The connection will set as the new value of the dynamic value
1899
+ // Navigate to external-integration-connections/:valueOwnerId
1900
+ EditorService.navigate(
1901
+ `external-integration-connections/${
1902
+ entity.id
1903
+ }?integrationName=${integrationName}${
1904
+ localOnlyDefault ? '&onlyDefault=true' : ''
1905
+ }`
1906
+ );
1907
+ // props.project.integrationsService.connect(integrationName);
1908
+
1909
+ return;
1910
+ }
1911
+ }
1912
+ }
1913
+
1914
+ if (workingDataType.entity?.name === PrimitiveTypes.Boolean) {
1915
+ _handleLiteralValueChange(
1916
+ !dynamicValue?.value?.value,
1917
+ localOnlyDefault
1918
+ );
1919
+ return;
1920
+ }
1921
+
1922
+ if (dataType.isObject() && !dataType.asType) {
1923
+ // Open the value editor
1924
+ props.project.emit('json-editor-dialog-open', {
1925
+ value: dynamicValue?.value || null,
1926
+ valueOwner: entity,
1927
+ valueType: dynamicValue?.type,
1928
+ draggableObject: props.canvasElement?.draggableObject,
1929
+ project: props.project,
1930
+ onlyDefault: localOnlyDefault
1931
+ });
1932
+ return;
1933
+ }
1934
+
1935
+ setIsEditingValue(true);
1936
+ setPreferedLocalType(type);
1937
+
1938
+ if (props.canvasElement) {
1939
+ props.project.canvas?.unselect(
1940
+ props.canvasElement.draggableObject
1941
+ );
1942
+ props.canvasElement.draggableObject.deletable = false;
1943
+ props.canvasElement.draggableObject.selectable = false;
1944
+ }
1945
+ }}
1946
+ onDelete={(dynamicValue, e) => {
1947
+ e.stopPropagation();
1948
+
1949
+ _handleLiteralValueDelete(dynamicValue);
1950
+ }}
1951
+ />
1952
+ );
1953
+
1954
+ return <>{props.children(dynamicValueContent)}</>;
1955
+ };
1956
+
1957
+ export default DynamicValueEntry;