@oneuptime/common 14.0.8 → 14.0.9
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.
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/KubernetesAiAgent.ts +364 -0
- package/Models/DatabaseModels/KubernetesCluster.ts +3 -3
- package/Models/DatabaseModels/Project.ts +55 -5
- package/Models/DatabaseModels/ProxmoxResource.ts +49 -1
- package/Models/DatabaseModels/RunnerJob.ts +75 -0
- package/Models/DatabaseModels/TeamComplianceSetting.ts +143 -2
- package/Models/DatabaseModels/WorkspaceProjectAuthToken.ts +17 -0
- package/Server/API/AIChatAPI.ts +6 -3
- package/Server/API/AIInvestigationAPI.ts +17 -10
- package/Server/API/AutoRemediationAPI.ts +207 -25
- package/Server/API/KubernetesClusterAiAccessAPI.ts +623 -21
- package/Server/API/MicrosoftTeamsAPI.ts +93 -14
- package/Server/API/ProxmoxResourceAPI.ts +244 -14
- package/Server/Infrastructure/GlobalCache.ts +32 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.ts +99 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.ts +137 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.ts +42 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +6 -0
- package/Server/Middleware/TelemetryIngest.ts +41 -18
- package/Server/Services/AIService.ts +70 -1
- package/Server/Services/AlertService.ts +352 -11
- package/Server/Services/AlertSeverityService.ts +65 -15
- package/Server/Services/AutoRemediationRuleService.ts +1 -1
- package/Server/Services/IncidentService.ts +280 -104
- package/Server/Services/IncidentSeverityService.ts +66 -15
- package/Server/Services/KubernetesAiAgentJobService.ts +185 -0
- package/Server/Services/KubernetesAiAgentService.ts +1634 -0
- package/Server/Services/KubernetesClusterAiAccessService.ts +1118 -451
- package/Server/Services/KubernetesClusterService.ts +129 -21
- package/Server/Services/ProjectService.ts +32 -0
- package/Server/Services/ProxmoxResourceService.ts +322 -5
- package/Server/Services/RunnerJobService.ts +241 -104
- package/Server/Services/RunnerService.ts +1 -1
- package/Server/Services/ScheduledMaintenanceService.ts +737 -1
- package/Server/Services/ScheduledMaintenanceStateTimelineService.ts +414 -56
- package/Server/Services/TeamComplianceSettingService.ts +1125 -9
- package/Server/Utils/AI/ClusterAccess/ClusterAccessContext.ts +67 -9
- package/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.ts +39 -10
- package/Server/Utils/AI/ClusterAccess/KubectlJobRunner.ts +14 -3
- package/Server/Utils/AI/Remediation/RemediationCommandTools.ts +37 -15
- package/Server/Utils/AI/Remediation/RemediationExecutionRunner.ts +67 -24
- package/Server/Utils/AI/SRE/AIInvestigationEngine.ts +48 -5
- package/Server/Utils/AI/SRE/IncidentPostmortemRunner.ts +40 -8
- package/Server/Utils/AI/SRE/InvestigationEligibility.ts +13 -2
- package/Server/Utils/AI/SRE/InvestigationGrader.ts +1 -1
- package/Server/Utils/AutoRemediation/CommandPlanExecutor.ts +6 -1
- package/Server/Utils/Telemetry/InventoryEntityRegistry.ts +133 -7
- package/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.ts +58 -4
- package/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.ts +447 -0
- package/Server/Utils/Telemetry/ProxmoxNativePush.ts +903 -0
- package/Server/Utils/Telemetry/TelemetryEntity.ts +87 -27
- package/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.ts +684 -47
- package/Tests/App/AdminDashboard/RowActionPlacementOverrides.test.tsx +278 -0
- package/Tests/App/Dashboard/AIChatChartWidgetZoom.test.tsx +738 -0
- package/Tests/App/Dashboard/AIFeaturesSettingsPointers.test.tsx +147 -0
- package/Tests/App/Dashboard/AIInsightsKubernetesClusterPage.test.tsx +1523 -0
- package/Tests/App/Dashboard/AdminUserNotificationMethodsPage.test.tsx +463 -3
- package/Tests/App/Dashboard/AffectedResourcesPickerDropdownPlacement.test.tsx +958 -0
- package/Tests/App/Dashboard/AffectedResourcesPickerFocusLeave.test.tsx +595 -0
- package/Tests/App/Dashboard/AskAiAvailability.test.ts +20 -3
- package/Tests/App/Dashboard/AskAiDisabled.test.tsx +8 -3
- package/Tests/App/Dashboard/CephRateChartReload.test.tsx +1456 -0
- package/Tests/App/Dashboard/CephTimeRangeZoom.test.tsx +1229 -0
- package/Tests/App/Dashboard/ChartCardTimeRangeZoom.test.tsx +151 -0
- package/Tests/App/Dashboard/ChartCardZoomAffordances.test.tsx +257 -0
- package/Tests/App/Dashboard/ChartRefetchFrame.test.tsx +141 -0
- package/Tests/App/Dashboard/ChartZoomHarness.tsx +249 -0
- package/Tests/App/Dashboard/ChartZoomStandIn.tsx +131 -0
- package/Tests/App/Dashboard/CloudServerlessSlowLoads.test.tsx +628 -0
- package/Tests/App/Dashboard/CloudServerlessTimeRangeZoom.test.tsx +607 -0
- package/Tests/App/Dashboard/ClusterAccessNotice.test.tsx +91 -19
- package/Tests/App/Dashboard/CompanionMetricsTabZoom.test.tsx +632 -0
- package/Tests/App/Dashboard/ContainerChartZoomStandIn.tsx +195 -0
- package/Tests/App/Dashboard/ContainerHostOverviewSlowLoads.test.tsx +542 -0
- package/Tests/App/Dashboard/ContainerHostOverviewTimeRangeZoom.test.tsx +848 -0
- package/Tests/App/Dashboard/ContainerMetricsTimeRangeZoom.test.tsx +561 -0
- package/Tests/App/Dashboard/DashboardBoardWideZoomShell.test.tsx +1147 -0
- package/Tests/App/Dashboard/DashboardEditPermissions.test.tsx +3 -2
- package/Tests/App/Dashboard/DashboardHistogramWidgetDragCursor.test.tsx +399 -0
- package/Tests/App/Dashboard/DashboardHistogramWidgetZoom.test.tsx +985 -0
- package/Tests/App/Dashboard/DashboardHistogramWidgetZoomHint.test.tsx +803 -0
- package/Tests/App/Dashboard/DashboardLazyPages.test.tsx +1 -0
- package/Tests/App/Dashboard/DashboardSettingsPreviewZoom.test.tsx +679 -0
- package/Tests/App/Dashboard/DashboardSloAndDataSourceChartZoom.test.tsx +881 -0
- package/Tests/App/Dashboard/DashboardTraceStatusWidgets.test.tsx +878 -0
- package/Tests/App/Dashboard/DatabaseMetricChartModalTimeRangeZoom.test.tsx +442 -0
- package/Tests/App/Dashboard/DatabaseOverviewTimeRangeZoom.test.tsx +831 -0
- package/Tests/App/Dashboard/DatabaseServerComponents.test.tsx +43 -0
- package/Tests/App/Dashboard/DockerSwarmInsightsTimeRangeZoom.test.tsx +524 -0
- package/Tests/App/Dashboard/DockerSwarmRateChartRefresh.test.tsx +259 -0
- package/Tests/App/Dashboard/EdgeDetailPanelHistory.test.tsx +763 -0
- package/Tests/App/Dashboard/EdgeDetailPanelTimeRangeZoom.test.tsx +547 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsCases.tsx +565 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsKathmandu.test.tsx +73 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsKolkata.test.tsx +74 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsNewYork.test.tsx +72 -0
- package/Tests/App/Dashboard/EdgeHistoryBucketsUtc.test.tsx +72 -0
- package/Tests/App/Dashboard/EmbeddedMetricCardRefresh.test.tsx +310 -0
- package/Tests/App/Dashboard/EmbeddedMetricCardTimeRangeZoom.test.tsx +536 -0
- package/Tests/App/Dashboard/EscalationRuleReadiness.test.tsx +3 -1
- package/Tests/App/Dashboard/EscalationRuleRowActions.test.tsx +660 -0
- package/Tests/App/Dashboard/EventNotes.test.tsx +2 -2
- package/Tests/App/Dashboard/EventOverviewPages.test.tsx +587 -13
- package/Tests/App/Dashboard/EventOverviewSnapshotExplorerZoom.test.tsx +1139 -0
- package/Tests/App/Dashboard/EventOverviewSnapshotZoomAcrossTabs.test.tsx +1057 -0
- package/Tests/App/Dashboard/EventOverviewTelemetrySnapshotZoom.test.tsx +757 -0
- package/Tests/App/Dashboard/ExceptionOccurrenceTrendZoom.test.tsx +675 -0
- package/Tests/App/Dashboard/ExceptionOccurrencesZoomSurvivesViewSwitch.test.tsx +405 -0
- package/Tests/App/Dashboard/ExceptionSignalPages.test.tsx +67 -3
- package/Tests/App/Dashboard/ExceptionTablesSpanStatus.test.tsx +515 -0
- package/Tests/App/Dashboard/ExplorerOwnZoomRegression.test.tsx +739 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisCases.tsx +461 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisKathmandu.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisKolkata.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisNewYork.test.tsx +25 -0
- package/Tests/App/Dashboard/FlowBandwidthAxisUtc.test.tsx +24 -0
- package/Tests/App/Dashboard/FlowTopTalkersZoomRefetch.test.tsx +722 -0
- package/Tests/App/Dashboard/FlowViewportGuard.test.tsx +2526 -0
- package/Tests/App/Dashboard/HostPagesSlowLoads.test.tsx +872 -0
- package/Tests/App/Dashboard/HostPagesTimeRangeZoom.test.tsx +1208 -0
- package/Tests/App/Dashboard/IncidentRootCauseTimeRangeZoom.test.tsx +358 -0
- package/Tests/App/Dashboard/InfrastructureGraph.test.tsx +100 -9
- package/Tests/App/Dashboard/InfrastructureMetricsTabTimeRangeZoom.test.tsx +485 -0
- package/Tests/App/Dashboard/InvestigationDrawerCompanionZoom.test.tsx +655 -0
- package/Tests/App/Dashboard/InvestigationDrawerZoom.test.tsx +830 -0
- package/Tests/App/Dashboard/InvestigationNotStarted.test.tsx +338 -2
- package/Tests/App/Dashboard/InvoicesPayInvoice.test.tsx +454 -16
- package/Tests/App/Dashboard/KubernetesClusterAiAccessSettings.test.ts +799 -819
- package/Tests/App/Dashboard/KubernetesClusterAiAgentOverviewCard.test.tsx +367 -0
- package/Tests/App/Dashboard/KubernetesClusterAiAgentStatus.test.ts +1202 -0
- package/Tests/App/Dashboard/KubernetesClusterAiDocumentationMarkdown.test.ts +106 -0
- package/Tests/App/Dashboard/KubernetesClusterAiNavigation.test.tsx +354 -0
- package/Tests/App/Dashboard/KubernetesClusterAiPage.test.tsx +1884 -2054
- package/Tests/App/Dashboard/KubernetesClusterAiPageServerParity.test.ts +478 -179
- package/Tests/App/Dashboard/KubernetesClusterMetricTooltips.test.ts +50 -0
- package/Tests/App/Dashboard/KubernetesClusterOverviewTooltips.test.tsx +2 -1
- package/Tests/App/Dashboard/KubernetesClusterOverviewZoom.test.tsx +1217 -0
- package/Tests/App/Dashboard/KubernetesClusterPagesZoom.test.tsx +731 -0
- package/Tests/App/Dashboard/KubernetesCostsLoadRecovery.test.tsx +869 -0
- package/Tests/App/Dashboard/KubernetesCostsZoom.test.tsx +1214 -0
- package/Tests/App/Dashboard/KubernetesCostsZoomExactHours.test.tsx +692 -0
- package/Tests/App/Dashboard/KubernetesNetworkThroughputReload.test.tsx +902 -0
- package/Tests/App/Dashboard/KubernetesNetworkZoomBucketEdges.test.tsx +571 -0
- package/Tests/App/Dashboard/KubernetesOverviewZoomBucketEdges.test.tsx +697 -0
- package/Tests/App/Dashboard/KubernetesResourceMetricsTabZoom.test.tsx +633 -0
- package/Tests/App/Dashboard/LogsExplorerTimeRangeZoom.test.tsx +470 -0
- package/Tests/App/Dashboard/LogsInsightsTimeRangeZoom.test.tsx +948 -0
- package/Tests/App/Dashboard/LogsViewerPinnedWindowZoom.test.tsx +486 -0
- package/Tests/App/Dashboard/MetricChartsBucketInspectorDoubleClick.test.tsx +1001 -0
- package/Tests/App/Dashboard/MetricExplorerInvestigationAutoRefresh.test.tsx +514 -0
- package/Tests/App/Dashboard/MetricExplorerSavedViewZoomRoundTrip.test.tsx +581 -0
- package/Tests/App/Dashboard/MetricExplorerTimeRangeZoom.test.tsx +1162 -0
- package/Tests/App/Dashboard/MetricMonitorPreviewZoomLabel.test.ts +72 -0
- package/Tests/App/Dashboard/MetricRowSparklineTimeRangeZoom.test.tsx +204 -0
- package/Tests/App/Dashboard/MetricViewFirstResultLands.test.tsx +408 -0
- package/Tests/App/Dashboard/MetricViewOwnZoomResetPlacement.test.tsx +952 -0
- package/Tests/App/Dashboard/MetricViewTimeRange.test.ts +139 -0
- package/Tests/App/Dashboard/MetricViewTimeRangeZoom.test.tsx +556 -0
- package/Tests/App/Dashboard/MonitorMetricsChartWrappersZoom.test.tsx +552 -0
- package/Tests/App/Dashboard/MonitorMetricsTabsTimeRangeZoom.test.tsx +740 -0
- package/Tests/App/Dashboard/MonitorOverviewChartsTimeRangeZoom.test.tsx +735 -0
- package/Tests/App/Dashboard/MonitorStepPreviewsTimeRangeZoom.test.tsx +835 -0
- package/Tests/App/Dashboard/NetworkDeviceTimeRangeZoom.test.tsx +1115 -0
- package/Tests/App/Dashboard/OnCallPreventionGuards.test.tsx +186 -17
- package/Tests/App/Dashboard/OnCallRulesDeleteGuard.test.tsx +155 -46
- package/Tests/App/Dashboard/PasskeySettings.test.tsx +87 -2
- package/Tests/App/Dashboard/ProjectAISettingsPages.test.tsx +884 -0
- package/Tests/App/Dashboard/ProxmoxNodeRemove.test.tsx +621 -0
- package/Tests/App/Dashboard/ProxmoxOverviewSlowLoads.test.tsx +584 -0
- package/Tests/App/Dashboard/ProxmoxPagesTimeRangeZoom.test.tsx +823 -0
- package/Tests/App/Dashboard/ProxmoxRateChartReload.test.tsx +1253 -0
- package/Tests/App/Dashboard/PublicDashboardBoardWideZoom.test.tsx +605 -0
- package/Tests/App/Dashboard/RealRowsLineChart.tsx +250 -0
- package/Tests/App/Dashboard/RechartsHostsPlotCursor.test.tsx +513 -0
- package/Tests/App/Dashboard/RowActionPlacementOverrides.test.tsx +865 -0
- package/Tests/App/Dashboard/RumOverviewTimeRangeZoom.test.tsx +877 -0
- package/Tests/App/Dashboard/RunnerKubernetesAgentForm.test.tsx +20 -4
- package/Tests/App/Dashboard/RunnerSupersededByAiAgentNote.test.tsx +296 -0
- package/Tests/App/Dashboard/SecurityEventConnectionsTable.test.tsx +146 -36
- package/Tests/App/Dashboard/ServiceDatabaseSlowLoads.test.tsx +1166 -0
- package/Tests/App/Dashboard/ServiceMapGraph.test.tsx +1243 -104
- package/Tests/App/Dashboard/ServiceOverviewTimeRangeZoom.test.tsx +792 -0
- package/Tests/App/Dashboard/SloBudgetBurnDownZoom.test.tsx +771 -0
- package/Tests/App/Dashboard/SloBudgetBurnDownZoomAffordances.test.tsx +380 -0
- package/Tests/App/Dashboard/SloEventMetricsBarChartZoom.test.tsx +369 -0
- package/Tests/App/Dashboard/SloHistoryChartsTimeRangeZoom.test.tsx +694 -0
- package/Tests/App/Dashboard/SloHistoryChartsZoomAffordances.test.tsx +497 -0
- package/Tests/App/Dashboard/SloMetricsTimeRangeZoom.test.tsx +541 -0
- package/Tests/App/Dashboard/SlowLoadHarness.ts +123 -0
- package/Tests/App/Dashboard/SnapshotExplorerPrimaryZoom.test.tsx +1194 -0
- package/Tests/App/Dashboard/SnapshotViewerPinnedWindow.test.tsx +620 -0
- package/Tests/App/Dashboard/TelemetrySnapshotPanelTimeRangeZoom.test.tsx +765 -0
- package/Tests/App/Dashboard/TelemetrySnapshotZoom.test.tsx +516 -0
- package/Tests/App/Dashboard/TelemetrySnapshotZoomAcrossTabs.test.tsx +827 -0
- package/Tests/App/Dashboard/TimeRangeZoomPageHarness.tsx +463 -0
- package/Tests/App/Dashboard/TraceChartEditorStatusSplit.test.tsx +543 -0
- package/Tests/App/Dashboard/TraceStatusPresentation.test.tsx +967 -0
- package/Tests/App/Dashboard/TraceTimelineMinimapZoom.test.tsx +315 -0
- package/Tests/App/Dashboard/TracesAnalyticsStatusSplit.test.tsx +778 -0
- package/Tests/App/Dashboard/TracesAnalyticsViewZoom.test.tsx +349 -0
- package/Tests/App/Dashboard/TracesExplorerTimeRangeZoom.test.tsx +551 -0
- package/Tests/App/Dashboard/TracesStatusChartAndFacet.test.tsx +687 -0
- package/Tests/App/Dashboard/TracesViewerStaleResponses.test.tsx +458 -0
- package/Tests/App/Dashboard/UptimeStripsExcludedFromZoom.test.tsx +406 -0
- package/Tests/App/Dashboard/VMwareOverviewSlowLoads.test.tsx +535 -0
- package/Tests/App/Dashboard/VMwarePagesTimeRangeZoom.test.tsx +606 -0
- package/Tests/App/Dashboard/ValueWidgetSparklineStaleHover.test.tsx +1292 -0
- package/Tests/App/Dashboard/ValueWidgetSparklineZoom.test.tsx +765 -0
- package/Tests/App/StatusPage/StatusPageResourceExplorer.test.tsx +98 -0
- package/Tests/Models/DatabaseModels/KubernetesAiAgentModel.test.ts +295 -0
- package/Tests/Models/DatabaseModels/TeamComplianceSettingModel.test.ts +347 -0
- package/Tests/Server/API/AIChatRouteAuthorization.test.ts +58 -0
- package/Tests/Server/API/AIGenerationProjectAIToggle.test.ts +1 -1
- package/Tests/Server/API/AIInvestigationAPI.test.ts +123 -45
- package/Tests/Server/API/AutoRemediationApproveClusterRound.test.ts +1329 -0
- package/Tests/Server/API/AutoRemediationApproveKubectlRecheck.test.ts +25 -2
- package/Tests/Server/API/KubernetesClusterAiAccessAPI.test.ts +2 -0
- package/Tests/Server/API/KubernetesClusterAiAccessAPIAgent.test.ts +903 -0
- package/Tests/Server/API/MicrosoftTeamsChatsRefreshRoute.test.ts +667 -0
- package/Tests/Server/API/MicrosoftTeamsManifest.test.ts +294 -6
- package/Tests/Server/API/ProxmoxResourceAPIRemoveNode.test.ts +1932 -0
- package/Tests/Server/Infrastructure/GlobalCache.test.ts +195 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesAiAgentAndAiDefaultsMigration.test.ts +623 -0
- package/Tests/Server/Infrastructure/Postgres/AddKubernetesClusterAiAccessMigration.test.ts +87 -10
- package/Tests/Server/Infrastructure/Postgres/AddTeamComplianceRuleScopeMigration.test.ts +622 -0
- package/Tests/Server/Middleware/TelemetryIngestBrowserKey.test.ts +61 -4
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerPinnedKey.test.ts +98 -2
- package/Tests/Server/Middleware/TelemetryIngestKubernetesAgentRunnerRateLimit.test.ts +105 -2
- package/Tests/Server/Services/AIServiceBalanceBlocker.test.ts +282 -0
- package/Tests/Server/Services/AlertMonitorClearWritesNull.test.ts +409 -0
- package/Tests/Server/Services/AlertMonitorEditFeed.test.ts +474 -0
- package/Tests/Server/Services/AlertMonitorEditGuard.test.ts +610 -0
- package/Tests/Server/Services/AutoRemediationClusterRuleEngine.test.ts +2 -0
- package/Tests/Server/Services/AutoRemediationRuleCommandRunners.test.ts +2 -1
- package/Tests/Server/Services/IncidentAffectedMonitorsEdit.test.ts +1360 -0
- package/Tests/Server/Services/IncidentAlertSloLinkSurvivesEdit.test.ts +3 -1
- package/Tests/Server/Services/IncidentSeverityDeletePausesComplianceRules.test.ts +488 -0
- package/Tests/Server/Services/KubernetesAiAgentJobService.test.ts +329 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceHelpers.test.ts +618 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceLifecycle.test.ts +1444 -0
- package/Tests/Server/Services/KubernetesAiAgentServiceRegister.test.ts +1666 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessDeletedRunnerRemedy.test.ts +140 -111
- package/Tests/Server/Services/KubernetesClusterAiAccessGapNextSteps.test.ts +267 -105
- package/Tests/Server/Services/KubernetesClusterAiAccessLegacySuperseded.test.ts +440 -0
- package/Tests/Server/Services/KubernetesClusterAiAccessService.test.ts +567 -411
- package/Tests/Server/Services/KubernetesClusterAiAccessTarget.test.ts +1168 -0
- package/Tests/Server/Services/KubernetesClusterAiSettingsPermission.test.ts +410 -12
- package/Tests/Server/Services/KubernetesClusterServiceAiAccessFeed.test.ts +55 -0
- package/Tests/Server/Services/ProjectServiceNewProjectAiDefaults.test.ts +288 -0
- package/Tests/Server/Services/ProxmoxResourcePostgres.test.ts +5633 -0
- package/Tests/Server/Services/ProxmoxResourceService.test.ts +6458 -5
- package/Tests/Server/Services/RunnerJobEnqueueKubectl.test.ts +48 -15
- package/Tests/Server/Services/RunnerJobEnqueueKubectlAiAgent.test.ts +620 -0
- package/Tests/Server/Services/RunnerJobKubectlWriteScope.test.ts +170 -3
- package/Tests/Server/Services/RunnerJobTimeoutReason.test.ts +72 -0
- package/Tests/Server/Services/RunnerServiceAgentName.test.ts +6 -4
- package/Tests/Server/Services/ScheduledMaintenanceAttachmentEdit.test.ts +2113 -0
- package/Tests/Server/Services/ScheduledMaintenanceMonitorRelease.test.ts +972 -0
- package/Tests/Server/Services/TeamComplianceSettingPostgres.test.ts +2237 -0
- package/Tests/Server/Services/TeamComplianceSettingService.test.ts +3988 -138
- package/Tests/Server/Utils/AI/ClusterAccessContext.test.ts +107 -1
- package/Tests/Server/Utils/AI/IncidentPostmortemRunner.test.ts +351 -0
- package/Tests/Server/Utils/AI/InvestigationClusterAccessWiring.test.ts +2 -0
- package/Tests/Server/Utils/AI/InvestigationEligibility.test.ts +310 -0
- package/Tests/Server/Utils/AI/KubectlInvestigationToolkit.test.ts +70 -0
- package/Tests/Server/Utils/AI/KubectlJobRunnerFinishedJob.test.ts +58 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectl.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsKubectlOutcome.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsLiveCluster.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationCommandToolsRunnerScope.test.ts +125 -1
- package/Tests/Server/Utils/AI/RemediationExecutionRunner.test.ts +252 -3
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerClusterMode.test.ts +2 -0
- package/Tests/Server/Utils/AI/RemediationExecutionRunnerProjectGates.test.ts +240 -0
- package/Tests/Server/Utils/AI/RemediationKubectlCopyParity.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutor.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanExecutorUnknownRun.test.ts +2 -0
- package/Tests/Server/Utils/AutoRemediation/CommandPlanVerification.test.ts +2 -0
- package/Tests/Server/Utils/Telemetry/HostAssetAttributesFromOtlp.test.ts +68 -0
- package/Tests/Server/Utils/Telemetry/InventoryMirrorPostgres.test.ts +370 -0
- package/Tests/Server/Utils/Telemetry/NetworkDeviceInventoryAttributes.test.ts +522 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.test.ts +155 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.test.ts +8631 -0
- package/Tests/Server/Utils/Telemetry/ProxmoxNativePush.test.ts +2852 -0
- package/Tests/Server/Utils/Telemetry/TelemetryEntity.test.ts +367 -1
- package/Tests/Server/Utils/Telemetry/TelemetryIngestionKeyGuard.test.ts +45 -3
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsChats.test.ts +25 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNames.test.ts +3119 -0
- package/Tests/Server/Utils/Workspace/MicrosoftTeamsGroupChatNamesPostgres.test.ts +1721 -0
- package/Tests/Types/Kubernetes/KubernetesAgentChartAiAccess.test.ts +581 -113
- package/Tests/Types/Kubernetes/KubernetesAiAgentAccessContract.test.ts +510 -0
- package/Tests/Types/Team/ComplianceRule.test.ts +1029 -0
- package/Tests/Types/Team/TeamComplianceStatus.test.ts +176 -0
- package/Tests/UI/Components/ActionButton/RowActions.test.tsx +641 -0
- package/Tests/UI/Components/ActionButton/RowActionsAccessibility.test.tsx +414 -0
- package/Tests/UI/Components/ActionButton/SplitActionButtons.test.ts +565 -0
- package/Tests/UI/Components/Charts/BarChartDragToSelect.test.tsx +386 -0
- package/Tests/UI/Components/Charts/ChartDoubleClickResetWithoutDblclick.test.tsx +1025 -0
- package/Tests/UI/Components/Charts/ChartGroupPageZoomHint.test.tsx +196 -0
- package/Tests/UI/Components/Charts/ChartPlaceholdersTakeDoubleClick.test.tsx +1861 -0
- package/Tests/UI/Components/Charts/ChartPlotClicksWhileResetArmed.test.tsx +382 -0
- package/Tests/UI/Components/Charts/ChartRangeSelection.test.tsx +704 -0
- package/Tests/UI/Components/Charts/ChartRangeSelectionDoubleClickReset.test.tsx +1481 -0
- package/Tests/UI/Components/Charts/ChartRangeSelectionRealRecharts.test.tsx +918 -0
- package/Tests/UI/Components/Charts/ChartRowBucketStart.test.ts +350 -0
- package/Tests/UI/Components/Charts/DoubleClickReset.test.tsx +996 -0
- package/Tests/UI/Components/Charts/HistogramDoubleClickResetRealRecharts.test.tsx +965 -0
- package/Tests/UI/Components/Charts/HistogramDriftThenRefetch.test.tsx +277 -0
- package/Tests/UI/Components/Charts/HistogramRangeSelectionDataChange.test.tsx +1757 -0
- package/Tests/UI/Components/Charts/HistogramRangeSelectionRealRecharts.test.tsx +560 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/ChartPageTimeRangeZoom.test.tsx +513 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.test.tsx +845 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.test.tsx +119 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHintTailwind.test.tsx +274 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.test.ts +433 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.test.tsx +863 -0
- package/Tests/UI/Components/Charts/TimeRangeZoom/ZoomDocsPromises.test.tsx +1147 -0
- package/Tests/UI/Components/DisabledButtonTooltip.test.tsx +14 -3
- package/Tests/UI/Components/EntityDropdownEscape.test.tsx +454 -0
- package/Tests/UI/Components/EntityDropdownFocusLeave.test.tsx +420 -0
- package/Tests/UI/Components/Forms/FormFieldDropdownDisabled.test.tsx +233 -0
- package/Tests/UI/Components/Input.test.tsx +80 -1
- package/Tests/UI/Components/LogsAnalyticsViewZoom.test.tsx +947 -0
- package/Tests/UI/Components/LogsHistogramDragTooltip.test.tsx +17 -5
- package/Tests/UI/Components/LogsViewerAnalyticsZoom.test.tsx +501 -0
- package/Tests/UI/Components/LogsViewerHistogramZoom.test.tsx +1 -1
- package/Tests/UI/Components/ModelTable/BaseModelTableBulkDelete.test.tsx +6 -4
- package/Tests/UI/Components/ModelTable/BaseModelTablePermissionGating.test.tsx +60 -8
- package/Tests/UI/Components/ModelTable/BaseModelTableRowActions.test.tsx +476 -0
- package/Tests/UI/Components/ModelTable/ModelTableWrapContent.test.tsx +7 -5
- package/Tests/UI/Components/MoreMenuPortal.test.tsx +623 -0
- package/Tests/UI/Components/StatusPage/ResourceGridActions.test.tsx +538 -0
- package/Tests/UI/Components/StatusPage/ResourceGridSelection.test.tsx +14 -4
- package/Tests/UI/Components/TableCellWrapping.test.tsx +3 -3
- package/Tests/UI/Components/TableRowActions.test.tsx +472 -0
- package/Tests/UI/Components/TelemetryHistogramDragTooltip.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerHistogramClickZoom.test.tsx +1 -1
- package/Tests/UI/Components/TelemetryViewer/TelemetryViewerZoomScope.test.tsx +470 -0
- package/Tests/UI/Components/TelemetryViewer/UseViewerTimeRangeZoom.test.tsx +571 -0
- package/Tests/UI/Components/TelemetryViewer/ViewerDoubleClickResetUnderDataChange.test.tsx +928 -0
- package/Tests/UI/Components/TelemetryViewer/ViewerFollowsEnclosingZoom.test.tsx +1569 -0
- package/Tests/UI/Components/Toggle.test.tsx +66 -0
- package/Tests/UI/MicrosoftTeams/MicrosoftTeamsChatsCardRefreshNames.test.tsx +1023 -0
- package/Tests/UI/Rum/ChunkLoader.test.ts +201 -0
- package/Tests/UI/Rum/FidelityNotices.test.ts +54 -0
- package/Tests/UI/Rum/ReplayCorrelationPanel.test.tsx +72 -0
- package/Tests/UI/Rum/ReplayFrameCapture.test.ts +1009 -9
- package/Tests/UI/Rum/ReplayRecordedAssets.test.ts +1069 -0
- package/Tests/UI/Rum/ReplayStage.test.tsx +913 -2
- package/Tests/UI/Rum/SessionReplayTable.test.tsx +443 -8
- package/Tests/UI/Rum/SessionReplayUsersTable.test.tsx +439 -9
- package/Tests/UI/Rum/UserFlowTablesRowActions.test.tsx +501 -0
- package/Tests/Utils/AiRemediation/KubectlPolicyChartRbacParity.test.ts +47 -19
- package/Tests/Utils/AiRemediation/KubectlWriteScopeCallerParity.test.ts +2 -0
- package/Tests/Utils/AiRemediation/KubernetesAiAgentPolicyCopyParity.test.ts +396 -0
- package/Tests/Utils/Dashboard/DashboardTimeRangeZoom.test.ts +104 -1
- package/Types/AI/AIRunType.ts +9 -4
- package/Types/AI/InvestigationNotStartedReason.ts +6 -0
- package/Types/AutoRemediation/AiRemediationCommandPlan.ts +14 -16
- package/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.ts +28 -0
- package/Types/Dashboard/DashboardComponents/DashboardTraceChartComponent.ts +4 -2
- package/Types/Kubernetes/KubernetesClusterAiAccess.ts +263 -32
- package/Types/Kubernetes/KubernetesClusterAiAccessPermissions.ts +20 -16
- package/Types/Kubernetes/KubernetesClusterAiInsights.ts +81 -0
- package/Types/Monitor/ProxmoxAlertTemplates.ts +4 -4
- package/Types/Team/ComplianceNotificationChannel.ts +22 -0
- package/Types/Team/ComplianceRule.ts +434 -0
- package/Types/Team/ComplianceRuleType.ts +21 -0
- package/Types/Team/TeamComplianceStatus.ts +81 -0
- package/Types/Telemetry/TelemetryIngestSurface.ts +28 -0
- package/UI/Components/ActionButton/ActionButtonSchema.ts +21 -0
- package/UI/Components/ActionButton/RowActions.tsx +238 -0
- package/UI/Components/ActionButton/SplitActionButtons.ts +173 -0
- package/UI/Components/Charts/Area/AreaChart.tsx +32 -2
- package/UI/Components/Charts/Bar/BarChart.tsx +40 -3
- package/UI/Components/Charts/ChartGroup/ChartGroup.tsx +37 -11
- package/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.tsx +80 -243
- package/UI/Components/Charts/ChartLibrary/BarChart/BarChart.tsx +122 -31
- package/UI/Components/Charts/ChartLibrary/LineChart/LineChart.tsx +95 -244
- package/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.ts +214 -0
- package/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.ts +32 -0
- package/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.ts +599 -0
- package/UI/Components/Charts/Line/LineChart.tsx +32 -2
- package/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.tsx +70 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.tsx +226 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.tsx +73 -0
- package/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.ts +163 -0
- package/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.ts +215 -0
- package/UI/Components/Charts/Utils/DataPoint.ts +20 -8
- package/UI/Components/Charts/Utils/XAxis.ts +75 -0
- package/UI/Components/Charts/Utils/useHistogramRangeSelection.ts +493 -59
- package/UI/Components/EntityDropdown/EntityDropdown.tsx +107 -11
- package/UI/Components/Forms/Fields/FormField.tsx +10 -0
- package/UI/Components/Input/Input.tsx +90 -57
- package/UI/Components/List/ListRow.tsx +8 -74
- package/UI/Components/LogsViewer/LogsViewer.tsx +40 -11
- package/UI/Components/LogsViewer/components/LogTimeRangePicker.tsx +22 -6
- package/UI/Components/LogsViewer/components/LogsAnalyticsView.tsx +209 -6
- package/UI/Components/LogsViewer/components/LogsHistogram.tsx +127 -84
- package/UI/Components/LogsViewer/components/LogsViewerToolbar.tsx +3 -0
- package/UI/Components/ModelTable/BaseModelTable.tsx +12 -1
- package/UI/Components/MoreMenu/MoreMenu.tsx +365 -30
- package/UI/Components/MoreMenu/MoreMenuItem.tsx +70 -17
- package/UI/Components/OrderedStatesList/Item.tsx +7 -72
- package/UI/Components/StatusPage/ResourceGrid.tsx +126 -77
- package/UI/Components/Table/TableBody.tsx +8 -2
- package/UI/Components/Table/TableRow.tsx +20 -140
- package/UI/Components/TelemetryViewer/TelemetryViewer.tsx +41 -10
- package/UI/Components/TelemetryViewer/components/TelemetryHistogram.tsx +47 -9
- package/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.tsx +25 -6
- package/UI/Components/TelemetryViewer/types.ts +2 -0
- package/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.ts +448 -0
- package/UI/Components/Toggle/Toggle.tsx +26 -0
- package/UI/Components/Tooltip/Tooltip.tsx +8 -1
- package/UI/Styles/Theme.css +14 -2
- package/Utils/AiRemediation/CommandPolicy.ts +1 -1
- package/Utils/AiRemediation/KubectlPolicy.ts +1 -1
- package/Utils/Dashboard/DashboardTimeRangeZoom.ts +46 -2
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js +385 -0
- package/build/dist/Models/DatabaseModels/KubernetesAiAgent.js.map +1 -0
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js +3 -3
- package/build/dist/Models/DatabaseModels/KubernetesCluster.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Project.js +56 -5
- package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js +51 -1
- package/build/dist/Models/DatabaseModels/ProxmoxResource.js.map +1 -1
- package/build/dist/Models/DatabaseModels/RunnerJob.js +74 -0
- package/build/dist/Models/DatabaseModels/RunnerJob.js.map +1 -1
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js +134 -3
- package/build/dist/Models/DatabaseModels/TeamComplianceSetting.js.map +1 -1
- package/build/dist/Models/DatabaseModels/WorkspaceProjectAuthToken.js.map +1 -1
- package/build/dist/Server/API/AIChatAPI.js +6 -1
- package/build/dist/Server/API/AIChatAPI.js.map +1 -1
- package/build/dist/Server/API/AIInvestigationAPI.js +17 -10
- package/build/dist/Server/API/AIInvestigationAPI.js.map +1 -1
- package/build/dist/Server/API/AutoRemediationAPI.js +144 -24
- package/build/dist/Server/API/AutoRemediationAPI.js.map +1 -1
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js +436 -22
- package/build/dist/Server/API/KubernetesClusterAiAccessAPI.js.map +1 -1
- package/build/dist/Server/API/MicrosoftTeamsAPI.js +69 -13
- package/build/dist/Server/API/MicrosoftTeamsAPI.js.map +1 -1
- package/build/dist/Server/API/ProxmoxResourceAPI.js +187 -14
- package/build/dist/Server/API/ProxmoxResourceAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/GlobalCache.js +27 -0
- package/build/dist/Server/Infrastructure/GlobalCache.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js +50 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796000000000-AddTeamComplianceRuleScope.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js +84 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796100000000-AddKubernetesAiAgentAndAiDefaults.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js +31 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1796200000000-AddProxmoxResourceNativePushColumns.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +6 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/TelemetryIngest.js +34 -19
- package/build/dist/Server/Middleware/TelemetryIngest.js.map +1 -1
- package/build/dist/Server/Services/AIService.js +59 -1
- package/build/dist/Server/Services/AIService.js.map +1 -1
- package/build/dist/Server/Services/AlertService.js +248 -13
- package/build/dist/Server/Services/AlertService.js.map +1 -1
- package/build/dist/Server/Services/AlertSeverityService.js +51 -15
- package/build/dist/Server/Services/AlertSeverityService.js.map +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js +1 -1
- package/build/dist/Server/Services/AutoRemediationRuleService.js.map +1 -1
- package/build/dist/Server/Services/IncidentService.js +199 -72
- package/build/dist/Server/Services/IncidentService.js.map +1 -1
- package/build/dist/Server/Services/IncidentSeverityService.js +51 -15
- package/build/dist/Server/Services/IncidentSeverityService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesAiAgentJobService.js +158 -0
- package/build/dist/Server/Services/KubernetesAiAgentJobService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesAiAgentService.js +1145 -0
- package/build/dist/Server/Services/KubernetesAiAgentService.js.map +1 -0
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js +842 -371
- package/build/dist/Server/Services/KubernetesClusterAiAccessService.js.map +1 -1
- package/build/dist/Server/Services/KubernetesClusterService.js +86 -17
- package/build/dist/Server/Services/KubernetesClusterService.js.map +1 -1
- package/build/dist/Server/Services/ProjectService.js +22 -0
- package/build/dist/Server/Services/ProjectService.js.map +1 -1
- package/build/dist/Server/Services/ProxmoxResourceService.js +258 -3
- package/build/dist/Server/Services/ProxmoxResourceService.js.map +1 -1
- package/build/dist/Server/Services/RunnerJobService.js +178 -92
- package/build/dist/Server/Services/RunnerJobService.js.map +1 -1
- package/build/dist/Server/Services/RunnerService.js +1 -1
- package/build/dist/Server/Services/RunnerService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceService.js +535 -3
- package/build/dist/Server/Services/ScheduledMaintenanceService.js.map +1 -1
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js +316 -46
- package/build/dist/Server/Services/ScheduledMaintenanceStateTimelineService.js.map +1 -1
- package/build/dist/Server/Services/TeamComplianceSettingService.js +833 -7
- package/build/dist/Server/Services/TeamComplianceSettingService.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js +52 -9
- package/build/dist/Server/Utils/AI/ClusterAccess/ClusterAccessContext.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js +13 -9
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlInvestigationToolkit.js.map +1 -1
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js +7 -3
- package/build/dist/Server/Utils/AI/ClusterAccess/KubectlJobRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js +29 -15
- package/build/dist/Server/Utils/AI/Remediation/RemediationCommandTools.js.map +1 -1
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js +56 -20
- package/build/dist/Server/Utils/AI/Remediation/RemediationExecutionRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js +39 -5
- package/build/dist/Server/Utils/AI/SRE/AIInvestigationEngine.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js +30 -3
- package/build/dist/Server/Utils/AI/SRE/IncidentPostmortemRunner.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js +13 -2
- package/build/dist/Server/Utils/AI/SRE/InvestigationEligibility.js.map +1 -1
- package/build/dist/Server/Utils/AI/SRE/InvestigationGrader.js +1 -1
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js +4 -2
- package/build/dist/Server/Utils/AutoRemediation/CommandPlanExecutor.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js +111 -6
- package/build/dist/Server/Utils/Telemetry/InventoryEntityRegistry.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js +40 -4
- package/build/dist/Server/Utils/Telemetry/ProxmoxCephSnapshotScan.js.map +1 -1
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js +296 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativeNodeLiveness.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js +699 -0
- package/build/dist/Server/Utils/Telemetry/ProxmoxNativePush.js.map +1 -0
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js +77 -19
- package/build/dist/Server/Utils/Telemetry/TelemetryEntity.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js +505 -42
- package/build/dist/Server/Utils/Workspace/MicrosoftTeams/MicrosoftTeams.js.map +1 -1
- package/build/dist/Types/AI/AIRunType.js +9 -4
- package/build/dist/Types/AI/AIRunType.js.map +1 -1
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js +10 -16
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPlan.js.map +1 -1
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js +28 -0
- package/build/dist/Types/AutoRemediation/AiRemediationCommandPolicyVerdict.js.map +1 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js +72 -16
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccess.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js +20 -16
- package/build/dist/Types/Kubernetes/KubernetesClusterAiAccessPermissions.js.map +1 -1
- package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js +17 -0
- package/build/dist/Types/Kubernetes/KubernetesClusterAiInsights.js.map +1 -0
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js +4 -4
- package/build/dist/Types/Monitor/ProxmoxAlertTemplates.js.map +1 -1
- package/build/dist/Types/Team/ComplianceNotificationChannel.js +23 -0
- package/build/dist/Types/Team/ComplianceNotificationChannel.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRule.js +304 -0
- package/build/dist/Types/Team/ComplianceRule.js.map +1 -0
- package/build/dist/Types/Team/ComplianceRuleType.js +21 -0
- package/build/dist/Types/Team/ComplianceRuleType.js.map +1 -1
- package/build/dist/Types/Team/TeamComplianceStatus.js +2 -0
- package/build/dist/Types/Team/TeamComplianceStatus.js.map +1 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js +25 -0
- package/build/dist/Types/Telemetry/TelemetryIngestSurface.js.map +1 -1
- package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js +20 -1
- package/build/dist/UI/Components/ActionButton/ActionButtonSchema.js.map +1 -1
- package/build/dist/UI/Components/ActionButton/RowActions.js +113 -0
- package/build/dist/UI/Components/ActionButton/RowActions.js.map +1 -0
- package/build/dist/UI/Components/ActionButton/SplitActionButtons.js +71 -0
- package/build/dist/UI/Components/ActionButton/SplitActionButtons.js.map +1 -0
- package/build/dist/UI/Components/Charts/Area/AreaChart.js +16 -1
- package/build/dist/UI/Components/Charts/Area/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js +16 -1
- package/build/dist/UI/Components/Charts/Bar/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js +27 -5
- package/build/dist/UI/Components/Charts/ChartGroup/ChartGroup.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js +61 -194
- package/build/dist/UI/Components/Charts/ChartLibrary/AreaChart/AreaChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js +84 -26
- package/build/dist/UI/Components/Charts/ChartLibrary/BarChart/BarChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js +75 -196
- package/build/dist/UI/Components/Charts/ChartLibrary/LineChart/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js +133 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/DoubleClick.js.map +1 -1
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js +26 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartBucketsChange.js.map +1 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js +371 -0
- package/build/dist/UI/Components/Charts/ChartLibrary/Utils/UseChartRangeSelection.js.map +1 -0
- package/build/dist/UI/Components/Charts/Line/LineChart.js +16 -1
- package/build/dist/UI/Components/Charts/Line/LineChart.js.map +1 -1
- package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js +35 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/ResetTimeRangeZoomButton.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js +107 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomContext.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js +41 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomHint.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js +117 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/TimeRangeZoomUtil.js.map +1 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js +121 -0
- package/build/dist/UI/Components/Charts/TimeRangeZoom/UseTimeRangeZoom.js.map +1 -0
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js +15 -7
- package/build/dist/UI/Components/Charts/Utils/DataPoint.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/XAxis.js +70 -0
- package/build/dist/UI/Components/Charts/Utils/XAxis.js.map +1 -1
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js +305 -38
- package/build/dist/UI/Components/Charts/Utils/useHistogramRangeSelection.js.map +1 -1
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js +89 -14
- package/build/dist/UI/Components/EntityDropdown/EntityDropdown.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +11 -2
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +69 -54
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/List/ListRow.js +4 -39
- package/build/dist/UI/Components/List/ListRow.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js +31 -8
- package/build/dist/UI/Components/LogsViewer/LogsViewer.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js +10 -1
- package/build/dist/UI/Components/LogsViewer/components/LogTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js +139 -21
- package/build/dist/UI/Components/LogsViewer/components/LogsAnalyticsView.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js +30 -8
- package/build/dist/UI/Components/LogsViewer/components/LogsHistogram.js.map +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js +1 -1
- package/build/dist/UI/Components/LogsViewer/components/LogsViewerToolbar.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +10 -0
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js +253 -14
- package/build/dist/UI/Components/MoreMenu/MoreMenu.js.map +1 -1
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js +43 -13
- package/build/dist/UI/Components/MoreMenu/MoreMenuItem.js.map +1 -1
- package/build/dist/UI/Components/OrderedStatesList/Item.js +2 -38
- package/build/dist/UI/Components/OrderedStatesList/Item.js.map +1 -1
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js +53 -15
- package/build/dist/UI/Components/StatusPage/ResourceGrid.js.map +1 -1
- package/build/dist/UI/Components/Table/TableBody.js +6 -2
- package/build/dist/UI/Components/Table/TableBody.js.map +1 -1
- package/build/dist/UI/Components/Table/TableRow.js +12 -75
- package/build/dist/UI/Components/Table/TableRow.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js +32 -7
- package/build/dist/UI/Components/TelemetryViewer/TelemetryViewer.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js +27 -9
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryHistogram.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js +11 -1
- package/build/dist/UI/Components/TelemetryViewer/components/TelemetryTimeRangePicker.js.map +1 -1
- package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js +272 -0
- package/build/dist/UI/Components/TelemetryViewer/useViewerTimeRangeZoom.js.map +1 -0
- package/build/dist/UI/Components/Toggle/Toggle.js +14 -1
- package/build/dist/UI/Components/Toggle/Toggle.js.map +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js +1 -1
- package/build/dist/UI/Components/Tooltip/Tooltip.js.map +1 -1
- package/build/dist/Utils/AiRemediation/CommandPolicy.js +1 -1
- package/build/dist/Utils/AiRemediation/CommandPolicy.js.map +1 -1
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js +1 -1
- package/build/dist/Utils/AiRemediation/KubectlPolicy.js.map +1 -1
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js +27 -1
- package/build/dist/Utils/Dashboard/DashboardTimeRangeZoom.js.map +1 -1
- package/package.json +1 -1
|
@@ -5,11 +5,15 @@ import React, {
|
|
|
5
5
|
useEffect,
|
|
6
6
|
useId,
|
|
7
7
|
useImperativeHandle,
|
|
8
|
+
useLayoutEffect,
|
|
8
9
|
useState,
|
|
9
10
|
} from "react";
|
|
11
|
+
import { createPortal } from "react-dom";
|
|
10
12
|
import IconProp from "../../../Types/Icon/IconProp";
|
|
11
13
|
import useComponentOutsideClick from "../../Types/UseComponentOutsideClick";
|
|
14
|
+
import { consumePressForAnchoredPopup } from "../../Types/LayeredDismissal";
|
|
12
15
|
import Button, { ButtonStyleType } from "../Button/Button";
|
|
16
|
+
import DROPDOWN_MENU_Z_INDEX from "../Dropdown/DropdownMenuZIndex";
|
|
13
17
|
|
|
14
18
|
export interface ComponentProps {
|
|
15
19
|
children: Array<ReactElement>;
|
|
@@ -41,8 +45,54 @@ export interface ComponentProps {
|
|
|
41
45
|
* know they are at the bottom say so; everything else keeps opening down.
|
|
42
46
|
*/
|
|
43
47
|
isOpeningUpwards?: boolean | undefined;
|
|
48
|
+
/*
|
|
49
|
+
* Render the open menu into document.body, `fixed` against its trigger,
|
|
50
|
+
* instead of absolutely inside the trigger's wrapper. For triggers that live
|
|
51
|
+
* inside a clipping container - a table row sits in an `overflow-x-auto`
|
|
52
|
+
* scroller, so an absolute menu under its last row is cut off or scrolls the
|
|
53
|
+
* table instead of showing. Placement follows the other portalled popups:
|
|
54
|
+
* below the trigger and right-aligned to it, flipped above when there is not
|
|
55
|
+
* room below, clamped to the viewport.
|
|
56
|
+
*/
|
|
57
|
+
isMenuPortaled?: boolean | undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// Matches the mt-2 / mb-2 gap the in-place menu keeps from its trigger.
|
|
61
|
+
const PORTALED_MENU_GAP_PX: number = 8;
|
|
62
|
+
const PORTALED_MENU_VIEWPORT_PADDING_PX: number = 8;
|
|
63
|
+
// w-56, for the first measurement before the menu has a width of its own.
|
|
64
|
+
const PORTALED_MENU_FALLBACK_WIDTH_PX: number = 224;
|
|
65
|
+
|
|
66
|
+
/*
|
|
67
|
+
* Exactly one of left / right is set, and exactly one of top / bottom. Right
|
|
68
|
+
* is the usual anchor: it lines the menu's right edge up with the trigger's
|
|
69
|
+
* whatever width the menu turns out to have.
|
|
70
|
+
*/
|
|
71
|
+
interface PortaledMenuPosition {
|
|
72
|
+
top: number | undefined;
|
|
73
|
+
bottom: number | undefined;
|
|
74
|
+
left: number | undefined;
|
|
75
|
+
right: number | undefined;
|
|
76
|
+
isAbove: boolean;
|
|
44
77
|
}
|
|
45
78
|
|
|
79
|
+
/*
|
|
80
|
+
* A fullscreen element hides everything outside it, so a menu opened from
|
|
81
|
+
* inside one has to be portalled into it rather than into the body.
|
|
82
|
+
*/
|
|
83
|
+
const getMenuPortalTarget: () => HTMLElement | null =
|
|
84
|
+
(): HTMLElement | null => {
|
|
85
|
+
if (typeof document === "undefined") {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const fullscreenElement: Element | null = document.fullscreenElement;
|
|
90
|
+
|
|
91
|
+
return fullscreenElement instanceof HTMLElement
|
|
92
|
+
? fullscreenElement
|
|
93
|
+
: document.body;
|
|
94
|
+
};
|
|
95
|
+
|
|
46
96
|
const isMenuItemDisabled: (item: HTMLElement) => boolean = (
|
|
47
97
|
item: HTMLElement,
|
|
48
98
|
): boolean => {
|
|
@@ -67,6 +117,9 @@ const MoreMenu: React.ForwardRefExoticComponent<
|
|
|
67
117
|
const { ref, isComponentVisible, setIsComponentVisible } =
|
|
68
118
|
useComponentOutsideClick(false);
|
|
69
119
|
const [focusedIndex, setFocusedIndex] = useState<number>(-1);
|
|
120
|
+
const isMenuPortaled: boolean = Boolean(props.isMenuPortaled);
|
|
121
|
+
const [portaledMenuPosition, setPortaledMenuPosition] =
|
|
122
|
+
useState<PortaledMenuPosition | null>(null);
|
|
70
123
|
|
|
71
124
|
/*
|
|
72
125
|
* Menu sections and dividers are valid top-level children, so the list of
|
|
@@ -103,7 +156,15 @@ const MoreMenu: React.ForwardRefExoticComponent<
|
|
|
103
156
|
return Array.from(
|
|
104
157
|
menuElement.querySelectorAll<HTMLElement>('[role="menuitem"]'),
|
|
105
158
|
).filter((item: HTMLElement) => {
|
|
106
|
-
|
|
159
|
+
/*
|
|
160
|
+
* A locked item that explains itself (MoreMenuItem with a tooltip)
|
|
161
|
+
* stays in the roving focus so its reason can be reached from the
|
|
162
|
+
* keyboard; activating it is still refused below.
|
|
163
|
+
*/
|
|
164
|
+
return (
|
|
165
|
+
!isMenuItemDisabled(item) ||
|
|
166
|
+
item.getAttribute("data-focusable-when-disabled") === "true"
|
|
167
|
+
);
|
|
107
168
|
});
|
|
108
169
|
}, [ref]);
|
|
109
170
|
|
|
@@ -169,6 +230,195 @@ const MoreMenu: React.ForwardRefExoticComponent<
|
|
|
169
230
|
}
|
|
170
231
|
}, [props.isDisabled, isComponentVisible, setIsComponentVisible]);
|
|
171
232
|
|
|
233
|
+
const updatePortaledMenuPosition: () => void = useCallback((): void => {
|
|
234
|
+
if (typeof window === "undefined") {
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
const trigger: HTMLElement | null = document.getElementById(buttonId);
|
|
239
|
+
|
|
240
|
+
if (!trigger) {
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const menuElement: HTMLElement | null = ref.current as HTMLElement | null;
|
|
245
|
+
const triggerRect: DOMRect = trigger.getBoundingClientRect();
|
|
246
|
+
const menuWidth: number =
|
|
247
|
+
menuElement?.offsetWidth || PORTALED_MENU_FALLBACK_WIDTH_PX;
|
|
248
|
+
const menuHeight: number = menuElement?.offsetHeight || 0;
|
|
249
|
+
|
|
250
|
+
/*
|
|
251
|
+
* `right` on a fixed element is measured from the edge of the layout
|
|
252
|
+
* viewport, which stops short of a classic vertical scrollbar - so the
|
|
253
|
+
* width that matters is clientWidth, not innerWidth.
|
|
254
|
+
*/
|
|
255
|
+
const viewportWidth: number =
|
|
256
|
+
document.documentElement.clientWidth || window.innerWidth;
|
|
257
|
+
// The same holds for `bottom` and a classic horizontal scrollbar.
|
|
258
|
+
const viewportHeight: number =
|
|
259
|
+
document.documentElement.clientHeight || window.innerHeight;
|
|
260
|
+
|
|
261
|
+
/*
|
|
262
|
+
* Right edge to right edge, like the in-place menu's `right-0`, and
|
|
263
|
+
* anchored by that right edge rather than by a left computed from the
|
|
264
|
+
* menu's width. The width is not settled at first measurement: the
|
|
265
|
+
* Tailwind runtime the dashboards load generates the rule for a class
|
|
266
|
+
* the page has not used yet a moment AFTER the element carrying it
|
|
267
|
+
* mounts, so the first width read is the unstyled one. A left-anchored
|
|
268
|
+
* menu then grew rightwards off the screen; a right-anchored one just
|
|
269
|
+
* grows leftwards into place.
|
|
270
|
+
*/
|
|
271
|
+
const isOverflowingLeft: boolean =
|
|
272
|
+
triggerRect.right - menuWidth < PORTALED_MENU_VIEWPORT_PADDING_PX;
|
|
273
|
+
|
|
274
|
+
const right: number | undefined = isOverflowingLeft
|
|
275
|
+
? undefined
|
|
276
|
+
: Math.max(
|
|
277
|
+
viewportWidth - triggerRect.right,
|
|
278
|
+
PORTALED_MENU_VIEWPORT_PADDING_PX,
|
|
279
|
+
);
|
|
280
|
+
/*
|
|
281
|
+
* Without room to hang leftwards - a trigger near the left edge, as on
|
|
282
|
+
* the mobile cards - the menu hangs rightwards from the trigger's own
|
|
283
|
+
* left edge instead, still kept inside the viewport.
|
|
284
|
+
*/
|
|
285
|
+
const left: number | undefined = isOverflowingLeft
|
|
286
|
+
? Math.max(
|
|
287
|
+
Math.min(
|
|
288
|
+
triggerRect.left,
|
|
289
|
+
viewportWidth - PORTALED_MENU_VIEWPORT_PADDING_PX - menuWidth,
|
|
290
|
+
),
|
|
291
|
+
PORTALED_MENU_VIEWPORT_PADDING_PX,
|
|
292
|
+
)
|
|
293
|
+
: undefined;
|
|
294
|
+
|
|
295
|
+
const spaceBelow: number =
|
|
296
|
+
viewportHeight -
|
|
297
|
+
triggerRect.bottom -
|
|
298
|
+
PORTALED_MENU_GAP_PX -
|
|
299
|
+
PORTALED_MENU_VIEWPORT_PADDING_PX;
|
|
300
|
+
const spaceAbove: number =
|
|
301
|
+
triggerRect.top -
|
|
302
|
+
PORTALED_MENU_GAP_PX -
|
|
303
|
+
PORTALED_MENU_VIEWPORT_PADDING_PX;
|
|
304
|
+
const isAbove: boolean = props.isOpeningUpwards
|
|
305
|
+
? spaceAbove >= menuHeight || spaceAbove > spaceBelow
|
|
306
|
+
: menuHeight > spaceBelow && spaceAbove > spaceBelow;
|
|
307
|
+
|
|
308
|
+
setPortaledMenuPosition({
|
|
309
|
+
top: isAbove ? undefined : triggerRect.bottom + PORTALED_MENU_GAP_PX,
|
|
310
|
+
bottom: isAbove
|
|
311
|
+
? viewportHeight - triggerRect.top + PORTALED_MENU_GAP_PX
|
|
312
|
+
: undefined,
|
|
313
|
+
left,
|
|
314
|
+
right,
|
|
315
|
+
isAbove,
|
|
316
|
+
});
|
|
317
|
+
}, [buttonId, props.isOpeningUpwards, ref]);
|
|
318
|
+
|
|
319
|
+
/*
|
|
320
|
+
* Measured before paint, so the menu never flashes at the corner of the
|
|
321
|
+
* viewport; until then it is mounted `visibility: hidden`. Repositioned on
|
|
322
|
+
* every scroll (captured, because the table's own scroller does not bubble
|
|
323
|
+
* one to window) so it stays attached to its trigger.
|
|
324
|
+
*/
|
|
325
|
+
useLayoutEffect(() => {
|
|
326
|
+
if (!isMenuPortaled || !isComponentVisible) {
|
|
327
|
+
setPortaledMenuPosition(null);
|
|
328
|
+
return undefined;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
let animationFrame: number | null = null;
|
|
332
|
+
|
|
333
|
+
const schedulePositionUpdate: () => void = (): void => {
|
|
334
|
+
if (animationFrame !== null) {
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
animationFrame = window.requestAnimationFrame((): void => {
|
|
339
|
+
animationFrame = null;
|
|
340
|
+
updatePortaledMenuPosition();
|
|
341
|
+
});
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
updatePortaledMenuPosition();
|
|
345
|
+
|
|
346
|
+
window.addEventListener("resize", schedulePositionUpdate);
|
|
347
|
+
document.addEventListener("scroll", schedulePositionUpdate, true);
|
|
348
|
+
|
|
349
|
+
/*
|
|
350
|
+
* The menu's own size decides whether it fits below its trigger, and
|
|
351
|
+
* that size can change after it opens - its styles arriving late (see
|
|
352
|
+
* updatePortaledMenuPosition), or its items changing. Place it again
|
|
353
|
+
* whenever it does.
|
|
354
|
+
*/
|
|
355
|
+
const menuElement: HTMLElement | null = ref.current as HTMLElement | null;
|
|
356
|
+
const resizeObserver: ResizeObserver | null =
|
|
357
|
+
menuElement && typeof ResizeObserver !== "undefined"
|
|
358
|
+
? new ResizeObserver(schedulePositionUpdate)
|
|
359
|
+
: null;
|
|
360
|
+
|
|
361
|
+
if (menuElement && resizeObserver) {
|
|
362
|
+
resizeObserver.observe(menuElement);
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return () => {
|
|
366
|
+
window.removeEventListener("resize", schedulePositionUpdate);
|
|
367
|
+
document.removeEventListener("scroll", schedulePositionUpdate, true);
|
|
368
|
+
resizeObserver?.disconnect();
|
|
369
|
+
if (animationFrame !== null) {
|
|
370
|
+
window.cancelAnimationFrame(animationFrame);
|
|
371
|
+
}
|
|
372
|
+
};
|
|
373
|
+
}, [isMenuPortaled, isComponentVisible, ref, updatePortaledMenuPosition]);
|
|
374
|
+
|
|
375
|
+
/*
|
|
376
|
+
* A portalled menu is not inside the Modal it was opened from, so a press
|
|
377
|
+
* outside it could also read as a press on that Modal's backdrop. The press
|
|
378
|
+
* is spent on closing the menu; claim it so the dialog behind survives.
|
|
379
|
+
*/
|
|
380
|
+
useEffect(() => {
|
|
381
|
+
if (!isMenuPortaled || !isComponentVisible) {
|
|
382
|
+
return undefined;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
const handlePointerDown: (event: MouseEvent) => void = (
|
|
386
|
+
event: MouseEvent,
|
|
387
|
+
): void => {
|
|
388
|
+
const target: EventTarget | null = event.target;
|
|
389
|
+
|
|
390
|
+
if (!(target instanceof Node)) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
const menuElement: HTMLElement | null =
|
|
395
|
+
ref.current as HTMLElement | null;
|
|
396
|
+
|
|
397
|
+
if (
|
|
398
|
+
menuElement?.contains(target) ||
|
|
399
|
+
document.getElementById(buttonId)?.contains(target)
|
|
400
|
+
) {
|
|
401
|
+
return;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
consumePressForAnchoredPopup(event);
|
|
405
|
+
};
|
|
406
|
+
|
|
407
|
+
document.addEventListener("mousedown", handlePointerDown, true);
|
|
408
|
+
|
|
409
|
+
return () => {
|
|
410
|
+
document.removeEventListener("mousedown", handlePointerDown, true);
|
|
411
|
+
};
|
|
412
|
+
}, [buttonId, isMenuPortaled, isComponentVisible, ref]);
|
|
413
|
+
|
|
414
|
+
/*
|
|
415
|
+
* A portalled menu is `visibility: hidden` until it has been measured, and
|
|
416
|
+
* a hidden element refuses focus - so the first item is focused once the
|
|
417
|
+
* menu has a position, not merely once it is open.
|
|
418
|
+
*/
|
|
419
|
+
const isMenuPlaced: boolean =
|
|
420
|
+
!isMenuPortaled || portaledMenuPosition !== null;
|
|
421
|
+
|
|
172
422
|
useEffect(() => {
|
|
173
423
|
const menuItems: Array<HTMLElement> = getMenuItems();
|
|
174
424
|
|
|
@@ -176,6 +426,10 @@ const MoreMenu: React.ForwardRefExoticComponent<
|
|
|
176
426
|
item.tabIndex = index === focusedIndex ? 0 : -1;
|
|
177
427
|
});
|
|
178
428
|
|
|
429
|
+
if (!isMenuPlaced) {
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
|
|
179
433
|
if (focusedIndex >= 0 && menuItems.length > 0) {
|
|
180
434
|
const safeFocusedIndex: number = Math.min(
|
|
181
435
|
focusedIndex,
|
|
@@ -188,7 +442,13 @@ const MoreMenu: React.ForwardRefExoticComponent<
|
|
|
188
442
|
menuItems[safeFocusedIndex]?.focus();
|
|
189
443
|
}
|
|
190
444
|
}
|
|
191
|
-
}, [
|
|
445
|
+
}, [
|
|
446
|
+
focusedIndex,
|
|
447
|
+
getMenuItems,
|
|
448
|
+
isComponentVisible,
|
|
449
|
+
isMenuPlaced,
|
|
450
|
+
props.children,
|
|
451
|
+
]);
|
|
192
452
|
|
|
193
453
|
const restoreFocusToTrigger: () => void = useCallback((): void => {
|
|
194
454
|
/*
|
|
@@ -231,6 +491,16 @@ const MoreMenu: React.ForwardRefExoticComponent<
|
|
|
231
491
|
|
|
232
492
|
if (event.key === "Tab") {
|
|
233
493
|
setIsComponentVisible(false);
|
|
494
|
+
|
|
495
|
+
/*
|
|
496
|
+
* A portalled menu sits at the end of the body, so the browser's own
|
|
497
|
+
* Tab would carry focus from it to whatever follows the body - out
|
|
498
|
+
* of the table, and out of any dialog it is in. Hand focus back to
|
|
499
|
+
* the trigger first and let the same Tab move on from there.
|
|
500
|
+
*/
|
|
501
|
+
if (isMenuPortaled) {
|
|
502
|
+
focusTrigger();
|
|
503
|
+
}
|
|
234
504
|
return;
|
|
235
505
|
}
|
|
236
506
|
|
|
@@ -311,6 +581,7 @@ const MoreMenu: React.ForwardRefExoticComponent<
|
|
|
311
581
|
focusTrigger,
|
|
312
582
|
getMenuItems,
|
|
313
583
|
isComponentVisible,
|
|
584
|
+
isMenuPortaled,
|
|
314
585
|
setIsComponentVisible,
|
|
315
586
|
],
|
|
316
587
|
);
|
|
@@ -337,6 +608,36 @@ const MoreMenu: React.ForwardRefExoticComponent<
|
|
|
337
608
|
}
|
|
338
609
|
};
|
|
339
610
|
|
|
611
|
+
/*
|
|
612
|
+
* Hand focus back to the trigger BEFORE the chosen item's own handler runs.
|
|
613
|
+
* Most items open a dialog (Edit, Delete, Show ID), and Modal remembers
|
|
614
|
+
* whatever held focus when it first rendered so it can return focus there
|
|
615
|
+
* on close. Left alone, that is the menu item - which the same update
|
|
616
|
+
* unmounts - so closing the dialog dropped focus to <body>. With the
|
|
617
|
+
* trigger focused first, the dialog remembers the trigger instead; an item
|
|
618
|
+
* that moves focus somewhere itself still wins, because it runs after.
|
|
619
|
+
*/
|
|
620
|
+
const handleMenuClickCapture: (
|
|
621
|
+
event: React.MouseEvent<HTMLDivElement>,
|
|
622
|
+
) => void = (event: React.MouseEvent<HTMLDivElement>): void => {
|
|
623
|
+
const eventTarget: EventTarget = event.target;
|
|
624
|
+
|
|
625
|
+
if (!(eventTarget instanceof Element)) {
|
|
626
|
+
return;
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
const menuItem: Element | null = eventTarget.closest('[role="menuitem"]');
|
|
630
|
+
|
|
631
|
+
if (
|
|
632
|
+
menuItem instanceof HTMLElement &&
|
|
633
|
+
event.currentTarget.contains(menuItem) &&
|
|
634
|
+
!isMenuItemDisabled(menuItem) &&
|
|
635
|
+
isComponentVisible
|
|
636
|
+
) {
|
|
637
|
+
focusTrigger();
|
|
638
|
+
}
|
|
639
|
+
};
|
|
640
|
+
|
|
340
641
|
const getNativeButtonTrigger: () => ReactElement | null =
|
|
341
642
|
(): ReactElement | null => {
|
|
342
643
|
if (!customTrigger || !isNativeButtonTrigger) {
|
|
@@ -378,6 +679,63 @@ const MoreMenu: React.ForwardRefExoticComponent<
|
|
|
378
679
|
});
|
|
379
680
|
};
|
|
380
681
|
|
|
682
|
+
const isMenuAbove: boolean = isMenuPortaled
|
|
683
|
+
? Boolean(portaledMenuPosition?.isAbove)
|
|
684
|
+
: Boolean(props.isOpeningUpwards);
|
|
685
|
+
|
|
686
|
+
const menuPortalTarget: HTMLElement | null = isMenuPortaled
|
|
687
|
+
? getMenuPortalTarget()
|
|
688
|
+
: null;
|
|
689
|
+
|
|
690
|
+
const menu: ReactElement = (
|
|
691
|
+
<div
|
|
692
|
+
ref={ref}
|
|
693
|
+
id={menuId}
|
|
694
|
+
/*
|
|
695
|
+
* Once settled the menu carries no transform class at all: a
|
|
696
|
+
* lingering scale would make it the containing block for any
|
|
697
|
+
* position:fixed descendant (the Modal invariant).
|
|
698
|
+
*/
|
|
699
|
+
className={`${
|
|
700
|
+
/*
|
|
701
|
+
* The portalled menu takes its place and layer from the inline
|
|
702
|
+
* style below instead.
|
|
703
|
+
*/
|
|
704
|
+
isMenuPortaled
|
|
705
|
+
? "w-56 rounded-lg"
|
|
706
|
+
: "absolute right-0 z-50 w-56 rounded-lg"
|
|
707
|
+
} bg-white text-left shadow-xl ring-1 ring-gray-200 focus:outline-none py-1 transition duration-150 ease-out motion-reduce:transition-none ${
|
|
708
|
+
isMenuAbove
|
|
709
|
+
? `${isMenuPortaled ? "" : "bottom-full mb-2 "}origin-bottom-right`
|
|
710
|
+
: `${isMenuPortaled ? "" : "mt-2 "}origin-top-right`
|
|
711
|
+
} ${hasMenuEntered ? "opacity-100" : "opacity-0 scale-95"}`}
|
|
712
|
+
style={
|
|
713
|
+
isMenuPortaled
|
|
714
|
+
? {
|
|
715
|
+
position: "fixed",
|
|
716
|
+
top: portaledMenuPosition?.top,
|
|
717
|
+
bottom: portaledMenuPosition?.bottom,
|
|
718
|
+
left: portaledMenuPosition ? portaledMenuPosition.left : 0,
|
|
719
|
+
right: portaledMenuPosition?.right,
|
|
720
|
+
zIndex: DROPDOWN_MENU_Z_INDEX,
|
|
721
|
+
visibility: portaledMenuPosition ? "visible" : "hidden",
|
|
722
|
+
}
|
|
723
|
+
: undefined
|
|
724
|
+
}
|
|
725
|
+
role="menu"
|
|
726
|
+
aria-orientation="vertical"
|
|
727
|
+
aria-labelledby={buttonId}
|
|
728
|
+
onClickCapture={handleMenuClickCapture}
|
|
729
|
+
onClick={handleMenuClick}
|
|
730
|
+
>
|
|
731
|
+
{props.children.map((child: ReactElement, index: number) => {
|
|
732
|
+
return (
|
|
733
|
+
<React.Fragment key={child.key || index}>{child}</React.Fragment>
|
|
734
|
+
);
|
|
735
|
+
})}
|
|
736
|
+
</div>
|
|
737
|
+
);
|
|
738
|
+
|
|
381
739
|
return (
|
|
382
740
|
<div
|
|
383
741
|
className="relative inline-block text-left"
|
|
@@ -463,34 +821,11 @@ const MoreMenu: React.ForwardRefExoticComponent<
|
|
|
463
821
|
</div>
|
|
464
822
|
)}
|
|
465
823
|
|
|
466
|
-
{isComponentVisible &&
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
* Once settled the menu carries no transform class at all: a
|
|
472
|
-
* lingering scale would make it the containing block for any
|
|
473
|
-
* position:fixed descendant (the Modal invariant).
|
|
474
|
-
*/
|
|
475
|
-
className={`absolute right-0 z-50 w-56 rounded-lg bg-white shadow-xl ring-1 ring-gray-200 focus:outline-none py-1 transition duration-150 ease-out motion-reduce:transition-none ${
|
|
476
|
-
props.isOpeningUpwards
|
|
477
|
-
? "bottom-full mb-2 origin-bottom-right"
|
|
478
|
-
: "mt-2 origin-top-right"
|
|
479
|
-
} ${hasMenuEntered ? "opacity-100" : "opacity-0 scale-95"}`}
|
|
480
|
-
role="menu"
|
|
481
|
-
aria-orientation="vertical"
|
|
482
|
-
aria-labelledby={buttonId}
|
|
483
|
-
onClick={handleMenuClick}
|
|
484
|
-
>
|
|
485
|
-
{props.children.map((child: ReactElement, index: number) => {
|
|
486
|
-
return (
|
|
487
|
-
<React.Fragment key={child.key || index}>
|
|
488
|
-
{child}
|
|
489
|
-
</React.Fragment>
|
|
490
|
-
);
|
|
491
|
-
})}
|
|
492
|
-
</div>
|
|
493
|
-
)}
|
|
824
|
+
{isComponentVisible && !isMenuPortaled && menu}
|
|
825
|
+
{isComponentVisible &&
|
|
826
|
+
isMenuPortaled &&
|
|
827
|
+
menuPortalTarget &&
|
|
828
|
+
createPortal(menu, menuPortalTarget)}
|
|
494
829
|
</div>
|
|
495
830
|
);
|
|
496
831
|
},
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { FunctionComponent, ReactElement } from "react";
|
|
1
|
+
import React, { FunctionComponent, ReactElement, useId } from "react";
|
|
2
2
|
import IconProp from "../../../Types/Icon/IconProp";
|
|
3
3
|
import Icon from "../Icon/Icon";
|
|
4
4
|
import Tooltip from "../Tooltip/Tooltip";
|
|
@@ -15,12 +15,51 @@ export interface ComponentProps {
|
|
|
15
15
|
* Shown on hover - the place a locked menu item says why it is locked.
|
|
16
16
|
*/
|
|
17
17
|
tooltip?: string | undefined;
|
|
18
|
+
/*
|
|
19
|
+
* Red text and a red hover, for the items that delete or remove something.
|
|
20
|
+
* The menu is where a table puts those, so they need to read as dangerous
|
|
21
|
+
* without a button border to say so.
|
|
22
|
+
*/
|
|
23
|
+
isDestructive?: boolean | undefined;
|
|
24
|
+
/*
|
|
25
|
+
* Keep the icon's gutter even when this item has no icon, so its label lines
|
|
26
|
+
* up with the labels of the items around it that do.
|
|
27
|
+
*/
|
|
28
|
+
isIconSpaceReserved?: boolean | undefined;
|
|
18
29
|
}
|
|
19
30
|
|
|
20
31
|
const MoreMenuItem: FunctionComponent<ComponentProps> = (
|
|
21
32
|
props: ComponentProps,
|
|
22
33
|
): ReactElement => {
|
|
23
34
|
const isDisabled: boolean = Boolean(props.isDisabled);
|
|
35
|
+
const isDestructive: boolean = Boolean(props.isDestructive);
|
|
36
|
+
const reasonId: string = useId();
|
|
37
|
+
|
|
38
|
+
/*
|
|
39
|
+
* A locked item that says why it is locked stays reachable. Table rows now
|
|
40
|
+
* keep their permission-locked actions in the ⋯ menu ("You need the Delete
|
|
41
|
+
* permission"), and a natively disabled button can neither take focus nor
|
|
42
|
+
* show a tooltip on focus - so the explanation would exist for the mouse
|
|
43
|
+
* only. Such an item is aria-disabled instead: MoreMenu's roving focus
|
|
44
|
+
* lands on it, the reason is announced through aria-describedby and shown
|
|
45
|
+
* by the tooltip, and activating it does nothing. A locked item with nothing
|
|
46
|
+
* to say stays natively disabled and is skipped, as before.
|
|
47
|
+
*/
|
|
48
|
+
const isExplainedLock: boolean = isDisabled && Boolean(props.tooltip);
|
|
49
|
+
|
|
50
|
+
const colorClassName: string = isDestructive
|
|
51
|
+
? "text-red-600"
|
|
52
|
+
: "text-gray-700";
|
|
53
|
+
|
|
54
|
+
/*
|
|
55
|
+
* Keyboard focus gets the same highlight as the pointer's hover, so an item
|
|
56
|
+
* reached with the arrow keys looks exactly as active as one under the mouse.
|
|
57
|
+
*/
|
|
58
|
+
const stateClassName: string = isDisabled
|
|
59
|
+
? "cursor-not-allowed opacity-50 focus-visible:outline-none focus-visible:bg-gray-100"
|
|
60
|
+
: isDestructive
|
|
61
|
+
? "cursor-pointer hover:bg-red-50 hover:text-red-700 focus-visible:outline-none focus-visible:bg-red-50 focus-visible:text-red-700"
|
|
62
|
+
: "cursor-pointer hover:bg-indigo-50 hover:text-gray-900 focus-visible:outline-none focus-visible:bg-indigo-50 focus-visible:text-gray-900";
|
|
24
63
|
|
|
25
64
|
const menuItem: ReactElement = (
|
|
26
65
|
/*
|
|
@@ -30,23 +69,36 @@ const MoreMenuItem: FunctionComponent<ComponentProps> = (
|
|
|
30
69
|
*/
|
|
31
70
|
<button
|
|
32
71
|
type="button"
|
|
33
|
-
className={`group mx-1 flex w-[calc(100%-0.5rem)] items-center rounded-md px-3 py-2 text-left text-sm
|
|
34
|
-
|
|
35
|
-
}
|
|
72
|
+
className={`group mx-1 flex w-[calc(100%-0.5rem)] items-center rounded-md px-3 py-2 text-left text-sm transition-colors duration-100 ${colorClassName} ${stateClassName} ${
|
|
73
|
+
props.className || ""
|
|
74
|
+
}`}
|
|
36
75
|
role="menuitem"
|
|
37
76
|
tabIndex={-1}
|
|
38
|
-
disabled={isDisabled}
|
|
77
|
+
disabled={isDisabled && !isExplainedLock}
|
|
39
78
|
aria-disabled={isDisabled}
|
|
79
|
+
aria-describedby={isExplainedLock ? reasonId : undefined}
|
|
80
|
+
data-focusable-when-disabled={isExplainedLock ? "true" : undefined}
|
|
40
81
|
onClick={() => {
|
|
82
|
+
if (isDisabled) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
41
86
|
props.onClick();
|
|
42
87
|
}}
|
|
43
88
|
>
|
|
44
89
|
{props.icon && (
|
|
45
90
|
<Icon
|
|
46
91
|
icon={props.icon}
|
|
47
|
-
className={`mr-2.5 h-4 w-4
|
|
92
|
+
className={`mr-2.5 h-4 w-4 shrink-0 transition-colors duration-100 ${
|
|
93
|
+
isDestructive
|
|
94
|
+
? `text-red-500 ${isDisabled ? "" : "group-hover:text-red-600"}`
|
|
95
|
+
: `text-gray-400 ${isDisabled ? "" : "group-hover:text-indigo-500"}`
|
|
96
|
+
} ${props.iconClassName || ""}`}
|
|
48
97
|
/>
|
|
49
98
|
)}
|
|
99
|
+
{!props.icon && props.isIconSpaceReserved && (
|
|
100
|
+
<span className="mr-2.5 h-4 w-4 shrink-0" aria-hidden="true"></span>
|
|
101
|
+
)}
|
|
50
102
|
<div className="flex w-full justify-between items-center">
|
|
51
103
|
<div className="font-medium">{props.text}</div>
|
|
52
104
|
<div>{props.rightElement}</div>
|
|
@@ -58,20 +110,21 @@ const MoreMenuItem: FunctionComponent<ComponentProps> = (
|
|
|
58
110
|
return menuItem;
|
|
59
111
|
}
|
|
60
112
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
*/
|
|
68
|
-
if (isDisabled) {
|
|
113
|
+
if (isExplainedLock) {
|
|
114
|
+
/*
|
|
115
|
+
* The reason sits outside the button so it describes the item without
|
|
116
|
+
* becoming part of its name - the item is still "Delete", not "Delete You
|
|
117
|
+
* do not have permission to delete this Monitor.".
|
|
118
|
+
*/
|
|
69
119
|
return (
|
|
70
|
-
|
|
71
|
-
<
|
|
120
|
+
<>
|
|
121
|
+
<Tooltip text={props.tooltip} isTriggerAlreadyDescribed={true}>
|
|
72
122
|
{menuItem}
|
|
123
|
+
</Tooltip>
|
|
124
|
+
<span id={reasonId} className="sr-only">
|
|
125
|
+
{props.tooltip}
|
|
73
126
|
</span>
|
|
74
|
-
|
|
127
|
+
</>
|
|
75
128
|
);
|
|
76
129
|
}
|
|
77
130
|
|