@oneuptime/common 12.0.6 → 12.0.8

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 (594) hide show
  1. package/Models/DatabaseModels/AIInsight.ts +1 -1
  2. package/Models/DatabaseModels/DatabaseBaseModel/FileModel.ts +2 -3
  3. package/Models/DatabaseModels/DeletedProject.ts +595 -0
  4. package/Models/DatabaseModels/Index.ts +2 -0
  5. package/Models/DatabaseModels/Monitor.ts +111 -0
  6. package/Models/DatabaseModels/Project.ts +3 -3
  7. package/Models/DatabaseModels/TelemetryEntity.ts +45 -0
  8. package/Models/DatabaseModels/TelemetryEntityRelationship.ts +26 -0
  9. package/Models/DatabaseModels/WorkflowLog.ts +38 -0
  10. package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +19 -1
  11. package/Server/API/FileAPI.ts +15 -2
  12. package/Server/API/MicrosoftTeamsAPI.ts +6 -1
  13. package/Server/API/ProjectAPI.ts +214 -0
  14. package/Server/API/StatusPageAPI.ts +39 -6
  15. package/Server/API/UserAPI.ts +16 -1
  16. package/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.ts +50 -0
  17. package/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.ts +67 -0
  18. package/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.ts +39 -0
  19. package/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.ts +41 -0
  20. package/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.ts +17 -0
  21. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +10 -0
  22. package/Server/Middleware/MasterAdminAuthorization.ts +11 -6
  23. package/Server/Services/AIAgentService.ts +20 -0
  24. package/Server/Services/DashboardDomainService.ts +73 -28
  25. package/Server/Services/DatabaseService.ts +1 -0
  26. package/Server/Services/DeletedProjectService.ts +138 -0
  27. package/Server/Services/FileService.ts +61 -0
  28. package/Server/Services/IncidentEpisodePublicNoteService.ts +18 -0
  29. package/Server/Services/IncidentPublicNoteService.ts +18 -0
  30. package/Server/Services/Index.ts +2 -0
  31. package/Server/Services/MonitorService.ts +311 -0
  32. package/Server/Services/ProbeService.ts +20 -0
  33. package/Server/Services/ProjectService.ts +297 -1
  34. package/Server/Services/PushNotificationService.ts +71 -0
  35. package/Server/Services/ScheduledMaintenancePublicNoteService.ts +18 -0
  36. package/Server/Services/StatusPageAnnouncementService.ts +53 -0
  37. package/Server/Services/StatusPageDomainService.ts +73 -28
  38. package/Server/Services/TeamMemberService.ts +117 -12
  39. package/Server/Services/TelemetryEntityRelationshipService.ts +3 -0
  40. package/Server/Services/TelemetryEntityService.ts +114 -1
  41. package/Server/Services/TelemetryIngestionKeyService.ts +1 -0
  42. package/Server/Services/UserWebhookService.ts +34 -109
  43. package/Server/Services/WorkspaceNotificationRuleService.ts +69 -0
  44. package/Server/Services/WorkspaceProjectAuthTokenService.ts +37 -1
  45. package/Server/Types/Database/DeleteById.ts +2 -0
  46. package/Server/Types/Database/DeleteOneBy.ts +6 -0
  47. package/Server/Types/Domain.ts +41 -0
  48. package/Server/Types/Workflow/Components/API/Delete.ts +2 -1
  49. package/Server/Types/Workflow/Components/API/Get.ts +2 -1
  50. package/Server/Types/Workflow/Components/API/Patch.ts +2 -1
  51. package/Server/Types/Workflow/Components/API/Post.ts +2 -1
  52. package/Server/Types/Workflow/Components/API/Put.ts +2 -1
  53. package/Server/Types/Workflow/Components/API/Utils.ts +85 -3
  54. package/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.ts +25 -19
  55. package/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.ts +6 -5
  56. package/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.ts +32 -14
  57. package/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.ts +31 -13
  58. package/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.ts +29 -20
  59. package/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.ts +28 -21
  60. package/Server/Types/Workflow/Components/BaseModel/LogComponentError.ts +89 -0
  61. package/Server/Types/Workflow/Components/BaseModel/ModelArguments.ts +208 -0
  62. package/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.ts +11 -0
  63. package/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.ts +41 -18
  64. package/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.ts +45 -19
  65. package/Server/Types/Workflow/Components/Discord/SendMessageToChannel.ts +16 -9
  66. package/Server/Types/Workflow/Components/IncomingWebhookUtils.ts +66 -0
  67. package/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.ts +15 -9
  68. package/Server/Types/Workflow/Components/Slack/SendMessageToChannel.ts +17 -0
  69. package/Server/Types/Workflow/TriggerCode.ts +12 -0
  70. package/Server/Types/Workflow/Workflow.ts +5 -0
  71. package/Server/Utils/AI/Chat/ObservabilityChatPrompt.ts +1 -1
  72. package/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.ts +171 -0
  73. package/Server/Utils/AI/SRE/FixFromIncidentTaskTrigger.ts +3 -3
  74. package/Server/Utils/AI/SRE/Insights/FixRouting.ts +3 -2
  75. package/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.ts +1 -1
  76. package/Server/Utils/AI/Toolbox/CodeWriteTools.ts +6 -6
  77. package/Server/Utils/CodeRepository/GitHub/GitHub.ts +43 -5
  78. package/Server/Utils/DataSource/EgressGuard.ts +176 -16
  79. package/Server/Utils/DataSource/HttpFetch.ts +6 -45
  80. package/Server/Utils/Execute.ts +8 -0
  81. package/Server/Utils/InlineImageAccessTokenSync.ts +23 -0
  82. package/Server/Utils/LLM/LLMService.ts +57 -12
  83. package/Server/Utils/Monitor/MonitorAlert.ts +40 -0
  84. package/Server/Utils/Monitor/MonitorDependencySuppression.ts +192 -0
  85. package/Server/Utils/Monitor/MonitorIncident.ts +40 -0
  86. package/Server/Utils/Monitor/MonitorResource.ts +36 -0
  87. package/Server/Utils/Response.ts +142 -6
  88. package/Server/Utils/SSRFProtection.ts +273 -60
  89. package/Server/Utils/StartServer.ts +8 -0
  90. package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +689 -0
  91. package/Server/Utils/VM/VMAPI.ts +56 -8
  92. package/Server/Utils/VM/VMRunner.ts +88 -1
  93. package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +555 -49
  94. package/Server/Utils/Workspace/Slack/Slack.ts +25 -2
  95. package/Server/Utils/Workspace/WorkspaceBase.ts +6 -0
  96. package/Tests/App/Dashboard/DangerZone.test.tsx +334 -0
  97. package/Tests/App/Dashboard/DashboardVariableAllContract.test.tsx +539 -0
  98. package/Tests/App/Dashboard/DashboardVariableSelector.test.tsx +678 -0
  99. package/Tests/App/Dashboard/DashboardVariablesDiscard.test.tsx +706 -0
  100. package/Tests/App/Dashboard/DashboardVariablesModal.test.tsx +508 -0
  101. package/Tests/App/Dashboard/MonitorCriteriaAttributeFilter.test.tsx +574 -0
  102. package/Tests/App/PublicDashboard/DashboardVariableSelector.test.tsx +470 -0
  103. package/Tests/App/StatusPage/StatusPageDetailPagesNotFound.test.tsx +308 -0
  104. package/Tests/Models/DatabaseModels/DeletedProjectModel.test.ts +251 -0
  105. package/Tests/Models/DatabaseModels/SavedViewJSONColumnTuples.test.ts +115 -0
  106. package/Tests/Server/API/FileAPIAccessControl.test.ts +316 -0
  107. package/Tests/Server/API/ProjectAPI.test.ts +299 -1
  108. package/Tests/Server/API/ProjectAPIAdjustBalance.test.ts +459 -0
  109. package/Tests/Server/API/ProjectAPIAdjustBalanceBillingDisabled.test.ts +177 -0
  110. package/Tests/Server/API/UserProjectsAPI.test.ts +478 -4
  111. package/Tests/Server/Services/DatabaseServiceDeletionReason.test.ts +123 -0
  112. package/Tests/Server/Services/DeletedProjectService.test.ts +415 -0
  113. package/Tests/Server/Services/DeletedProjectServiceSelfHosted.test.ts +70 -0
  114. package/Tests/Server/Services/DomainSubdomainHooks.test.ts +94 -0
  115. package/Tests/Server/Services/FileIsPublicBooleanMigration.test.ts +244 -0
  116. package/Tests/Server/Services/FileServiceMimeType.test.ts +89 -0
  117. package/Tests/Server/Services/MonitorServiceDependencyValidation.test.ts +702 -0
  118. package/Tests/Server/Services/ProjectServiceAdjustBalance.test.ts +615 -0
  119. package/Tests/Server/Services/ProjectServiceDeleteAudit.test.ts +406 -0
  120. package/Tests/Server/Services/PublishTimeImageVisibility.test.ts +450 -0
  121. package/Tests/Server/Services/TeamMemberAutoAcceptInvitation.test.ts +669 -0
  122. package/Tests/Server/Services/TelemetryEntityManualCreate.test.ts +248 -0
  123. package/Tests/Server/Services/UserWebhookSSRF.test.ts +174 -0
  124. package/Tests/Server/Services/WebPushEndpointAllowlist.test.ts +133 -0
  125. package/Tests/Server/Services/WorkspaceProjectAuthTokenRepoint.test.ts +618 -0
  126. package/Tests/Server/Types/Workflow/Components/ApiComponentErrorPort.test.ts +26 -1
  127. package/Tests/Server/Types/Workflow/Components/ApiComponentHeaders.test.ts +192 -0
  128. package/Tests/Server/Types/Workflow/Components/ApiComponentSsrf.test.ts +215 -0
  129. package/Tests/Server/Types/Workflow/Components/BaseModelDatabaseComponents.test.ts +742 -0
  130. package/Tests/Server/Types/Workflow/Components/ChatWebhookComponents.test.ts +256 -0
  131. package/Tests/Server/Types/Workflow/Components/ModelArguments.test.ts +371 -0
  132. package/Tests/Server/Utils/AI/CodeAgentCommandGuard.test.ts +204 -0
  133. package/Tests/Server/Utils/AI/CodeAgentWriteLimits.test.ts +213 -0
  134. package/Tests/Server/Utils/AI/CodeWriteTools.test.ts +52 -5
  135. package/Tests/Server/Utils/AI/LLMServiceBaseUrl.test.ts +3 -0
  136. package/Tests/Server/Utils/AI/LLMServiceEgressGuard.test.ts +315 -0
  137. package/Tests/Server/Utils/AI/LLMServiceModelCompatibility.test.ts +3 -0
  138. package/Tests/Server/Utils/AI/LLMServiceRequestPolicy.test.ts +17 -5
  139. package/Tests/Server/Utils/AI/LLMServiceToolCalling.test.ts +14 -1
  140. package/Tests/Server/Utils/AI/ObservabilityChatPrompt.test.ts +35 -0
  141. package/Tests/Server/Utils/AI/StubLLMEgressGuard.ts +25 -0
  142. package/Tests/Server/Utils/AnalyticsDatabase/QuerySettingsHelper.test.ts +152 -0
  143. package/Tests/Server/Utils/Dashboard/PublicDashboardResourceListPolicy.test.ts +62 -7
  144. package/Tests/Server/Utils/DataSource/EgressGuard.test.ts +69 -0
  145. package/Tests/Server/Utils/DataSource/EgressGuardPinning.test.ts +330 -0
  146. package/Tests/Server/Utils/GitHubCreatePullRequestWithToken.test.ts +393 -0
  147. package/Tests/Server/Utils/InlineImageAccessTokenSync.test.ts +202 -0
  148. package/Tests/Server/Utils/Monitor/MonitorDependencySuppression.test.ts +811 -0
  149. package/Tests/Server/Utils/Monitor/MonitorDependencySuppressionCreatorSkip.test.ts +604 -0
  150. package/Tests/Server/Utils/ResponseSendFileResponse.test.ts +192 -0
  151. package/Tests/Server/Utils/SSRFProtectionBypasses.test.ts +406 -0
  152. package/Tests/Server/Utils/Telemetry/InventoryEntityRegistry.test.ts +322 -0
  153. package/Tests/Server/Utils/VM/VMAPISubstitution.test.ts +243 -0
  154. package/Tests/Server/Utils/VM/VMRunnerSsrf.test.ts +194 -0
  155. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelSend.test.ts +1169 -0
  156. package/Tests/Server/Utils/Workspace/MicrosoftTeamsChannelsList.test.ts +2 -0
  157. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTeamInstalls.test.ts +1605 -0
  158. package/Tests/Server/Utils/Workspace/MicrosoftTeamsTenantResolution.test.ts +1218 -0
  159. package/Tests/Types/AI/AIChatMessageStatus.test.ts +79 -0
  160. package/Tests/Types/AI/AIInsightStatus.test.ts +40 -0
  161. package/Tests/Types/API/HostnameAuthorityParsing.test.ts +157 -0
  162. package/Tests/Types/Dashboard/DashboardTemplateInvariants.test.ts +27 -0
  163. package/Tests/Types/DataSource/DataSourceLimits.test.ts +71 -0
  164. package/Tests/Types/DataSource/DataSourceType.test.ts +181 -0
  165. package/Tests/Types/DomainSubdomainValidation.test.ts +90 -0
  166. package/Tests/Types/JSONFunctions.test.ts +252 -1
  167. package/Tests/Types/Monitor/SnmpMonitor/SnmpAuthProtocol.test.ts +61 -0
  168. package/Tests/Types/Monitor/SnmpMonitor/SnmpPrivProtocol.test.ts +62 -0
  169. package/Tests/Types/Monitor/SnmpMonitor/SnmpSecurityLevel.test.ts +68 -0
  170. package/Tests/Types/Monitor/SnmpMonitor/SnmpVersion.test.ts +51 -0
  171. package/Tests/Types/SerializableObjectDictionaryImportCycle.test.ts +197 -0
  172. package/Tests/Types/Telemetry/EntityTypeGroups.test.ts +140 -0
  173. package/Tests/Types/Workflow/StepTrace.test.ts +235 -0
  174. package/Tests/Types/Workflow/TemplateSyntax.test.ts +379 -0
  175. package/Tests/Types/Workflow/Templates.test.ts +403 -0
  176. package/Tests/UI/Components/404.test.tsx +1 -1
  177. package/Tests/UI/Components/Alert.test.tsx +1 -1
  178. package/Tests/UI/Components/Badge.test.tsx +1 -1
  179. package/Tests/UI/Components/BasicForm.test.tsx +39 -10
  180. package/Tests/UI/Components/Button.test.tsx +1 -1
  181. package/Tests/UI/Components/Card.test.tsx +1 -1
  182. package/Tests/UI/Components/Charts/AxisTickColor.test.tsx +1 -1
  183. package/Tests/UI/Components/ColorViewer.test.tsx +1 -1
  184. package/Tests/UI/Components/ComponentsModal.test.tsx +7 -1
  185. package/Tests/UI/Components/CustomTimeRangeModal.test.tsx +459 -0
  186. package/Tests/UI/Components/DictionaryAttributeFilterRow.test.tsx +477 -0
  187. package/Tests/UI/Components/DictionaryOfStrings.test.tsx +1 -1
  188. package/Tests/UI/Components/Dropdown.test.tsx +1 -1
  189. package/Tests/UI/Components/FilePicker.test.tsx +1 -1
  190. package/Tests/UI/Components/Forms/AnchoredFieldPopupKeyboard.test.tsx +382 -0
  191. package/Tests/UI/Components/Forms/ColorPickerPicking.test.tsx +569 -0
  192. package/Tests/UI/Components/Forms/ValidationJSON.test.ts +241 -0
  193. package/Tests/UI/Components/HiddenText.test.tsx +1 -1
  194. package/Tests/UI/Components/Input.test.tsx +1 -1
  195. package/Tests/UI/Components/Loader.test.tsx +1 -1
  196. package/Tests/UI/Components/LogTimeRangePicker.test.tsx +43 -1
  197. package/Tests/UI/Components/MasterPage.test.tsx +1 -1
  198. package/Tests/UI/Components/ModalPortalDismissal.test.tsx +579 -0
  199. package/Tests/UI/Components/ModelDelete.test.tsx +214 -0
  200. package/Tests/UI/Components/ModelTable/BaseModelTableBulkSelectAll.test.tsx +1 -1
  201. package/Tests/UI/Components/ModelTable/BaseModelTableColumnCustomization.test.tsx +1 -1
  202. package/Tests/UI/Components/ModelTable/BaseModelTableSearchLabels.test.tsx +1 -1
  203. package/Tests/UI/Components/ModelTable/BaseModelTableUrlState.test.tsx +1 -1
  204. package/Tests/UI/Components/ModelTable/CustomFieldColumns.test.tsx +1 -1
  205. package/Tests/UI/Components/NavBar.test.tsx +1 -1
  206. package/Tests/UI/Components/OperatorSelectorKeyboard.test.tsx +1 -1
  207. package/Tests/UI/Components/Pagination.test.tsx +1 -1
  208. package/Tests/UI/Components/Pill.test.tsx +1 -1
  209. package/Tests/UI/Components/Probe.test.tsx +1 -1
  210. package/Tests/UI/Components/ProgressBar.test.tsx +1 -1
  211. package/Tests/UI/Components/RadioButtons.test.tsx +1 -1
  212. package/Tests/UI/Components/SideMenuItem.test.tsx +1 -1
  213. package/Tests/UI/Components/SideOver.test.tsx +500 -6
  214. package/Tests/UI/Components/Tabs.test.tsx +1 -1
  215. package/Tests/UI/Components/TelemetrySearchBar.test.tsx +1 -1
  216. package/Tests/UI/Components/TelemetryTimeRangePicker.test.tsx +50 -8
  217. package/Tests/UI/Components/TextArea.test.tsx +1 -1
  218. package/Tests/UI/Components/TimeRangePickerDropdown.test.tsx +325 -0
  219. package/Tests/UI/Components/Toast.test.tsx +1 -1
  220. package/Tests/UI/Components/Toggle.test.tsx +1 -1
  221. package/Tests/UI/Components/TopSection.test.tsx +1 -1
  222. package/Tests/UI/Components/UseLiveLogsRefresh.test.tsx +1 -1
  223. package/Tests/UI/Components/Workflow/GraphLint.test.ts +821 -0
  224. package/Tests/UI/Components/Workflow/ModelColumnEditor.test.ts +287 -0
  225. package/Tests/UI/Components/Workflow/ModelColumnEditorServerContract.test.ts +185 -0
  226. package/Tests/UI/Components/Workflow/ModelSchema.test.ts +174 -0
  227. package/Tests/UI/Components/Workflow/RunStatusWatcher.test.ts +152 -0
  228. package/Tests/UI/Components/Workflow/Utils.test.ts +192 -0
  229. package/Tests/UI/Monitor/MonitorStepCriteriaView.test.tsx +432 -0
  230. package/Tests/UI/Rum/ReplayScrubber.test.tsx +1 -1
  231. package/Tests/UI/Rum/ReplayStage.test.tsx +1 -1
  232. package/Tests/UI/Telemetry/TelemetrySnapshotWindowAlert.test.tsx +1 -1
  233. package/Tests/UI/Utils/LocalStorageArrayRoundTrip.test.ts +72 -0
  234. package/Tests/Utils/Dashboard/HtmlWidgetDocument.test.ts +19 -2
  235. package/Tests/Utils/Dashboard/ModelQueryVariableInterpolation.test.ts +44 -0
  236. package/Tests/Utils/Dashboard/VariableInterpolation.test.ts +288 -5
  237. package/Tests/Utils/Dashboard/VariableUrlState.test.ts +42 -0
  238. package/Tests/Utils/DataSource/DataSourceQueryText.test.ts +27 -0
  239. package/Tests/Utils/LegacySerializedArray.test.ts +139 -0
  240. package/Tests/Utils/Monitor/MonitorDependencyRule.test.ts +190 -0
  241. package/Tests/Utils/Monitor/NetworkDeviceRoleUtil.test.ts +514 -0
  242. package/Tests/Utils/Monitor/NetworkTopologyUtil.test.ts +240 -0
  243. package/Tests/Utils/Realtime.test.ts +78 -0
  244. package/Tests/Utils/Schema/AnalyticsModelSchema.test.ts +469 -0
  245. package/Tests/Utils/Schema/ModelSchema.test.ts +268 -0
  246. package/Tests/Utils/Telemetry/EntityKeyNonTelemetry.test.ts +193 -0
  247. package/Tests/Utils/Telemetry/SavedViewFilters.test.ts +246 -0
  248. package/Tests/__mocks__/i18next-browser-languagedetector.js +21 -0
  249. package/Types/AI/FixPullRequestCiStatus.ts +1 -1
  250. package/Types/AI/FixVerificationStatus.ts +2 -2
  251. package/Types/API/Hostname.ts +92 -4
  252. package/Types/API/URL.ts +43 -25
  253. package/Types/Billing/BalanceAdjustmentType.ts +14 -0
  254. package/Types/Billing/ProjectBalanceType.ts +13 -0
  255. package/Types/Domain.ts +26 -0
  256. package/Types/File/MimeType.ts +11 -0
  257. package/Types/JSONFunctions.ts +15 -0
  258. package/Types/Monitor/SnmpMonitor/NetworkTopology.ts +31 -0
  259. package/Types/SerializableObjectDictionary.ts +133 -39
  260. package/Types/Telemetry/EntitySource.ts +40 -0
  261. package/Types/Telemetry/EntityType.ts +27 -0
  262. package/Types/Telemetry/EntityTypeGroups.ts +65 -0
  263. package/Types/Telemetry/TelemetrySavedViewState.ts +9 -1
  264. package/Types/Workflow/Component.ts +29 -0
  265. package/Types/Workflow/Components/API.ts +35 -0
  266. package/Types/Workflow/Components/BaseModel.ts +96 -28
  267. package/Types/Workflow/StepTrace.ts +181 -0
  268. package/Types/Workflow/TemplateSyntax.ts +499 -0
  269. package/Types/Workflow/Templates.ts +316 -0
  270. package/Typings/Index.d.ts +12 -0
  271. package/UI/Components/Date/CustomTimeRangeModal.tsx +278 -0
  272. package/UI/Components/Date/TimeRangePickerDropdown.tsx +250 -0
  273. package/UI/Components/Dictionary/Dictionary.tsx +23 -6
  274. package/UI/Components/Forms/Fields/ColorPicker.tsx +66 -10
  275. package/UI/Components/Forms/Fields/IconPicker.tsx +48 -10
  276. package/UI/Components/Forms/Types/Field.ts +7 -0
  277. package/UI/Components/Forms/Validation.ts +63 -1
  278. package/UI/Components/GanttChart/ChartContainer.tsx +4 -3
  279. package/UI/Components/Input/Input.tsx +31 -3
  280. package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +11 -216
  281. package/UI/Components/Modal/ConfirmModal.tsx +10 -5
  282. package/UI/Components/Modal/Modal.tsx +64 -51
  283. package/UI/Components/ModelDelete/ModelDelete.tsx +23 -6
  284. package/UI/Components/SideOver/SideOver.tsx +195 -68
  285. package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +11 -210
  286. package/UI/Components/Workflow/ArgumentsForm.tsx +194 -7
  287. package/UI/Components/Workflow/Component.tsx +28 -26
  288. package/UI/Components/Workflow/ComponentSettingsModal.tsx +69 -8
  289. package/UI/Components/Workflow/GraphLint.ts +591 -0
  290. package/UI/Components/Workflow/ModelColumnEditor.tsx +396 -0
  291. package/UI/Components/Workflow/ModelSchema.ts +196 -0
  292. package/UI/Components/Workflow/RunForm.tsx +41 -7
  293. package/UI/Components/Workflow/RunStatusWatcher.ts +122 -0
  294. package/UI/Components/Workflow/StepTraceViewer.tsx +186 -0
  295. package/UI/Components/Workflow/Utils.ts +93 -1
  296. package/UI/Components/Workflow/Workflow.tsx +77 -4
  297. package/UI/Types/LayeredDismissal.ts +31 -0
  298. package/UI/Types/UseAnchoredFieldPopup.ts +99 -0
  299. package/UI/Utils/PageScrollLock.ts +66 -0
  300. package/Utils/Dashboard/HtmlWidgetDocument.ts +4 -2
  301. package/Utils/Dashboard/VariableInterpolation.ts +19 -1
  302. package/Utils/LegacySerializedArray.ts +60 -0
  303. package/Utils/Monitor/MonitorDependencyRule.ts +88 -0
  304. package/Utils/Monitor/NetworkDeviceRoleUtil.ts +533 -0
  305. package/Utils/Monitor/NetworkTopologyUtil.ts +45 -7
  306. package/Utils/Telemetry/EntityKey.ts +66 -0
  307. package/Utils/Telemetry/SavedViewFilters.ts +88 -0
  308. package/build/dist/Models/DatabaseModels/AIInsight.js +1 -1
  309. package/build/dist/Models/DatabaseModels/AIInsight.js.map +1 -1
  310. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js +2 -3
  311. package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js.map +1 -1
  312. package/build/dist/Models/DatabaseModels/DeletedProject.js +640 -0
  313. package/build/dist/Models/DatabaseModels/DeletedProject.js.map +1 -0
  314. package/build/dist/Models/DatabaseModels/Index.js +2 -0
  315. package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
  316. package/build/dist/Models/DatabaseModels/Monitor.js +106 -0
  317. package/build/dist/Models/DatabaseModels/Monitor.js.map +1 -1
  318. package/build/dist/Models/DatabaseModels/Project.js +3 -3
  319. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  320. package/build/dist/Models/DatabaseModels/TelemetryEntity.js +47 -0
  321. package/build/dist/Models/DatabaseModels/TelemetryEntity.js.map +1 -1
  322. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js +27 -0
  323. package/build/dist/Models/DatabaseModels/TelemetryEntityRelationship.js.map +1 -1
  324. package/build/dist/Models/DatabaseModels/WorkflowLog.js +39 -0
  325. package/build/dist/Models/DatabaseModels/WorkflowLog.js.map +1 -1
  326. package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
  327. package/build/dist/Server/API/FileAPI.js +14 -2
  328. package/build/dist/Server/API/FileAPI.js.map +1 -1
  329. package/build/dist/Server/API/MicrosoftTeamsAPI.js +6 -1
  330. package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
  331. package/build/dist/Server/API/ProjectAPI.js +157 -4
  332. package/build/dist/Server/API/ProjectAPI.js.map +1 -1
  333. package/build/dist/Server/API/StatusPageAPI.js +27 -3
  334. package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
  335. package/build/dist/Server/API/UserAPI.js +16 -1
  336. package/build/dist/Server/API/UserAPI.js.map +1 -1
  337. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js +34 -0
  338. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786446545142-MigrationName.js.map +1 -0
  339. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js +30 -0
  340. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786449497966-AddMonitorDependency.js.map +1 -0
  341. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js +20 -0
  342. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786461136170-AddDeletedProjectTable.js.map +1 -0
  343. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js +20 -0
  344. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786551733814-MigrationName.js.map +1 -0
  345. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js +12 -0
  346. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1786559879134-AddWorkflowLogStepTrace.js.map +1 -0
  347. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +10 -0
  348. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  349. package/build/dist/Server/Middleware/MasterAdminAuthorization.js +11 -6
  350. package/build/dist/Server/Middleware/MasterAdminAuthorization.js.map +1 -1
  351. package/build/dist/Server/Services/AIAgentService.js +17 -0
  352. package/build/dist/Server/Services/AIAgentService.js.map +1 -1
  353. package/build/dist/Server/Services/DashboardDomainService.js +55 -18
  354. package/build/dist/Server/Services/DashboardDomainService.js.map +1 -1
  355. package/build/dist/Server/Services/DatabaseService.js +1 -0
  356. package/build/dist/Server/Services/DatabaseService.js.map +1 -1
  357. package/build/dist/Server/Services/DeletedProjectService.js +124 -0
  358. package/build/dist/Server/Services/DeletedProjectService.js.map +1 -0
  359. package/build/dist/Server/Services/FileService.js +52 -0
  360. package/build/dist/Server/Services/FileService.js.map +1 -1
  361. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js +10 -1
  362. package/build/dist/Server/Services/IncidentEpisodePublicNoteService.js.map +1 -1
  363. package/build/dist/Server/Services/IncidentPublicNoteService.js +10 -1
  364. package/build/dist/Server/Services/IncidentPublicNoteService.js.map +1 -1
  365. package/build/dist/Server/Services/Index.js +2 -0
  366. package/build/dist/Server/Services/Index.js.map +1 -1
  367. package/build/dist/Server/Services/MonitorService.js +232 -0
  368. package/build/dist/Server/Services/MonitorService.js.map +1 -1
  369. package/build/dist/Server/Services/ProbeService.js +17 -0
  370. package/build/dist/Server/Services/ProbeService.js.map +1 -1
  371. package/build/dist/Server/Services/ProjectService.js +228 -6
  372. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  373. package/build/dist/Server/Services/PushNotificationService.js +56 -0
  374. package/build/dist/Server/Services/PushNotificationService.js.map +1 -1
  375. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js +10 -1
  376. package/build/dist/Server/Services/ScheduledMaintenancePublicNoteService.js.map +1 -1
  377. package/build/dist/Server/Services/StatusPageAnnouncementService.js +54 -0
  378. package/build/dist/Server/Services/StatusPageAnnouncementService.js.map +1 -1
  379. package/build/dist/Server/Services/StatusPageDomainService.js +55 -18
  380. package/build/dist/Server/Services/StatusPageDomainService.js.map +1 -1
  381. package/build/dist/Server/Services/TeamMemberService.js +97 -6
  382. package/build/dist/Server/Services/TeamMemberService.js.map +1 -1
  383. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js +3 -0
  384. package/build/dist/Server/Services/TelemetryEntityRelationshipService.js.map +1 -1
  385. package/build/dist/Server/Services/TelemetryEntityService.js +91 -1
  386. package/build/dist/Server/Services/TelemetryEntityService.js.map +1 -1
  387. package/build/dist/Server/Services/TelemetryIngestionKeyService.js +1 -0
  388. package/build/dist/Server/Services/TelemetryIngestionKeyService.js.map +1 -1
  389. package/build/dist/Server/Services/UserWebhookService.js +31 -87
  390. package/build/dist/Server/Services/UserWebhookService.js.map +1 -1
  391. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js +65 -0
  392. package/build/dist/Server/Services/WorkspaceNotificationRuleService.js.map +1 -1
  393. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js +23 -0
  394. package/build/dist/Server/Services/WorkspaceProjectAuthTokenService.js.map +1 -1
  395. package/build/dist/Server/Types/Domain.js +37 -0
  396. package/build/dist/Server/Types/Domain.js.map +1 -1
  397. package/build/dist/Server/Types/Workflow/Components/API/Delete.js +2 -1
  398. package/build/dist/Server/Types/Workflow/Components/API/Delete.js.map +1 -1
  399. package/build/dist/Server/Types/Workflow/Components/API/Get.js +2 -1
  400. package/build/dist/Server/Types/Workflow/Components/API/Get.js.map +1 -1
  401. package/build/dist/Server/Types/Workflow/Components/API/Patch.js +2 -1
  402. package/build/dist/Server/Types/Workflow/Components/API/Patch.js.map +1 -1
  403. package/build/dist/Server/Types/Workflow/Components/API/Post.js +2 -1
  404. package/build/dist/Server/Types/Workflow/Components/API/Post.js.map +1 -1
  405. package/build/dist/Server/Types/Workflow/Components/API/Put.js +2 -1
  406. package/build/dist/Server/Types/Workflow/Components/API/Put.js.map +1 -1
  407. package/build/dist/Server/Types/Workflow/Components/API/Utils.js +63 -2
  408. package/build/dist/Server/Types/Workflow/Components/API/Utils.js.map +1 -1
  409. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js +15 -11
  410. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateManyBaseModel.js.map +1 -1
  411. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js +2 -3
  412. package/build/dist/Server/Types/Workflow/Components/BaseModel/CreateOneBaseModel.js.map +1 -1
  413. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js +21 -10
  414. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteManyBaseModel.js.map +1 -1
  415. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js +21 -10
  416. package/build/dist/Server/Types/Workflow/Components/BaseModel/DeleteOneBaseModel.js.map +1 -1
  417. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js +18 -13
  418. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindManyBaseModel.js.map +1 -1
  419. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js +18 -13
  420. package/build/dist/Server/Types/Workflow/Components/BaseModel/FindOneBaseModel.js.map +1 -1
  421. package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js +43 -0
  422. package/build/dist/Server/Types/Workflow/Components/BaseModel/LogComponentError.js.map +1 -0
  423. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js +116 -0
  424. package/build/dist/Server/Types/Workflow/Components/BaseModel/ModelArguments.js.map +1 -0
  425. package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js +7 -0
  426. package/build/dist/Server/Types/Workflow/Components/BaseModel/OnTriggerBaseModel.js.map +1 -1
  427. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js +24 -13
  428. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateManyBaseModel.js.map +1 -1
  429. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js +27 -13
  430. package/build/dist/Server/Types/Workflow/Components/BaseModel/UpdateOneBaseModel.js.map +1 -1
  431. package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js +14 -6
  432. package/build/dist/Server/Types/Workflow/Components/Discord/SendMessageToChannel.js.map +1 -1
  433. package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js +42 -0
  434. package/build/dist/Server/Types/Workflow/Components/IncomingWebhookUtils.js.map +1 -0
  435. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js +15 -6
  436. package/build/dist/Server/Types/Workflow/Components/MicrosoftTeams/SendMessageToChannel.js.map +1 -1
  437. package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js +10 -2
  438. package/build/dist/Server/Types/Workflow/Components/Slack/SendMessageToChannel.js.map +1 -1
  439. package/build/dist/Server/Types/Workflow/TriggerCode.js.map +1 -1
  440. package/build/dist/Server/Utils/AI/Chat/ObservabilityChatPrompt.js +1 -1
  441. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js +141 -0
  442. package/build/dist/Server/Utils/AI/CodeFix/CodeAgentWorkspaceGuard.js.map +1 -1
  443. package/build/dist/Server/Utils/AI/SRE/Insights/FixRouting.js.map +1 -1
  444. package/build/dist/Server/Utils/AI/SRE/TelemetryImprovementTaskTrigger.js +1 -1
  445. package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js +6 -6
  446. package/build/dist/Server/Utils/AI/Toolbox/CodeWriteTools.js.map +1 -1
  447. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js +39 -5
  448. package/build/dist/Server/Utils/CodeRepository/GitHub/GitHub.js.map +1 -1
  449. package/build/dist/Server/Utils/DataSource/EgressGuard.js +94 -10
  450. package/build/dist/Server/Utils/DataSource/EgressGuard.js.map +1 -1
  451. package/build/dist/Server/Utils/DataSource/HttpFetch.js +1 -19
  452. package/build/dist/Server/Utils/DataSource/HttpFetch.js.map +1 -1
  453. package/build/dist/Server/Utils/Execute.js +2 -2
  454. package/build/dist/Server/Utils/Execute.js.map +1 -1
  455. package/build/dist/Server/Utils/InlineImageAccessTokenSync.js +13 -0
  456. package/build/dist/Server/Utils/InlineImageAccessTokenSync.js.map +1 -1
  457. package/build/dist/Server/Utils/LLM/LLMService.js +43 -12
  458. package/build/dist/Server/Utils/LLM/LLMService.js.map +1 -1
  459. package/build/dist/Server/Utils/Monitor/MonitorAlert.js +44 -24
  460. package/build/dist/Server/Utils/Monitor/MonitorAlert.js.map +1 -1
  461. package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js +158 -0
  462. package/build/dist/Server/Utils/Monitor/MonitorDependencySuppression.js.map +1 -0
  463. package/build/dist/Server/Utils/Monitor/MonitorIncident.js +50 -30
  464. package/build/dist/Server/Utils/Monitor/MonitorIncident.js.map +1 -1
  465. package/build/dist/Server/Utils/Monitor/MonitorResource.js +32 -0
  466. package/build/dist/Server/Utils/Monitor/MonitorResource.js.map +1 -1
  467. package/build/dist/Server/Utils/Response.js +112 -5
  468. package/build/dist/Server/Utils/Response.js.map +1 -1
  469. package/build/dist/Server/Utils/SSRFProtection.js +219 -53
  470. package/build/dist/Server/Utils/SSRFProtection.js.map +1 -1
  471. package/build/dist/Server/Utils/StartServer.js +7 -0
  472. package/build/dist/Server/Utils/StartServer.js.map +1 -1
  473. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +507 -0
  474. package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -0
  475. package/build/dist/Server/Utils/VM/VMAPI.js +51 -4
  476. package/build/dist/Server/Utils/VM/VMAPI.js.map +1 -1
  477. package/build/dist/Server/Utils/VM/VMRunner.js +73 -1
  478. package/build/dist/Server/Utils/VM/VMRunner.js.map +1 -1
  479. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +445 -43
  480. package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
  481. package/build/dist/Server/Utils/Workspace/Slack/Slack.js +18 -1
  482. package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
  483. package/build/dist/Server/Utils/Workspace/WorkspaceBase.js.map +1 -1
  484. package/build/dist/Types/AI/FixPullRequestCiStatus.js +1 -1
  485. package/build/dist/Types/AI/FixVerificationStatus.js +2 -2
  486. package/build/dist/Types/API/Hostname.js +73 -4
  487. package/build/dist/Types/API/Hostname.js.map +1 -1
  488. package/build/dist/Types/API/URL.js +42 -24
  489. package/build/dist/Types/API/URL.js.map +1 -1
  490. package/build/dist/Types/Billing/BalanceAdjustmentType.js +15 -0
  491. package/build/dist/Types/Billing/BalanceAdjustmentType.js.map +1 -0
  492. package/build/dist/Types/Billing/ProjectBalanceType.js +14 -0
  493. package/build/dist/Types/Billing/ProjectBalanceType.js.map +1 -0
  494. package/build/dist/Types/Domain.js +22 -0
  495. package/build/dist/Types/Domain.js.map +1 -1
  496. package/build/dist/Types/File/MimeType.js +11 -0
  497. package/build/dist/Types/File/MimeType.js.map +1 -1
  498. package/build/dist/Types/JSONFunctions.js +14 -0
  499. package/build/dist/Types/JSONFunctions.js.map +1 -1
  500. package/build/dist/Types/SerializableObjectDictionary.js +133 -39
  501. package/build/dist/Types/SerializableObjectDictionary.js.map +1 -1
  502. package/build/dist/Types/Telemetry/EntitySource.js +39 -0
  503. package/build/dist/Types/Telemetry/EntitySource.js.map +1 -0
  504. package/build/dist/Types/Telemetry/EntityType.js +27 -0
  505. package/build/dist/Types/Telemetry/EntityType.js.map +1 -1
  506. package/build/dist/Types/Telemetry/EntityTypeGroups.js +57 -0
  507. package/build/dist/Types/Telemetry/EntityTypeGroups.js.map +1 -0
  508. package/build/dist/Types/Workflow/Component.js +21 -0
  509. package/build/dist/Types/Workflow/Component.js.map +1 -1
  510. package/build/dist/Types/Workflow/Components/API.js +35 -0
  511. package/build/dist/Types/Workflow/Components/API.js.map +1 -1
  512. package/build/dist/Types/Workflow/Components/BaseModel.js +87 -28
  513. package/build/dist/Types/Workflow/Components/BaseModel.js.map +1 -1
  514. package/build/dist/Types/Workflow/StepTrace.js +104 -0
  515. package/build/dist/Types/Workflow/StepTrace.js.map +1 -0
  516. package/build/dist/Types/Workflow/TemplateSyntax.js +326 -0
  517. package/build/dist/Types/Workflow/TemplateSyntax.js.map +1 -0
  518. package/build/dist/Types/Workflow/Templates.js +218 -0
  519. package/build/dist/Types/Workflow/Templates.js.map +1 -0
  520. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js +126 -0
  521. package/build/dist/UI/Components/Date/CustomTimeRangeModal.js.map +1 -0
  522. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js +123 -0
  523. package/build/dist/UI/Components/Date/TimeRangePickerDropdown.js.map +1 -0
  524. package/build/dist/UI/Components/Dictionary/Dictionary.js +22 -6
  525. package/build/dist/UI/Components/Dictionary/Dictionary.js.map +1 -1
  526. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js +52 -13
  527. package/build/dist/UI/Components/Forms/Fields/ColorPicker.js.map +1 -1
  528. package/build/dist/UI/Components/Forms/Fields/IconPicker.js +28 -12
  529. package/build/dist/UI/Components/Forms/Fields/IconPicker.js.map +1 -1
  530. package/build/dist/UI/Components/Forms/Validation.js +44 -0
  531. package/build/dist/UI/Components/Forms/Validation.js.map +1 -1
  532. package/build/dist/UI/Components/GanttChart/ChartContainer.js +4 -3
  533. package/build/dist/UI/Components/GanttChart/ChartContainer.js.map +1 -1
  534. package/build/dist/UI/Components/Input/Input.js +12 -4
  535. package/build/dist/UI/Components/Input/Input.js.map +1 -1
  536. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +5 -108
  537. package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
  538. package/build/dist/UI/Components/Modal/ConfirmModal.js +3 -1
  539. package/build/dist/UI/Components/Modal/ConfirmModal.js.map +1 -1
  540. package/build/dist/UI/Components/Modal/Modal.js +55 -39
  541. package/build/dist/UI/Components/Modal/Modal.js.map +1 -1
  542. package/build/dist/UI/Components/ModelDelete/ModelDelete.js +11 -6
  543. package/build/dist/UI/Components/ModelDelete/ModelDelete.js.map +1 -1
  544. package/build/dist/UI/Components/SideOver/SideOver.js +105 -30
  545. package/build/dist/UI/Components/SideOver/SideOver.js.map +1 -1
  546. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +5 -105
  547. package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
  548. package/build/dist/UI/Components/Workflow/ArgumentsForm.js +140 -11
  549. package/build/dist/UI/Components/Workflow/ArgumentsForm.js.map +1 -1
  550. package/build/dist/UI/Components/Workflow/Component.js +20 -19
  551. package/build/dist/UI/Components/Workflow/Component.js.map +1 -1
  552. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js +31 -3
  553. package/build/dist/UI/Components/Workflow/ComponentSettingsModal.js.map +1 -1
  554. package/build/dist/UI/Components/Workflow/GraphLint.js +396 -0
  555. package/build/dist/UI/Components/Workflow/GraphLint.js.map +1 -0
  556. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js +225 -0
  557. package/build/dist/UI/Components/Workflow/ModelColumnEditor.js.map +1 -0
  558. package/build/dist/UI/Components/Workflow/ModelSchema.js +118 -0
  559. package/build/dist/UI/Components/Workflow/ModelSchema.js.map +1 -0
  560. package/build/dist/UI/Components/Workflow/RunForm.js +22 -6
  561. package/build/dist/UI/Components/Workflow/RunForm.js.map +1 -1
  562. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js +76 -0
  563. package/build/dist/UI/Components/Workflow/RunStatusWatcher.js.map +1 -0
  564. package/build/dist/UI/Components/Workflow/StepTraceViewer.js +76 -0
  565. package/build/dist/UI/Components/Workflow/StepTraceViewer.js.map +1 -0
  566. package/build/dist/UI/Components/Workflow/Utils.js +73 -1
  567. package/build/dist/UI/Components/Workflow/Utils.js.map +1 -1
  568. package/build/dist/UI/Components/Workflow/Workflow.js +51 -6
  569. package/build/dist/UI/Components/Workflow/Workflow.js.map +1 -1
  570. package/build/dist/UI/Types/LayeredDismissal.js +21 -0
  571. package/build/dist/UI/Types/LayeredDismissal.js.map +1 -0
  572. package/build/dist/UI/Types/UseAnchoredFieldPopup.js +74 -1
  573. package/build/dist/UI/Types/UseAnchoredFieldPopup.js.map +1 -1
  574. package/build/dist/UI/Utils/PageScrollLock.js +52 -0
  575. package/build/dist/UI/Utils/PageScrollLock.js.map +1 -0
  576. package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js +4 -2
  577. package/build/dist/Utils/Dashboard/HtmlWidgetDocument.js.map +1 -1
  578. package/build/dist/Utils/Dashboard/VariableInterpolation.js +19 -1
  579. package/build/dist/Utils/Dashboard/VariableInterpolation.js.map +1 -1
  580. package/build/dist/Utils/LegacySerializedArray.js +51 -0
  581. package/build/dist/Utils/LegacySerializedArray.js.map +1 -0
  582. package/build/dist/Utils/Monitor/MonitorDependencyRule.js +47 -0
  583. package/build/dist/Utils/Monitor/MonitorDependencyRule.js.map +1 -0
  584. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js +386 -0
  585. package/build/dist/Utils/Monitor/NetworkDeviceRoleUtil.js.map +1 -0
  586. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js +35 -6
  587. package/build/dist/Utils/Monitor/NetworkTopologyUtil.js.map +1 -1
  588. package/build/dist/Utils/Telemetry/EntityKey.js +52 -0
  589. package/build/dist/Utils/Telemetry/EntityKey.js.map +1 -1
  590. package/build/dist/Utils/Telemetry/SavedViewFilters.js +52 -0
  591. package/build/dist/Utils/Telemetry/SavedViewFilters.js.map +1 -0
  592. package/jest.config.json +3 -0
  593. package/package.json +1 -1
  594. package/tsconfig.json +3 -1
@@ -0,0 +1,250 @@
1
+ import React, {
2
+ FunctionComponent,
3
+ ReactElement,
4
+ useCallback,
5
+ useEffect,
6
+ useRef,
7
+ useState,
8
+ } from "react";
9
+ import InBetween from "../../../Types/BaseDatabase/InBetween";
10
+ import IconProp from "../../../Types/Icon/IconProp";
11
+ import RangeStartAndEndDateTime, {
12
+ RangeStartAndEndDateTimeUtil,
13
+ } from "../../../Types/Time/RangeStartAndEndDateTime";
14
+ import TimeRange from "../../../Types/Time/TimeRange";
15
+ import {
16
+ DropdownHorizontalAlignment,
17
+ getDropdownAlignmentClassName,
18
+ useDropdownHorizontalAlignment,
19
+ } from "../../Utils/DropdownAlignment";
20
+ import Icon from "../Icon/Icon";
21
+ import CustomTimeRangeModal from "./CustomTimeRangeModal";
22
+
23
+ export interface TimeRangePickerPresetOption {
24
+ range: TimeRange;
25
+ label: string;
26
+ }
27
+
28
+ export interface ComponentProps {
29
+ value: RangeStartAndEndDateTime;
30
+ onChange: (value: RangeStartAndEndDateTime) => void;
31
+ /*
32
+ * Prefix for the trigger and panel test ids, so each surface embedding this
33
+ * picker keeps the selector its own tests were written against.
34
+ */
35
+ dataTestIdPrefix: string;
36
+ dropdownWidthInPx: number;
37
+ }
38
+
39
+ export const CUSTOM_RANGE_OPTION_LABEL: string = "Custom Range...";
40
+
41
+ // Preset options to show in the dropdown, ordered shortest window first.
42
+ export const TIME_RANGE_PRESET_OPTIONS: Array<TimeRangePickerPresetOption> = [
43
+ { range: TimeRange.PAST_FIVE_MINS, label: "Past 5 Minutes" },
44
+ { range: TimeRange.PAST_FIFTEEN_MINS, label: "Past 15 Minutes" },
45
+ { range: TimeRange.PAST_THIRTY_MINS, label: "Past 30 Minutes" },
46
+ { range: TimeRange.PAST_ONE_HOUR, label: "Past 1 Hour" },
47
+ { range: TimeRange.PAST_TWO_HOURS, label: "Past 2 Hours" },
48
+ { range: TimeRange.PAST_THREE_HOURS, label: "Past 3 Hours" },
49
+ { range: TimeRange.PAST_ONE_DAY, label: "Past 1 Day" },
50
+ { range: TimeRange.PAST_TWO_DAYS, label: "Past 2 Days" },
51
+ { range: TimeRange.PAST_ONE_WEEK, label: "Past 1 Week" },
52
+ { range: TimeRange.PAST_TWO_WEEKS, label: "Past 2 Weeks" },
53
+ { range: TimeRange.PAST_ONE_MONTH, label: "Past 1 Month" },
54
+ { range: TimeRange.PAST_THREE_MONTHS, label: "Past 3 Months" },
55
+ ];
56
+
57
+ function formatDateShort(date: Date): string {
58
+ const month: string = date.toLocaleString("en-US", { month: "short" });
59
+ const day: number = date.getDate();
60
+ const hours: string = date.getHours().toString().padStart(2, "0");
61
+ const minutes: string = date.getMinutes().toString().padStart(2, "0");
62
+ return `${month} ${day}, ${hours}:${minutes}`;
63
+ }
64
+
65
+ export function getTimeRangeButtonLabel(
66
+ value: RangeStartAndEndDateTime,
67
+ ): string {
68
+ if (value.range === TimeRange.CUSTOM && value.startAndEndDate) {
69
+ const start: string = formatDateShort(value.startAndEndDate.startValue);
70
+ const end: string = formatDateShort(value.startAndEndDate.endValue);
71
+ return `${start} – ${end}`;
72
+ }
73
+
74
+ const preset: TimeRangePickerPresetOption | undefined =
75
+ TIME_RANGE_PRESET_OPTIONS.find((opt: TimeRangePickerPresetOption) => {
76
+ return opt.range === value.range;
77
+ });
78
+ return preset ? preset.label : value.range;
79
+ }
80
+
81
+ const TimeRangePickerDropdown: FunctionComponent<ComponentProps> = (
82
+ props: ComponentProps,
83
+ ): ReactElement => {
84
+ const [isOpen, setIsOpen] = useState<boolean>(false);
85
+ /*
86
+ * The custom window is edited in a modal rather than inline in this panel.
87
+ * Two `datetime-local` fields never fitted the 288px dropdown, and the native
88
+ * calendar those fields open renders outside this container — so the
89
+ * click-outside handler below tore the panel down the moment a date was
90
+ * clicked, which is what made "Custom Range..." look broken.
91
+ */
92
+ const [customSeedValue, setCustomSeedValue] =
93
+ useState<InBetween<Date> | null>(null);
94
+ const containerRef: React.RefObject<HTMLDivElement> = useRef<HTMLDivElement>(
95
+ null!,
96
+ );
97
+ const buttonRef: React.RefObject<HTMLButtonElement> =
98
+ useRef<HTMLButtonElement>(null!);
99
+ const dropdownRef: React.RefObject<HTMLDivElement> = useRef<HTMLDivElement>(
100
+ null!,
101
+ );
102
+
103
+ const alignment: DropdownHorizontalAlignment = useDropdownHorizontalAlignment(
104
+ {
105
+ isOpen: isOpen,
106
+ anchorRef: buttonRef,
107
+ dropdownRef: dropdownRef,
108
+ dropdownWidthInPx: props.dropdownWidthInPx,
109
+ },
110
+ );
111
+
112
+ // Close on click outside
113
+ useEffect(() => {
114
+ const handleClickOutside: (e: MouseEvent) => void = (
115
+ e: MouseEvent,
116
+ ): void => {
117
+ if (
118
+ containerRef.current &&
119
+ !containerRef.current.contains(e.target as Node)
120
+ ) {
121
+ setIsOpen(false);
122
+ }
123
+ };
124
+
125
+ document.addEventListener("mousedown", handleClickOutside);
126
+ return () => {
127
+ document.removeEventListener("mousedown", handleClickOutside);
128
+ };
129
+ }, []);
130
+
131
+ const handlePresetSelect: (range: TimeRange) => void = useCallback(
132
+ (range: TimeRange): void => {
133
+ props.onChange({ range });
134
+ setIsOpen(false);
135
+ },
136
+ [props],
137
+ );
138
+
139
+ const openCustomModal: () => void = useCallback((): void => {
140
+ /*
141
+ * Seed the editor with the window currently on screen — the custom range
142
+ * if one is already applied, otherwise the absolute bounds of the selected
143
+ * preset, so the user edits what they are looking at.
144
+ */
145
+ setCustomSeedValue(
146
+ props.value.range === TimeRange.CUSTOM && props.value.startAndEndDate
147
+ ? props.value.startAndEndDate
148
+ : RangeStartAndEndDateTimeUtil.getStartAndEndDate(props.value),
149
+ );
150
+ setIsOpen(false);
151
+ }, [props.value]);
152
+
153
+ const buttonLabel: string = getTimeRangeButtonLabel(props.value);
154
+
155
+ return (
156
+ <div ref={containerRef} className="relative">
157
+ <button
158
+ ref={buttonRef}
159
+ type="button"
160
+ data-testid={`${props.dataTestIdPrefix}-button`}
161
+ aria-haspopup="true"
162
+ aria-expanded={isOpen}
163
+ className={`inline-flex items-center gap-1.5 rounded-md border px-2.5 py-1.5 text-xs font-medium shadow-sm transition-colors ${
164
+ isOpen
165
+ ? "border-indigo-300 bg-indigo-50 text-indigo-700"
166
+ : "border-gray-200 bg-white text-gray-700 hover:border-gray-300 hover:bg-gray-50"
167
+ }`}
168
+ onClick={() => {
169
+ setIsOpen(!isOpen);
170
+ }}
171
+ >
172
+ <Icon icon={IconProp.Clock} className="h-3.5 w-3.5" />
173
+ <span>{buttonLabel}</span>
174
+ <Icon
175
+ icon={IconProp.ChevronDown}
176
+ className={`h-3 w-3 transition-transform ${isOpen ? "rotate-180" : ""}`}
177
+ />
178
+ </button>
179
+
180
+ {isOpen && (
181
+ <div
182
+ ref={dropdownRef}
183
+ data-testid={`${props.dataTestIdPrefix}-dropdown`}
184
+ data-align={alignment}
185
+ className={`absolute ${getDropdownAlignmentClassName(
186
+ alignment,
187
+ )} top-full z-50 mt-1 w-72 max-w-[calc(100vw-1rem)] rounded-lg border border-gray-200 bg-white shadow-lg`}
188
+ >
189
+ {/* Preset options */}
190
+ <div className="max-h-64 overflow-y-auto py-1">
191
+ {TIME_RANGE_PRESET_OPTIONS.map(
192
+ (option: TimeRangePickerPresetOption) => {
193
+ const isActive: boolean = props.value.range === option.range;
194
+
195
+ return (
196
+ <button
197
+ key={option.range}
198
+ type="button"
199
+ className={`flex w-full items-center px-3 py-1.5 text-left text-sm transition-colors ${
200
+ isActive
201
+ ? "bg-indigo-50 font-medium text-indigo-700"
202
+ : "text-gray-700 hover:bg-gray-50"
203
+ }`}
204
+ onClick={() => {
205
+ handlePresetSelect(option.range);
206
+ }}
207
+ >
208
+ {option.label}
209
+ </button>
210
+ );
211
+ },
212
+ )}
213
+
214
+ {/* Custom option — opens the editor in a modal */}
215
+ <button
216
+ type="button"
217
+ data-testid={`${props.dataTestIdPrefix}-custom-option`}
218
+ className={`flex w-full items-center px-3 py-1.5 text-left text-sm transition-colors ${
219
+ props.value.range === TimeRange.CUSTOM
220
+ ? "bg-indigo-50 font-medium text-indigo-700"
221
+ : "text-gray-700 hover:bg-gray-50"
222
+ }`}
223
+ onClick={openCustomModal}
224
+ >
225
+ {CUSTOM_RANGE_OPTION_LABEL}
226
+ </button>
227
+ </div>
228
+ </div>
229
+ )}
230
+
231
+ {customSeedValue && (
232
+ <CustomTimeRangeModal
233
+ initialValue={customSeedValue}
234
+ onClose={() => {
235
+ setCustomSeedValue(null);
236
+ }}
237
+ onSave={(startAndEndDate: InBetween<Date>) => {
238
+ setCustomSeedValue(null);
239
+ props.onChange({
240
+ range: TimeRange.CUSTOM,
241
+ startAndEndDate: startAndEndDate,
242
+ });
243
+ }}
244
+ />
245
+ )}
246
+ </div>
247
+ );
248
+ };
249
+
250
+ export default TimeRangePickerDropdown;
@@ -164,7 +164,16 @@ const DictionaryForm: FunctionComponent<ComponentProps> = (
164
164
  * numeric/boolean inputs always represent equality.
165
165
  */
166
166
  if (item.type === ValueType.Number) {
167
- result[item.key] = item.value as number;
167
+ /*
168
+ * An empty number box is a row the user is still filling in, not a
169
+ * filter for "". Leaving the key out of the result keeps it out of the
170
+ * query until an actual number is typed — which is what the value
171
+ * input used to achieve by deleting the row outright.
172
+ */
173
+ if (typeof item.value !== "number" || isNaN(item.value)) {
174
+ return;
175
+ }
176
+ result[item.key] = item.value;
168
177
  return;
169
178
  }
170
179
  if (item.type === ValueType.Boolean) {
@@ -495,12 +504,20 @@ const DictionaryForm: FunctionComponent<ComponentProps> = (
495
504
  placeholder={props.valuePlaceholder}
496
505
  onChange={(value: string) => {
497
506
  const newData: Array<Item> = [...data];
507
+ const parsedValue: number = parseInt(value);
498
508
 
499
- if (typeof value === "string" && value.length > 0) {
500
- newData[index]!.value = parseInt(value);
501
- } else {
502
- delete newData[index];
503
- }
509
+ /*
510
+ * Emptying the box empties this row's value it does not
511
+ * remove the row. `delete` on an array leaves a hole, so
512
+ * clearing the number silently threw away the filter the
513
+ * user was in the middle of writing, and the next
514
+ * `[...data]` materialised that hole as `undefined` and
515
+ * crashed the whole form on the following render.
516
+ */
517
+ newData[index]!.value =
518
+ value.length > 0 && !isNaN(parsedValue)
519
+ ? parsedValue
520
+ : "";
504
521
 
505
522
  setData(newData);
506
523
  onDataChange(newData);
@@ -10,6 +10,7 @@ import React, {
10
10
  FunctionComponent,
11
11
  ReactElement,
12
12
  useEffect,
13
+ useId,
13
14
  useState,
14
15
  } from "react";
15
16
  import { createPortal } from "react-dom";
@@ -43,14 +44,20 @@ const ColorPicker: FunctionComponent<ComponentProps> = (
43
44
  anchorRef,
44
45
  popupRef,
45
46
  isPopupOpen,
47
+ popupId,
46
48
  popupPosition,
47
49
  portalTarget,
50
+ onTriggerKeyDown,
48
51
  togglePopup,
49
52
  }: AnchoredFieldPopup = useAnchoredFieldPopup({
50
53
  popupMaxHeight: COLOR_PICKER_POPUP_MAX_HEIGHT_PX,
51
54
  popupWidth: COLOR_PICKER_POPUP_WIDTH_PX,
52
55
  });
53
56
 
57
+ const isInteractive: boolean = !props.readOnly && !props.disabled;
58
+ const generatedId: string = useId();
59
+ const errorId: string = `${generatedId}-color-picker-error`;
60
+
54
61
  const [isInitialValuesInitialized, setIsInitialValuesInitialized] =
55
62
  useState<boolean>(false);
56
63
 
@@ -79,20 +86,39 @@ const ColorPicker: FunctionComponent<ComponentProps> = (
79
86
  >
80
87
  <div
81
88
  onClick={() => {
82
- if (!props.readOnly) {
89
+ if (isInteractive) {
83
90
  togglePopup();
84
91
  }
85
92
  }}
93
+ aria-hidden="true"
86
94
  className="rounded h-5 w-5 border border-gray-200 cursor-pointer"
87
95
  style={{ backgroundColor: color.toString() }}
88
96
  ></div>
89
97
 
90
98
  <Input
91
99
  onClick={() => {
92
- if (!props.readOnly) {
100
+ if (isInteractive) {
93
101
  togglePopup();
94
102
  }
95
103
  }}
104
+ /*
105
+ * The field is a trigger, not a text box: it is readOnly and its only
106
+ * job is to open the picker. Without this a keyboard user cannot
107
+ * reach the picker at all, which on a required colour - the Create
108
+ * Label form - means they cannot submit the form either.
109
+ */
110
+ onKeyDown={isInteractive ? onTriggerKeyDown : undefined}
111
+ ariaHasPopup="dialog"
112
+ ariaExpanded={isPopupOpen}
113
+ ariaControls={isPopupOpen ? popupId : undefined}
114
+ /*
115
+ * The message below belongs to the whole control rather than to this
116
+ * input, so it has to be pointed at explicitly - otherwise "Label
117
+ * Color is required." is on screen and nowhere in the accessibility
118
+ * tree, and a screen reader user is told only that the form failed.
119
+ */
120
+ ariaDescribedby={props.error ? errorId : undefined}
121
+ ariaInvalid={Boolean(props.error)}
96
122
  disabled={props.disabled}
97
123
  dataTestId={props.dataTestId}
98
124
  onBlur={props.onBlur}
@@ -113,16 +139,24 @@ const ColorPicker: FunctionComponent<ComponentProps> = (
113
139
  onFocus={props.onFocus || undefined}
114
140
  />
115
141
  {color && !props.disabled && (
116
- <Icon
117
- icon={IconProp.Close}
118
- className="text-gray-400 h-5 w-5 cursor-pointer hover:text-gray-600"
142
+ /*
143
+ * A button, not a bare svg with a click handler: undoing a choice has
144
+ * to be reachable by the same keyboard that made it.
145
+ */
146
+ <button
147
+ type="button"
148
+ aria-label="Clear color"
149
+ title="Clear color"
150
+ className="flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 rounded"
119
151
  onClick={() => {
120
152
  setColor("");
121
153
  if (props.onChange) {
122
154
  props.onChange(null);
123
155
  }
124
156
  }}
125
- />
157
+ >
158
+ <Icon icon={IconProp.Close} className="h-5 w-5 cursor-pointer" />
159
+ </button>
126
160
  )}
127
161
  </div>
128
162
  {/*
@@ -134,6 +168,9 @@ const ColorPicker: FunctionComponent<ComponentProps> = (
134
168
  <div
135
169
  ref={popupRef}
136
170
  data-testid="color-picker-popup"
171
+ id={popupId}
172
+ role="dialog"
173
+ aria-label="Color picker"
137
174
  tabIndex={-1}
138
175
  className="fixed overflow-auto rounded-md shadow-lg"
139
176
  style={{
@@ -147,10 +184,24 @@ const ColorPicker: FunctionComponent<ComponentProps> = (
147
184
  >
148
185
  <ChromePicker
149
186
  color={color}
187
+ /*
188
+ * The field stores a bare hex, so an alpha channel it cannot
189
+ * represent is worse than no alpha at all: react-color reports
190
+ * a fully transparent colour as the literal "transparent",
191
+ * which sails through Color (it validates nothing) and is then
192
+ * rejected on save as longer than the ten characters the column
193
+ * holds - for a colour the user can see in the swatch.
194
+ */
195
+ disableAlpha={true}
196
+ /*
197
+ * One callback, not two. The swatch used to be painted from
198
+ * onChange and the form fed from onChangeComplete, which
199
+ * react-color debounces by 100ms — so for that window the field
200
+ * showed a colour the form did not hold yet. The value always
201
+ * arrived in the end, but there is no reason for the two to
202
+ * disagree at all.
203
+ */
150
204
  onChange={(color: ColorResult) => {
151
- setColor(color.hex);
152
- }}
153
- onChangeComplete={(color: ColorResult) => {
154
205
  return handleChange(color.hex);
155
206
  }}
156
207
  />
@@ -159,7 +210,12 @@ const ColorPicker: FunctionComponent<ComponentProps> = (
159
210
  )
160
211
  : null}
161
212
  {props.error && (
162
- <p data-testid="error-message" className="mt-1 text-sm text-red-400">
213
+ <p
214
+ id={errorId}
215
+ role="alert"
216
+ data-testid="error-message"
217
+ className="mt-1 text-sm text-red-400"
218
+ >
163
219
  {props.error}
164
220
  </p>
165
221
  )}
@@ -9,6 +9,7 @@ import React, {
9
9
  FunctionComponent,
10
10
  ReactElement,
11
11
  useEffect,
12
+ useId,
12
13
  useState,
13
14
  } from "react";
14
15
  import { createPortal } from "react-dom";
@@ -41,15 +42,21 @@ const IconPicker: FunctionComponent<ComponentProps> = (
41
42
  anchorRef,
42
43
  popupRef,
43
44
  isPopupOpen,
45
+ popupId,
44
46
  popupPosition,
45
47
  portalTarget,
46
48
  closePopup,
49
+ onTriggerKeyDown,
47
50
  togglePopup,
48
51
  }: AnchoredFieldPopup = useAnchoredFieldPopup({
49
52
  popupMaxHeight: ICON_PICKER_POPUP_MAX_HEIGHT_PX,
50
53
  popupWidth: ICON_PICKER_POPUP_WIDTH_PX,
51
54
  });
52
55
 
56
+ const isInteractive: boolean = !props.readOnly && !props.disabled;
57
+ const generatedId: string = useId();
58
+ const errorId: string = `${generatedId}-icon-picker-error`;
59
+
53
60
  const [isInitialValuesInitialized, setIsInitialValuesInitialized] =
54
61
  useState<boolean>(false);
55
62
 
@@ -84,10 +91,11 @@ const IconPicker: FunctionComponent<ComponentProps> = (
84
91
  >
85
92
  <div
86
93
  onClick={() => {
87
- if (!props.readOnly && !props.disabled) {
94
+ if (isInteractive) {
88
95
  togglePopup();
89
96
  }
90
97
  }}
98
+ aria-hidden="true"
91
99
  className="flex items-center justify-center h-5 w-5 cursor-pointer"
92
100
  >
93
101
  {selectedIcon ? (
@@ -99,10 +107,18 @@ const IconPicker: FunctionComponent<ComponentProps> = (
99
107
 
100
108
  <Input
101
109
  onClick={() => {
102
- if (!props.readOnly && !props.disabled) {
110
+ if (isInteractive) {
103
111
  togglePopup();
104
112
  }
105
113
  }}
114
+ // The field is a trigger, not a text box - see ColorPicker.
115
+ onKeyDown={isInteractive ? onTriggerKeyDown : undefined}
116
+ ariaHasPopup="dialog"
117
+ ariaExpanded={isPopupOpen}
118
+ ariaControls={isPopupOpen ? popupId : undefined}
119
+ // The message below belongs to the control, not to this input.
120
+ ariaDescribedby={props.error ? errorId : undefined}
121
+ ariaInvalid={Boolean(props.error)}
106
122
  disabled={props.disabled}
107
123
  dataTestId={props.dataTestId}
108
124
  onBlur={props.onBlur}
@@ -119,14 +135,19 @@ const IconPicker: FunctionComponent<ComponentProps> = (
119
135
  onFocus={props.onFocus || undefined}
120
136
  />
121
137
  {selectedIcon && !props.disabled && (
122
- <Icon
123
- icon={IconProp.Close}
124
- className="text-gray-400 h-5 w-5 cursor-pointer hover:text-gray-600"
138
+ // A button, not a bare svg with a click handler - see ColorPicker.
139
+ <button
140
+ type="button"
141
+ aria-label="Clear icon"
142
+ title="Clear icon"
143
+ className="flex items-center text-gray-400 hover:text-gray-600 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 rounded"
125
144
  onClick={() => {
126
145
  setSelectedIcon(null);
127
146
  props.onChange(null);
128
147
  }}
129
- />
148
+ >
149
+ <Icon icon={IconProp.Close} className="h-5 w-5 cursor-pointer" />
150
+ </button>
130
151
  )}
131
152
  </div>
132
153
  {/*
@@ -138,6 +159,9 @@ const IconPicker: FunctionComponent<ComponentProps> = (
138
159
  <div
139
160
  ref={popupRef}
140
161
  data-testid="icon-picker-popup"
162
+ id={popupId}
163
+ role="dialog"
164
+ aria-label="Icon picker"
141
165
  tabIndex={-1}
142
166
  className="fixed flex flex-col overflow-hidden bg-white border border-gray-200 rounded-lg shadow-lg p-3"
143
167
  style={{
@@ -166,13 +190,22 @@ const IconPicker: FunctionComponent<ComponentProps> = (
166
190
  {/* Icons grid */}
167
191
  <div className="grid grid-cols-6 gap-2 min-h-0 flex-1 overflow-y-auto">
168
192
  {filteredIcons.map((icon: IconProp) => {
193
+ /*
194
+ * A button rather than a div: the grid is the only way to set
195
+ * this field, so every cell has to be reachable by Tab and
196
+ * answer to Enter and Space. type="button" keeps it from
197
+ * submitting the form the field sits in.
198
+ */
169
199
  return (
170
- <div
200
+ <button
171
201
  key={icon}
202
+ type="button"
172
203
  onClick={() => {
173
204
  handleChange(icon);
174
205
  }}
175
- className={`flex items-center justify-center p-2 rounded cursor-pointer hover:bg-gray-100 ${
206
+ aria-pressed={selectedIcon === icon}
207
+ aria-label={icon}
208
+ className={`flex items-center justify-center p-2 rounded cursor-pointer hover:bg-gray-100 focus:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500 ${
176
209
  selectedIcon === icon
177
210
  ? "bg-indigo-100 ring-2 ring-indigo-500"
178
211
  : ""
@@ -180,7 +213,7 @@ const IconPicker: FunctionComponent<ComponentProps> = (
180
213
  title={icon}
181
214
  >
182
215
  <Icon icon={icon} className="h-5 w-5 text-gray-600" />
183
- </div>
216
+ </button>
184
217
  );
185
218
  })}
186
219
  </div>
@@ -195,7 +228,12 @@ const IconPicker: FunctionComponent<ComponentProps> = (
195
228
  )
196
229
  : null}
197
230
  {props.error && (
198
- <p data-testid="error-message" className="mt-1 text-sm text-red-400">
231
+ <p
232
+ id={errorId}
233
+ role="alert"
234
+ data-testid="error-message"
235
+ className="mt-1 text-sm text-red-400"
236
+ >
199
237
  {props.error}
200
238
  </p>
201
239
  )}
@@ -92,6 +92,13 @@ export default interface Field<TEntity> {
92
92
  | undefined;
93
93
  styleType?: FormFieldStyleType | undefined;
94
94
  showIf?: ((item: FormValues<TEntity>) => boolean) | undefined;
95
+ /**
96
+ * For a JSON field: judge its contents by JSON5's rules rather than JSON's.
97
+ * Set it where the code that eventually reads this value uses
98
+ * JSONFunctions.parse, so validation cannot reject a value that would have
99
+ * been read back perfectly well.
100
+ */
101
+ allowJSON5?: boolean | undefined;
95
102
  onChange?:
96
103
  | ((
97
104
  value: any,
@@ -12,8 +12,12 @@ import Email from "../../../Types/Email";
12
12
  import BadDataException from "../../../Types/Exception/BadDataException";
13
13
  import Exception from "../../../Types/Exception/Exception";
14
14
  import GenericObject from "../../../Types/GenericObject";
15
- import { JSONObject } from "../../../Types/JSON";
15
+ import { JSONObject, JSONValue } from "../../../Types/JSON";
16
16
  import Phone from "../../../Types/Phone";
17
+ import {
18
+ JSONSyntaxCheckResult,
19
+ checkJSONSyntax,
20
+ } from "../../../Types/Workflow/TemplateSyntax";
17
21
  import { Logger } from "../../Utils/Logger";
18
22
  import Port from "../../../Types/Port";
19
23
  import Typeof from "../../../Types/Typeof";
@@ -320,6 +324,50 @@ export default class Validation {
320
324
  return null;
321
325
  }
322
326
 
327
+ /**
328
+ * A JSON field whose contents are not JSON.
329
+ *
330
+ * Until this existed, a stray trailing comma saved cleanly and only surfaced
331
+ * when something tried to parse it — for a workflow that meant a real run,
332
+ * at whatever hour the trigger fired, ending in
333
+ * "Invalid JSON provided for argument request-body"
334
+ * (RunWorkflow.getComponentArguments).
335
+ *
336
+ * Takes the raw value rather than the stringified `content` the other
337
+ * validators get, because a JSON-typed field can legitimately already hold a
338
+ * parsed object, and `String(anObject)` is "[object Object]" — which is not
339
+ * JSON, and would fail every time.
340
+ *
341
+ * Tolerates {{...}} handlebars: workflow arguments are templates, and
342
+ * `{"retries": {{local.variables.retryCount}}}` is not JSON as written but is
343
+ * JSON by the time it is parsed. checkJSONSyntax masks those before parsing
344
+ * and declines to judge anything containing a {{#each}} loop at all.
345
+ */
346
+ public static validateJSONSyntax<T extends GenericObject>(
347
+ value: JSONValue | undefined,
348
+ field: Field<T>,
349
+ ): string | null {
350
+ if (field.fieldType !== FormFieldSchemaType.JSON) {
351
+ return null;
352
+ }
353
+
354
+ const result: JSONSyntaxCheckResult = checkJSONSyntax(value, {
355
+ allowJSON5: field.allowJSON5,
356
+ });
357
+
358
+ if (result.isValid) {
359
+ return null;
360
+ }
361
+
362
+ return translateValidationMessage(
363
+ "{{field}} is not valid JSON. {{parserMessage}}",
364
+ {
365
+ field: field.title || field.name || "",
366
+ parserMessage: result.errorMessage || "",
367
+ },
368
+ );
369
+ }
370
+
323
371
  public static validate<T extends GenericObject>(args: {
324
372
  formFields: Array<Field<T>>;
325
373
  values: FormValues<T>;
@@ -375,6 +423,20 @@ export default class Validation {
375
423
  errors[name] = resultValidateData;
376
424
  }
377
425
 
426
+ /*
427
+ * Fed the raw value, not `content` — see validateJSONSyntax. An
428
+ * already-parsed object stringifies to "[object Object]", which would
429
+ * fail the check every time it was handed the stringified form.
430
+ */
431
+ const resultJSONSyntax: string | null = this.validateJSONSyntax(
432
+ (entries as JSONObject)[name] as JSONValue | undefined,
433
+ field,
434
+ );
435
+
436
+ if (resultJSONSyntax) {
437
+ errors[name] = resultJSONSyntax;
438
+ }
439
+
378
440
  const resultMatch: string | null = this.validateMatchField(
379
441
  content,
380
442
  field,