@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,119 @@
|
|
|
1
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import { useState } from 'react';
|
|
3
|
+
import Box from '@massdriver/ui/Box';
|
|
4
|
+
import Tabs from '@massdriver/ui/Tabs';
|
|
5
|
+
import Tab from '@massdriver/ui/Tab';
|
|
6
|
+
import IconButton from '@massdriver/ui/IconButton';
|
|
7
|
+
import Menu, { MenuItem } from '@massdriver/ui/Menu';
|
|
8
|
+
import MoreHorizIcon from '@massdriver/ui/icons/MoreHorizIcon';
|
|
9
|
+
import stylin from '@massdriver/ui/stylin';
|
|
10
|
+
import { useOverflowMeasure } from './useOverflowMeasure.esm.js';
|
|
11
|
+
|
|
12
|
+
const MORE_BUTTON_WIDTH = 48;
|
|
13
|
+
const MIN_VISIBLE = 5;
|
|
14
|
+
const InstanceTabs = ({
|
|
15
|
+
tabs,
|
|
16
|
+
activeTab,
|
|
17
|
+
onTabChange
|
|
18
|
+
}) => {
|
|
19
|
+
const [anchorEl, setAnchorEl] = useState(null);
|
|
20
|
+
const { containerRef, visibleCount, measured } = useOverflowMeasure({
|
|
21
|
+
itemCount: tabs.length,
|
|
22
|
+
minVisible: MIN_VISIBLE,
|
|
23
|
+
moreButtonWidth: MORE_BUTTON_WIDTH
|
|
24
|
+
});
|
|
25
|
+
const visibleTabs = tabs.slice(0, visibleCount);
|
|
26
|
+
const overflowTabs = tabs.slice(visibleCount);
|
|
27
|
+
const hasOverflow = overflowTabs.length > 0;
|
|
28
|
+
const overflowSelected = overflowTabs.some((tab) => tab.id === activeTab);
|
|
29
|
+
return /* @__PURE__ */ jsxs(TabContainer, { ref: containerRef, children: [
|
|
30
|
+
/* @__PURE__ */ jsx(TabsWrapper, { children: /* @__PURE__ */ jsx(StyledTabs, { value: overflowSelected ? false : activeTab, children: visibleTabs.map((tab) => /* @__PURE__ */ jsx(
|
|
31
|
+
StyledTab,
|
|
32
|
+
{
|
|
33
|
+
label: tab.label,
|
|
34
|
+
value: tab.id,
|
|
35
|
+
onClick: () => onTabChange(tab.id),
|
|
36
|
+
measured
|
|
37
|
+
},
|
|
38
|
+
tab.id
|
|
39
|
+
)) }) }),
|
|
40
|
+
hasOverflow ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
41
|
+
/* @__PURE__ */ jsx(
|
|
42
|
+
MoreButton,
|
|
43
|
+
{
|
|
44
|
+
size: "small",
|
|
45
|
+
onClick: (event) => setAnchorEl(event.currentTarget),
|
|
46
|
+
"aria-label": "more tabs",
|
|
47
|
+
selected: overflowSelected,
|
|
48
|
+
children: /* @__PURE__ */ jsx(MoreHorizIcon, { fontSize: "small" })
|
|
49
|
+
}
|
|
50
|
+
),
|
|
51
|
+
/* @__PURE__ */ jsx(
|
|
52
|
+
Menu,
|
|
53
|
+
{
|
|
54
|
+
anchorEl,
|
|
55
|
+
open: Boolean(anchorEl),
|
|
56
|
+
onClose: () => setAnchorEl(null),
|
|
57
|
+
children: overflowTabs.map((tab) => /* @__PURE__ */ jsx(
|
|
58
|
+
MenuItem,
|
|
59
|
+
{
|
|
60
|
+
selected: tab.id === activeTab,
|
|
61
|
+
onClick: () => {
|
|
62
|
+
onTabChange(tab.id);
|
|
63
|
+
setAnchorEl(null);
|
|
64
|
+
},
|
|
65
|
+
children: tab.label
|
|
66
|
+
},
|
|
67
|
+
tab.id
|
|
68
|
+
))
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
] }) : null
|
|
72
|
+
] });
|
|
73
|
+
};
|
|
74
|
+
const TabContainer = stylin(Box)(({ theme }) => ({
|
|
75
|
+
display: "flex",
|
|
76
|
+
alignItems: "center",
|
|
77
|
+
borderBottom: `1px solid ${theme.palette.divider}`,
|
|
78
|
+
backgroundColor: theme.palette.background.paper
|
|
79
|
+
}));
|
|
80
|
+
const TabsWrapper = stylin(Box)({
|
|
81
|
+
flex: 1,
|
|
82
|
+
minWidth: 0,
|
|
83
|
+
overflow: "hidden"
|
|
84
|
+
});
|
|
85
|
+
const StyledTabs = stylin(Tabs)({
|
|
86
|
+
width: "100%"
|
|
87
|
+
});
|
|
88
|
+
const StyledTab = stylin(Tab, ["measured"])(
|
|
89
|
+
({ measured }) => ({
|
|
90
|
+
...measured && { flex: 1 }
|
|
91
|
+
})
|
|
92
|
+
);
|
|
93
|
+
const MoreButton = stylin(IconButton, ["selected"])(
|
|
94
|
+
({ theme, selected }) => ({
|
|
95
|
+
flexShrink: 0,
|
|
96
|
+
borderRadius: 0,
|
|
97
|
+
height: "100%",
|
|
98
|
+
width: MORE_BUTTON_WIDTH,
|
|
99
|
+
position: "relative",
|
|
100
|
+
color: selected ? theme.palette.primary.main : theme.palette.text.secondary,
|
|
101
|
+
"&:hover": {
|
|
102
|
+
backgroundColor: theme.palette.action.hover
|
|
103
|
+
},
|
|
104
|
+
...selected && {
|
|
105
|
+
"&::after": {
|
|
106
|
+
content: '""',
|
|
107
|
+
position: "absolute",
|
|
108
|
+
bottom: 0,
|
|
109
|
+
left: 0,
|
|
110
|
+
right: 0,
|
|
111
|
+
height: 2,
|
|
112
|
+
backgroundColor: theme.palette.primary.main
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
})
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
export { InstanceTabs };
|
|
119
|
+
//# sourceMappingURL=InstanceTabs.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InstanceTabs.esm.js","sources":["../../../../src/features/environment/InstanceDrawer/InstanceTabs.tsx"],"sourcesContent":["import { useState } from 'react';\nimport Box from '@massdriver/ui/Box';\nimport Tabs from '@massdriver/ui/Tabs';\nimport Tab from '@massdriver/ui/Tab';\nimport IconButton from '@massdriver/ui/IconButton';\nimport Menu, { MenuItem } from '@massdriver/ui/Menu';\nimport MoreHorizIcon from '@massdriver/ui/icons/MoreHorizIcon';\nimport stylin from '@massdriver/ui/stylin';\nimport { useOverflowMeasure } from './useOverflowMeasure';\n\nconst MORE_BUTTON_WIDTH = 48;\nconst MIN_VISIBLE = 5;\n\ninterface TabDef {\n id: string;\n label: string;\n}\n\n/**\n * Instance drawer tab bar. Ported from the web app's `InstanceTabs`: the\n * `@massdriver/ui` `Tabs`/`Tab` are custom (selection flows via context, the\n * change handler is an `onClick` per tab — not MUI's `onChange`). Overflowing\n * tabs collapse into a \"more\" menu.\n */\nexport const InstanceTabs = ({\n tabs,\n activeTab,\n onTabChange,\n}: {\n tabs: TabDef[];\n activeTab: string;\n onTabChange: (tabId: string) => void;\n}) => {\n const [anchorEl, setAnchorEl] = useState<HTMLElement | null>(null);\n const { containerRef, visibleCount, measured } = useOverflowMeasure({\n itemCount: tabs.length,\n minVisible: MIN_VISIBLE,\n moreButtonWidth: MORE_BUTTON_WIDTH,\n });\n\n const visibleTabs = tabs.slice(0, visibleCount);\n const overflowTabs = tabs.slice(visibleCount);\n const hasOverflow = overflowTabs.length > 0;\n const overflowSelected = overflowTabs.some(tab => tab.id === activeTab);\n\n return (\n <TabContainer ref={containerRef}>\n <TabsWrapper>\n <StyledTabs value={overflowSelected ? false : activeTab}>\n {visibleTabs.map(tab => (\n <StyledTab\n key={tab.id}\n label={tab.label}\n value={tab.id}\n onClick={() => onTabChange(tab.id)}\n measured={measured}\n />\n ))}\n </StyledTabs>\n </TabsWrapper>\n {hasOverflow ? (\n <>\n <MoreButton\n size=\"small\"\n onClick={(event: any) => setAnchorEl(event.currentTarget)}\n aria-label=\"more tabs\"\n selected={overflowSelected}\n >\n <MoreHorizIcon fontSize=\"small\" />\n </MoreButton>\n <Menu\n anchorEl={anchorEl}\n open={Boolean(anchorEl)}\n onClose={() => setAnchorEl(null)}\n >\n {overflowTabs.map(tab => (\n <MenuItem\n key={tab.id}\n selected={tab.id === activeTab}\n onClick={() => {\n onTabChange(tab.id);\n setAnchorEl(null);\n }}\n >\n {tab.label}\n </MenuItem>\n ))}\n </Menu>\n </>\n ) : null}\n </TabContainer>\n );\n};\n\nexport default InstanceTabs;\n\nconst TabContainer = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n alignItems: 'center',\n borderBottom: `1px solid ${theme.palette.divider}`,\n backgroundColor: theme.palette.background.paper,\n}));\n\nconst TabsWrapper = stylin(Box)({\n flex: 1,\n minWidth: 0,\n overflow: 'hidden',\n});\n\nconst StyledTabs = stylin(Tabs)({\n width: '100%',\n});\n\nconst StyledTab = stylin(Tab, ['measured'])(\n ({ measured }: { measured: boolean }) => ({\n ...(measured && { flex: 1 }),\n }),\n);\n\nconst MoreButton = stylin(IconButton, ['selected'])(\n ({ theme, selected }: { theme: any; selected: boolean }) => ({\n flexShrink: 0,\n borderRadius: 0,\n height: '100%',\n width: MORE_BUTTON_WIDTH,\n position: 'relative',\n color: selected ? theme.palette.primary.main : theme.palette.text.secondary,\n '&:hover': {\n backgroundColor: theme.palette.action.hover,\n },\n ...(selected && {\n '&::after': {\n content: '\"\"',\n position: 'absolute',\n bottom: 0,\n left: 0,\n right: 0,\n height: 2,\n backgroundColor: theme.palette.primary.main,\n },\n }),\n }),\n);\n"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { jsx, Fragment } from 'react/jsx-runtime';
|
|
2
|
+
import Box from '@massdriver/ui/Box';
|
|
3
|
+
import Alert from '@massdriver/ui/Alert';
|
|
4
|
+
import LoadingIndicator from '@massdriver/ui/LoadingIndicator';
|
|
5
|
+
import stylin from '@massdriver/ui/stylin';
|
|
6
|
+
|
|
7
|
+
const TabState = ({
|
|
8
|
+
loading,
|
|
9
|
+
error,
|
|
10
|
+
children
|
|
11
|
+
}) => {
|
|
12
|
+
if (loading) {
|
|
13
|
+
return /* @__PURE__ */ jsx(Centered, { children: /* @__PURE__ */ jsx(LoadingIndicator, {}) });
|
|
14
|
+
}
|
|
15
|
+
if (error) {
|
|
16
|
+
return /* @__PURE__ */ jsx(Padded, { children: /* @__PURE__ */ jsx(Alert, { severity: "error", children: String(error.message ?? error) }) });
|
|
17
|
+
}
|
|
18
|
+
return /* @__PURE__ */ jsx(Fragment, { children });
|
|
19
|
+
};
|
|
20
|
+
const Centered = stylin(Box)(({ theme }) => ({
|
|
21
|
+
display: "flex",
|
|
22
|
+
justifyContent: "center",
|
|
23
|
+
padding: theme.spacing(6)
|
|
24
|
+
}));
|
|
25
|
+
const Padded = stylin(Box)(({ theme }) => ({
|
|
26
|
+
padding: theme.spacing(2)
|
|
27
|
+
}));
|
|
28
|
+
|
|
29
|
+
export { TabState };
|
|
30
|
+
//# sourceMappingURL=TabState.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TabState.esm.js","sources":["../../../../src/features/environment/InstanceDrawer/TabState.tsx"],"sourcesContent":["import { ReactNode } from 'react';\nimport Box from '@massdriver/ui/Box';\nimport Alert from '@massdriver/ui/Alert';\nimport LoadingIndicator from '@massdriver/ui/LoadingIndicator';\nimport stylin from '@massdriver/ui/stylin';\n\n/** Loading/error/content gate shared by the drawer tabs. */\nexport const TabState = ({\n loading,\n error,\n children,\n}: {\n loading: boolean;\n error?: Error | null;\n children: ReactNode;\n}) => {\n if (loading) {\n return (\n <Centered>\n <LoadingIndicator />\n </Centered>\n );\n }\n if (error) {\n return (\n <Padded>\n <Alert severity=\"error\">{String(error.message ?? error)}</Alert>\n </Padded>\n );\n }\n return <>{children}</>;\n};\n\nconst Centered = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n justifyContent: 'center',\n padding: theme.spacing(6),\n}));\n\nconst Padded = stylin(Box)(({ theme }: { theme: any }) => ({\n padding: theme.spacing(2),\n}));\n"],"names":[],"mappings":";;;;;;AAOO,MAAM,WAAW,CAAC;AAAA,EACvB,OAAA;AAAA,EACA,KAAA;AAAA,EACA;AACF,CAAA,KAIM;AACJ,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,uBACE,GAAA,CAAC,QAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,CAAA,EACpB,CAAA;AAAA,EAEJ;AACA,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,uBACE,GAAA,CAAC,MAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,OAAA,EAAS,QAAA,EAAA,MAAA,CAAO,KAAA,CAAM,OAAA,IAAW,KAAK,CAAA,EAAE,CAAA,EAC1D,CAAA;AAAA,EAEJ;AACA,EAAA,uCAAU,QAAA,EAAS,CAAA;AACrB;AAEA,MAAM,WAAW,MAAA,CAAO,GAAG,EAAE,CAAC,EAAE,OAAM,MAAuB;AAAA,EAC3D,OAAA,EAAS,MAAA;AAAA,EACT,cAAA,EAAgB,QAAA;AAAA,EAChB,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAC;AAC1B,CAAA,CAAE,CAAA;AAEF,MAAM,SAAS,MAAA,CAAO,GAAG,EAAE,CAAC,EAAE,OAAM,MAAuB;AAAA,EACzD,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,CAAC;AAC1B,CAAA,CAAE,CAAA;;;;"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
import { useApi } from '@backstage/frontend-plugin-api';
|
|
4
|
+
import useAsync from 'react-use/esm/useAsync';
|
|
5
|
+
import { print } from 'graphql';
|
|
6
|
+
import Alert from '@massdriver/ui/Alert';
|
|
7
|
+
import { massdriverApiRef } from '../../../api.esm.js';
|
|
8
|
+
|
|
9
|
+
const useQuery = (document, options = {}) => {
|
|
10
|
+
const api = useApi(massdriverApiRef);
|
|
11
|
+
const query = useMemo(() => print(document), [document]);
|
|
12
|
+
const variables = options.variables ?? {};
|
|
13
|
+
const skip = Boolean(options.skip);
|
|
14
|
+
const variablesKey = JSON.stringify(variables);
|
|
15
|
+
const { value, loading, error } = useAsync(async () => {
|
|
16
|
+
if (skip) return void 0;
|
|
17
|
+
return await api.query(query, variables);
|
|
18
|
+
}, [api, query, variablesKey, skip]);
|
|
19
|
+
return { data: value, loading, error };
|
|
20
|
+
};
|
|
21
|
+
const ErrorDisplay = ({ error }) => /* @__PURE__ */ jsx(Alert, { severity: "error", children: String(error?.message ?? error ?? "Failed to load field options.") });
|
|
22
|
+
const formsDataSource = { useQuery, ErrorDisplay };
|
|
23
|
+
|
|
24
|
+
export { formsDataSource };
|
|
25
|
+
//# sourceMappingURL=formsDataSource.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"formsDataSource.esm.js","sources":["../../../../src/features/environment/InstanceDrawer/formsDataSource.tsx"],"sourcesContent":["import { useMemo } from 'react';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\nimport { print, type DocumentNode } from 'graphql';\nimport Alert from '@massdriver/ui/Alert';\nimport { massdriverApiRef } from '../../../api';\n\n// Relay-backed executor injected into @massdriver/forms' DataSourceProvider.\n// The package's data-fetching fields own their GQL documents and call this\n// `useQuery(document, { variables })`, expecting an Apollo-style\n// `{ data, loading, error }`. There is no Apollo in the plugin, so we print the\n// document to a string and run it through the Backstage relay, which injects\n// `organizationId` + the service-account token server-side. Mirrors the web\n// app's `shared/rjsf/dataSource.js` (which injects `shared/apollo`'s useQuery).\nconst useQuery = (\n document: DocumentNode,\n options: { variables?: Record<string, unknown>; skip?: boolean } = {},\n) => {\n const api = useApi(massdriverApiRef);\n const query = useMemo(() => print(document), [document]);\n const variables = options.variables ?? {};\n const skip = Boolean(options.skip);\n const variablesKey = JSON.stringify(variables);\n\n const { value, loading, error } = useAsync(async () => {\n if (skip) return undefined;\n return (await api.query(query, variables)) as unknown;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [api, query, variablesKey, skip]);\n\n return { data: value, loading, error };\n};\n\nconst ErrorDisplay = ({ error }: { error?: { message?: string } | null }) => (\n <Alert severity=\"error\">\n {String(error?.message ?? error ?? 'Failed to load field options.')}\n </Alert>\n);\n\n/** DataSourceProvider value — stable module-level object (a hook fn + a\n * component), so the provider never re-mounts consumers. */\nexport const formsDataSource = { useQuery, ErrorDisplay };\n\nexport default formsDataSource;\n"],"names":[],"mappings":";;;;;;;;AAcA,MAAM,QAAA,GAAW,CACf,QAAA,EACA,OAAA,GAAmE,EAAC,KACjE;AACH,EAAA,MAAM,GAAA,GAAM,OAAO,gBAAgB,CAAA;AACnC,EAAA,MAAM,KAAA,GAAQ,QAAQ,MAAM,KAAA,CAAM,QAAQ,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AACvD,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,SAAA,IAAa,EAAC;AACxC,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,OAAA,CAAQ,IAAI,CAAA;AACjC,EAAA,MAAM,YAAA,GAAe,IAAA,CAAK,SAAA,CAAU,SAAS,CAAA;AAE7C,EAAA,MAAM,EAAE,KAAA,EAAO,OAAA,EAAS,KAAA,EAAM,GAAI,SAAS,YAAY;AACrD,IAAA,IAAI,MAAM,OAAO,MAAA;AACjB,IAAA,OAAQ,MAAM,GAAA,CAAI,KAAA,CAAM,KAAA,EAAO,SAAS,CAAA;AAAA,EAE1C,GAAG,CAAC,GAAA,EAAK,KAAA,EAAO,YAAA,EAAc,IAAI,CAAC,CAAA;AAEnC,EAAA,OAAO,EAAE,IAAA,EAAM,KAAA,EAAO,OAAA,EAAS,KAAA,EAAM;AACvC,CAAA;AAEA,MAAM,YAAA,GAAe,CAAC,EAAE,KAAA,uBACtB,GAAA,CAAC,KAAA,EAAA,EAAM,QAAA,EAAS,OAAA,EACb,QAAA,EAAA,MAAA,CAAO,KAAA,EAAO,OAAA,IAAW,KAAA,IAAS,+BAA+B,CAAA,EACpE,CAAA;AAKK,MAAM,eAAA,GAAkB,EAAE,QAAA,EAAU,YAAA;;;;"}
|
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { formatInstanceStatus, composeInstanceStatus } from '../../../utils/instanceStatuses.esm.js';
|
|
2
|
+
export { isDeploymentActive } from '../../../utils/instanceStatuses.esm.js';
|
|
3
|
+
|
|
4
|
+
const parseMap = (value) => {
|
|
5
|
+
if (value == null) return null;
|
|
6
|
+
if (typeof value === "object") return value;
|
|
7
|
+
try {
|
|
8
|
+
return JSON.parse(value);
|
|
9
|
+
} catch {
|
|
10
|
+
return null;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
const formatAttributeValue = (value) => {
|
|
14
|
+
if (value === "*") return "any";
|
|
15
|
+
if (Array.isArray(value))
|
|
16
|
+
return value.length === 0 ? "any" : value.join(", ");
|
|
17
|
+
return String(value);
|
|
18
|
+
};
|
|
19
|
+
const getReleaseChannel = (version, resolvedVersion) => !version || version === resolvedVersion ? null : { channel: version };
|
|
20
|
+
const getFiringAlerts = (items) => (items ?? []).filter(
|
|
21
|
+
(alarm) => alarm?.currentState?.status === "ALARM"
|
|
22
|
+
);
|
|
23
|
+
const formatPropertyValue = (value) => {
|
|
24
|
+
if (value === null || value === void 0) return "\u2014";
|
|
25
|
+
if (typeof value === "object") return JSON.stringify(value, null, 2);
|
|
26
|
+
return String(value);
|
|
27
|
+
};
|
|
28
|
+
const PROPERTY_PAGE_SIZE = 5;
|
|
29
|
+
const filterAndPaginateProperties = (properties = [], { search = "", page = 1 } = {}) => {
|
|
30
|
+
const normalized = search.trim().toLowerCase();
|
|
31
|
+
const filtered = normalized ? properties.filter((property) => {
|
|
32
|
+
const name = property?.name?.toLowerCase() ?? "";
|
|
33
|
+
const path = property?.path?.toLowerCase() ?? "";
|
|
34
|
+
const value = String(property?.value ?? "").toLowerCase();
|
|
35
|
+
return name.includes(normalized) || path.includes(normalized) || value.includes(normalized);
|
|
36
|
+
}) : properties;
|
|
37
|
+
const totalPages = Math.max(
|
|
38
|
+
1,
|
|
39
|
+
Math.ceil(filtered.length / PROPERTY_PAGE_SIZE)
|
|
40
|
+
);
|
|
41
|
+
const safePage = Math.min(Math.max(page, 1), totalPages);
|
|
42
|
+
const start = (safePage - 1) * PROPERTY_PAGE_SIZE;
|
|
43
|
+
return {
|
|
44
|
+
items: filtered.slice(start, start + PROPERTY_PAGE_SIZE),
|
|
45
|
+
totalPages,
|
|
46
|
+
page: safePage
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
const ALARMS_DOCS_URL = "https://docs.massdriver.cloud/platform-operations/monitoring-and-alarms";
|
|
50
|
+
const OPERATOR_PHRASES = {
|
|
51
|
+
GREATER_THAN: "above",
|
|
52
|
+
GREATER_THAN_OR_EQUAL_TO: "at or above",
|
|
53
|
+
LESS_THAN: "below",
|
|
54
|
+
LESS_THAN_OR_EQUAL_TO: "at or below"
|
|
55
|
+
};
|
|
56
|
+
const describeOperator = (operator) => (operator && OPERATOR_PHRASES[operator]) ?? operator ?? "";
|
|
57
|
+
const formatPeriod = (period) => {
|
|
58
|
+
if (!period) return "";
|
|
59
|
+
if (period >= 60 && period % 60 === 0) {
|
|
60
|
+
const minutes = period / 60;
|
|
61
|
+
return `${minutes} minute${minutes === 1 ? "" : "s"}`;
|
|
62
|
+
}
|
|
63
|
+
return `${period} seconds`;
|
|
64
|
+
};
|
|
65
|
+
const describeThreshold = (alarm) => {
|
|
66
|
+
const hasComparison = alarm.comparisonOperator && alarm.threshold !== null && alarm.threshold !== void 0;
|
|
67
|
+
if (!hasComparison && !alarm.period) return null;
|
|
68
|
+
const parts = [];
|
|
69
|
+
if (hasComparison) {
|
|
70
|
+
parts.push(
|
|
71
|
+
`${describeOperator(alarm.comparisonOperator)} ${alarm.threshold}`
|
|
72
|
+
);
|
|
73
|
+
}
|
|
74
|
+
if (alarm.period) parts.push(`for ${formatPeriod(alarm.period)}`);
|
|
75
|
+
return parts.join(" ");
|
|
76
|
+
};
|
|
77
|
+
const isFiring = (alarm) => alarm?.currentState?.status === "ALARM";
|
|
78
|
+
const STATUS_LABEL = { ALARM: "Firing", OK: "OK" };
|
|
79
|
+
const getStatusLabel = (currentState) => {
|
|
80
|
+
if (!currentState) return "No data";
|
|
81
|
+
return (currentState.status && STATUS_LABEL[currentState.status]) ?? currentState.status ?? "No data";
|
|
82
|
+
};
|
|
83
|
+
const getSeverity = (alarm) => isFiring(alarm) ? "firing" : alarm.currentState ? "ok" : "unknown";
|
|
84
|
+
const formatMetricLine = (metric) => {
|
|
85
|
+
if (!metric) return null;
|
|
86
|
+
const path = [metric.namespace, metric.name].filter(Boolean).join(" / ");
|
|
87
|
+
if (!path && !metric.statistic) return null;
|
|
88
|
+
if (!path) return metric.statistic ?? null;
|
|
89
|
+
if (!metric.statistic) return path;
|
|
90
|
+
return `${path} (${metric.statistic})`;
|
|
91
|
+
};
|
|
92
|
+
const formatAlarmDimensions = (dimensions) => (dimensions ?? []).filter(Boolean).map((dimension) => `${dimension.name}=${dimension.value}`).join(", ");
|
|
93
|
+
const bucketAlarms = (items) => {
|
|
94
|
+
const sorted = [...items ?? []].filter((alarm) => Boolean(alarm)).sort(
|
|
95
|
+
(left, right) => (left.displayName ?? "").localeCompare(right.displayName ?? "")
|
|
96
|
+
);
|
|
97
|
+
return {
|
|
98
|
+
firing: sorted.filter(isFiring),
|
|
99
|
+
configured: sorted.filter((alarm) => !isFiring(alarm)),
|
|
100
|
+
total: sorted.length
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
const RESOURCE_STATE = {
|
|
104
|
+
CREATED: "CREATED",
|
|
105
|
+
UNCREATED: "UNCREATED"
|
|
106
|
+
};
|
|
107
|
+
const buildResourceRows = (bundleResources, instanceResources) => {
|
|
108
|
+
const producedByField = new Map(
|
|
109
|
+
(instanceResources ?? []).filter(
|
|
110
|
+
(produced) => Boolean(produced?.field)
|
|
111
|
+
).map((produced) => [produced.field, produced])
|
|
112
|
+
);
|
|
113
|
+
const fromBundle = (bundleResources ?? []).filter(
|
|
114
|
+
(bundleResource) => Boolean(bundleResource?.name)
|
|
115
|
+
).map((bundleResource) => {
|
|
116
|
+
const produced = producedByField.get(bundleResource.name) ?? null;
|
|
117
|
+
return {
|
|
118
|
+
field: bundleResource.name,
|
|
119
|
+
required: produced ? Boolean(produced.required) : Boolean(bundleResource.required),
|
|
120
|
+
resource: produced?.resource ?? null,
|
|
121
|
+
resourceType: produced?.resourceType ?? bundleResource.resourceType,
|
|
122
|
+
state: produced ? RESOURCE_STATE.CREATED : RESOURCE_STATE.UNCREATED
|
|
123
|
+
};
|
|
124
|
+
});
|
|
125
|
+
const bundleFields = new Set(fromBundle.map((row) => row.field));
|
|
126
|
+
const orphanProduced = (instanceResources ?? []).filter(
|
|
127
|
+
(produced) => Boolean(produced?.field) && !bundleFields.has(produced.field)
|
|
128
|
+
).map((produced) => ({
|
|
129
|
+
field: produced.field,
|
|
130
|
+
required: Boolean(produced.required),
|
|
131
|
+
resource: produced.resource ?? null,
|
|
132
|
+
resourceType: produced.resourceType,
|
|
133
|
+
state: RESOURCE_STATE.CREATED
|
|
134
|
+
}));
|
|
135
|
+
return [...fromBundle, ...orphanProduced].sort(
|
|
136
|
+
(rowA, rowB) => rowA.field.localeCompare(rowB.field)
|
|
137
|
+
);
|
|
138
|
+
};
|
|
139
|
+
const formatGrantConditions = (recipientConditions) => {
|
|
140
|
+
if (recipientConditions === "*" || recipientConditions === null) {
|
|
141
|
+
return "every recipient in the organization";
|
|
142
|
+
}
|
|
143
|
+
if (typeof recipientConditions === "string") {
|
|
144
|
+
try {
|
|
145
|
+
return formatGrantConditions(JSON.parse(recipientConditions));
|
|
146
|
+
} catch {
|
|
147
|
+
return recipientConditions;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
if (typeof recipientConditions === "object") {
|
|
151
|
+
const entries = Object.entries(
|
|
152
|
+
recipientConditions
|
|
153
|
+
);
|
|
154
|
+
if (entries.length === 0) return "no conditions";
|
|
155
|
+
return entries.map(
|
|
156
|
+
([key, value]) => `${key}: ${Array.isArray(value) ? value.join(", ") : String(value)}`
|
|
157
|
+
).join(" \xB7 ");
|
|
158
|
+
}
|
|
159
|
+
return String(recipientConditions);
|
|
160
|
+
};
|
|
161
|
+
const formatPayload = (payload) => {
|
|
162
|
+
if (payload == null) return "";
|
|
163
|
+
try {
|
|
164
|
+
return JSON.stringify(payload, null, 2);
|
|
165
|
+
} catch {
|
|
166
|
+
return String(payload);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
const DEPENDENCY_STATE = {
|
|
170
|
+
REMOTE_REFERENCE: "REMOTE_REFERENCE",
|
|
171
|
+
CONNECTION: "CONNECTION",
|
|
172
|
+
ENV_DEFAULT: "ENV_DEFAULT",
|
|
173
|
+
UNFULFILLED: "UNFULFILLED"
|
|
174
|
+
};
|
|
175
|
+
const FULFILLED_STATES = /* @__PURE__ */ new Set([
|
|
176
|
+
DEPENDENCY_STATE.REMOTE_REFERENCE,
|
|
177
|
+
DEPENDENCY_STATE.CONNECTION,
|
|
178
|
+
DEPENDENCY_STATE.ENV_DEFAULT
|
|
179
|
+
]);
|
|
180
|
+
const buildDependencyRows = (bundleDependencies, instanceDependencies) => {
|
|
181
|
+
const byField = new Map(
|
|
182
|
+
(instanceDependencies ?? []).filter((dep) => Boolean(dep?.field)).map((dep) => [dep.field, dep])
|
|
183
|
+
);
|
|
184
|
+
return (bundleDependencies ?? []).filter(
|
|
185
|
+
(dep) => Boolean(dep) && dep?.resourceType?.connectionOrientation !== "ENVIRONMENT_DEFAULT"
|
|
186
|
+
).map((bundleDep) => {
|
|
187
|
+
const instanceDep = byField.get(bundleDep.name) ?? null;
|
|
188
|
+
const source = instanceDep?.source ?? null;
|
|
189
|
+
const sourceType = source?.__typename;
|
|
190
|
+
const state = sourceType === "RemoteReference" ? DEPENDENCY_STATE.REMOTE_REFERENCE : sourceType === "Connection" ? DEPENDENCY_STATE.CONNECTION : sourceType === "EnvironmentDefault" ? DEPENDENCY_STATE.ENV_DEFAULT : DEPENDENCY_STATE.UNFULFILLED;
|
|
191
|
+
return {
|
|
192
|
+
field: bundleDep.name,
|
|
193
|
+
required: instanceDep ? Boolean(instanceDep.required) : Boolean(bundleDep.required),
|
|
194
|
+
resourceType: instanceDep?.resourceType ?? bundleDep.resourceType,
|
|
195
|
+
state,
|
|
196
|
+
source
|
|
197
|
+
};
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
const groupDependenciesBySection = (rows) => ({
|
|
201
|
+
fulfilled: rows.filter((row) => FULFILLED_STATES.has(row.state)),
|
|
202
|
+
unfulfilled: rows.filter((row) => !FULFILLED_STATES.has(row.state))
|
|
203
|
+
});
|
|
204
|
+
const formatElapsed = (seconds) => {
|
|
205
|
+
if (!seconds || seconds <= 0) return null;
|
|
206
|
+
const minutes = Math.floor(seconds / 60);
|
|
207
|
+
return `${minutes}m ${seconds % 60}s`;
|
|
208
|
+
};
|
|
209
|
+
const truncateDeploymentId = (id) => {
|
|
210
|
+
if (!id) return "";
|
|
211
|
+
const parts = id.split("-");
|
|
212
|
+
return parts.length > 1 ? parts[parts.length - 1] : id;
|
|
213
|
+
};
|
|
214
|
+
const PLAN_SOURCE_REGEX = /^Planning deployment ([0-9a-fA-F-]{36})(?:\n([\s\S]*))?$/;
|
|
215
|
+
const ROLLBACK_SOURCE_REGEX = /^Rollback to deployment ([0-9a-fA-F-]{36}) \(v([^)]*)\)(?:\n([\s\S]*))?$/;
|
|
216
|
+
const parsePlanMessage = (message) => {
|
|
217
|
+
if (!message) return null;
|
|
218
|
+
const match = PLAN_SOURCE_REGEX.exec(message);
|
|
219
|
+
return match ? { sourceId: match[1], sourceMessage: match[2] ?? "" } : null;
|
|
220
|
+
};
|
|
221
|
+
const parseRollbackMessage = (message) => {
|
|
222
|
+
if (!message) return null;
|
|
223
|
+
const match = ROLLBACK_SOURCE_REGEX.exec(message);
|
|
224
|
+
return match ? { sourceId: match[1], version: match[2], sourceMessage: match[3] ?? "" } : null;
|
|
225
|
+
};
|
|
226
|
+
const stripMessageContext = (message) => {
|
|
227
|
+
const current = message ?? "";
|
|
228
|
+
if (!current) return current;
|
|
229
|
+
const plan = parsePlanMessage(current);
|
|
230
|
+
if (plan) return stripMessageContext(plan.sourceMessage);
|
|
231
|
+
const rollback = parseRollbackMessage(current);
|
|
232
|
+
if (rollback) return stripMessageContext(rollback.sourceMessage);
|
|
233
|
+
return current;
|
|
234
|
+
};
|
|
235
|
+
const formatDeploymentStatus = (action, status) => formatInstanceStatus(composeInstanceStatus(action, status));
|
|
236
|
+
const STATUSES_WITHOUT_LOGS = ["PROPOSED", "APPROVED", "REJECTED"];
|
|
237
|
+
const deploymentHasLogs = (status) => Boolean(status) && !STATUSES_WITHOUT_LOGS.includes(status);
|
|
238
|
+
const composeLogsText = (logs) => {
|
|
239
|
+
if (!Array.isArray(logs) || logs.length === 0) return "";
|
|
240
|
+
const joined = logs.map((line) => line?.message ?? "").join("");
|
|
241
|
+
return `
|
|
242
|
+
${joined}${joined.endsWith("\n") ? "" : "\n"}`;
|
|
243
|
+
};
|
|
244
|
+
const RELATIVE_UNITS = [
|
|
245
|
+
{ unit: "year", seconds: 31536e3 },
|
|
246
|
+
{ unit: "month", seconds: 2592e3 },
|
|
247
|
+
{ unit: "week", seconds: 604800 },
|
|
248
|
+
{ unit: "day", seconds: 86400 },
|
|
249
|
+
{ unit: "hour", seconds: 3600 },
|
|
250
|
+
{ unit: "minute", seconds: 60 },
|
|
251
|
+
{ unit: "second", seconds: 1 }
|
|
252
|
+
];
|
|
253
|
+
const RELATIVE_FORMATTER = new Intl.RelativeTimeFormat("en", {
|
|
254
|
+
numeric: "auto"
|
|
255
|
+
});
|
|
256
|
+
const formatRelativeTime = (isoString, fallback = "\u2014") => {
|
|
257
|
+
if (!isoString) return fallback;
|
|
258
|
+
const date = new Date(isoString);
|
|
259
|
+
if (Number.isNaN(date.getTime())) return fallback;
|
|
260
|
+
const diff = (date.getTime() - Date.now()) / 1e3;
|
|
261
|
+
const absDiff = Math.abs(diff);
|
|
262
|
+
for (const { unit, seconds } of RELATIVE_UNITS) {
|
|
263
|
+
if (absDiff >= seconds || unit === "second") {
|
|
264
|
+
return RELATIVE_FORMATTER.format(Math.round(diff / seconds), unit);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
return fallback;
|
|
268
|
+
};
|
|
269
|
+
const ABSOLUTE_FORMATTER = new Intl.DateTimeFormat("en", {
|
|
270
|
+
month: "short",
|
|
271
|
+
day: "numeric",
|
|
272
|
+
hour: "numeric",
|
|
273
|
+
minute: "2-digit"
|
|
274
|
+
});
|
|
275
|
+
const formatAbsoluteDateTime = (isoString, fallback = "") => {
|
|
276
|
+
if (!isoString) return fallback;
|
|
277
|
+
const date = new Date(isoString);
|
|
278
|
+
return Number.isNaN(date.getTime()) ? fallback : ABSOLUTE_FORMATTER.format(date);
|
|
279
|
+
};
|
|
280
|
+
|
|
281
|
+
export { ALARMS_DOCS_URL, DEPENDENCY_STATE, RESOURCE_STATE, STATUSES_WITHOUT_LOGS, bucketAlarms, buildDependencyRows, buildResourceRows, composeLogsText, deploymentHasLogs, describeThreshold, filterAndPaginateProperties, formatAbsoluteDateTime, formatAlarmDimensions, formatAttributeValue, formatDeploymentStatus, formatElapsed, formatGrantConditions, formatMetricLine, formatPayload, formatPropertyValue, formatRelativeTime, getFiringAlerts, getReleaseChannel, getSeverity, getStatusLabel, groupDependenciesBySection, isFiring, parseMap, parsePlanMessage, parseRollbackMessage, stripMessageContext, truncateDeploymentId };
|
|
282
|
+
//# sourceMappingURL=helpers.esm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.esm.js","sources":["../../../../src/features/environment/InstanceDrawer/helpers.ts"],"sourcesContent":["// Pure helpers ported from the web app's InstancePanel. Kept read-only and\n// dependency-free so the drawer can render every tab without app internals.\nimport {\n composeInstanceStatus,\n formatInstanceStatus,\n} from '../../../utils/instanceStatuses';\nimport type {\n Alarm,\n BundleResourceEntry,\n InstanceProperty,\n InstanceResourceEntry,\n ResourceType,\n} from './types';\n\n// --- Attributes --------------------------------------------------------------\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\n// --- Overview: version + properties ------------------------------------------\n\nexport const getReleaseChannel = (\n version?: string | null,\n resolvedVersion?: string | null,\n): { channel: string } | null =>\n !version || version === resolvedVersion ? null : { channel: version };\n\nexport const getFiringAlerts = (items?: (Alarm | null)[] | null): Alarm[] =>\n (items ?? []).filter(\n (alarm): alarm is Alarm => alarm?.currentState?.status === 'ALARM',\n );\n\nexport const formatPropertyValue = (value: unknown): string => {\n if (value === null || value === undefined) return '—';\n if (typeof value === 'object') return JSON.stringify(value, null, 2);\n return String(value);\n};\n\nconst PROPERTY_PAGE_SIZE = 5;\n\nexport interface PropertiesView {\n items: InstanceProperty[];\n totalPages: number;\n page: number;\n}\n\nexport const filterAndPaginateProperties = (\n properties: InstanceProperty[] = [],\n { search = '', page = 1 }: { search?: string; page?: number } = {},\n): PropertiesView => {\n const normalized = search.trim().toLowerCase();\n const filtered = normalized\n ? properties.filter(property => {\n const name = property?.name?.toLowerCase() ?? '';\n const path = property?.path?.toLowerCase() ?? '';\n const value = String(property?.value ?? '').toLowerCase();\n return (\n name.includes(normalized) ||\n path.includes(normalized) ||\n value.includes(normalized)\n );\n })\n : properties;\n\n const totalPages = Math.max(\n 1,\n Math.ceil(filtered.length / PROPERTY_PAGE_SIZE),\n );\n const safePage = Math.min(Math.max(page, 1), totalPages);\n const start = (safePage - 1) * PROPERTY_PAGE_SIZE;\n return {\n items: filtered.slice(start, start + PROPERTY_PAGE_SIZE),\n totalPages,\n page: safePage,\n };\n};\n\n// --- Alarms ------------------------------------------------------------------\n\nexport const ALARMS_DOCS_URL =\n 'https://docs.massdriver.cloud/platform-operations/monitoring-and-alarms';\n\nconst OPERATOR_PHRASES: Record<string, string> = {\n GREATER_THAN: 'above',\n GREATER_THAN_OR_EQUAL_TO: 'at or above',\n LESS_THAN: 'below',\n LESS_THAN_OR_EQUAL_TO: 'at or below',\n};\n\nconst describeOperator = (operator?: string | null): string =>\n (operator && OPERATOR_PHRASES[operator]) ?? operator ?? '';\n\nconst formatPeriod = (period?: number | null): string => {\n if (!period) return '';\n if (period >= 60 && period % 60 === 0) {\n const minutes = period / 60;\n return `${minutes} minute${minutes === 1 ? '' : 's'}`;\n }\n return `${period} seconds`;\n};\n\nexport const describeThreshold = (alarm: Alarm): string | null => {\n const hasComparison =\n alarm.comparisonOperator &&\n alarm.threshold !== null &&\n alarm.threshold !== undefined;\n if (!hasComparison && !alarm.period) return null;\n const parts: string[] = [];\n if (hasComparison) {\n parts.push(\n `${describeOperator(alarm.comparisonOperator)} ${alarm.threshold}`,\n );\n }\n if (alarm.period) parts.push(`for ${formatPeriod(alarm.period)}`);\n return parts.join(' ');\n};\n\nexport const isFiring = (alarm?: Alarm | null): boolean =>\n alarm?.currentState?.status === 'ALARM';\n\nconst STATUS_LABEL: Record<string, string> = { ALARM: 'Firing', OK: 'OK' };\n\nexport const getStatusLabel = (\n currentState?: Alarm['currentState'],\n): string => {\n if (!currentState) return 'No data';\n return (\n (currentState.status && STATUS_LABEL[currentState.status]) ??\n currentState.status ??\n 'No data'\n );\n};\n\nexport const getSeverity = (alarm: Alarm): 'firing' | 'ok' | 'unknown' =>\n isFiring(alarm) ? 'firing' : alarm.currentState ? 'ok' : 'unknown';\n\nexport const formatMetricLine = (metric?: Alarm['metric']): string | null => {\n if (!metric) return null;\n const path = [metric.namespace, metric.name].filter(Boolean).join(' / ');\n if (!path && !metric.statistic) return null;\n if (!path) return metric.statistic ?? null;\n if (!metric.statistic) return path;\n return `${path} (${metric.statistic})`;\n};\n\nexport const formatAlarmDimensions = (\n dimensions?:\n | ({ name?: string | null; value?: string | null } | null)[]\n | null,\n): string =>\n (dimensions ?? [])\n .filter(Boolean)\n .map(dimension => `${dimension!.name}=${dimension!.value}`)\n .join(', ');\n\nexport interface AlarmBuckets {\n firing: Alarm[];\n configured: Alarm[];\n total: number;\n}\n\nexport const bucketAlarms = (items?: (Alarm | null)[] | null): AlarmBuckets => {\n const sorted = [...(items ?? [])]\n .filter((alarm): alarm is Alarm => Boolean(alarm))\n .sort((left, right) =>\n (left.displayName ?? '').localeCompare(right.displayName ?? ''),\n );\n return {\n firing: sorted.filter(isFiring),\n configured: sorted.filter(alarm => !isFiring(alarm)),\n total: sorted.length,\n };\n};\n\n// --- Resources ---------------------------------------------------------------\n\nexport const RESOURCE_STATE = {\n CREATED: 'CREATED',\n UNCREATED: 'UNCREATED',\n} as const;\n\nexport interface ResourceRow {\n field: string;\n required: boolean;\n resource: InstanceResourceEntry['resource'] | null;\n resourceType?: ResourceType | null;\n state: 'CREATED' | 'UNCREATED';\n}\n\nexport const buildResourceRows = (\n bundleResources?: (BundleResourceEntry | null)[] | null,\n instanceResources?: (InstanceResourceEntry | null)[] | null,\n): ResourceRow[] => {\n const producedByField = new Map(\n (instanceResources ?? [])\n .filter((produced): produced is InstanceResourceEntry =>\n Boolean(produced?.field),\n )\n .map(produced => [produced.field, produced] as const),\n );\n\n const fromBundle: ResourceRow[] = (bundleResources ?? [])\n .filter((bundleResource): bundleResource is BundleResourceEntry =>\n Boolean(bundleResource?.name),\n )\n .map(bundleResource => {\n const produced = producedByField.get(bundleResource.name) ?? null;\n return {\n field: bundleResource.name,\n required: produced\n ? Boolean(produced.required)\n : Boolean(bundleResource.required),\n resource: produced?.resource ?? null,\n resourceType: produced?.resourceType ?? bundleResource.resourceType,\n state: produced ? RESOURCE_STATE.CREATED : RESOURCE_STATE.UNCREATED,\n };\n });\n\n const bundleFields = new Set(fromBundle.map(row => row.field));\n const orphanProduced: ResourceRow[] = (instanceResources ?? [])\n .filter(\n (produced): produced is InstanceResourceEntry =>\n Boolean(produced?.field) && !bundleFields.has(produced!.field),\n )\n .map(produced => ({\n field: produced.field,\n required: Boolean(produced.required),\n resource: produced.resource ?? null,\n resourceType: produced.resourceType,\n state: RESOURCE_STATE.CREATED,\n }));\n\n return [...fromBundle, ...orphanProduced].sort((rowA, rowB) =>\n rowA.field.localeCompare(rowB.field),\n );\n};\n\nexport const formatGrantConditions = (recipientConditions: unknown): string => {\n if (recipientConditions === '*' || recipientConditions === null) {\n return 'every recipient in the organization';\n }\n if (typeof recipientConditions === 'string') {\n try {\n return formatGrantConditions(JSON.parse(recipientConditions));\n } catch {\n return recipientConditions;\n }\n }\n if (typeof recipientConditions === 'object') {\n const entries = Object.entries(\n recipientConditions as Record<string, unknown>,\n );\n if (entries.length === 0) return 'no conditions';\n return entries\n .map(\n ([key, value]) =>\n `${key}: ${Array.isArray(value) ? value.join(', ') : String(value)}`,\n )\n .join(' · ');\n }\n return String(recipientConditions);\n};\n\nexport const formatPayload = (payload: unknown): string => {\n if (payload == null) return '';\n try {\n return JSON.stringify(payload, null, 2);\n } catch {\n return String(payload);\n }\n};\n\n// --- Dependencies ------------------------------------------------------------\n\nexport const DEPENDENCY_STATE = {\n REMOTE_REFERENCE: 'REMOTE_REFERENCE',\n CONNECTION: 'CONNECTION',\n ENV_DEFAULT: 'ENV_DEFAULT',\n UNFULFILLED: 'UNFULFILLED',\n} as const;\n\ntype DependencyState = (typeof DEPENDENCY_STATE)[keyof typeof DEPENDENCY_STATE];\n\nconst FULFILLED_STATES = new Set<DependencyState>([\n DEPENDENCY_STATE.REMOTE_REFERENCE,\n DEPENDENCY_STATE.CONNECTION,\n DEPENDENCY_STATE.ENV_DEFAULT,\n]);\n\n// Shapes matching DEPENDENCIES_QUERY's selections. Typed (rather than `any`)\n// so a schema field rename is a compile error here instead of a silent `—`.\nexport interface BundleDependency {\n name: string;\n required?: boolean | null;\n resourceType?: ResourceType | null;\n}\n\nexport interface DependencySource {\n __typename?: string;\n id?: string;\n // Connection members\n fromField?: string | null;\n fromInstance?: {\n id: string;\n name?: string | null;\n status?: string | null;\n environment?: { id: string } | null;\n } | null;\n link?: {\n id: string;\n fromComponent?: { id: string; name?: string | null } | null;\n } | null;\n // RemoteReference / EnvironmentDefault members\n resource?: {\n id: string;\n name?: string | null;\n resourceType?: ResourceType | null;\n } | null;\n}\n\nexport interface InstanceDependency {\n field: string;\n required?: boolean | null;\n resource?: { id: string; name?: string | null } | null;\n resourceType?: ResourceType | null;\n source?: DependencySource | null;\n}\n\nexport interface DependencyRow {\n field: string;\n required: boolean;\n resourceType?: ResourceType | null;\n state: DependencyState;\n source: DependencySource | null;\n}\n\n// The web app overlays a second `inbound links` query to distinguish\n// pending/link-and-default states; that overlay is dropped here (read-only,\n// single fetch), so state is derived purely from the dependency source type.\nexport const buildDependencyRows = (\n bundleDependencies?: (BundleDependency | null)[] | null,\n instanceDependencies?: (InstanceDependency | null)[] | null,\n): DependencyRow[] => {\n const byField = new Map(\n (instanceDependencies ?? [])\n .filter((dep): dep is InstanceDependency => Boolean(dep?.field))\n .map(dep => [dep.field, dep] as const),\n );\n\n return (bundleDependencies ?? [])\n .filter(\n (dep): dep is BundleDependency =>\n Boolean(dep) &&\n dep?.resourceType?.connectionOrientation !== 'ENVIRONMENT_DEFAULT',\n )\n .map(bundleDep => {\n const instanceDep = byField.get(bundleDep.name) ?? null;\n const source = instanceDep?.source ?? null;\n const sourceType = source?.__typename;\n const state: DependencyState =\n sourceType === 'RemoteReference'\n ? DEPENDENCY_STATE.REMOTE_REFERENCE\n : sourceType === 'Connection'\n ? DEPENDENCY_STATE.CONNECTION\n : sourceType === 'EnvironmentDefault'\n ? DEPENDENCY_STATE.ENV_DEFAULT\n : DEPENDENCY_STATE.UNFULFILLED;\n\n return {\n field: bundleDep.name,\n required: instanceDep\n ? Boolean(instanceDep.required)\n : Boolean(bundleDep.required),\n resourceType: instanceDep?.resourceType ?? bundleDep.resourceType,\n state,\n source,\n };\n });\n};\n\nexport const groupDependenciesBySection = (rows: DependencyRow[]) => ({\n fulfilled: rows.filter(row => FULFILLED_STATES.has(row.state)),\n unfulfilled: rows.filter(row => !FULFILLED_STATES.has(row.state)),\n});\n\n// --- History / deployment status ---------------------------------------------\n\nexport const formatElapsed = (seconds?: number | null): string | null => {\n if (!seconds || seconds <= 0) return null;\n const minutes = Math.floor(seconds / 60);\n return `${minutes}m ${seconds % 60}s`;\n};\n\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]*))?$/;\nconst ROLLBACK_SOURCE_REGEX =\n /^Rollback to deployment ([0-9a-fA-F-]{36}) \\(v([^)]*)\\)(?:\\n([\\s\\S]*))?$/;\n\n// Plan proposals encode their source deployment in the message (\"Planning\n// deployment <uuid>\\n<source-message>\"). Keep `sourceId` so the History tab can\n// link the plan back to the deployment it previews (mirrors the web app's\n// historyHelpers.js).\nexport const parsePlanMessage = (message?: string | null) => {\n if (!message) return null;\n const match = PLAN_SOURCE_REGEX.exec(message);\n return match ? { sourceId: match[1], sourceMessage: match[2] ?? '' } : null;\n};\n\n// Rollback proposals encode their source deployment + version in the message\n// (\"Rollback to deployment <uuid> (v<version>)\\n<source-message>\"). Keep\n// `sourceId`/`version` so the row can link back to the restored deployment.\nexport const parseRollbackMessage = (message?: 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\nexport const isRollback = (message?: string | null): boolean =>\n parseRollbackMessage(message) !== null;\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// Compound label for a single deployment row (action + deployment status).\n// The taxonomy lives in ../instanceStatuses — this is the text-only shorthand\n// for callers that hold the two primitives instead of a compound string.\nexport const formatDeploymentStatus = (\n action?: string | null,\n status?: string | null,\n): string => formatInstanceStatus(composeInstanceStatus(action, status));\n\n// Re-exported for the logs panel / history rows, which decide off deployment\n// liveness whether to keep the log subscription open.\nexport { isDeploymentActive } from '../../../utils/instanceStatuses';\n\n// Statuses that never produce a deployment log stream. Everything else has (or\n// will have) logs to view in-app.\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// 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// we concatenate without inserting extra separators and guarantee a trailing \\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\n// --- Relative / absolute time (local, avoids app util) -----------------------\n\nconst RELATIVE_UNITS: Array<{\n unit: Intl.RelativeTimeFormatUnit;\n seconds: number;\n}> = [\n { unit: 'year', seconds: 31536000 },\n { unit: 'month', seconds: 2592000 },\n { unit: 'week', seconds: 604800 },\n { unit: 'day', seconds: 86400 },\n { unit: 'hour', seconds: 3600 },\n { unit: 'minute', seconds: 60 },\n { unit: 'second', seconds: 1 },\n];\n\nconst RELATIVE_FORMATTER = new Intl.RelativeTimeFormat('en', {\n numeric: 'auto',\n});\n\nexport const formatRelativeTime = (\n isoString?: string | null,\n fallback = '—',\n): string => {\n if (!isoString) return fallback;\n const date = new Date(isoString);\n if (Number.isNaN(date.getTime())) return fallback;\n const diff = (date.getTime() - Date.now()) / 1000;\n const absDiff = Math.abs(diff);\n for (const { unit, seconds } of RELATIVE_UNITS) {\n if (absDiff >= seconds || unit === 'second') {\n return RELATIVE_FORMATTER.format(Math.round(diff / seconds), unit);\n }\n }\n return fallback;\n};\n\nconst ABSOLUTE_FORMATTER = new Intl.DateTimeFormat('en', {\n month: 'short',\n day: 'numeric',\n hour: 'numeric',\n minute: '2-digit',\n});\n\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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"}
|