@massdriver/backstage-plugin 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +202 -0
- package/README.md +196 -0
- package/dist/MassdriverRouter.esm.js +78 -0
- package/dist/MassdriverRouter.esm.js.map +1 -0
- package/dist/api.esm.js +119 -0
- package/dist/api.esm.js.map +1 -0
- package/dist/assets/massdriver-logo-dark.svg +55 -0
- package/dist/assets/massdriver-logo-light.svg +50 -0
- package/dist/components/AttributesColumn.esm.js +95 -0
- package/dist/components/AttributesColumn.esm.js.map +1 -0
- package/dist/components/AttributesSummaryCell.esm.js +103 -0
- package/dist/components/AttributesSummaryCell.esm.js.map +1 -0
- package/dist/components/AuthedIcon.esm.js +26 -0
- package/dist/components/AuthedIcon.esm.js.map +1 -0
- package/dist/components/ConditionsCell.esm.js +48 -0
- package/dist/components/ConditionsCell.esm.js.map +1 -0
- package/dist/components/DisabledAction.esm.js +30 -0
- package/dist/components/DisabledAction.esm.js.map +1 -0
- package/dist/components/EntityMassdriverContent/EntityMassdriverContent.esm.js +80 -0
- package/dist/components/EntityMassdriverContent/EntityMassdriverContent.esm.js.map +1 -0
- package/dist/components/EntityMassdriverContent/index.esm.js +6 -0
- package/dist/components/EntityMassdriverContent/index.esm.js.map +1 -0
- package/dist/components/EntityMassdriverOverviewCard/EntityMassdriverOverviewCard.esm.js +75 -0
- package/dist/components/EntityMassdriverOverviewCard/EntityMassdriverOverviewCard.esm.js.map +1 -0
- package/dist/components/EntityMassdriverOverviewCard/index.esm.js +6 -0
- package/dist/components/EntityMassdriverOverviewCard/index.esm.js.map +1 -0
- package/dist/components/ForkPill.esm.js +84 -0
- package/dist/components/ForkPill.esm.js.map +1 -0
- package/dist/components/InstanceStatusIndicator.esm.js +21 -0
- package/dist/components/InstanceStatusIndicator.esm.js.map +1 -0
- package/dist/components/InstanceStatusPill.esm.js +67 -0
- package/dist/components/InstanceStatusPill.esm.js.map +1 -0
- package/dist/components/MassdriverIcon.esm.js +13 -0
- package/dist/components/MassdriverIcon.esm.js.map +1 -0
- package/dist/components/MassdriverSidebarItem.esm.js +45 -0
- package/dist/components/MassdriverSidebarItem.esm.js.map +1 -0
- package/dist/components/NotFound.esm.js +44 -0
- package/dist/components/NotFound.esm.js.map +1 -0
- package/dist/components/OpenInMassdriverButton.esm.js +24 -0
- package/dist/components/OpenInMassdriverButton.esm.js.map +1 -0
- package/dist/components/PageLayout.esm.js +88 -0
- package/dist/components/PageLayout.esm.js.map +1 -0
- package/dist/components/RouterLinkAdapter.esm.js +12 -0
- package/dist/components/RouterLinkAdapter.esm.js.map +1 -0
- package/dist/components/VersionBadge.esm.js +57 -0
- package/dist/components/VersionBadge.esm.js.map +1 -0
- package/dist/components/grantColumns.esm.js +56 -0
- package/dist/components/grantColumns.esm.js.map +1 -0
- package/dist/components/icons/BundleIcon.esm.js +7 -0
- package/dist/components/icons/BundleIcon.esm.js.map +1 -0
- package/dist/components/icons/FolderOutlinedIcon.esm.js +7 -0
- package/dist/components/icons/FolderOutlinedIcon.esm.js.map +1 -0
- package/dist/components/icons/TokenIcon.esm.js +7 -0
- package/dist/components/icons/TokenIcon.esm.js.map +1 -0
- package/dist/entity.esm.js +23 -0
- package/dist/entity.esm.js.map +1 -0
- package/dist/features/environment/CompareDeploymentsDialog/CompareDeploymentsDialog.esm.js +115 -0
- package/dist/features/environment/CompareDeploymentsDialog/CompareDeploymentsDialog.esm.js.map +1 -0
- package/dist/features/environment/CompareDeploymentsDialog/ResultsStep.esm.js +165 -0
- package/dist/features/environment/CompareDeploymentsDialog/ResultsStep.esm.js.map +1 -0
- package/dist/features/environment/CompareDeploymentsDialog/SelectStep.esm.js +216 -0
- package/dist/features/environment/CompareDeploymentsDialog/SelectStep.esm.js.map +1 -0
- package/dist/features/environment/CompareDeploymentsDialog/compareColumns.esm.js +86 -0
- package/dist/features/environment/CompareDeploymentsDialog/compareColumns.esm.js.map +1 -0
- package/dist/features/environment/CompareDeploymentsDialog/flattenDeploymentComparison.esm.js +57 -0
- package/dist/features/environment/CompareDeploymentsDialog/flattenDeploymentComparison.esm.js.map +1 -0
- package/dist/features/environment/CompareDeploymentsDialog/queries.esm.js +53 -0
- package/dist/features/environment/CompareDeploymentsDialog/queries.esm.js.map +1 -0
- package/dist/features/environment/CompareEnvironmentsDialog/CompareEnvironmentsDialog.esm.js +94 -0
- package/dist/features/environment/CompareEnvironmentsDialog/CompareEnvironmentsDialog.esm.js.map +1 -0
- package/dist/features/environment/CompareEnvironmentsDialog/ComparisonValueCell.esm.js +67 -0
- package/dist/features/environment/CompareEnvironmentsDialog/ComparisonValueCell.esm.js.map +1 -0
- package/dist/features/environment/CompareEnvironmentsDialog/ResultsStep.esm.js +202 -0
- package/dist/features/environment/CompareEnvironmentsDialog/ResultsStep.esm.js.map +1 -0
- package/dist/features/environment/CompareEnvironmentsDialog/SelectStep.esm.js +183 -0
- package/dist/features/environment/CompareEnvironmentsDialog/SelectStep.esm.js.map +1 -0
- package/dist/features/environment/CompareEnvironmentsDialog/compareColumns.esm.js +73 -0
- package/dist/features/environment/CompareEnvironmentsDialog/compareColumns.esm.js.map +1 -0
- package/dist/features/environment/CompareEnvironmentsDialog/flattenComparison.esm.js +70 -0
- package/dist/features/environment/CompareEnvironmentsDialog/flattenComparison.esm.js.map +1 -0
- package/dist/features/environment/CompareEnvironmentsDialog/queries.esm.js +32 -0
- package/dist/features/environment/CompareEnvironmentsDialog/queries.esm.js.map +1 -0
- package/dist/features/environment/EnvironmentGraphPage.esm.js +131 -0
- package/dist/features/environment/EnvironmentGraphPage.esm.js.map +1 -0
- package/dist/features/environment/GraphHeader/EnvironmentDefaults.esm.js +252 -0
- package/dist/features/environment/GraphHeader/EnvironmentDefaults.esm.js.map +1 -0
- package/dist/features/environment/GraphHeader/GraphHeader.esm.js +247 -0
- package/dist/features/environment/GraphHeader/GraphHeader.esm.js.map +1 -0
- package/dist/features/environment/GraphHeader/HeaderActions.esm.js +127 -0
- package/dist/features/environment/GraphHeader/HeaderActions.esm.js.map +1 -0
- package/dist/features/environment/GraphHeader/Switcher.esm.js +75 -0
- package/dist/features/environment/GraphHeader/Switcher.esm.js.map +1 -0
- package/dist/features/environment/GraphHeader/queries.esm.js +60 -0
- package/dist/features/environment/GraphHeader/queries.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/AlarmCard.esm.js +151 -0
- package/dist/features/environment/InstanceDrawer/AlarmCard.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/InstanceDrawer.esm.js +165 -0
- package/dist/features/environment/InstanceDrawer/InstanceDrawer.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/InstanceDrawerHeader.esm.js +241 -0
- package/dist/features/environment/InstanceDrawer/InstanceDrawerHeader.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/InstanceTabs.esm.js +119 -0
- package/dist/features/environment/InstanceDrawer/InstanceTabs.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/TabState.esm.js +30 -0
- package/dist/features/environment/InstanceDrawer/TabState.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/formsDataSource.esm.js +25 -0
- package/dist/features/environment/InstanceDrawer/formsDataSource.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/helpers.esm.js +282 -0
- package/dist/features/environment/InstanceDrawer/helpers.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/queries.esm.js +281 -0
- package/dist/features/environment/InstanceDrawer/queries.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/tabs/ConfigTab.esm.js +170 -0
- package/dist/features/environment/InstanceDrawer/tabs/ConfigTab.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/tabs/DependenciesTab.esm.js +413 -0
- package/dist/features/environment/InstanceDrawer/tabs/DependenciesTab.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/tabs/DeploymentLogsPanel.esm.js +191 -0
- package/dist/features/environment/InstanceDrawer/tabs/DeploymentLogsPanel.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/tabs/DeploymentReadOnlyActions.esm.js +63 -0
- package/dist/features/environment/InstanceDrawer/tabs/DeploymentReadOnlyActions.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/tabs/GuideTab.esm.js +48 -0
- package/dist/features/environment/InstanceDrawer/tabs/GuideTab.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/tabs/HistoryTab.esm.js +446 -0
- package/dist/features/environment/InstanceDrawer/tabs/HistoryTab.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/tabs/MonitorTab.esm.js +146 -0
- package/dist/features/environment/InstanceDrawer/tabs/MonitorTab.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/tabs/OverviewTab.esm.js +572 -0
- package/dist/features/environment/InstanceDrawer/tabs/OverviewTab.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/tabs/ResourcesTab.esm.js +471 -0
- package/dist/features/environment/InstanceDrawer/tabs/ResourcesTab.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/tabs/SecretsTab.esm.js +109 -0
- package/dist/features/environment/InstanceDrawer/tabs/SecretsTab.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/tabs/ViewDeploymentDetails.esm.js +384 -0
- package/dist/features/environment/InstanceDrawer/tabs/ViewDeploymentDetails.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/tabs/flattenParams.esm.js +23 -0
- package/dist/features/environment/InstanceDrawer/tabs/flattenParams.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/useInstanceApiQuery.esm.js +6 -0
- package/dist/features/environment/InstanceDrawer/useInstanceApiQuery.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/useOverflowMeasure.esm.js +55 -0
- package/dist/features/environment/InstanceDrawer/useOverflowMeasure.esm.js.map +1 -0
- package/dist/features/environment/InstanceDrawer/useResizableWidth.esm.js +44 -0
- package/dist/features/environment/InstanceDrawer/useResizableWidth.esm.js.map +1 -0
- package/dist/features/environment/components/InstanceStatusPill.esm.js +54 -0
- package/dist/features/environment/components/InstanceStatusPill.esm.js.map +1 -0
- package/dist/features/environment/graph/Diagram.esm.js +143 -0
- package/dist/features/environment/graph/Diagram.esm.js.map +1 -0
- package/dist/features/environment/graph/DiagramNode.constants.esm.js +5 -0
- package/dist/features/environment/graph/DiagramNode.constants.esm.js.map +1 -0
- package/dist/features/environment/graph/DiagramNode.esm.js +221 -0
- package/dist/features/environment/graph/DiagramNode.esm.js.map +1 -0
- package/dist/features/environment/graph/NodeMeta.esm.js +182 -0
- package/dist/features/environment/graph/NodeMeta.esm.js.map +1 -0
- package/dist/features/environment/graph/NodeVersionBadges.esm.js +150 -0
- package/dist/features/environment/graph/NodeVersionBadges.esm.js.map +1 -0
- package/dist/features/environment/graph/diagramFactory.esm.js +151 -0
- package/dist/features/environment/graph/diagramFactory.esm.js.map +1 -0
- package/dist/features/environment/graph/handles/ExpandableHandleWrapper.esm.js +174 -0
- package/dist/features/environment/graph/handles/ExpandableHandleWrapper.esm.js.map +1 -0
- package/dist/features/environment/graph/handles/NodeHandle.esm.js +45 -0
- package/dist/features/environment/graph/handles/NodeHandle.esm.js.map +1 -0
- package/dist/features/environment/graph/handles/NodeHandleTooltip.esm.js +134 -0
- package/dist/features/environment/graph/handles/NodeHandleTooltip.esm.js.map +1 -0
- package/dist/features/environment/graph/handles/handleTypes.esm.js +170 -0
- package/dist/features/environment/graph/handles/handleTypes.esm.js.map +1 -0
- package/dist/features/environment/graph/handles/useAnimationFrameSync.esm.js +19 -0
- package/dist/features/environment/graph/handles/useAnimationFrameSync.esm.js.map +1 -0
- package/dist/features/environment/graph/handles/useRadialPositions.esm.js +37 -0
- package/dist/features/environment/graph/handles/useRadialPositions.esm.js.map +1 -0
- package/dist/features/environment/graph/handles/useTransitionLifecycle.esm.js +19 -0
- package/dist/features/environment/graph/handles/useTransitionLifecycle.esm.js.map +1 -0
- package/dist/features/environment/graph/hasUndeployedPlan.esm.js +43 -0
- package/dist/features/environment/graph/hasUndeployedPlan.esm.js.map +1 -0
- package/dist/features/environment/graph/queries.esm.js +103 -0
- package/dist/features/environment/graph/queries.esm.js.map +1 -0
- package/dist/features/environment/graph/useDiagramSnapshot.esm.js +43 -0
- package/dist/features/environment/graph/useDiagramSnapshot.esm.js.map +1 -0
- package/dist/features/environment/realtime/RealtimeProvider.esm.js +43 -0
- package/dist/features/environment/realtime/RealtimeProvider.esm.js.map +1 -0
- package/dist/features/environment/realtime/queries.esm.js +76 -0
- package/dist/features/environment/realtime/queries.esm.js.map +1 -0
- package/dist/features/environment/realtime/useLiveRelayQuery.esm.js +36 -0
- package/dist/features/environment/realtime/useLiveRelayQuery.esm.js.map +1 -0
- package/dist/features/project/ProjectDetailsPage.esm.js +101 -0
- package/dist/features/project/ProjectDetailsPage.esm.js.map +1 -0
- package/dist/features/project/tabs/ComponentsTab.esm.js +149 -0
- package/dist/features/project/tabs/ComponentsTab.esm.js.map +1 -0
- package/dist/features/project/tabs/EnvStatus.esm.js +149 -0
- package/dist/features/project/tabs/EnvStatus.esm.js.map +1 -0
- package/dist/features/project/tabs/EnvironmentsTab.esm.js +199 -0
- package/dist/features/project/tabs/EnvironmentsTab.esm.js.map +1 -0
- package/dist/features/project/tabs/OverviewTab.esm.js +420 -0
- package/dist/features/project/tabs/OverviewTab.esm.js.map +1 -0
- package/dist/features/projects/ProjectsListPage.esm.js +50 -0
- package/dist/features/projects/ProjectsListPage.esm.js.map +1 -0
- package/dist/features/projects/ProjectsListPageLazy.esm.js +12 -0
- package/dist/features/projects/ProjectsListPageLazy.esm.js.map +1 -0
- package/dist/features/projects/projectColumns.esm.js +38 -0
- package/dist/features/projects/projectColumns.esm.js.map +1 -0
- package/dist/features/projects/useProjects.esm.js +48 -0
- package/dist/features/projects/useProjects.esm.js.map +1 -0
- package/dist/features/repo/DeploymentLogsDrawer.esm.js +213 -0
- package/dist/features/repo/DeploymentLogsDrawer.esm.js.map +1 -0
- package/dist/features/repo/DeploymentLogsDrawer.loading.esm.js +43 -0
- package/dist/features/repo/DeploymentLogsDrawer.loading.esm.js.map +1 -0
- package/dist/features/repo/FileTree.esm.js +179 -0
- package/dist/features/repo/FileTree.esm.js.map +1 -0
- package/dist/features/repo/FileViewer.esm.js +115 -0
- package/dist/features/repo/FileViewer.esm.js.map +1 -0
- package/dist/features/repo/FileViewer.helpers.esm.js +54 -0
- package/dist/features/repo/FileViewer.helpers.esm.js.map +1 -0
- package/dist/features/repo/RepoDetailsPage.esm.js +127 -0
- package/dist/features/repo/RepoDetailsPage.esm.js.map +1 -0
- package/dist/features/repo/RepoEmptyState.esm.js +58 -0
- package/dist/features/repo/RepoEmptyState.esm.js.map +1 -0
- package/dist/features/repo/RepoNoVersionsState.esm.js +29 -0
- package/dist/features/repo/RepoNoVersionsState.esm.js.map +1 -0
- package/dist/features/repo/RepoTabHeader.esm.js +30 -0
- package/dist/features/repo/RepoTabHeader.esm.js.map +1 -0
- package/dist/features/repo/RepoTabLayout.esm.js +18 -0
- package/dist/features/repo/RepoTabLayout.esm.js.map +1 -0
- package/dist/features/repo/RepoVersionSelect.esm.js +176 -0
- package/dist/features/repo/RepoVersionSelect.esm.js.map +1 -0
- package/dist/features/repo/ViewDeploymentDetailsDialog.esm.js +427 -0
- package/dist/features/repo/ViewDeploymentDetailsDialog.esm.js.map +1 -0
- package/dist/features/repo/deploymentHelpers.esm.js +74 -0
- package/dist/features/repo/deploymentHelpers.esm.js.map +1 -0
- package/dist/features/repo/fileTreeHelpers.esm.js +45 -0
- package/dist/features/repo/fileTreeHelpers.esm.js.map +1 -0
- package/dist/features/repo/flattenParams.esm.js +23 -0
- package/dist/features/repo/flattenParams.esm.js.map +1 -0
- package/dist/features/repo/queries.esm.js +239 -0
- package/dist/features/repo/queries.esm.js.map +1 -0
- package/dist/features/repo/repoFilter.esm.js +9 -0
- package/dist/features/repo/repoFilter.esm.js.map +1 -0
- package/dist/features/repo/repoTabs.esm.js +22 -0
- package/dist/features/repo/repoTabs.esm.js.map +1 -0
- package/dist/features/repo/resolveVersion.esm.js +22 -0
- package/dist/features/repo/resolveVersion.esm.js.map +1 -0
- package/dist/features/repo/tabs/DeploymentRow.esm.js +201 -0
- package/dist/features/repo/tabs/DeploymentRow.esm.js.map +1 -0
- package/dist/features/repo/tabs/DeploymentsTab.esm.js +188 -0
- package/dist/features/repo/tabs/DeploymentsTab.esm.js.map +1 -0
- package/dist/features/repo/tabs/DeploymentsTab.helpers.esm.js +46 -0
- package/dist/features/repo/tabs/DeploymentsTab.helpers.esm.js.map +1 -0
- package/dist/features/repo/tabs/DeploymentsTab.loading.esm.js +37 -0
- package/dist/features/repo/tabs/DeploymentsTab.loading.esm.js.map +1 -0
- package/dist/features/repo/tabs/FilesTab.esm.js +142 -0
- package/dist/features/repo/tabs/FilesTab.esm.js.map +1 -0
- package/dist/features/repo/tabs/InstanceRow.esm.js +121 -0
- package/dist/features/repo/tabs/InstanceRow.esm.js.map +1 -0
- package/dist/features/repo/tabs/InstancesTab.esm.js +147 -0
- package/dist/features/repo/tabs/InstancesTab.esm.js.map +1 -0
- package/dist/features/repo/tabs/InstancesTab.helpers.esm.js +44 -0
- package/dist/features/repo/tabs/InstancesTab.helpers.esm.js.map +1 -0
- package/dist/features/repo/tabs/InstancesTab.loading.esm.js +33 -0
- package/dist/features/repo/tabs/InstancesTab.loading.esm.js.map +1 -0
- package/dist/features/repo/tabs/OverviewTab.esm.js +77 -0
- package/dist/features/repo/tabs/OverviewTab.esm.js.map +1 -0
- package/dist/features/repo/tabs/PermissionsTab.esm.js +56 -0
- package/dist/features/repo/tabs/PermissionsTab.esm.js.map +1 -0
- package/dist/features/repo/tabs/VersionsTab.esm.js +152 -0
- package/dist/features/repo/tabs/VersionsTab.esm.js.map +1 -0
- package/dist/features/repo/useInfiniteRelayList.esm.js +92 -0
- package/dist/features/repo/useInfiniteRelayList.esm.js.map +1 -0
- package/dist/features/repo/useInfiniteScroll.esm.js +21 -0
- package/dist/features/repo/useInfiniteScroll.esm.js.map +1 -0
- package/dist/features/repos/ReposListPage.esm.js +53 -0
- package/dist/features/repos/ReposListPage.esm.js.map +1 -0
- package/dist/features/repos/queries.esm.js +40 -0
- package/dist/features/repos/queries.esm.js.map +1 -0
- package/dist/features/repos/repoColumns.esm.js +121 -0
- package/dist/features/repos/repoColumns.esm.js.map +1 -0
- package/dist/features/repos/useRepos.esm.js +22 -0
- package/dist/features/repos/useRepos.esm.js.map +1 -0
- package/dist/features/resource/OriginChip.esm.js +42 -0
- package/dist/features/resource/OriginChip.esm.js.map +1 -0
- package/dist/features/resource/ResourceDetailsPage.esm.js +167 -0
- package/dist/features/resource/ResourceDetailsPage.esm.js.map +1 -0
- package/dist/features/resource/queries.esm.js +141 -0
- package/dist/features/resource/queries.esm.js.map +1 -0
- package/dist/features/resource/tabs/GeneralTab.esm.js +247 -0
- package/dist/features/resource/tabs/GeneralTab.esm.js.map +1 -0
- package/dist/features/resource/tabs/GeneralTab.loading.esm.js +76 -0
- package/dist/features/resource/tabs/GeneralTab.loading.esm.js.map +1 -0
- package/dist/features/resource/tabs/PermissionsTab.esm.js +57 -0
- package/dist/features/resource/tabs/PermissionsTab.esm.js.map +1 -0
- package/dist/features/resource/tabs/SettingsTabLayout.esm.js +18 -0
- package/dist/features/resource/tabs/SettingsTabLayout.esm.js.map +1 -0
- package/dist/features/resource/tabs/TabHeader.esm.js +30 -0
- package/dist/features/resource/tabs/TabHeader.esm.js.map +1 -0
- package/dist/features/resource/tabs/UsagePanel.esm.js +35 -0
- package/dist/features/resource/tabs/UsagePanel.esm.js.map +1 -0
- package/dist/features/resource/tabs/UsageTab.esm.js +91 -0
- package/dist/features/resource/tabs/UsageTab.esm.js.map +1 -0
- package/dist/features/resource/tabs/UsageTab.helpers.esm.js +168 -0
- package/dist/features/resource/tabs/UsageTab.helpers.esm.js.map +1 -0
- package/dist/features/resources/ResourcesEmptyState.esm.js +148 -0
- package/dist/features/resources/ResourcesEmptyState.esm.js.map +1 -0
- package/dist/features/resources/ResourcesListPage.esm.js +115 -0
- package/dist/features/resources/ResourcesListPage.esm.js.map +1 -0
- package/dist/features/resources/queries.esm.js +50 -0
- package/dist/features/resources/queries.esm.js.map +1 -0
- package/dist/features/resources/resourceColumns.esm.js +158 -0
- package/dist/features/resources/resourceColumns.esm.js.map +1 -0
- package/dist/features/resources/resourceConstants.esm.js +7 -0
- package/dist/features/resources/resourceConstants.esm.js.map +1 -0
- package/dist/features/resources/toResourceRow.esm.js +29 -0
- package/dist/features/resources/toResourceRow.esm.js.map +1 -0
- package/dist/hooks/useAuthedSvg.esm.js +34 -0
- package/dist/hooks/useAuthedSvg.esm.js.map +1 -0
- package/dist/hooks/useCursorPagination.esm.js +40 -0
- package/dist/hooks/useCursorPagination.esm.js.map +1 -0
- package/dist/hooks/useMassdriverSubscription.esm.js +61 -0
- package/dist/hooks/useMassdriverSubscription.esm.js.map +1 -0
- package/dist/hooks/usePaginatedRelayQuery.esm.js +68 -0
- package/dist/hooks/usePaginatedRelayQuery.esm.js.map +1 -0
- package/dist/index.d.ts +256 -0
- package/dist/index.esm.js +8 -0
- package/dist/index.esm.js.map +1 -0
- package/dist/internalRoutes.esm.js +29 -0
- package/dist/internalRoutes.esm.js.map +1 -0
- package/dist/plugin.esm.js +57 -0
- package/dist/plugin.esm.js.map +1 -0
- package/dist/queries.esm.js +54 -0
- package/dist/queries.esm.js.map +1 -0
- package/dist/routes.esm.js +6 -0
- package/dist/routes.esm.js.map +1 -0
- package/dist/shell/MassdriverHeader.esm.js +37 -0
- package/dist/shell/MassdriverHeader.esm.js.map +1 -0
- package/dist/shell/MassdriverShell.esm.js +30 -0
- package/dist/shell/MassdriverShell.esm.js.map +1 -0
- package/dist/theme/MassdriverThemeScope.esm.js +30 -0
- package/dist/theme/MassdriverThemeScope.esm.js.map +1 -0
- package/dist/theme/ThemeModeContext.esm.js +35 -0
- package/dist/theme/ThemeModeContext.esm.js.map +1 -0
- package/dist/theme/muiClassNameAudit.esm.js +11 -0
- package/dist/theme/muiClassNameAudit.esm.js.map +1 -0
- package/dist/useInstances.esm.js +39 -0
- package/dist/useInstances.esm.js.map +1 -0
- package/dist/utils/attributes.esm.js +28 -0
- package/dist/utils/attributes.esm.js.map +1 -0
- package/dist/utils/conditions.esm.js +20 -0
- package/dist/utils/conditions.esm.js.map +1 -0
- package/dist/utils/formatRelativeTime.esm.js +40 -0
- package/dist/utils/formatRelativeTime.esm.js.map +1 -0
- package/dist/utils/instanceStatuses.esm.js +74 -0
- package/dist/utils/instanceStatuses.esm.js.map +1 -0
- package/package.json +92 -0
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { useSearchParams } from 'react-router-dom';
|
|
4
|
+
import { useApi } from '@backstage/frontend-plugin-api';
|
|
5
|
+
import useAsync from 'react-use/esm/useAsync';
|
|
6
|
+
import { Dialog, DialogHeader, DialogActions, DialogContent } from '@massdriver/ui/Dialog';
|
|
7
|
+
import Box from '@massdriver/ui/Box';
|
|
8
|
+
import Typography from '@massdriver/ui/Typography';
|
|
9
|
+
import Button from '@massdriver/ui/Button';
|
|
10
|
+
import Tooltip from '@massdriver/ui/Tooltip';
|
|
11
|
+
import IconButton from '@massdriver/ui/IconButton';
|
|
12
|
+
import CopyButton from '@massdriver/ui/CopyButton';
|
|
13
|
+
import Alert from '@massdriver/ui/Alert';
|
|
14
|
+
import LoadingIndicator from '@massdriver/ui/LoadingIndicator';
|
|
15
|
+
import DataList, { col } from '@massdriver/ui/DataList';
|
|
16
|
+
import stylin from '@massdriver/ui/stylin';
|
|
17
|
+
import CloseIcon from '@massdriver/ui/icons/CloseIcon';
|
|
18
|
+
import HistoryIcon from '@massdriver/ui/icons/HistoryIcon';
|
|
19
|
+
import { massdriverApiRef } from '../../api.esm.js';
|
|
20
|
+
import { InstanceStatusPill } from '../../components/InstanceStatusPill.esm.js';
|
|
21
|
+
import VersionBadge from '../../components/VersionBadge.esm.js';
|
|
22
|
+
import { composeInstanceStatus, formatInstanceStatus, isDeploymentActive } from '../../utils/instanceStatuses.esm.js';
|
|
23
|
+
import { formatRelativeTime } from '../../utils/formatRelativeTime.esm.js';
|
|
24
|
+
import { DEPLOYMENT_DETAIL_QUERY } from './queries.esm.js';
|
|
25
|
+
import { formatElapsed, formatAbsoluteDateTime, parsePlanMessage, parseRollbackMessage, stripMessageContext, deploymentHasLogs, parseMap, truncateDeploymentId, formatAttributeValue } from './deploymentHelpers.esm.js';
|
|
26
|
+
import flattenParams from './flattenParams.esm.js';
|
|
27
|
+
|
|
28
|
+
const TRUNCATE_LENGTH = 64;
|
|
29
|
+
const formatParamValue = (value) => {
|
|
30
|
+
if (typeof value === "string") return value;
|
|
31
|
+
try {
|
|
32
|
+
return JSON.stringify(value);
|
|
33
|
+
} catch {
|
|
34
|
+
return String(value);
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
const renderValueCell = (_value, row) => {
|
|
38
|
+
const value = row.value;
|
|
39
|
+
if (value == null) return /* @__PURE__ */ jsx(NullLiteral, { children: "null" });
|
|
40
|
+
const display = formatParamValue(value);
|
|
41
|
+
const truncated = display.length > TRUNCATE_LENGTH;
|
|
42
|
+
const visible = truncated ? `${display.slice(0, TRUNCATE_LENGTH)}\u2026` : display;
|
|
43
|
+
const cell = /* @__PURE__ */ jsx(ValueText, { children: visible });
|
|
44
|
+
return truncated ? /* @__PURE__ */ jsx(Tooltip, { title: display, arrow: true, placement: "top", children: /* @__PURE__ */ jsx("span", { children: cell }) }) : cell;
|
|
45
|
+
};
|
|
46
|
+
const COLUMNS = [
|
|
47
|
+
col.text("path", "Path", {
|
|
48
|
+
flex: 2,
|
|
49
|
+
minWidth: 200,
|
|
50
|
+
sortable: true,
|
|
51
|
+
searchable: true
|
|
52
|
+
}),
|
|
53
|
+
col.custom("value", "Value", renderValueCell, {
|
|
54
|
+
flex: 3,
|
|
55
|
+
minWidth: 220,
|
|
56
|
+
sortable: false,
|
|
57
|
+
searchable: false
|
|
58
|
+
})
|
|
59
|
+
];
|
|
60
|
+
const isActiveStatus = (derivedStatus) => {
|
|
61
|
+
if (!derivedStatus) return false;
|
|
62
|
+
const [, deploymentStatus] = derivedStatus.split("_");
|
|
63
|
+
return isDeploymentActive(deploymentStatus);
|
|
64
|
+
};
|
|
65
|
+
const buildHeading = (componentName, derivedStatus, time) => {
|
|
66
|
+
const verb = derivedStatus ? formatInstanceStatus(derivedStatus).toLowerCase() : null;
|
|
67
|
+
if (!componentName && !verb) return "Deployment";
|
|
68
|
+
if (!verb) return `${componentName} deployment`;
|
|
69
|
+
const tail = time && time !== "--" && !isActiveStatus(derivedStatus) ? ` ${time}` : "";
|
|
70
|
+
return componentName ? `${componentName} \xB7 ${verb}${tail}` : `${verb}${tail}`;
|
|
71
|
+
};
|
|
72
|
+
const ViewDeploymentDetailsDialog = () => {
|
|
73
|
+
const api = useApi(massdriverApiRef);
|
|
74
|
+
const [searchParams, setSearchParams] = useSearchParams();
|
|
75
|
+
const deploymentId = searchParams.get("deployment");
|
|
76
|
+
const open = Boolean(deploymentId);
|
|
77
|
+
const setParam = (key, value2) => {
|
|
78
|
+
setSearchParams(
|
|
79
|
+
(prev) => {
|
|
80
|
+
const next = new URLSearchParams(prev);
|
|
81
|
+
if (value2) next.set(key, value2);
|
|
82
|
+
else next.delete(key);
|
|
83
|
+
return next;
|
|
84
|
+
},
|
|
85
|
+
{ replace: false }
|
|
86
|
+
);
|
|
87
|
+
};
|
|
88
|
+
const onClose = () => setParam("deployment", null);
|
|
89
|
+
const onShowSource = (sourceId) => setParam("deployment", sourceId);
|
|
90
|
+
const { value, loading, error } = useAsync(async () => {
|
|
91
|
+
if (!deploymentId) return null;
|
|
92
|
+
const data = await api.query(DEPLOYMENT_DETAIL_QUERY, {
|
|
93
|
+
id: deploymentId
|
|
94
|
+
});
|
|
95
|
+
return data.deployment;
|
|
96
|
+
}, [api, deploymentId]);
|
|
97
|
+
const deployment = value;
|
|
98
|
+
const paramRows = useMemo(
|
|
99
|
+
() => flattenParams(deployment?.params),
|
|
100
|
+
[deployment?.params]
|
|
101
|
+
);
|
|
102
|
+
const derivedStatus = composeInstanceStatus(
|
|
103
|
+
deployment?.action,
|
|
104
|
+
deployment?.status
|
|
105
|
+
);
|
|
106
|
+
const componentName = deployment?.instance?.component?.name;
|
|
107
|
+
const elapsed = formatElapsed(deployment?.elapsedTime);
|
|
108
|
+
const occurredIso = deployment?.lastTransitionedAt ?? deployment?.createdAt;
|
|
109
|
+
const time = formatRelativeTime(occurredIso);
|
|
110
|
+
const absoluteDate = formatAbsoluteDateTime(occurredIso);
|
|
111
|
+
const deployedBy = deployment?.deployedBy ?? "system";
|
|
112
|
+
const statusLabel = formatInstanceStatus(derivedStatus);
|
|
113
|
+
const heading = buildHeading(componentName, derivedStatus, time);
|
|
114
|
+
const planSource = deployment?.action === "PLAN" ? parsePlanMessage(deployment?.message) : null;
|
|
115
|
+
const rollbackSource = parseRollbackMessage(deployment?.message);
|
|
116
|
+
const displayMessage = stripMessageContext(deployment?.message);
|
|
117
|
+
const isProposed = deployment?.status === "PROPOSED";
|
|
118
|
+
const hasLogs = deploymentHasLogs(deployment?.status);
|
|
119
|
+
const onViewLogs = () => {
|
|
120
|
+
if (!deployment) return;
|
|
121
|
+
setParam("logs", deployment.id);
|
|
122
|
+
};
|
|
123
|
+
const attributes = parseMap(deployment?.effectiveAttributes);
|
|
124
|
+
const attributeEntries = attributes ? Object.entries(attributes) : [];
|
|
125
|
+
return /* @__PURE__ */ jsxs(Dialog, { open, onClose, maxWidth: "md", fullWidth: true, children: [
|
|
126
|
+
/* @__PURE__ */ jsx(
|
|
127
|
+
DialogHeader,
|
|
128
|
+
{
|
|
129
|
+
icon: /* @__PURE__ */ jsx(HistoryIcon, {}),
|
|
130
|
+
actions: /* @__PURE__ */ jsx(IconButton, { onClick: onClose, "aria-label": "Close deployment details", children: /* @__PURE__ */ jsx(CloseIcon, {}) }),
|
|
131
|
+
children: heading
|
|
132
|
+
}
|
|
133
|
+
),
|
|
134
|
+
/* @__PURE__ */ jsx(Body, { children: loading ? /* @__PURE__ */ jsx(Centered, { children: /* @__PURE__ */ jsx(LoadingIndicator, {}) }) : error ? /* @__PURE__ */ jsx(Alert, { severity: "error", children: String(error.message ?? error) }) : deployment ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
135
|
+
/* @__PURE__ */ jsxs(SummaryCard, { children: [
|
|
136
|
+
/* @__PURE__ */ jsxs(SummaryHeader, { children: [
|
|
137
|
+
/* @__PURE__ */ jsxs(SummaryHeaderLeft, { children: [
|
|
138
|
+
/* @__PURE__ */ jsx(
|
|
139
|
+
InstanceStatusPill,
|
|
140
|
+
{
|
|
141
|
+
status: derivedStatus,
|
|
142
|
+
onClick: hasLogs ? onViewLogs : void 0
|
|
143
|
+
}
|
|
144
|
+
),
|
|
145
|
+
deployment.version ? /* @__PURE__ */ jsx(VersionBadge, { version: deployment.version }) : null
|
|
146
|
+
] }),
|
|
147
|
+
hasLogs ? /* @__PURE__ */ jsx(HeaderActions, { children: /* @__PURE__ */ jsx(
|
|
148
|
+
Button,
|
|
149
|
+
{
|
|
150
|
+
variant: "outlined",
|
|
151
|
+
size: "small",
|
|
152
|
+
onClick: onViewLogs,
|
|
153
|
+
children: "View logs"
|
|
154
|
+
}
|
|
155
|
+
) }) : null
|
|
156
|
+
] }),
|
|
157
|
+
/* @__PURE__ */ jsxs(DefList, { children: [
|
|
158
|
+
/* @__PURE__ */ jsxs(DefRow, { children: [
|
|
159
|
+
/* @__PURE__ */ jsx(DefLabel, { children: "Status" }),
|
|
160
|
+
/* @__PURE__ */ jsx(DefValue, { children: statusLabel })
|
|
161
|
+
] }),
|
|
162
|
+
/* @__PURE__ */ jsxs(DefRow, { children: [
|
|
163
|
+
/* @__PURE__ */ jsx(DefLabel, { children: "Occurred" }),
|
|
164
|
+
/* @__PURE__ */ jsxs(DefValue, { children: [
|
|
165
|
+
time,
|
|
166
|
+
absoluteDate ? /* @__PURE__ */ jsx(DefMuted, { children: ` \xB7 ${absoluteDate}` }) : null
|
|
167
|
+
] })
|
|
168
|
+
] }),
|
|
169
|
+
/* @__PURE__ */ jsxs(DefRow, { children: [
|
|
170
|
+
/* @__PURE__ */ jsx(DefLabel, { children: "Duration" }),
|
|
171
|
+
/* @__PURE__ */ jsx(DefValue, { children: elapsed ?? "\u2014" })
|
|
172
|
+
] }),
|
|
173
|
+
/* @__PURE__ */ jsxs(DefRow, { children: [
|
|
174
|
+
/* @__PURE__ */ jsx(DefLabel, { children: "Deployed by" }),
|
|
175
|
+
/* @__PURE__ */ jsx(DefValue, { children: /* @__PURE__ */ jsx("strong", { children: deployedBy }) })
|
|
176
|
+
] }),
|
|
177
|
+
/* @__PURE__ */ jsxs(DefRow, { children: [
|
|
178
|
+
/* @__PURE__ */ jsx(DefLabel, { children: "Deployment ID" }),
|
|
179
|
+
/* @__PURE__ */ jsxs(DefValue, { children: [
|
|
180
|
+
/* @__PURE__ */ jsx(Mono, { children: deployment.id }),
|
|
181
|
+
/* @__PURE__ */ jsx(
|
|
182
|
+
CopyButton,
|
|
183
|
+
{
|
|
184
|
+
text: deployment.id,
|
|
185
|
+
ariaLabel: "Copy deployment ID"
|
|
186
|
+
}
|
|
187
|
+
)
|
|
188
|
+
] })
|
|
189
|
+
] })
|
|
190
|
+
] }),
|
|
191
|
+
planSource ? /* @__PURE__ */ jsxs(PlanSourceBlock, { children: [
|
|
192
|
+
/* @__PURE__ */ jsxs(
|
|
193
|
+
PlanSourceLink,
|
|
194
|
+
{
|
|
195
|
+
variant: "text",
|
|
196
|
+
size: "small",
|
|
197
|
+
onClick: () => onShowSource(planSource.sourceId),
|
|
198
|
+
children: [
|
|
199
|
+
"Planned deployment of",
|
|
200
|
+
" ",
|
|
201
|
+
truncateDeploymentId(planSource.sourceId)
|
|
202
|
+
]
|
|
203
|
+
}
|
|
204
|
+
),
|
|
205
|
+
displayMessage ? /* @__PURE__ */ jsxs(MessageQuote, { children: [
|
|
206
|
+
'"',
|
|
207
|
+
displayMessage,
|
|
208
|
+
'"'
|
|
209
|
+
] }) : null
|
|
210
|
+
] }) : rollbackSource ? /* @__PURE__ */ jsxs(PlanSourceBlock, { children: [
|
|
211
|
+
/* @__PURE__ */ jsxs(
|
|
212
|
+
PlanSourceLink,
|
|
213
|
+
{
|
|
214
|
+
variant: "text",
|
|
215
|
+
size: "small",
|
|
216
|
+
onClick: () => onShowSource(rollbackSource.sourceId),
|
|
217
|
+
children: [
|
|
218
|
+
isProposed ? "Proposed rollback to deployment" : "Rollback to deployment",
|
|
219
|
+
" ",
|
|
220
|
+
truncateDeploymentId(rollbackSource.sourceId),
|
|
221
|
+
rollbackSource.version ? ` (v${rollbackSource.version})` : ""
|
|
222
|
+
]
|
|
223
|
+
}
|
|
224
|
+
),
|
|
225
|
+
displayMessage ? /* @__PURE__ */ jsxs(MessageQuote, { children: [
|
|
226
|
+
'"',
|
|
227
|
+
displayMessage,
|
|
228
|
+
'"'
|
|
229
|
+
] }) : null
|
|
230
|
+
] }) : displayMessage ? /* @__PURE__ */ jsxs(MessageQuote, { children: [
|
|
231
|
+
'"',
|
|
232
|
+
displayMessage,
|
|
233
|
+
'"'
|
|
234
|
+
] }) : null
|
|
235
|
+
] }),
|
|
236
|
+
/* @__PURE__ */ jsxs(Section, { children: [
|
|
237
|
+
/* @__PURE__ */ jsx(SectionHeading, { variant: "subtitle1", children: "Attributes" }),
|
|
238
|
+
/* @__PURE__ */ jsx(Card, { children: attributeEntries.length === 0 ? /* @__PURE__ */ jsx(EmptyNote, { children: "No effective attributes." }) : attributeEntries.map(([key, attrValue]) => /* @__PURE__ */ jsxs(RowLine, { children: [
|
|
239
|
+
/* @__PURE__ */ jsx(MonoLabel, { title: key, children: key }),
|
|
240
|
+
/* @__PURE__ */ jsx(MonoValue, { title: formatAttributeValue(attrValue), children: formatAttributeValue(attrValue) })
|
|
241
|
+
] }, key)) })
|
|
242
|
+
] }),
|
|
243
|
+
/* @__PURE__ */ jsxs(Section, { children: [
|
|
244
|
+
/* @__PURE__ */ jsx(SectionHeading, { variant: "subtitle1", children: "Snapshot params" }),
|
|
245
|
+
/* @__PURE__ */ jsx(
|
|
246
|
+
DataList,
|
|
247
|
+
{
|
|
248
|
+
rows: paramRows,
|
|
249
|
+
columns: COLUMNS,
|
|
250
|
+
searchable: true,
|
|
251
|
+
searchPlaceholder: "Search path\u2026",
|
|
252
|
+
defaultSort: { field: "path", direction: "asc" },
|
|
253
|
+
defaultPageSize: 5,
|
|
254
|
+
variant: "outlined",
|
|
255
|
+
size: "small",
|
|
256
|
+
emptyMessage: "No parameters captured for this deployment."
|
|
257
|
+
}
|
|
258
|
+
)
|
|
259
|
+
] })
|
|
260
|
+
] }) : null }),
|
|
261
|
+
/* @__PURE__ */ jsx(DialogActions, { children: /* @__PURE__ */ jsx(Button, { variant: "contained", onClick: onClose, children: "Close" }) })
|
|
262
|
+
] });
|
|
263
|
+
};
|
|
264
|
+
const Body = stylin(DialogContent)(({ theme }) => ({
|
|
265
|
+
display: "flex",
|
|
266
|
+
flexDirection: "column",
|
|
267
|
+
gap: theme.spacing(2),
|
|
268
|
+
"& > *": {
|
|
269
|
+
flexShrink: 0
|
|
270
|
+
}
|
|
271
|
+
}));
|
|
272
|
+
const Centered = stylin(Box)(({ theme }) => ({
|
|
273
|
+
display: "flex",
|
|
274
|
+
justifyContent: "center",
|
|
275
|
+
padding: theme.spacing(6)
|
|
276
|
+
}));
|
|
277
|
+
const SummaryCard = stylin(Box)(({ theme }) => ({
|
|
278
|
+
display: "flex",
|
|
279
|
+
flexDirection: "column",
|
|
280
|
+
gap: theme.spacing(2.5),
|
|
281
|
+
padding: theme.spacing(2.5, 3),
|
|
282
|
+
borderRadius: 1,
|
|
283
|
+
border: `1px solid ${theme.palette.divider}`,
|
|
284
|
+
backgroundColor: theme.palette.background.paper
|
|
285
|
+
}));
|
|
286
|
+
const SummaryHeader = stylin(Box)(({ theme }) => ({
|
|
287
|
+
display: "flex",
|
|
288
|
+
alignItems: "center",
|
|
289
|
+
justifyContent: "space-between",
|
|
290
|
+
flexWrap: "wrap",
|
|
291
|
+
gap: theme.spacing(1.5)
|
|
292
|
+
}));
|
|
293
|
+
const SummaryHeaderLeft = stylin(Box)(({ theme }) => ({
|
|
294
|
+
display: "flex",
|
|
295
|
+
alignItems: "center",
|
|
296
|
+
flexWrap: "wrap",
|
|
297
|
+
gap: theme.spacing(1.5)
|
|
298
|
+
}));
|
|
299
|
+
const HeaderActions = stylin(Box)(({ theme }) => ({
|
|
300
|
+
display: "flex",
|
|
301
|
+
alignItems: "center",
|
|
302
|
+
gap: theme.spacing(1)
|
|
303
|
+
}));
|
|
304
|
+
const DefList = stylin(Box)(({ theme }) => ({
|
|
305
|
+
display: "flex",
|
|
306
|
+
flexDirection: "column",
|
|
307
|
+
gap: theme.spacing(1.25)
|
|
308
|
+
}));
|
|
309
|
+
const DefRow = stylin(Box)(({ theme }) => ({
|
|
310
|
+
display: "grid",
|
|
311
|
+
gridTemplateColumns: `${theme.spacing(18)} 1fr`,
|
|
312
|
+
alignItems: "center",
|
|
313
|
+
gap: theme.spacing(2),
|
|
314
|
+
[theme.breakpoints.down("sm")]: {
|
|
315
|
+
gridTemplateColumns: "1fr",
|
|
316
|
+
gap: theme.spacing(0.25)
|
|
317
|
+
}
|
|
318
|
+
}));
|
|
319
|
+
const DefLabel = stylin(Typography)(({ theme }) => ({
|
|
320
|
+
color: theme.palette.text.secondary,
|
|
321
|
+
fontSize: theme.typography.body2.fontSize,
|
|
322
|
+
textTransform: "uppercase",
|
|
323
|
+
letterSpacing: "0.04em",
|
|
324
|
+
fontWeight: theme.typography.fontWeightMedium
|
|
325
|
+
}));
|
|
326
|
+
const DefValue = stylin(Typography)(({ theme }) => ({
|
|
327
|
+
color: theme.palette.text.primary,
|
|
328
|
+
fontSize: theme.typography.body1.fontSize,
|
|
329
|
+
display: "flex",
|
|
330
|
+
alignItems: "center",
|
|
331
|
+
gap: theme.spacing(0.75),
|
|
332
|
+
minWidth: 0
|
|
333
|
+
}));
|
|
334
|
+
const DefMuted = stylin("span")(({ theme }) => ({
|
|
335
|
+
color: theme.palette.text.secondary
|
|
336
|
+
}));
|
|
337
|
+
const Mono = stylin("span")(({ theme }) => ({
|
|
338
|
+
fontFamily: theme.typography.fontFamilyMono,
|
|
339
|
+
fontSize: theme.typography.body2.fontSize,
|
|
340
|
+
color: theme.palette.text.primary,
|
|
341
|
+
wordBreak: "break-all",
|
|
342
|
+
minWidth: 0
|
|
343
|
+
}));
|
|
344
|
+
const MessageQuote = stylin(Box)(({ theme }) => ({
|
|
345
|
+
fontStyle: "italic",
|
|
346
|
+
color: theme.palette.text.secondary,
|
|
347
|
+
borderLeft: `3px solid ${theme.palette.divider}`,
|
|
348
|
+
paddingLeft: theme.spacing(1.5),
|
|
349
|
+
paddingTop: theme.spacing(0.5),
|
|
350
|
+
paddingBottom: theme.spacing(0.5)
|
|
351
|
+
}));
|
|
352
|
+
const PlanSourceBlock = stylin(Box)(({ theme }) => ({
|
|
353
|
+
display: "flex",
|
|
354
|
+
flexDirection: "column",
|
|
355
|
+
gap: theme.spacing(1),
|
|
356
|
+
alignItems: "flex-start"
|
|
357
|
+
}));
|
|
358
|
+
const PlanSourceLink = stylin(Button)(({ theme }) => ({
|
|
359
|
+
alignSelf: "flex-start",
|
|
360
|
+
padding: theme.spacing(0.25, 1),
|
|
361
|
+
marginLeft: theme.spacing(-1)
|
|
362
|
+
}));
|
|
363
|
+
const Section = stylin(Box)(({ theme }) => ({
|
|
364
|
+
display: "flex",
|
|
365
|
+
flexDirection: "column",
|
|
366
|
+
gap: theme.spacing(1)
|
|
367
|
+
}));
|
|
368
|
+
const SectionHeading = stylin(Typography)(({ theme }) => ({
|
|
369
|
+
fontWeight: theme.typography.fontWeightBold
|
|
370
|
+
}));
|
|
371
|
+
const Card = stylin(Box)(({ theme }) => ({
|
|
372
|
+
border: `1px solid ${theme.palette.divider}`,
|
|
373
|
+
borderRadius: 1,
|
|
374
|
+
padding: theme.spacing(1),
|
|
375
|
+
display: "flex",
|
|
376
|
+
flexDirection: "column",
|
|
377
|
+
gap: theme.spacing(0.5),
|
|
378
|
+
overflow: "hidden"
|
|
379
|
+
}));
|
|
380
|
+
const RowLine = stylin(Box)(({ theme }) => ({
|
|
381
|
+
display: "flex",
|
|
382
|
+
alignItems: "center",
|
|
383
|
+
gap: theme.spacing(1),
|
|
384
|
+
flexWrap: "wrap",
|
|
385
|
+
minWidth: 0
|
|
386
|
+
}));
|
|
387
|
+
const MonoLabel = stylin(Typography)(({ theme }) => ({
|
|
388
|
+
fontSize: theme.typography.pxToRem(11),
|
|
389
|
+
color: theme.palette.text.secondary,
|
|
390
|
+
minWidth: 110,
|
|
391
|
+
fontFamily: theme.typography.fontFamilyMono,
|
|
392
|
+
overflow: "hidden",
|
|
393
|
+
textOverflow: "ellipsis",
|
|
394
|
+
whiteSpace: "nowrap"
|
|
395
|
+
}));
|
|
396
|
+
const MonoValue = stylin(Typography)(({ theme }) => ({
|
|
397
|
+
fontSize: theme.typography.pxToRem(12),
|
|
398
|
+
color: theme.palette.text.primary,
|
|
399
|
+
fontFamily: theme.typography.fontFamilyMono,
|
|
400
|
+
overflow: "hidden",
|
|
401
|
+
textOverflow: "ellipsis",
|
|
402
|
+
whiteSpace: "nowrap",
|
|
403
|
+
flex: 1,
|
|
404
|
+
minWidth: 0
|
|
405
|
+
}));
|
|
406
|
+
const EmptyNote = stylin(Typography)(({ theme }) => ({
|
|
407
|
+
fontSize: theme.typography.pxToRem(12),
|
|
408
|
+
color: theme.palette.text.secondary,
|
|
409
|
+
fontStyle: "italic"
|
|
410
|
+
}));
|
|
411
|
+
const ValueText = stylin(Box)(({ theme }) => ({
|
|
412
|
+
fontFamily: theme.typography.fontFamilyMono,
|
|
413
|
+
fontSize: theme.typography.caption.fontSize,
|
|
414
|
+
color: theme.palette.text.secondary,
|
|
415
|
+
whiteSpace: "nowrap",
|
|
416
|
+
overflow: "hidden",
|
|
417
|
+
textOverflow: "ellipsis"
|
|
418
|
+
}));
|
|
419
|
+
const NullLiteral = stylin(Box)(({ theme }) => ({
|
|
420
|
+
fontStyle: "italic",
|
|
421
|
+
color: theme.palette.text.secondary,
|
|
422
|
+
fontFamily: theme.typography.fontFamilyMono,
|
|
423
|
+
fontSize: theme.typography.caption.fontSize
|
|
424
|
+
}));
|
|
425
|
+
|
|
426
|
+
export { ViewDeploymentDetailsDialog };
|
|
427
|
+
//# sourceMappingURL=ViewDeploymentDetailsDialog.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ViewDeploymentDetailsDialog.esm.js","sources":["../../../src/features/repo/ViewDeploymentDetailsDialog.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\nimport {\n Dialog,\n DialogActions,\n DialogContent,\n DialogHeader,\n} from '@massdriver/ui/Dialog';\nimport Box from '@massdriver/ui/Box';\nimport Typography from '@massdriver/ui/Typography';\nimport Button from '@massdriver/ui/Button';\nimport Tooltip from '@massdriver/ui/Tooltip';\nimport IconButton from '@massdriver/ui/IconButton';\nimport CopyButton from '@massdriver/ui/CopyButton';\nimport Alert from '@massdriver/ui/Alert';\nimport LoadingIndicator from '@massdriver/ui/LoadingIndicator';\nimport DataList, { col } from '@massdriver/ui/DataList';\nimport stylin from '@massdriver/ui/stylin';\nimport CloseIcon from '@massdriver/ui/icons/CloseIcon';\nimport HistoryIcon from '@massdriver/ui/icons/HistoryIcon';\nimport { massdriverApiRef } from '../../api';\nimport { InstanceStatusPill } from '../../components/InstanceStatusPill';\nimport VersionBadge from '../../components/VersionBadge';\nimport {\n composeInstanceStatus,\n formatInstanceStatus,\n isDeploymentActive,\n} from '../../utils/instanceStatuses';\nimport { formatRelativeTime } from '../../utils/formatRelativeTime';\nimport { DEPLOYMENT_DETAIL_QUERY } from './queries';\nimport {\n deploymentHasLogs,\n formatAbsoluteDateTime,\n formatAttributeValue,\n formatElapsed,\n parseMap,\n parsePlanMessage,\n parseRollbackMessage,\n stripMessageContext,\n truncateDeploymentId,\n} from './deploymentHelpers';\nimport flattenParams from './flattenParams';\nimport type { DeploymentDetail } from './types';\n\nconst TRUNCATE_LENGTH = 64;\n\nconst formatParamValue = (value: unknown): string => {\n if (typeof value === 'string') return value;\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n};\n\n// Present-value cell mirroring the web dialog's ComparisonValueCell (that\n// component lives under features/environment here, which repo code can't\n// import — so its read-only rendering is inlined).\nconst renderValueCell = (_value: unknown, row: { value: unknown }) => {\n const value = row.value;\n if (value == null) return <NullLiteral>null</NullLiteral>;\n const display = formatParamValue(value);\n const truncated = display.length > TRUNCATE_LENGTH;\n const visible = truncated ? `${display.slice(0, TRUNCATE_LENGTH)}…` : display;\n const cell = <ValueText>{visible}</ValueText>;\n return truncated ? (\n <Tooltip title={display} arrow placement=\"top\">\n <span>{cell}</span>\n </Tooltip>\n ) : (\n cell\n );\n};\n\nconst COLUMNS = [\n col.text('path', 'Path', {\n flex: 2,\n minWidth: 200,\n sortable: true,\n searchable: true,\n }),\n col.custom('value', 'Value', renderValueCell, {\n flex: 3,\n minWidth: 220,\n sortable: false,\n searchable: false,\n }),\n];\n\nconst isActiveStatus = (derivedStatus?: string | null): boolean => {\n if (!derivedStatus) return false;\n const [, deploymentStatus] = derivedStatus.split('_');\n return isDeploymentActive(deploymentStatus);\n};\n\n// Heading reads as \"{component} · {action verb} [time-ago]\". Active deployments\n// drop the trailing time-ago (it reads oddly for an in-flight thing); terminal\n// states keep it. Ported from the web dialog's buildHeading.\nconst buildHeading = (\n componentName: string | null | undefined,\n derivedStatus: string | null,\n time: string,\n): string => {\n const verb = derivedStatus\n ? formatInstanceStatus(derivedStatus).toLowerCase()\n : null;\n if (!componentName && !verb) return 'Deployment';\n if (!verb) return `${componentName} deployment`;\n const tail =\n time && time !== '--' && !isActiveStatus(derivedStatus) ? ` ${time}` : '';\n return componentName ? `${componentName} · ${verb}${tail}` : `${verb}${tail}`;\n};\n\n/**\n * In-place deployment details dialog for the repo Deployments tab. Faithful port\n * of apps/web/shared/components/ViewDeploymentDetailsDialog — driven by the same\n * `deployment` URL param the web reads via useDialogParam (mirrored here with\n * react-router's useSearchParams). The web repo page passes\n * `canApprove={false} canPlan={false}` (and no canRollback), under which the web\n * view renders no approve/reject/plan/rollback affordance at all — so none are\n * ported. The status pill and a \"View logs\" button open the logs drawer (the\n * `logs` param); the plan/rollback source links re-target the `deployment`\n * param, as in the web.\n */\nexport const ViewDeploymentDetailsDialog = () => {\n const api = useApi(massdriverApiRef);\n const [searchParams, setSearchParams] = useSearchParams();\n const deploymentId = searchParams.get('deployment');\n const open = Boolean(deploymentId);\n\n const setParam = (key: string, value: string | null) => {\n setSearchParams(\n prev => {\n const next = new URLSearchParams(prev);\n if (value) next.set(key, value);\n else next.delete(key);\n return next;\n },\n { replace: false },\n );\n };\n\n const onClose = () => setParam('deployment', null);\n const onShowSource = (sourceId: string) => setParam('deployment', sourceId);\n\n const { value, loading, error } = useAsync(async () => {\n if (!deploymentId) return null;\n const data = (await api.query(DEPLOYMENT_DETAIL_QUERY, {\n id: deploymentId,\n })) as { deployment: DeploymentDetail | null };\n return data.deployment;\n }, [api, deploymentId]);\n\n const deployment = value;\n const paramRows = useMemo(\n () => flattenParams(deployment?.params),\n [deployment?.params],\n );\n\n const derivedStatus = composeInstanceStatus(\n deployment?.action,\n deployment?.status,\n );\n const componentName = deployment?.instance?.component?.name;\n const elapsed = formatElapsed(deployment?.elapsedTime);\n const occurredIso = deployment?.lastTransitionedAt ?? deployment?.createdAt;\n const time = formatRelativeTime(occurredIso);\n const absoluteDate = formatAbsoluteDateTime(occurredIso);\n const deployedBy = deployment?.deployedBy ?? 'system';\n const statusLabel = formatInstanceStatus(derivedStatus);\n const heading = buildHeading(componentName, derivedStatus, time);\n\n const planSource =\n deployment?.action === 'PLAN'\n ? parsePlanMessage(deployment?.message)\n : null;\n const rollbackSource = parseRollbackMessage(deployment?.message);\n const displayMessage = stripMessageContext(deployment?.message);\n const isProposed = deployment?.status === 'PROPOSED';\n const hasLogs = deploymentHasLogs(deployment?.status);\n\n // Keep the dialog open beneath the logs drawer (which renders above it),\n // matching the web — the drawer's own `logs` param drives it.\n const onViewLogs = () => {\n if (!deployment) return;\n setParam('logs', deployment.id);\n };\n\n const attributes = parseMap(deployment?.effectiveAttributes);\n const attributeEntries = attributes ? Object.entries(attributes) : [];\n\n return (\n <Dialog open={open} onClose={onClose} maxWidth=\"md\" fullWidth>\n <DialogHeader\n icon={<HistoryIcon />}\n actions={\n <IconButton onClick={onClose} aria-label=\"Close deployment details\">\n <CloseIcon />\n </IconButton>\n }\n >\n {heading}\n </DialogHeader>\n <Body>\n {loading ? (\n <Centered>\n <LoadingIndicator />\n </Centered>\n ) : error ? (\n <Alert severity=\"error\">{String(error.message ?? error)}</Alert>\n ) : deployment ? (\n <>\n <SummaryCard>\n <SummaryHeader>\n <SummaryHeaderLeft>\n <InstanceStatusPill\n status={derivedStatus}\n onClick={hasLogs ? onViewLogs : undefined}\n />\n {deployment.version ? (\n <VersionBadge version={deployment.version} />\n ) : null}\n </SummaryHeaderLeft>\n {hasLogs ? (\n <HeaderActions>\n <Button\n variant=\"outlined\"\n size=\"small\"\n onClick={onViewLogs}\n >\n View logs\n </Button>\n </HeaderActions>\n ) : null}\n </SummaryHeader>\n\n <DefList>\n <DefRow>\n <DefLabel>Status</DefLabel>\n <DefValue>{statusLabel}</DefValue>\n </DefRow>\n <DefRow>\n <DefLabel>Occurred</DefLabel>\n <DefValue>\n {time}\n {absoluteDate ? (\n <DefMuted>{` · ${absoluteDate}`}</DefMuted>\n ) : null}\n </DefValue>\n </DefRow>\n <DefRow>\n <DefLabel>Duration</DefLabel>\n <DefValue>{elapsed ?? '—'}</DefValue>\n </DefRow>\n <DefRow>\n <DefLabel>Deployed by</DefLabel>\n <DefValue>\n <strong>{deployedBy}</strong>\n </DefValue>\n </DefRow>\n <DefRow>\n <DefLabel>Deployment ID</DefLabel>\n <DefValue>\n <Mono>{deployment.id}</Mono>\n <CopyButton\n text={deployment.id}\n ariaLabel=\"Copy deployment ID\"\n />\n </DefValue>\n </DefRow>\n </DefList>\n\n {planSource ? (\n <PlanSourceBlock>\n <PlanSourceLink\n variant=\"text\"\n size=\"small\"\n onClick={() => onShowSource(planSource.sourceId)}\n >\n Planned deployment of{' '}\n {truncateDeploymentId(planSource.sourceId)}\n </PlanSourceLink>\n {displayMessage ? (\n <MessageQuote>\"{displayMessage}\"</MessageQuote>\n ) : null}\n </PlanSourceBlock>\n ) : rollbackSource ? (\n <PlanSourceBlock>\n <PlanSourceLink\n variant=\"text\"\n size=\"small\"\n onClick={() => onShowSource(rollbackSource.sourceId)}\n >\n {isProposed\n ? 'Proposed rollback to deployment'\n : 'Rollback to deployment'}{' '}\n {truncateDeploymentId(rollbackSource.sourceId)}\n {rollbackSource.version\n ? ` (v${rollbackSource.version})`\n : ''}\n </PlanSourceLink>\n {displayMessage ? (\n <MessageQuote>\"{displayMessage}\"</MessageQuote>\n ) : null}\n </PlanSourceBlock>\n ) : displayMessage ? (\n <MessageQuote>\"{displayMessage}\"</MessageQuote>\n ) : null}\n </SummaryCard>\n\n <Section>\n <SectionHeading variant=\"subtitle1\">Attributes</SectionHeading>\n <Card>\n {attributeEntries.length === 0 ? (\n <EmptyNote>No effective attributes.</EmptyNote>\n ) : (\n attributeEntries.map(([key, attrValue]) => (\n <RowLine key={key}>\n <MonoLabel title={key}>{key}</MonoLabel>\n <MonoValue title={formatAttributeValue(attrValue)}>\n {formatAttributeValue(attrValue)}\n </MonoValue>\n </RowLine>\n ))\n )}\n </Card>\n </Section>\n\n <Section>\n <SectionHeading variant=\"subtitle1\">\n Snapshot params\n </SectionHeading>\n <DataList\n rows={paramRows}\n columns={COLUMNS}\n searchable\n searchPlaceholder=\"Search path…\"\n defaultSort={{ field: 'path', direction: 'asc' }}\n defaultPageSize={5}\n variant=\"outlined\"\n size=\"small\"\n emptyMessage=\"No parameters captured for this deployment.\"\n />\n </Section>\n </>\n ) : null}\n </Body>\n <DialogActions>\n <Button variant=\"contained\" onClick={onClose}>\n Close\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n\nexport default ViewDeploymentDetailsDialog;\n\nconst Body = stylin(DialogContent)(({ theme }: { theme: any }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(2),\n '& > *': {\n flexShrink: 0,\n },\n}));\n\nconst Centered = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n justifyContent: 'center',\n padding: theme.spacing(6),\n}));\n\nconst SummaryCard = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(2.5),\n padding: theme.spacing(2.5, 3),\n borderRadius: 1,\n border: `1px solid ${theme.palette.divider}`,\n backgroundColor: theme.palette.background.paper,\n}));\n\nconst SummaryHeader = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n flexWrap: 'wrap',\n gap: theme.spacing(1.5),\n}));\n\nconst SummaryHeaderLeft = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n alignItems: 'center',\n flexWrap: 'wrap',\n gap: theme.spacing(1.5),\n}));\n\nconst HeaderActions = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n}));\n\nconst DefList = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1.25),\n}));\n\nconst DefRow = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'grid',\n gridTemplateColumns: `${theme.spacing(18)} 1fr`,\n alignItems: 'center',\n gap: theme.spacing(2),\n [theme.breakpoints.down('sm')]: {\n gridTemplateColumns: '1fr',\n gap: theme.spacing(0.25),\n },\n}));\n\nconst DefLabel = stylin(Typography)(({ theme }: { theme: any }) => ({\n color: theme.palette.text.secondary,\n fontSize: theme.typography.body2.fontSize,\n textTransform: 'uppercase',\n letterSpacing: '0.04em',\n fontWeight: theme.typography.fontWeightMedium,\n}));\n\nconst DefValue = stylin(Typography)(({ theme }: { theme: any }) => ({\n color: theme.palette.text.primary,\n fontSize: theme.typography.body1.fontSize,\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(0.75),\n minWidth: 0,\n}));\n\nconst DefMuted = stylin('span')(({ theme }: { theme: any }) => ({\n color: theme.palette.text.secondary,\n}));\n\nconst Mono = stylin('span')(({ theme }: { theme: any }) => ({\n fontFamily: theme.typography.fontFamilyMono,\n fontSize: theme.typography.body2.fontSize,\n color: theme.palette.text.primary,\n wordBreak: 'break-all',\n minWidth: 0,\n}));\n\nconst MessageQuote = stylin(Box)(({ theme }: { theme: any }) => ({\n fontStyle: 'italic',\n color: theme.palette.text.secondary,\n borderLeft: `3px solid ${theme.palette.divider}`,\n paddingLeft: theme.spacing(1.5),\n paddingTop: theme.spacing(0.5),\n paddingBottom: theme.spacing(0.5),\n}));\n\nconst PlanSourceBlock = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1),\n alignItems: 'flex-start',\n}));\n\nconst PlanSourceLink = stylin(Button)(({ theme }: { theme: any }) => ({\n alignSelf: 'flex-start',\n padding: theme.spacing(0.25, 1),\n marginLeft: theme.spacing(-1),\n}));\n\nconst Section = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1),\n}));\n\nconst SectionHeading = stylin(Typography)(({ theme }: { theme: any }) => ({\n fontWeight: theme.typography.fontWeightBold,\n}));\n\nconst Card = stylin(Box)(({ theme }: { theme: any }) => ({\n border: `1px solid ${theme.palette.divider}`,\n borderRadius: 1,\n padding: theme.spacing(1),\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n overflow: 'hidden',\n}));\n\nconst RowLine = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1),\n flexWrap: 'wrap',\n minWidth: 0,\n}));\n\nconst MonoLabel = stylin(Typography)(({ theme }: { theme: any }) => ({\n fontSize: theme.typography.pxToRem(11),\n color: theme.palette.text.secondary,\n minWidth: 110,\n fontFamily: theme.typography.fontFamilyMono,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n}));\n\nconst MonoValue = stylin(Typography)(({ theme }: { theme: any }) => ({\n fontSize: theme.typography.pxToRem(12),\n color: theme.palette.text.primary,\n fontFamily: theme.typography.fontFamilyMono,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: 1,\n minWidth: 0,\n}));\n\nconst EmptyNote = stylin(Typography)(({ theme }: { theme: any }) => ({\n fontSize: theme.typography.pxToRem(12),\n color: theme.palette.text.secondary,\n fontStyle: 'italic',\n}));\n\nconst ValueText = stylin(Box)(({ theme }: { theme: any }) => ({\n fontFamily: theme.typography.fontFamilyMono,\n fontSize: theme.typography.caption.fontSize,\n color: theme.palette.text.secondary,\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n}));\n\nconst NullLiteral = stylin(Box)(({ theme }: { theme: any }) => ({\n fontStyle: 'italic',\n color: theme.palette.text.secondary,\n fontFamily: theme.typography.fontFamilyMono,\n fontSize: theme.typography.caption.fontSize,\n}));\n"],"names":["value"],"mappings":"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"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import { formatInstanceStatus, composeInstanceStatus } from '../../utils/instanceStatuses.esm.js';
|
|
2
|
+
export { isDeploymentActive } from '../../utils/instanceStatuses.esm.js';
|
|
3
|
+
|
|
4
|
+
const truncateDeploymentId = (id) => {
|
|
5
|
+
if (!id) return "";
|
|
6
|
+
const parts = id.split("-");
|
|
7
|
+
return parts.length > 1 ? parts[parts.length - 1] : id;
|
|
8
|
+
};
|
|
9
|
+
const PLAN_SOURCE_REGEX = /^Planning deployment ([0-9a-fA-F-]{36})(?:\n([\s\S]*))?$/;
|
|
10
|
+
const parsePlanMessage = (message) => {
|
|
11
|
+
if (!message) return null;
|
|
12
|
+
const match = PLAN_SOURCE_REGEX.exec(message);
|
|
13
|
+
if (!match) return null;
|
|
14
|
+
return { sourceId: match[1], sourceMessage: match[2] ?? "" };
|
|
15
|
+
};
|
|
16
|
+
const formatElapsed = (seconds) => {
|
|
17
|
+
if (!seconds || seconds <= 0) return null;
|
|
18
|
+
const minutes = Math.floor(seconds / 60);
|
|
19
|
+
const remainder = seconds % 60;
|
|
20
|
+
return `${minutes}m ${remainder}s`;
|
|
21
|
+
};
|
|
22
|
+
const ROLLBACK_SOURCE_REGEX = /^Rollback to deployment ([0-9a-fA-F-]{36}) \(v([^)]*)\)(?:\n([\s\S]*))?$/;
|
|
23
|
+
const parseRollbackMessage = (message) => {
|
|
24
|
+
if (!message) return null;
|
|
25
|
+
const match = ROLLBACK_SOURCE_REGEX.exec(message);
|
|
26
|
+
return match ? { sourceId: match[1], version: match[2], sourceMessage: match[3] ?? "" } : null;
|
|
27
|
+
};
|
|
28
|
+
const stripMessageContext = (message) => {
|
|
29
|
+
const current = message ?? "";
|
|
30
|
+
if (!current) return current;
|
|
31
|
+
const plan = parsePlanMessage(current);
|
|
32
|
+
if (plan) return stripMessageContext(plan.sourceMessage);
|
|
33
|
+
const rollback = parseRollbackMessage(current);
|
|
34
|
+
if (rollback) return stripMessageContext(rollback.sourceMessage);
|
|
35
|
+
return current;
|
|
36
|
+
};
|
|
37
|
+
const formatDeploymentStatus = (action, status) => formatInstanceStatus(composeInstanceStatus(action, status));
|
|
38
|
+
const STATUSES_WITHOUT_LOGS = ["PROPOSED", "APPROVED", "REJECTED"];
|
|
39
|
+
const deploymentHasLogs = (status) => Boolean(status) && !STATUSES_WITHOUT_LOGS.includes(status);
|
|
40
|
+
const composeLogsText = (logs) => {
|
|
41
|
+
if (!Array.isArray(logs) || logs.length === 0) return "";
|
|
42
|
+
const joined = logs.map((line) => line?.message ?? "").join("");
|
|
43
|
+
return `
|
|
44
|
+
${joined}${joined.endsWith("\n") ? "" : "\n"}`;
|
|
45
|
+
};
|
|
46
|
+
const parseMap = (value) => {
|
|
47
|
+
if (value == null) return null;
|
|
48
|
+
if (typeof value === "object") return value;
|
|
49
|
+
try {
|
|
50
|
+
return JSON.parse(value);
|
|
51
|
+
} catch {
|
|
52
|
+
return null;
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
const formatAttributeValue = (value) => {
|
|
56
|
+
if (value === "*") return "any";
|
|
57
|
+
if (Array.isArray(value))
|
|
58
|
+
return value.length === 0 ? "any" : value.join(", ");
|
|
59
|
+
return String(value);
|
|
60
|
+
};
|
|
61
|
+
const ABSOLUTE_FORMATTER = new Intl.DateTimeFormat("en", {
|
|
62
|
+
month: "short",
|
|
63
|
+
day: "numeric",
|
|
64
|
+
hour: "numeric",
|
|
65
|
+
minute: "2-digit"
|
|
66
|
+
});
|
|
67
|
+
const formatAbsoluteDateTime = (isoString, fallback = "") => {
|
|
68
|
+
if (!isoString) return fallback;
|
|
69
|
+
const date = new Date(isoString);
|
|
70
|
+
return Number.isNaN(date.getTime()) ? fallback : ABSOLUTE_FORMATTER.format(date);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
export { STATUSES_WITHOUT_LOGS, composeLogsText, deploymentHasLogs, formatAbsoluteDateTime, formatAttributeValue, formatDeploymentStatus, formatElapsed, parseMap, parsePlanMessage, parseRollbackMessage, stripMessageContext, truncateDeploymentId };
|
|
74
|
+
//# sourceMappingURL=deploymentHelpers.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"deploymentHelpers.esm.js","sources":["../../../src/features/repo/deploymentHelpers.ts"],"sourcesContent":["// Ported from apps/web/shared/utils/historyHelpers.js and the web app's\n// ViewDeploymentDetailsDialog / DeploymentLogsDrawer components — the pieces the\n// deployments list, the in-place details dialog, and the logs drawer need.\nimport {\n composeInstanceStatus,\n formatInstanceStatus,\n} from '../../utils/instanceStatuses';\n\n// Re-exported for the logs drawer, which decides off deployment liveness\n// whether to keep the log subscription open.\nexport { isDeploymentActive } from '../../utils/instanceStatuses';\n\n/** The last hyphen-delimited segment of a deployment id (a short handle). */\nexport const truncateDeploymentId = (id?: string | null): string => {\n if (!id) return '';\n const parts = id.split('-');\n return parts.length > 1 ? parts[parts.length - 1] : id;\n};\n\nconst PLAN_SOURCE_REGEX =\n /^Planning deployment ([0-9a-fA-F-]{36})(?:\\n([\\s\\S]*))?$/;\n\n/**\n * Plan deployments encode their source deployment id in the message\n * (\"Planning deployment <uuid>\\n<source-message>\"). Returns the parsed source\n * id + human message, or null when the message isn't a plan precursor.\n */\nexport const parsePlanMessage = (\n message?: string | null,\n): { sourceId: string; sourceMessage: string } | null => {\n if (!message) return null;\n const match = PLAN_SOURCE_REGEX.exec(message);\n if (!match) return null;\n return { sourceId: match[1], sourceMessage: match[2] ?? '' };\n};\n\n/**\n * Ported from apps/web/shared/utils/historyHelpers.js — a deployment's elapsed\n * run time as \"Xm Ys\". Returns null for missing / non-positive durations so the\n * row can omit the segment entirely.\n */\nexport const formatElapsed = (seconds?: number | null): string | null => {\n if (!seconds || seconds <= 0) return null;\n const minutes = Math.floor(seconds / 60);\n const remainder = seconds % 60;\n return `${minutes}m ${remainder}s`;\n};\n\nconst ROLLBACK_SOURCE_REGEX =\n /^Rollback to deployment ([0-9a-fA-F-]{36}) \\(v([^)]*)\\)(?:\\n([\\s\\S]*))?$/;\n\n/**\n * Rollback proposals encode their source deployment + version in the message\n * (\"Rollback to deployment <uuid> (v<version>)\\n<source-message>\"). Returns the\n * parsed source id/version/message, or null when it isn't a rollback precursor.\n */\nexport const parseRollbackMessage = (\n message?: string | null,\n): { sourceId: string; version: string; sourceMessage: string } | null => {\n if (!message) return null;\n const match = ROLLBACK_SOURCE_REGEX.exec(message);\n return match\n ? { sourceId: match[1], version: match[2], sourceMessage: match[3] ?? '' }\n : null;\n};\n\n/**\n * Strip the plan/rollback precursor from a message, leaving only the\n * human-authored note. Recurses because a rollback's source can itself be a\n * plan. Ported from the web app's `stripMessageContext`.\n */\nexport const stripMessageContext = (message?: string | null): string => {\n const current = message ?? '';\n if (!current) return current;\n const plan = parsePlanMessage(current);\n if (plan) return stripMessageContext(plan.sourceMessage);\n const rollback = parseRollbackMessage(current);\n if (rollback) return stripMessageContext(rollback.sourceMessage);\n return current;\n};\n\n/**\n * Compound human label for a deployment (action + deployment status), e.g.\n * \"Provision Running\", \"Provisioning Failed\", \"Provisioned\".\n */\nexport const formatDeploymentStatus = (\n action?: string | null,\n status?: string | null,\n): string => formatInstanceStatus(composeInstanceStatus(action, status));\n\n// Statuses that never produce a deployment log stream — everything else has (or\n// will have) logs to view in-app. Ported from the web dialog's\n// STATUSES_WITHOUT_LOGS.\nexport const STATUSES_WITHOUT_LOGS = ['PROPOSED', 'APPROVED', 'REJECTED'];\n\nexport const deploymentHasLogs = (status?: string | null): boolean =>\n Boolean(status) && !STATUSES_WITHOUT_LOGS.includes(status as string);\n\n/**\n * Join a deployment's log batches into a single string for LogViewer, matching\n * the web app's `composeText`: each batch may already carry its own newlines, so\n * concatenate without inserting separators and guarantee a trailing newline.\n */\nexport const composeLogsText = (\n logs?: ({ message?: string | null } | null)[] | null,\n): string => {\n if (!Array.isArray(logs) || logs.length === 0) return '';\n const joined = logs.map(line => line?.message ?? '').join('');\n return `\\n${joined}${joined.endsWith('\\n') ? '' : '\\n'}`;\n};\n\nexport const parseMap = (value: unknown): Record<string, unknown> | null => {\n if (value == null) return null;\n if (typeof value === 'object') return value as Record<string, unknown>;\n try {\n return JSON.parse(value as string);\n } catch {\n return null;\n }\n};\n\nexport const formatAttributeValue = (value: unknown): string => {\n if (value === '*') return 'any';\n if (Array.isArray(value))\n return value.length === 0 ? 'any' : value.join(', ');\n return String(value);\n};\n\nconst ABSOLUTE_FORMATTER = new Intl.DateTimeFormat('en', {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n});\n\n/** Compact absolute timestamp for the details def-list (\"Jul 9, 3:04 PM\"). */\nexport const formatAbsoluteDateTime = (\n isoString?: string | null,\n fallback = '',\n): string => {\n if (!isoString) return fallback;\n const date = new Date(isoString);\n return Number.isNaN(date.getTime())\n ? fallback\n : ABSOLUTE_FORMATTER.format(date);\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const materialize = (node) => {
|
|
2
|
+
const folders = Object.values(node.children).map(materialize).sort((left, right) => left.name.localeCompare(right.name));
|
|
3
|
+
const files = [...node.files].sort(
|
|
4
|
+
(left, right) => left.name.localeCompare(right.name)
|
|
5
|
+
);
|
|
6
|
+
return { name: node.name, path: node.path, folders, files };
|
|
7
|
+
};
|
|
8
|
+
const buildFileTree = (files) => {
|
|
9
|
+
const root = { name: "", path: "", children: {}, files: [] };
|
|
10
|
+
(files ?? []).forEach((file) => {
|
|
11
|
+
if (!file?.name) return;
|
|
12
|
+
const segments = file.name.split("/").filter(Boolean);
|
|
13
|
+
if (segments.length === 0) return;
|
|
14
|
+
const fileName = segments[segments.length - 1];
|
|
15
|
+
const dirSegments = segments.slice(0, -1);
|
|
16
|
+
const dirNode = dirSegments.reduce((node, segment) => {
|
|
17
|
+
const path = node.path ? `${node.path}/${segment}` : segment;
|
|
18
|
+
if (!node.children[segment]) {
|
|
19
|
+
node.children[segment] = {
|
|
20
|
+
name: segment,
|
|
21
|
+
path,
|
|
22
|
+
children: {},
|
|
23
|
+
files: []
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
return node.children[segment];
|
|
27
|
+
}, root);
|
|
28
|
+
dirNode.files.push({ name: fileName, path: file.name, file });
|
|
29
|
+
});
|
|
30
|
+
return materialize(root);
|
|
31
|
+
};
|
|
32
|
+
const ancestorPaths = (selectedPath) => {
|
|
33
|
+
if (!selectedPath) return /* @__PURE__ */ new Set();
|
|
34
|
+
const segments = selectedPath.split("/").filter(Boolean);
|
|
35
|
+
const ancestors = /* @__PURE__ */ new Set();
|
|
36
|
+
segments.slice(0, -1).reduce((prefix, segment) => {
|
|
37
|
+
const path = prefix ? `${prefix}/${segment}` : segment;
|
|
38
|
+
ancestors.add(path);
|
|
39
|
+
return path;
|
|
40
|
+
}, "");
|
|
41
|
+
return ancestors;
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
export { ancestorPaths, buildFileTree };
|
|
45
|
+
//# sourceMappingURL=fileTreeHelpers.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileTreeHelpers.esm.js","sources":["../../../src/features/repo/fileTreeHelpers.ts"],"sourcesContent":["import type { RepoFile } from './types';\n\n// Ported from apps/web/features/repos/components/FileTree/FileTree.helpers.js.\n\nexport interface FileNode {\n name: string;\n path: string;\n file: RepoFile;\n}\n\nexport interface TreeNode {\n name: string;\n path: string;\n folders: TreeNode[];\n files: FileNode[];\n}\n\ninterface MutableNode {\n name: string;\n path: string;\n children: Record<string, MutableNode>;\n files: FileNode[];\n}\n\nconst materialize = (node: MutableNode): TreeNode => {\n const folders = Object.values(node.children)\n .map(materialize)\n .sort((left, right) => left.name.localeCompare(right.name));\n const files = [...node.files].sort((left, right) =>\n left.name.localeCompare(right.name),\n );\n return { name: node.name, path: node.path, folders, files };\n};\n\n/**\n * Build a nested tree from a flat list of files keyed by their path. Folders\n * sort before files; alpha within each group.\n */\nexport const buildFileTree = (\n files: RepoFile[] | null | undefined,\n): TreeNode => {\n const root: MutableNode = { name: '', path: '', children: {}, files: [] };\n\n (files ?? []).forEach(file => {\n if (!file?.name) return;\n const segments = file.name.split('/').filter(Boolean);\n if (segments.length === 0) return;\n\n const fileName = segments[segments.length - 1];\n const dirSegments = segments.slice(0, -1);\n\n const dirNode = dirSegments.reduce((node, segment) => {\n const path = node.path ? `${node.path}/${segment}` : segment;\n if (!node.children[segment]) {\n node.children[segment] = {\n name: segment,\n path,\n children: {},\n files: [],\n };\n }\n return node.children[segment];\n }, root);\n\n dirNode.files.push({ name: fileName, path: file.name, file });\n });\n\n return materialize(root);\n};\n\n/**\n * Returns the set of folder paths that contain `selectedPath`, so the tree can\n * auto-expand to reveal the selection.\n */\nexport const ancestorPaths = (\n selectedPath: string | null | undefined,\n): Set<string> => {\n if (!selectedPath) return new Set();\n const segments = selectedPath.split('/').filter(Boolean);\n const ancestors = new Set<string>();\n segments.slice(0, -1).reduce((prefix, segment) => {\n const path = prefix ? `${prefix}/${segment}` : segment;\n ancestors.add(path);\n return path;\n }, '');\n return ancestors;\n};\n"],"names":[],"mappings":"AAwBA,MAAM,WAAA,GAAc,CAAC,IAAA,KAAgC;AACnD,EAAA,MAAM,UAAU,MAAA,CAAO,MAAA,CAAO,KAAK,QAAQ,CAAA,CACxC,IAAI,WAAW,CAAA,CACf,IAAA,CAAK,CAAC,MAAM,KAAA,KAAU,IAAA,CAAK,KAAK,aAAA,CAAc,KAAA,CAAM,IAAI,CAAC,CAAA;AAC5D,EAAA,MAAM,KAAA,GAAQ,CAAC,GAAG,IAAA,CAAK,KAAK,CAAA,CAAE,IAAA;AAAA,IAAK,CAAC,IAAA,EAAM,KAAA,KACxC,KAAK,IAAA,CAAK,aAAA,CAAc,MAAM,IAAI;AAAA,GACpC;AACA,EAAA,OAAO,EAAE,MAAM,IAAA,CAAK,IAAA,EAAM,MAAM,IAAA,CAAK,IAAA,EAAM,SAAS,KAAA,EAAM;AAC5D,CAAA;AAMO,MAAM,aAAA,GAAgB,CAC3B,KAAA,KACa;AACb,EAAA,MAAM,IAAA,GAAoB,EAAE,IAAA,EAAM,EAAA,EAAI,IAAA,EAAM,EAAA,EAAI,QAAA,EAAU,EAAC,EAAG,KAAA,EAAO,EAAC,EAAE;AAExE,EAAA,CAAC,KAAA,IAAS,EAAC,EAAG,OAAA,CAAQ,CAAA,IAAA,KAAQ;AAC5B,IAAA,IAAI,CAAC,MAAM,IAAA,EAAM;AACjB,IAAA,MAAM,WAAW,IAAA,CAAK,IAAA,CAAK,MAAM,GAAG,CAAA,CAAE,OAAO,OAAO,CAAA;AACpD,IAAA,IAAI,QAAA,CAAS,WAAW,CAAA,EAAG;AAE3B,IAAA,MAAM,QAAA,GAAW,QAAA,CAAS,QAAA,CAAS,MAAA,GAAS,CAAC,CAAA;AAC7C,IAAA,MAAM,WAAA,GAAc,QAAA,CAAS,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AAExC,IAAA,MAAM,OAAA,GAAU,WAAA,CAAY,MAAA,CAAO,CAAC,MAAM,OAAA,KAAY;AACpD,MAAA,MAAM,IAAA,GAAO,KAAK,IAAA,GAAO,CAAA,EAAG,KAAK,IAAI,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,GAAK,OAAA;AACrD,MAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,EAAG;AAC3B,QAAA,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,GAAI;AAAA,UACvB,IAAA,EAAM,OAAA;AAAA,UACN,IAAA;AAAA,UACA,UAAU,EAAC;AAAA,UACX,OAAO;AAAC,SACV;AAAA,MACF;AACA,MAAA,OAAO,IAAA,CAAK,SAAS,OAAO,CAAA;AAAA,IAC9B,GAAG,IAAI,CAAA;AAEP,IAAA,OAAA,CAAQ,KAAA,CAAM,KAAK,EAAE,IAAA,EAAM,UAAU,IAAA,EAAM,IAAA,CAAK,IAAA,EAAM,IAAA,EAAM,CAAA;AAAA,EAC9D,CAAC,CAAA;AAED,EAAA,OAAO,YAAY,IAAI,CAAA;AACzB;AAMO,MAAM,aAAA,GAAgB,CAC3B,YAAA,KACgB;AAChB,EAAA,IAAI,CAAC,YAAA,EAAc,uBAAO,IAAI,GAAA,EAAI;AAClC,EAAA,MAAM,WAAW,YAAA,CAAa,KAAA,CAAM,GAAG,CAAA,CAAE,OAAO,OAAO,CAAA;AACvD,EAAA,MAAM,SAAA,uBAAgB,GAAA,EAAY;AAClC,EAAA,QAAA,CAAS,MAAM,CAAA,EAAG,EAAE,EAAE,MAAA,CAAO,CAAC,QAAQ,OAAA,KAAY;AAChD,IAAA,MAAM,OAAO,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,GAAK,OAAA;AAC/C,IAAA,SAAA,CAAU,IAAI,IAAI,CAAA;AAClB,IAAA,OAAO,IAAA;AAAA,EACT,GAAG,EAAE,CAAA;AACL,EAAA,OAAO,SAAA;AACT;;;;"}
|