@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,1490 @@
1
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import {
3
+ ChangeSet,
4
+ ChangeSetEntityChangeType,
5
+ DataTypeState,
6
+ EntityId,
7
+ EntityType,
8
+ getIsInteractive,
9
+ ProjectState,
10
+ PropertyState,
11
+ resolveEntityName,
12
+ READABLE_ENTITY_TYPES,
13
+ EntityError,
14
+ propertyValidation,
15
+ translateLogicErrorCode,
16
+ EntityInstanceErrorCode,
17
+ IPropertyShallowTransfer,
18
+ lowercaseFirstLetter,
19
+ StateMutationErrorCode,
20
+ checkHasBaseEntity,
21
+ DefinitionEntityState,
22
+ BaseEntityNames,
23
+ toSentenceCase,
24
+ translateLogicErrorCodeShort,
25
+ getRecursiveParentsIds,
26
+ StateMutationAction,
27
+ } from '@elyx-code/project-logic-tree';
28
+ import {
29
+ Alert,
30
+ Autocomplete,
31
+ TextField,
32
+ Tooltip as MuiTooltip,
33
+ Box,
34
+ Checkbox,
35
+ Stack,
36
+ Collapse,
37
+ FormGroup,
38
+ FormControlLabel,
39
+ Chip,
40
+ } from '@mui/material';
41
+ import CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';
42
+ import CheckBoxIcon from '@mui/icons-material/CheckBox';
43
+ import CancelIcon from '@mui/icons-material/Cancel';
44
+ import { EditorService } from '../../../services/editor';
45
+ import DataTypeBuilder, {
46
+ AllowedDataTypeListTypes,
47
+ ILiteralValueOption,
48
+ } from '../../data-type/DataTypeBuilder';
49
+ import Tooltip from '../../../lib/tooltip/Tooltip';
50
+ import Button from '../../../lib/button/Button';
51
+ import { useParams } from 'react-router-dom';
52
+ import EntityIcon from '../../entity-icon/EntityIcon';
53
+ import DynamicValueEntry from '../../dynamic-value/DynamicValueEntry';
54
+ import EntityDialogSectionHeader from '../../EntityDialogSectionHeader';
55
+ import WarningIcon from '../../../assets/warning-sign-24px.png';
56
+ import { DataTypeBuilderOption } from '../../../services/editor/utils';
57
+ import { Logger } from '@elyx-code/common-ts-utils';
58
+ import { debounce } from '../../../utils';
59
+
60
+ const icon = <CheckBoxOutlineBlankIcon fontSize='small' />;
61
+ const checkedIcon = <CheckBoxIcon fontSize='small' />;
62
+
63
+ export interface IPropertyProps {
64
+ project: EditorService;
65
+ entity?: PropertyState;
66
+ onClose?: (e: any) => void;
67
+ }
68
+
69
+ export enum PropertyErrorEnum {
70
+ NameRequired = 'name-required',
71
+ IncompleteDataType = 'incomplete-data-type',
72
+ }
73
+
74
+ export type PropertyError = PropertyErrorEnum | EntityInstanceErrorCode;
75
+
76
+ export function fromPropertyErrorToReadableMessage(
77
+ error: PropertyError | string,
78
+ ): string {
79
+ switch (error) {
80
+ case PropertyErrorEnum.NameRequired:
81
+ return 'Name is required';
82
+ case PropertyErrorEnum.IncompleteDataType:
83
+ return 'The composition of the data type is incomplete. Please fill in all required fields on each data type element.';
84
+ default:
85
+ return toSentenceCase(error);
86
+ }
87
+ }
88
+
89
+ function calculatePropertyCreationFormErrors(
90
+ entity: PropertyState,
91
+ ): (PropertyError | string)[] {
92
+ const errors: (PropertyError | string)[] = [];
93
+
94
+ if (!entity.name) {
95
+ errors.push(PropertyErrorEnum.NameRequired);
96
+ }
97
+
98
+ if (!!entity.dataType) {
99
+ if (!entity.dataType.isResolved) {
100
+ errors.push(PropertyErrorEnum.IncompleteDataType);
101
+ }
102
+
103
+ const flatErrors = (
104
+ entity.dataType.toFlat().filter((child) => {
105
+ if (child.type === EntityType.DataType) {
106
+ if (child.id === entity.dataType.id) {
107
+ // This is the root data type, skip
108
+ return true;
109
+ }
110
+
111
+ const allParentsOfNestedDT = getRecursiveParentsIds(child);
112
+
113
+ if (allParentsOfNestedDT.includes(entity.dataType.id)) {
114
+ // This is a nested data type that creates a circular reference
115
+ return true;
116
+ } else {
117
+ return false;
118
+ }
119
+ }
120
+
121
+ return false;
122
+ }) as DataTypeState[]
123
+ ).flatMap((dt) => dt.getShallowErrors());
124
+
125
+ if (flatErrors.length > 0) {
126
+ errors.push(
127
+ ...flatErrors.map((err) => translateLogicErrorCodeShort(err)),
128
+ );
129
+ }
130
+ }
131
+
132
+ return errors;
133
+ }
134
+
135
+ // Not all entity types can have inputs with any data type
136
+ // Sometimes, like in the case of a search, the data type of its inputs can only be a primitive type or a list of primitives
137
+ // This function, given an option, will return some metadata that will help it render the option in the data type builder
138
+ export function resolveDataTypeOptionConfigForProperty(
139
+ option: DataTypeBuilderOption | ILiteralValueOption,
140
+ input: PropertyState,
141
+ ): {
142
+ disabled: boolean;
143
+ tooltip: React.ReactNode;
144
+ } {
145
+ // if (input.parent.type === EntityType.DefinitionEntity) {
146
+ // if (
147
+ // option?.type !== EntityType.PrimitiveEntity ||
148
+ // [
149
+ // PrimitiveTypes.KeyValue,
150
+ // PrimitiveTypes.Untyped,
151
+ // PrimitiveTypes.ActionDescriptor,
152
+ // PrimitiveTypes.EntityTemplate,
153
+ // ].includes(option?.name as PrimitiveTypes)
154
+ // ) {
155
+ // return {
156
+ // disabled: true,
157
+ // tooltip:
158
+ // 'Search statements can only have primitive data types as inputs',
159
+ // };
160
+ // }
161
+ // }
162
+
163
+ return {
164
+ disabled: false,
165
+ tooltip: null,
166
+ };
167
+ }
168
+
169
+ export function resolveDataTypeAsTypeConfigForProperty(input: PropertyState): {
170
+ disabled: boolean;
171
+ tooltip: React.ReactNode;
172
+ } {
173
+ // if (input.parent.type === EntityType.Search) {
174
+ // return {
175
+ // disabled: true,
176
+ // tooltip:
177
+ // 'Search statements cannot have template values as inputs, only instances of primitive data types',
178
+ // };
179
+ // }
180
+
181
+ return {
182
+ disabled: false,
183
+ tooltip: null,
184
+ };
185
+ }
186
+
187
+ export function resolveDataTypeLikeConfigForProperty(input: PropertyState): {
188
+ disabled: boolean;
189
+ tooltip: React.ReactNode;
190
+ } {
191
+ // if (input.parent.type === EntityType.Search) {
192
+ // return {
193
+ // disabled: true,
194
+ // tooltip:
195
+ // 'Search statements can only have primitive data types as inputs',
196
+ // };
197
+ // }
198
+
199
+ return {
200
+ disabled: false,
201
+ tooltip: null,
202
+ };
203
+ }
204
+
205
+ export function resolveDataTypeAsListConfigForProperty(input: PropertyState): {
206
+ allowed: AllowedDataTypeListTypes;
207
+ tooltip: React.ReactNode;
208
+ } {
209
+ // if (input.parent.type === EntityType.Search) {
210
+ // return {
211
+ // allowed: AllowedDataTypeListTypes.Flat,
212
+ // tooltip:
213
+ // 'Search statements can only have a single flat level of list values for inputs',
214
+ // };
215
+ // }
216
+
217
+ return {
218
+ allowed: AllowedDataTypeListTypes.All,
219
+ tooltip: null,
220
+ };
221
+ }
222
+
223
+ const Property: React.FC<IPropertyProps> = ({
224
+ project,
225
+ entity: _entity,
226
+ onClose,
227
+ }) => {
228
+ const [updateKey, setUpdateKey] = useState(0);
229
+ const { entityId } = useParams<{
230
+ entityType: EntityType;
231
+ entityId: EntityId;
232
+ }>();
233
+
234
+ const entity: PropertyState | null =
235
+ _entity || (project?.logic?.get(entityId) as PropertyState | null) || null;
236
+
237
+ const [dataType, _setDataType] = useState<DataTypeState | null>(
238
+ entity?.dataType || null,
239
+ );
240
+ const [entityName, setEntityName] = useState<string>(entity.name);
241
+ const [entityNameErrors, setEntityNameErrors] = useState<EntityError[]>(
242
+ propertyValidation.validatePropertyEntityName(entity),
243
+ );
244
+ const [entityDescription, setEntityDescription] = useState<string>(
245
+ entity.description,
246
+ );
247
+
248
+ const [implementsValue, setImplementsValue] = useState<
249
+ IPropertyShallowTransfer[]
250
+ >(entity.implements.map((ent) => ent.toShallowJSON()));
251
+
252
+ const [isAbstract, _setIsAbstract] = useState<boolean>(entity.abstract);
253
+ const [isStatic, _setIsStatic] = useState<boolean>(entity.static);
254
+ const [isConstant, _setIsConstant] = useState<boolean>(entity.constant);
255
+ const [isUnique, _setIsUnique] = useState<boolean>(entity.unique);
256
+ const [isRequired, _setIsRequired] = useState<boolean>(entity.required);
257
+
258
+ const [metadataSectionOpen, setMetadataSectionOpen] = useState(true);
259
+ const [dataTypeSectionOpen, setDataTypeSectionOpen] = useState(false);
260
+ const [defaultValueSectionOpen, setDefaultValueSectionOpen] = useState(false);
261
+ const [baseFunctionalitySectionOpen, setBaseFunctionalitySectionOpen] =
262
+ useState(false);
263
+ const [interactivitySectionOpen, setInteractivitySectionOpen] =
264
+ useState(false);
265
+
266
+ const setIsRequired = useCallback((value: boolean) => {
267
+ _setIsRequired(value);
268
+
269
+ const changeSet = project?.logic?.addChangeSet(
270
+ new ChangeSet(
271
+ project?.logic,
272
+ ProjectState.sessionAuthor,
273
+ new Date().toISOString(),
274
+ entity,
275
+ false,
276
+ value ? StateMutationAction.MakePropertyRequired : StateMutationAction.MakePropertyNonRequired
277
+ ),
278
+ );
279
+
280
+ entity?.metaSync({ required: value }, changeSet);
281
+
282
+ entity?.afterAllChildrenInitialized(changeSet);
283
+
284
+ project.renderAndCloseChangeSet(changeSet);
285
+ }, []);
286
+
287
+ const setIsConstant = useCallback((value: boolean) => {
288
+ _setIsConstant(value);
289
+
290
+ const changeSet = project?.logic?.addChangeSet(
291
+ new ChangeSet(
292
+ project?.logic,
293
+ ProjectState.sessionAuthor,
294
+ new Date().toISOString(),
295
+ entity,
296
+ false,
297
+ value
298
+ ? StateMutationAction.MakePropertyConstant
299
+ : StateMutationAction.MakePropertyNonConstant,
300
+ ),
301
+ );
302
+
303
+ entity?.metaSync({ constant: value }, changeSet);
304
+
305
+ entity?.afterAllChildrenInitialized(changeSet);
306
+
307
+ project.renderAndCloseChangeSet(changeSet);
308
+ }, []);
309
+
310
+ const setIsUnique = useCallback((value: boolean) => {
311
+ _setIsUnique(value);
312
+
313
+ const changeSet = project?.logic?.addChangeSet(
314
+ new ChangeSet(
315
+ project?.logic,
316
+ ProjectState.sessionAuthor,
317
+ new Date().toISOString(),
318
+ entity,
319
+ false,
320
+ value
321
+ ? StateMutationAction.MakePropertyUnique
322
+ : StateMutationAction.MakePropertyNonUnique,
323
+ ),
324
+ );
325
+
326
+ entity?.metaSync({ unique: value }, changeSet);
327
+
328
+ entity?.afterAllChildrenInitialized(changeSet);
329
+
330
+ project.renderAndCloseChangeSet(changeSet);
331
+ }, []);
332
+
333
+ const setIsStatic = useCallback((value: boolean) => {
334
+ _setIsStatic(value);
335
+
336
+ const changeSet = project?.logic?.addChangeSet(
337
+ new ChangeSet(
338
+ project?.logic,
339
+ ProjectState.sessionAuthor,
340
+ new Date().toISOString(),
341
+ entity,
342
+ false,
343
+ value
344
+ ? StateMutationAction.MakePropertyStatic
345
+ : StateMutationAction.MakePropertyNonStatic,
346
+ ),
347
+ );
348
+
349
+ entity?.metaSync({ static: value }, changeSet);
350
+
351
+ entity?.afterAllChildrenInitialized(changeSet);
352
+
353
+ project.renderAndCloseChangeSet(changeSet);
354
+ }, []);
355
+
356
+ const setIsAbstract = useCallback((value: boolean) => {
357
+ _setIsAbstract(value);
358
+
359
+ const changeSet = project?.logic?.addChangeSet(
360
+ new ChangeSet(
361
+ project?.logic,
362
+ ProjectState.sessionAuthor,
363
+ new Date().toISOString(),
364
+ entity,
365
+ false,
366
+ value
367
+ ? StateMutationAction.MakePropertyAbstract
368
+ : StateMutationAction.MakePropertyNonAbstract,
369
+ ),
370
+ );
371
+
372
+ entity?.metaSync({ abstract: value }, changeSet);
373
+
374
+ entity?.afterAllChildrenInitialized(changeSet);
375
+
376
+ project.renderAndCloseChangeSet(changeSet);
377
+ }, []);
378
+
379
+ const debouncedOnChangeName = useCallback(
380
+ debounce(
381
+ (value: string) => {
382
+ const changeSet = project?.logic?.addChangeSet(
383
+ new ChangeSet(
384
+ project?.logic,
385
+ ProjectState.sessionAuthor,
386
+ new Date().toISOString(),
387
+ entity,
388
+ false,
389
+ StateMutationAction.RenameProperty
390
+ ),
391
+ );
392
+
393
+ setUpdateKey((prev) => prev + 1);
394
+ entity?.metaSync({ name: value || null }, changeSet);
395
+
396
+ project.renderAndCloseChangeSet(changeSet);
397
+ if (changeSet.has(entity.id)) {
398
+ project.emit(entity.id, {});
399
+ }
400
+ },
401
+ 1500,
402
+ false,
403
+ ),
404
+ [],
405
+ );
406
+
407
+ const debouncedOnChangeDescription = useCallback(
408
+ debounce(
409
+ (value: string) => {
410
+ const changeSet = project?.logic?.addChangeSet(
411
+ new ChangeSet(
412
+ project?.logic,
413
+ ProjectState.sessionAuthor,
414
+ new Date().toISOString(),
415
+ entity,
416
+ false,
417
+ StateMutationAction.ChangePropertyDescription,
418
+ ),
419
+ );
420
+
421
+ setUpdateKey((prev) => prev + 1);
422
+ entity?.metaSync({ description: value || null }, changeSet);
423
+
424
+ project.renderAndCloseChangeSet(changeSet);
425
+ if (changeSet.has(entity.id)) {
426
+ project.emit(entity.id, {});
427
+ }
428
+ },
429
+ 600,
430
+ false,
431
+ ),
432
+ [],
433
+ );
434
+
435
+ const [errors, setErrors] = useState<(PropertyError | string)[]>(
436
+ calculatePropertyCreationFormErrors(entity),
437
+ );
438
+
439
+ const setDataType = (
440
+ newDataTypeEntity: DataTypeState | null,
441
+ changeSet: ChangeSet | null,
442
+ ) => {
443
+ newDataTypeEntity?.setParent(entity, changeSet);
444
+ entity?.setDataType(newDataTypeEntity, changeSet);
445
+
446
+ changeSet?.add(entity, ChangeSetEntityChangeType.Affected);
447
+
448
+ _setDataType(newDataTypeEntity);
449
+ setUpdateKey((prev) => prev + 1);
450
+
451
+ project.renderAndCloseChangeSet(changeSet);
452
+ };
453
+
454
+ useEffect(() => {
455
+ const newErrors = calculatePropertyCreationFormErrors(entity);
456
+ setErrors(newErrors);
457
+ project.emit(entity.parent.id, {});
458
+ }, [
459
+ entityName,
460
+ updateKey,
461
+ isAbstract,
462
+ isStatic,
463
+ isConstant,
464
+ isRequired,
465
+ entityName,
466
+ entityDescription,
467
+ ]);
468
+
469
+ const implementsOptions = useMemo(() => {
470
+ const options = entity.parent.implementedPropertiesFromOriginalParents;
471
+
472
+ return options.map((opt) => opt.toShallowJSON());
473
+ }, [entity.parent]);
474
+
475
+ const isFinal =
476
+ entity.defaultValue?.isFinal ||
477
+ entity.constant ||
478
+ entity.implements.some((impl) => impl.constant) ||
479
+ !getIsInteractive(entity.parent);
480
+
481
+ return (
482
+ <div
483
+ style={{
484
+ display: 'flex',
485
+ flexGrow: 1,
486
+ height: '100%',
487
+ overflowY: 'scroll',
488
+ }}
489
+ >
490
+ {/* We need the 'span' for the react ref */}
491
+ <span
492
+ style={{
493
+ maxHeight: '100%',
494
+ maxWidth: '100%',
495
+ flexGrow: 1,
496
+ height: '100%',
497
+ }}
498
+ >
499
+ <div
500
+ style={{
501
+ display: 'flex',
502
+ flexDirection: 'column',
503
+ height: '100%',
504
+ gap: '4px',
505
+ justifyContent: 'space-between',
506
+ }}
507
+ >
508
+ <span
509
+ style={{
510
+ maxWidth: '100%',
511
+ maxHeight: '100%',
512
+ overflowY: 'scroll',
513
+ display: 'flex',
514
+ flexDirection: 'column',
515
+ height: '100%',
516
+ }}
517
+ >
518
+ <section
519
+ style={{
520
+ display: 'flex',
521
+ flexDirection: 'column',
522
+ paddingBottom: metadataSectionOpen ? 20 : 0,
523
+ }}
524
+ >
525
+ <EntityDialogSectionHeader
526
+ title='Name and description'
527
+ subtitle={`Add a name and description for this ${READABLE_ENTITY_TYPES[
528
+ entity.type
529
+ ].singular.toLowerCase()}`}
530
+ hideShowSuffix='the name and description section'
531
+ open={metadataSectionOpen}
532
+ onToggle={() => setMetadataSectionOpen(!metadataSectionOpen)}
533
+ />
534
+
535
+ <Collapse in={metadataSectionOpen}>
536
+ <div
537
+ style={{
538
+ marginTop: 6,
539
+ display: 'flex',
540
+ flexDirection: 'column',
541
+ gap: 12,
542
+ marginLeft: 80,
543
+ paddingRight: 40,
544
+ }}
545
+ >
546
+ <TextField
547
+ label='Property name'
548
+ variant='outlined'
549
+ disabled={!entity.editable}
550
+ style={{ width: '50%' }}
551
+ size='small'
552
+ value={entityName || ''}
553
+ onChange={(e) => {
554
+ Logger.log('Name change: ', e.target.value);
555
+ const validationResult =
556
+ propertyValidation.validatePropertyEntityName(
557
+ entity,
558
+ e.target.value,
559
+ );
560
+
561
+ setEntityName(e.target.value);
562
+
563
+ if (!validationResult.length) {
564
+ debouncedOnChangeName(e.target.value);
565
+ }
566
+
567
+ setEntityNameErrors(validationResult);
568
+ }}
569
+ error={!!entityNameErrors.length}
570
+ helperText={
571
+ !!entityNameErrors.length
572
+ ? entityNameErrors
573
+ .map((err) => translateLogicErrorCode(err))
574
+ .join('. ')
575
+ : ''
576
+ }
577
+ />
578
+
579
+ <TextField
580
+ label='Property description'
581
+ variant='outlined'
582
+ disabled={!entity.editable}
583
+ fullWidth
584
+ multiline
585
+ minRows={3}
586
+ size='small'
587
+ value={entityDescription || ''}
588
+ onChange={(e) => {
589
+ setEntityDescription(e.target.value);
590
+ debouncedOnChangeDescription(e.target.value);
591
+ }}
592
+ />
593
+ </div>
594
+ </Collapse>
595
+ </section>
596
+
597
+ <hr
598
+ style={{
599
+ margin: '1px 0',
600
+ border: '1px solid rgba(0,0,0,0.08)',
601
+ }}
602
+ />
603
+
604
+ <section
605
+ style={{
606
+ display: 'flex',
607
+ flexDirection: 'column',
608
+ paddingBottom: baseFunctionalitySectionOpen ? 20 : 0,
609
+ }}
610
+ >
611
+ <EntityDialogSectionHeader
612
+ title='Base functionality'
613
+ subtitle='Link this property to functionality from an existing base property'
614
+ hideShowSuffix='the base functionality section'
615
+ open={baseFunctionalitySectionOpen}
616
+ onToggle={() =>
617
+ setBaseFunctionalitySectionOpen(!baseFunctionalitySectionOpen)
618
+ }
619
+ />
620
+
621
+ <Collapse in={baseFunctionalitySectionOpen}>
622
+ <div
623
+ style={{
624
+ marginTop: 6,
625
+ display: 'flex',
626
+ flexDirection: 'column',
627
+ gap: 20,
628
+ marginLeft: 80,
629
+ paddingRight: 40,
630
+ }}
631
+ >
632
+ <Autocomplete
633
+ id='implements'
634
+ multiple
635
+ disabled={!entity.editable}
636
+ options={implementsOptions}
637
+ getOptionLabel={(option) => option.name}
638
+ isOptionEqualToValue={(option, value) =>
639
+ option.id === value.id
640
+ }
641
+ value={implementsValue}
642
+ disableClearable={
643
+ !getIsInteractive(entity.parent) ||
644
+ entity.implements.some((impl) => impl.required)
645
+ }
646
+ getOptionDisabled={(option) => {
647
+ if (
648
+ option.type === EntityType.Property &&
649
+ !option.abstract
650
+ ) {
651
+ return true;
652
+ }
653
+
654
+ const alreadyImplemented =
655
+ !!entity.parent.ownDeclaredProperties.find(
656
+ (p) =>
657
+ p.id !== entity.id &&
658
+ p.implements.find((impl) => impl.id === option.id),
659
+ );
660
+
661
+ return alreadyImplemented;
662
+ }}
663
+ renderOption={(props, option, { selected }) => {
664
+ const { key, ...optionProps } = props;
665
+ const ent = project.logic.get(option.id) as PropertyState;
666
+
667
+ return (
668
+ <MuiTooltip
669
+ key={key}
670
+ title={(() => {
671
+ if (
672
+ option.type === EntityType.Property &&
673
+ !option.abstract
674
+ ) {
675
+ return 'This property is implementable';
676
+ }
677
+
678
+ const alreadyImplemented =
679
+ !!entity.parent.ownDeclaredProperties.find(
680
+ (p) =>
681
+ p.id !== entity.id &&
682
+ p.implements.find(
683
+ (impl) => impl.id === option.id,
684
+ ),
685
+ );
686
+
687
+ if (alreadyImplemented) {
688
+ return 'This base property is already implemented by another property in the current node';
689
+ }
690
+ })()}
691
+ placement='bottom'
692
+ arrow
693
+ enterDelay={
694
+ (() => {
695
+ if (
696
+ option.type === EntityType.Property &&
697
+ !option.abstract
698
+ ) {
699
+ return true;
700
+ }
701
+
702
+ const alreadyImplemented =
703
+ !!entity.parent.ownDeclaredProperties.find(
704
+ (p) =>
705
+ p.id !== entity.id &&
706
+ p.implements.find(
707
+ (impl) => impl.id === option.id,
708
+ ),
709
+ );
710
+
711
+ return alreadyImplemented;
712
+ })()
713
+ ? 100
714
+ : 400
715
+ }
716
+ leaveDelay={200}
717
+ >
718
+ <Box
719
+ component='li'
720
+ sx={{ '& > img': { mr: 2, flexShrink: 0 } }}
721
+ {...optionProps}
722
+ >
723
+ <Checkbox
724
+ icon={icon}
725
+ checkedIcon={checkedIcon}
726
+ style={{ marginRight: 8 }}
727
+ checked={
728
+ implementsValue.findIndex(
729
+ (v) => v.id === ent.id,
730
+ ) > -1
731
+ }
732
+ />
733
+ <Stack direction='row' gap={1} alignItems='center'>
734
+ <EntityIcon entity={ent} project={project} />
735
+ {resolveEntityName(ent, project.logic)}
736
+ </Stack>
737
+ </Box>
738
+ </MuiTooltip>
739
+ );
740
+ }}
741
+ renderTags={(selected) => (
742
+ <Stack gap={1} direction='row' flexWrap='wrap'>
743
+ {selected.map((value) => {
744
+ const ent = project.logic.get(
745
+ value.id,
746
+ ) as PropertyState;
747
+
748
+ return (
749
+ <MuiTooltip
750
+ title={(() => {
751
+ if (
752
+ (ent.parent.type ===
753
+ EntityType.DefinitionEntity ||
754
+ ent.parent.type ===
755
+ EntityType.BuiltInBaseEntity) &&
756
+ !ent.parent.additionalProperties
757
+ ) {
758
+ return 'This property must implement at least one base property because the parent definition doesn\'t allow additional "unrecognized" properties.';
759
+ }
760
+ return '';
761
+ })()}
762
+ placement='top'
763
+ arrow
764
+ enterDelay={100}
765
+ leaveDelay={200}
766
+ >
767
+ <Box
768
+ component='span'
769
+ sx={{ display: 'inline-block' }}
770
+ >
771
+ <Chip
772
+ avatar={
773
+ <EntityIcon
774
+ entity={ent}
775
+ style={{ marginLeft: 8 }}
776
+ size='small'
777
+ project={project}
778
+ />
779
+ }
780
+ key={value.id}
781
+ label={resolveEntityName(ent, project.logic)}
782
+ disabled={(() => {
783
+ if (
784
+ (ent.parent.type ===
785
+ EntityType.DefinitionEntity ||
786
+ ent.parent.type ===
787
+ EntityType.BuiltInBaseEntity) &&
788
+ !ent.parent.additionalProperties
789
+ ) {
790
+ return true;
791
+ }
792
+ return false;
793
+ })()}
794
+ onDelete={() => {
795
+ const changeSet =
796
+ project?.logic?.addChangeSet(
797
+ new ChangeSet(
798
+ project?.logic,
799
+ ProjectState.sessionAuthor,
800
+ new Date().toISOString(),
801
+ entity,
802
+ false,
803
+ StateMutationAction.RemovePropertyBaseImplementation,
804
+ ),
805
+ );
806
+
807
+ const fullEnt = project.logic.get(
808
+ value.id,
809
+ ) as PropertyState;
810
+
811
+ entity?.removeImplementation(
812
+ fullEnt,
813
+ changeSet,
814
+ );
815
+
816
+ changeSet.add(
817
+ entity,
818
+ ChangeSetEntityChangeType.Updated,
819
+ );
820
+
821
+ setImplementsValue(
822
+ implementsValue.filter(
823
+ (v) => v.id !== value.id,
824
+ ),
825
+ );
826
+ project.emit(entity.id, {});
827
+
828
+ project.renderAndCloseChangeSet(changeSet);
829
+ }}
830
+ deleteIcon={
831
+ <CancelIcon
832
+ onMouseDown={(event) =>
833
+ event.stopPropagation()
834
+ }
835
+ />
836
+ }
837
+ />
838
+ </Box>
839
+ </MuiTooltip>
840
+ );
841
+ })}
842
+ </Stack>
843
+ )}
844
+ onChange={(_, newValue) => {
845
+ // Filter out duplicates
846
+ const sanitizedValue = newValue.filter(
847
+ (v, i, a) => a.findIndex((t) => t.id === v.id) === i,
848
+ );
849
+
850
+ const changeSet = project?.logic?.addChangeSet(
851
+ new ChangeSet(
852
+ project?.logic,
853
+ ProjectState.sessionAuthor,
854
+ new Date().toISOString(),
855
+ entity,
856
+ false,
857
+ StateMutationAction.AddPropertyBaseImplementation,
858
+ ),
859
+ );
860
+
861
+ const existingEntities = entity.implements.map(
862
+ (ent) => ent.id,
863
+ );
864
+ const newEntities = sanitizedValue.map((ent) => ent.id);
865
+
866
+ const toAdd = newEntities.filter(
867
+ (ent) => !existingEntities.includes(ent),
868
+ );
869
+ const toRemove = existingEntities.filter((ent) => {
870
+ const currentEnt = project.logic.get(
871
+ ent,
872
+ ) as PropertyState;
873
+ if (
874
+ (currentEnt.parent.type ===
875
+ EntityType.DefinitionEntity ||
876
+ currentEnt.parent.type ===
877
+ EntityType.BuiltInBaseEntity) &&
878
+ !currentEnt.parent.additionalProperties
879
+ ) {
880
+ return false;
881
+ }
882
+
883
+ if (!newEntities.includes(ent)) {
884
+ return true;
885
+ }
886
+ });
887
+
888
+ toAdd.forEach((ent) => {
889
+ const fullEnt = project.logic.get(ent) as PropertyState;
890
+ entity?.addImplementation(fullEnt, changeSet);
891
+
892
+ changeSet.add(
893
+ entity,
894
+ ChangeSetEntityChangeType.Updated,
895
+ );
896
+ });
897
+
898
+ toRemove.forEach((ent) => {
899
+ const fullEnt = project.logic.get(ent) as PropertyState;
900
+ entity?.removeImplementation(fullEnt, changeSet);
901
+
902
+ changeSet.add(
903
+ entity,
904
+ ChangeSetEntityChangeType.Updated,
905
+ );
906
+ });
907
+
908
+ if (toAdd.length || toRemove.length) {
909
+ setImplementsValue(sanitizedValue);
910
+ entity.afterAllChildrenInitialized(changeSet);
911
+ project.emit(entity.id, {});
912
+ }
913
+
914
+ project.renderAndCloseChangeSet(changeSet);
915
+ }}
916
+ renderInput={(params) => (
917
+ <TextField
918
+ {...params}
919
+ label='Implements'
920
+ variant='outlined'
921
+ size='small'
922
+ />
923
+ )}
924
+ />
925
+ </div>
926
+ </Collapse>
927
+ </section>
928
+
929
+ <hr
930
+ style={{
931
+ margin: '1px 0',
932
+ border: '1px solid rgba(0,0,0,0.08)',
933
+ }}
934
+ />
935
+
936
+ <section
937
+ style={{
938
+ display: 'flex',
939
+ flexDirection: 'column',
940
+ paddingBottom: dataTypeSectionOpen ? 20 : 0,
941
+ }}
942
+ >
943
+ <EntityDialogSectionHeader
944
+ title='Data type'
945
+ subtitle='Select the type of data that this property will hold'
946
+ hideShowSuffix='the data type section'
947
+ open={dataTypeSectionOpen}
948
+ onToggle={() => setDataTypeSectionOpen(!dataTypeSectionOpen)}
949
+ headerStartIcon={
950
+ <EntityIcon entity={entity} project={project} />
951
+ }
952
+ />
953
+
954
+ <Collapse in={dataTypeSectionOpen}>
955
+ <div
956
+ style={{
957
+ display: 'flex',
958
+ flexDirection: 'column',
959
+ gap: 20,
960
+ marginLeft: 80,
961
+ paddingRight: 40,
962
+ }}
963
+ >
964
+ <DataTypeBuilder
965
+ project={project}
966
+ topParent={entity}
967
+ dataType={dataType}
968
+ readOnly={!entity.editable}
969
+ baseDataTypes={entity.implements.map(
970
+ (impl) => impl.dataType,
971
+ )}
972
+ onChangeSet={() => {
973
+ const newChangeSet = project.logic.addChangeSet(
974
+ new ChangeSet(
975
+ project.logic,
976
+ ProjectState.sessionAuthor,
977
+ new Date().toISOString(),
978
+ entity,
979
+ false,
980
+ StateMutationAction.ChangePropertyDataType,
981
+ ),
982
+ );
983
+
984
+ return newChangeSet;
985
+ }}
986
+ onChange={(newDataTypeEntity, changeSet) => {
987
+ setDataType(newDataTypeEntity, changeSet);
988
+ }}
989
+ lists={
990
+ resolveDataTypeAsListConfigForProperty(entity).allowed
991
+ }
992
+ getOptionDisabled={(option) =>
993
+ resolveDataTypeOptionConfigForProperty(option, entity)
994
+ .disabled
995
+ }
996
+ getListDisabledTooltip={(option) =>
997
+ resolveDataTypeAsListConfigForProperty(entity).tooltip
998
+ }
999
+ getOptionTooltip={(option) =>
1000
+ resolveDataTypeOptionConfigForProperty(option, entity)
1001
+ .tooltip
1002
+ }
1003
+ disallowAsType={
1004
+ resolveDataTypeAsTypeConfigForProperty(entity).disabled
1005
+ }
1006
+ getAsTypeDisabledTooltip={() =>
1007
+ resolveDataTypeAsTypeConfigForProperty(entity).tooltip
1008
+ }
1009
+ disallowLike={
1010
+ resolveDataTypeLikeConfigForProperty(entity).disabled
1011
+ }
1012
+ getLikeDisabledTooltip={() =>
1013
+ resolveDataTypeLikeConfigForProperty(entity).tooltip
1014
+ }
1015
+ />
1016
+ </div>
1017
+ </Collapse>
1018
+ </section>
1019
+
1020
+ <hr
1021
+ style={{
1022
+ margin: '1px 0',
1023
+ border: '1px solid rgba(0,0,0,0.08)',
1024
+ }}
1025
+ />
1026
+
1027
+ <section
1028
+ style={{
1029
+ display: 'flex',
1030
+ flexDirection: 'column',
1031
+ paddingBottom: defaultValueSectionOpen ? 20 : 0,
1032
+ }}
1033
+ >
1034
+ <EntityDialogSectionHeader
1035
+ title={isFinal ? 'Value' : 'Default value'}
1036
+ subtitle={
1037
+ isFinal
1038
+ ? 'The value of this property'
1039
+ : 'The initial value, if no other is given when the property is first used'
1040
+ }
1041
+ hideShowSuffix={
1042
+ isFinal ? 'the value section' : 'the default value section'
1043
+ }
1044
+ open={defaultValueSectionOpen}
1045
+ onToggle={() =>
1046
+ setDefaultValueSectionOpen(!defaultValueSectionOpen)
1047
+ }
1048
+ headerStartIcon={
1049
+ !!entity.errors.find(
1050
+ (error) =>
1051
+ error.code ===
1052
+ EntityInstanceErrorCode.MissingRequiredValue,
1053
+ ) ? (
1054
+ <MuiTooltip
1055
+ title='Missing required value'
1056
+ placement='top'
1057
+ arrow
1058
+ >
1059
+ <img
1060
+ style={{ width: 20, height: 20 }}
1061
+ id={'logic-error-icon--' + entity.id}
1062
+ src={WarningIcon}
1063
+ className={'warning-icon logic-error-icon'}
1064
+ />
1065
+ </MuiTooltip>
1066
+ ) : null
1067
+ }
1068
+ />
1069
+
1070
+ <Collapse in={defaultValueSectionOpen}>
1071
+ <div
1072
+ style={{
1073
+ marginTop: 6,
1074
+ display: 'flex',
1075
+ flexDirection: 'column',
1076
+ gap: 20,
1077
+ marginLeft: 80,
1078
+ paddingRight: 40,
1079
+ }}
1080
+ >
1081
+ <DynamicValueEntry
1082
+ entity={entity}
1083
+ project={project}
1084
+ parentDisabledReasons={
1085
+ !entity.editable
1086
+ ? [StateMutationErrorCode.ActionOwnerEntityNotEditable]
1087
+ : []
1088
+ }
1089
+ onlyDefault
1090
+ >
1091
+ {(extraContent) => extraContent}
1092
+ </DynamicValueEntry>
1093
+ </div>
1094
+ </Collapse>
1095
+ </section>
1096
+
1097
+ <hr
1098
+ style={{
1099
+ margin: '1px 0',
1100
+ border: '1px solid rgba(0,0,0,0.08)',
1101
+ }}
1102
+ />
1103
+
1104
+ <section
1105
+ style={{
1106
+ display: 'flex',
1107
+ flexDirection: 'column',
1108
+ paddingBottom: interactivitySectionOpen ? 20 : 0,
1109
+ }}
1110
+ >
1111
+ <EntityDialogSectionHeader
1112
+ title='Interactivity'
1113
+ subtitle='Define how this property is used in the logic'
1114
+ hideShowSuffix='the interactivity section'
1115
+ open={interactivitySectionOpen}
1116
+ onToggle={() =>
1117
+ setInteractivitySectionOpen(!interactivitySectionOpen)
1118
+ }
1119
+ />
1120
+
1121
+ <Collapse in={interactivitySectionOpen}>
1122
+ <div
1123
+ style={{
1124
+ marginTop: 6,
1125
+ display: 'flex',
1126
+ flexDirection: 'row',
1127
+ gap: 12,
1128
+ marginLeft: 80,
1129
+ paddingRight: 40,
1130
+ }}
1131
+ >
1132
+ <MuiTooltip
1133
+ title={(() => {
1134
+ const prefix = 'Cannot change interactivity, because: ';
1135
+ const reasons: string[] = [];
1136
+
1137
+ if (!!entity.parent.abstract && !!entity.abstract) {
1138
+ reasons.push(
1139
+ 'The parent definition node is a template definition',
1140
+ );
1141
+ }
1142
+ if (!entity.parent.abstract && !entity.abstract) {
1143
+ reasons.push(
1144
+ 'The parent definition node is not a template definition',
1145
+ );
1146
+ }
1147
+ if (entity.implements.some((impl) => impl.abstract)) {
1148
+ reasons.push(
1149
+ 'It must match the base property being implemented',
1150
+ );
1151
+ }
1152
+
1153
+ if (!reasons.length) {
1154
+ return '';
1155
+ }
1156
+
1157
+ return prefix + reasons.join('. ');
1158
+ })()}
1159
+ placement='bottom'
1160
+ arrow
1161
+ enterDelay={
1162
+ (!entity.parent.abstract && !entity.abstract) ||
1163
+ (!!entity.parent.abstract && !!entity.abstract) ||
1164
+ entity.implements.some((impl) => impl.abstract)
1165
+ ? 100
1166
+ : 400
1167
+ }
1168
+ leaveDelay={200}
1169
+ >
1170
+ <FormGroup>
1171
+ <FormControlLabel
1172
+ control={
1173
+ <Checkbox
1174
+ disabled={
1175
+ !entity.editable ||
1176
+ (!entity.parent.abstract && !entity.abstract) ||
1177
+ (!!entity.parent.abstract && !!entity.abstract) ||
1178
+ entity.implements.some((impl) => impl.abstract)
1179
+ }
1180
+ className='property-builder--abstract-checkbox'
1181
+ checked={isAbstract}
1182
+ onChange={(e) => {
1183
+ const value = e.target.checked;
1184
+ setIsAbstract(value);
1185
+ }}
1186
+ />
1187
+ }
1188
+ label={'Template definition'}
1189
+ />
1190
+ </FormGroup>
1191
+ </MuiTooltip>
1192
+
1193
+ <MuiTooltip
1194
+ title={
1195
+ entity.parent.static
1196
+ ? 'Cannot change interactivity, because the parent definition node is a single copy global definition'
1197
+ : entity.implements.some((impl) => impl.static)
1198
+ ? 'Cannot change interactivity, because it must match the base property being implemented'
1199
+ : ''
1200
+ }
1201
+ placement='bottom'
1202
+ arrow
1203
+ enterDelay={
1204
+ entity.parent.static ||
1205
+ entity.implements.some((impl) => impl.static)
1206
+ ? 100
1207
+ : 400
1208
+ }
1209
+ leaveDelay={200}
1210
+ >
1211
+ <FormGroup>
1212
+ <FormControlLabel
1213
+ control={
1214
+ <Checkbox
1215
+ disabled={
1216
+ !entity.editable ||
1217
+ entity.parent.static ||
1218
+ entity.implements.some((impl) => impl.static)
1219
+ }
1220
+ className='property-builder--static-checkbox'
1221
+ checked={isStatic}
1222
+ onChange={(e) => {
1223
+ const value = e.target.checked;
1224
+ setIsStatic(value);
1225
+ }}
1226
+ />
1227
+ }
1228
+ label={'Single global copy'}
1229
+ />
1230
+ </FormGroup>
1231
+ </MuiTooltip>
1232
+
1233
+ <MuiTooltip
1234
+ title={
1235
+ entity.implements.some((impl) => impl.required) &&
1236
+ !!isRequired
1237
+ ? 'Cannot change interactivity, because it must match the base property being implemented. When checked, the value of this property must be present in any representation of the parent definition-entity as a value'
1238
+ : 'When checked, the value of this property must be present in any representation of the parent definition-entity as a value'
1239
+ // 'When checked, the value of this property must be present in any representation of the parent definition-entity as a value'
1240
+ }
1241
+ placement='bottom'
1242
+ arrow
1243
+ enterDelay={
1244
+ !!entity.implements.some((impl) => impl.required)
1245
+ ? 100
1246
+ : 400
1247
+ }
1248
+ leaveDelay={200}
1249
+ >
1250
+ <FormGroup>
1251
+ <FormControlLabel
1252
+ control={
1253
+ <Checkbox
1254
+ // disabled={!entity.editable || !!entity.implements}
1255
+ // It should only be able to be made non-required if:
1256
+ // - The property is editable
1257
+ // - It does not implement any base property that is required
1258
+ disabled={
1259
+ !entity.editable ||
1260
+ (entity.implements.some(
1261
+ (impl) => impl.required,
1262
+ ) &&
1263
+ !!isRequired)
1264
+ }
1265
+ className='property-builder--required-checkbox'
1266
+ checked={isRequired}
1267
+ onChange={(e) => {
1268
+ const value = e.target.checked;
1269
+ setIsRequired(value);
1270
+ }}
1271
+ />
1272
+ }
1273
+ label={'Required'}
1274
+ />
1275
+ </FormGroup>
1276
+ </MuiTooltip>
1277
+
1278
+ <MuiTooltip
1279
+ title={
1280
+ isConstant &&
1281
+ entity.implements.some((impl) => impl.constant)
1282
+ ? 'Cannot change interactivity, because it must match the base property being implemented. Indicates whether the logic can edit an existing value, or the first value set is the only value'
1283
+ : 'Whether the logic can edit an existing value, or the first value set is the only value'
1284
+ }
1285
+ placement='bottom'
1286
+ arrow
1287
+ enterDelay={
1288
+ isConstant &&
1289
+ entity.implements.some((impl) => impl.constant)
1290
+ ? 100
1291
+ : 400
1292
+ }
1293
+ leaveDelay={200}
1294
+ >
1295
+ <FormGroup>
1296
+ <FormControlLabel
1297
+ control={
1298
+ <Checkbox
1299
+ disabled={
1300
+ !entity.editable ||
1301
+ (isConstant &&
1302
+ entity.implements.some((impl) => impl.constant))
1303
+ }
1304
+ className='property-builder--required-checkbox'
1305
+ checked={isConstant}
1306
+ onChange={(e) => {
1307
+ const value = e.target.checked;
1308
+ setIsConstant(value);
1309
+ }}
1310
+ />
1311
+ }
1312
+ label={'Editable value'}
1313
+ />
1314
+ </FormGroup>
1315
+ </MuiTooltip>
1316
+
1317
+ {checkHasBaseEntity(
1318
+ entity.parent as DefinitionEntityState,
1319
+ BaseEntityNames.PERSISTED_ENTITY,
1320
+ ) && (
1321
+ <MuiTooltip
1322
+ title={
1323
+ isUnique &&
1324
+ entity.implements.some((impl) => impl.unique)
1325
+ ? 'Cannot change interactivity, because it must match the base property being implemented. Indicates whether the logic can edit an existing value, or the first value set is the only value'
1326
+ : 'Whether the value has to be unique among all other properties of this kind'
1327
+ }
1328
+ placement='bottom'
1329
+ arrow
1330
+ enterDelay={
1331
+ isUnique &&
1332
+ entity.implements.some((impl) => impl.unique)
1333
+ ? 100
1334
+ : 400
1335
+ }
1336
+ leaveDelay={200}
1337
+ >
1338
+ <FormGroup>
1339
+ <FormControlLabel
1340
+ control={
1341
+ <Checkbox
1342
+ disabled={
1343
+ !entity.editable ||
1344
+ (isUnique &&
1345
+ entity.implements.some((impl) => impl.unique))
1346
+ }
1347
+ className='property-builder--unique-checkbox'
1348
+ checked={isUnique}
1349
+ onChange={(e) => {
1350
+ const value = e.target.checked;
1351
+ setIsUnique(value);
1352
+ }}
1353
+ />
1354
+ }
1355
+ label={'Unique'}
1356
+ />
1357
+ </FormGroup>
1358
+ </MuiTooltip>
1359
+ )}
1360
+ </div>
1361
+ </Collapse>
1362
+ </section>
1363
+ </span>
1364
+
1365
+ {errors.length > 0 && (
1366
+ <div
1367
+ style={{
1368
+ marginTop: 20,
1369
+ marginRight: 40,
1370
+ marginLeft: 80,
1371
+ }}
1372
+ >
1373
+ <Alert severity='error'>
1374
+ {errors.length === 1 ? (
1375
+ <span
1376
+ style={{
1377
+ display: 'flex',
1378
+ alignItems: 'center',
1379
+ gap: 6,
1380
+ }}
1381
+ >
1382
+ <h4
1383
+ style={{
1384
+ margin: 0,
1385
+ display: 'flex',
1386
+ }}
1387
+ >
1388
+ Error:
1389
+ </h4>
1390
+ <p
1391
+ style={{
1392
+ margin: 0,
1393
+ display: 'flex',
1394
+ }}
1395
+ >
1396
+ {fromPropertyErrorToReadableMessage(errors[0])}
1397
+ </p>
1398
+ </span>
1399
+ ) : (
1400
+ <>
1401
+ <h4
1402
+ style={{
1403
+ margin: 0,
1404
+ }}
1405
+ >
1406
+ Errors
1407
+ </h4>
1408
+ <br className='quarter-space' />
1409
+ <ul
1410
+ style={{
1411
+ listStyleType: 'none',
1412
+ padding: 0,
1413
+ }}
1414
+ >
1415
+ {errors.map((error, index) => (
1416
+ <li
1417
+ key={index}
1418
+ style={{
1419
+ display: 'flex',
1420
+ alignItems: 'center',
1421
+ }}
1422
+ >
1423
+ {/* Circle */}
1424
+ <span
1425
+ style={{
1426
+ fontSize: 10,
1427
+ marginRight: 5,
1428
+ }}
1429
+ >
1430
+ &#9679;
1431
+ </span>
1432
+ <p
1433
+ style={{
1434
+ margin: 0,
1435
+ // fontSize: 10,
1436
+ }}
1437
+ >
1438
+ {fromPropertyErrorToReadableMessage(error)}
1439
+ </p>
1440
+ </li>
1441
+ ))}
1442
+ </ul>
1443
+ </>
1444
+ )}
1445
+ </Alert>
1446
+ </div>
1447
+ )}
1448
+
1449
+ <div
1450
+ style={{
1451
+ alignSelf: 'flex-start',
1452
+ display: 'flex',
1453
+ flexDirection: 'row',
1454
+ justifyContent: 'flex-end',
1455
+ width: '100%',
1456
+ gap: '16px',
1457
+ padding: '0 40px',
1458
+ }}
1459
+ >
1460
+ <Button
1461
+ id='property--done-button'
1462
+ onClick={(e: any) => {
1463
+ onClose?.(e);
1464
+ }}
1465
+ color='primary'
1466
+ disabled={errors.length > 0}
1467
+ >
1468
+ Done
1469
+ </Button>
1470
+ <Tooltip
1471
+ anchorQuerySelector='#property--done-button'
1472
+ placement='bottom'
1473
+ openDelay={100}
1474
+ >
1475
+ {errors.length > 0
1476
+ ? `Resolve the errors to save the ${lowercaseFirstLetter(
1477
+ READABLE_ENTITY_TYPES[entity.type].singular,
1478
+ )}`
1479
+ : `Save the ${lowercaseFirstLetter(
1480
+ READABLE_ENTITY_TYPES[entity.type].singular,
1481
+ )}`}
1482
+ </Tooltip>
1483
+ </div>
1484
+ </div>
1485
+ </span>
1486
+ </div>
1487
+ );
1488
+ };
1489
+
1490
+ export default Property;