@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.
Files changed (346) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +196 -0
  3. package/dist/MassdriverRouter.esm.js +78 -0
  4. package/dist/MassdriverRouter.esm.js.map +1 -0
  5. package/dist/api.esm.js +119 -0
  6. package/dist/api.esm.js.map +1 -0
  7. package/dist/assets/massdriver-logo-dark.svg +55 -0
  8. package/dist/assets/massdriver-logo-light.svg +50 -0
  9. package/dist/components/AttributesColumn.esm.js +95 -0
  10. package/dist/components/AttributesColumn.esm.js.map +1 -0
  11. package/dist/components/AttributesSummaryCell.esm.js +103 -0
  12. package/dist/components/AttributesSummaryCell.esm.js.map +1 -0
  13. package/dist/components/AuthedIcon.esm.js +26 -0
  14. package/dist/components/AuthedIcon.esm.js.map +1 -0
  15. package/dist/components/ConditionsCell.esm.js +48 -0
  16. package/dist/components/ConditionsCell.esm.js.map +1 -0
  17. package/dist/components/DisabledAction.esm.js +30 -0
  18. package/dist/components/DisabledAction.esm.js.map +1 -0
  19. package/dist/components/EntityMassdriverContent/EntityMassdriverContent.esm.js +80 -0
  20. package/dist/components/EntityMassdriverContent/EntityMassdriverContent.esm.js.map +1 -0
  21. package/dist/components/EntityMassdriverContent/index.esm.js +6 -0
  22. package/dist/components/EntityMassdriverContent/index.esm.js.map +1 -0
  23. package/dist/components/EntityMassdriverOverviewCard/EntityMassdriverOverviewCard.esm.js +75 -0
  24. package/dist/components/EntityMassdriverOverviewCard/EntityMassdriverOverviewCard.esm.js.map +1 -0
  25. package/dist/components/EntityMassdriverOverviewCard/index.esm.js +6 -0
  26. package/dist/components/EntityMassdriverOverviewCard/index.esm.js.map +1 -0
  27. package/dist/components/ForkPill.esm.js +84 -0
  28. package/dist/components/ForkPill.esm.js.map +1 -0
  29. package/dist/components/InstanceStatusIndicator.esm.js +21 -0
  30. package/dist/components/InstanceStatusIndicator.esm.js.map +1 -0
  31. package/dist/components/InstanceStatusPill.esm.js +67 -0
  32. package/dist/components/InstanceStatusPill.esm.js.map +1 -0
  33. package/dist/components/MassdriverIcon.esm.js +13 -0
  34. package/dist/components/MassdriverIcon.esm.js.map +1 -0
  35. package/dist/components/MassdriverSidebarItem.esm.js +45 -0
  36. package/dist/components/MassdriverSidebarItem.esm.js.map +1 -0
  37. package/dist/components/NotFound.esm.js +44 -0
  38. package/dist/components/NotFound.esm.js.map +1 -0
  39. package/dist/components/OpenInMassdriverButton.esm.js +24 -0
  40. package/dist/components/OpenInMassdriverButton.esm.js.map +1 -0
  41. package/dist/components/PageLayout.esm.js +88 -0
  42. package/dist/components/PageLayout.esm.js.map +1 -0
  43. package/dist/components/RouterLinkAdapter.esm.js +12 -0
  44. package/dist/components/RouterLinkAdapter.esm.js.map +1 -0
  45. package/dist/components/VersionBadge.esm.js +57 -0
  46. package/dist/components/VersionBadge.esm.js.map +1 -0
  47. package/dist/components/grantColumns.esm.js +56 -0
  48. package/dist/components/grantColumns.esm.js.map +1 -0
  49. package/dist/components/icons/BundleIcon.esm.js +7 -0
  50. package/dist/components/icons/BundleIcon.esm.js.map +1 -0
  51. package/dist/components/icons/FolderOutlinedIcon.esm.js +7 -0
  52. package/dist/components/icons/FolderOutlinedIcon.esm.js.map +1 -0
  53. package/dist/components/icons/TokenIcon.esm.js +7 -0
  54. package/dist/components/icons/TokenIcon.esm.js.map +1 -0
  55. package/dist/entity.esm.js +23 -0
  56. package/dist/entity.esm.js.map +1 -0
  57. package/dist/features/environment/CompareDeploymentsDialog/CompareDeploymentsDialog.esm.js +115 -0
  58. package/dist/features/environment/CompareDeploymentsDialog/CompareDeploymentsDialog.esm.js.map +1 -0
  59. package/dist/features/environment/CompareDeploymentsDialog/ResultsStep.esm.js +165 -0
  60. package/dist/features/environment/CompareDeploymentsDialog/ResultsStep.esm.js.map +1 -0
  61. package/dist/features/environment/CompareDeploymentsDialog/SelectStep.esm.js +216 -0
  62. package/dist/features/environment/CompareDeploymentsDialog/SelectStep.esm.js.map +1 -0
  63. package/dist/features/environment/CompareDeploymentsDialog/compareColumns.esm.js +86 -0
  64. package/dist/features/environment/CompareDeploymentsDialog/compareColumns.esm.js.map +1 -0
  65. package/dist/features/environment/CompareDeploymentsDialog/flattenDeploymentComparison.esm.js +57 -0
  66. package/dist/features/environment/CompareDeploymentsDialog/flattenDeploymentComparison.esm.js.map +1 -0
  67. package/dist/features/environment/CompareDeploymentsDialog/queries.esm.js +53 -0
  68. package/dist/features/environment/CompareDeploymentsDialog/queries.esm.js.map +1 -0
  69. package/dist/features/environment/CompareEnvironmentsDialog/CompareEnvironmentsDialog.esm.js +94 -0
  70. package/dist/features/environment/CompareEnvironmentsDialog/CompareEnvironmentsDialog.esm.js.map +1 -0
  71. package/dist/features/environment/CompareEnvironmentsDialog/ComparisonValueCell.esm.js +67 -0
  72. package/dist/features/environment/CompareEnvironmentsDialog/ComparisonValueCell.esm.js.map +1 -0
  73. package/dist/features/environment/CompareEnvironmentsDialog/ResultsStep.esm.js +202 -0
  74. package/dist/features/environment/CompareEnvironmentsDialog/ResultsStep.esm.js.map +1 -0
  75. package/dist/features/environment/CompareEnvironmentsDialog/SelectStep.esm.js +183 -0
  76. package/dist/features/environment/CompareEnvironmentsDialog/SelectStep.esm.js.map +1 -0
  77. package/dist/features/environment/CompareEnvironmentsDialog/compareColumns.esm.js +73 -0
  78. package/dist/features/environment/CompareEnvironmentsDialog/compareColumns.esm.js.map +1 -0
  79. package/dist/features/environment/CompareEnvironmentsDialog/flattenComparison.esm.js +70 -0
  80. package/dist/features/environment/CompareEnvironmentsDialog/flattenComparison.esm.js.map +1 -0
  81. package/dist/features/environment/CompareEnvironmentsDialog/queries.esm.js +32 -0
  82. package/dist/features/environment/CompareEnvironmentsDialog/queries.esm.js.map +1 -0
  83. package/dist/features/environment/EnvironmentGraphPage.esm.js +131 -0
  84. package/dist/features/environment/EnvironmentGraphPage.esm.js.map +1 -0
  85. package/dist/features/environment/GraphHeader/EnvironmentDefaults.esm.js +252 -0
  86. package/dist/features/environment/GraphHeader/EnvironmentDefaults.esm.js.map +1 -0
  87. package/dist/features/environment/GraphHeader/GraphHeader.esm.js +247 -0
  88. package/dist/features/environment/GraphHeader/GraphHeader.esm.js.map +1 -0
  89. package/dist/features/environment/GraphHeader/HeaderActions.esm.js +127 -0
  90. package/dist/features/environment/GraphHeader/HeaderActions.esm.js.map +1 -0
  91. package/dist/features/environment/GraphHeader/Switcher.esm.js +75 -0
  92. package/dist/features/environment/GraphHeader/Switcher.esm.js.map +1 -0
  93. package/dist/features/environment/GraphHeader/queries.esm.js +60 -0
  94. package/dist/features/environment/GraphHeader/queries.esm.js.map +1 -0
  95. package/dist/features/environment/InstanceDrawer/AlarmCard.esm.js +151 -0
  96. package/dist/features/environment/InstanceDrawer/AlarmCard.esm.js.map +1 -0
  97. package/dist/features/environment/InstanceDrawer/InstanceDrawer.esm.js +165 -0
  98. package/dist/features/environment/InstanceDrawer/InstanceDrawer.esm.js.map +1 -0
  99. package/dist/features/environment/InstanceDrawer/InstanceDrawerHeader.esm.js +241 -0
  100. package/dist/features/environment/InstanceDrawer/InstanceDrawerHeader.esm.js.map +1 -0
  101. package/dist/features/environment/InstanceDrawer/InstanceTabs.esm.js +119 -0
  102. package/dist/features/environment/InstanceDrawer/InstanceTabs.esm.js.map +1 -0
  103. package/dist/features/environment/InstanceDrawer/TabState.esm.js +30 -0
  104. package/dist/features/environment/InstanceDrawer/TabState.esm.js.map +1 -0
  105. package/dist/features/environment/InstanceDrawer/formsDataSource.esm.js +25 -0
  106. package/dist/features/environment/InstanceDrawer/formsDataSource.esm.js.map +1 -0
  107. package/dist/features/environment/InstanceDrawer/helpers.esm.js +282 -0
  108. package/dist/features/environment/InstanceDrawer/helpers.esm.js.map +1 -0
  109. package/dist/features/environment/InstanceDrawer/queries.esm.js +281 -0
  110. package/dist/features/environment/InstanceDrawer/queries.esm.js.map +1 -0
  111. package/dist/features/environment/InstanceDrawer/tabs/ConfigTab.esm.js +170 -0
  112. package/dist/features/environment/InstanceDrawer/tabs/ConfigTab.esm.js.map +1 -0
  113. package/dist/features/environment/InstanceDrawer/tabs/DependenciesTab.esm.js +413 -0
  114. package/dist/features/environment/InstanceDrawer/tabs/DependenciesTab.esm.js.map +1 -0
  115. package/dist/features/environment/InstanceDrawer/tabs/DeploymentLogsPanel.esm.js +191 -0
  116. package/dist/features/environment/InstanceDrawer/tabs/DeploymentLogsPanel.esm.js.map +1 -0
  117. package/dist/features/environment/InstanceDrawer/tabs/DeploymentReadOnlyActions.esm.js +63 -0
  118. package/dist/features/environment/InstanceDrawer/tabs/DeploymentReadOnlyActions.esm.js.map +1 -0
  119. package/dist/features/environment/InstanceDrawer/tabs/GuideTab.esm.js +48 -0
  120. package/dist/features/environment/InstanceDrawer/tabs/GuideTab.esm.js.map +1 -0
  121. package/dist/features/environment/InstanceDrawer/tabs/HistoryTab.esm.js +446 -0
  122. package/dist/features/environment/InstanceDrawer/tabs/HistoryTab.esm.js.map +1 -0
  123. package/dist/features/environment/InstanceDrawer/tabs/MonitorTab.esm.js +146 -0
  124. package/dist/features/environment/InstanceDrawer/tabs/MonitorTab.esm.js.map +1 -0
  125. package/dist/features/environment/InstanceDrawer/tabs/OverviewTab.esm.js +572 -0
  126. package/dist/features/environment/InstanceDrawer/tabs/OverviewTab.esm.js.map +1 -0
  127. package/dist/features/environment/InstanceDrawer/tabs/ResourcesTab.esm.js +471 -0
  128. package/dist/features/environment/InstanceDrawer/tabs/ResourcesTab.esm.js.map +1 -0
  129. package/dist/features/environment/InstanceDrawer/tabs/SecretsTab.esm.js +109 -0
  130. package/dist/features/environment/InstanceDrawer/tabs/SecretsTab.esm.js.map +1 -0
  131. package/dist/features/environment/InstanceDrawer/tabs/ViewDeploymentDetails.esm.js +384 -0
  132. package/dist/features/environment/InstanceDrawer/tabs/ViewDeploymentDetails.esm.js.map +1 -0
  133. package/dist/features/environment/InstanceDrawer/tabs/flattenParams.esm.js +23 -0
  134. package/dist/features/environment/InstanceDrawer/tabs/flattenParams.esm.js.map +1 -0
  135. package/dist/features/environment/InstanceDrawer/useInstanceApiQuery.esm.js +6 -0
  136. package/dist/features/environment/InstanceDrawer/useInstanceApiQuery.esm.js.map +1 -0
  137. package/dist/features/environment/InstanceDrawer/useOverflowMeasure.esm.js +55 -0
  138. package/dist/features/environment/InstanceDrawer/useOverflowMeasure.esm.js.map +1 -0
  139. package/dist/features/environment/InstanceDrawer/useResizableWidth.esm.js +44 -0
  140. package/dist/features/environment/InstanceDrawer/useResizableWidth.esm.js.map +1 -0
  141. package/dist/features/environment/components/InstanceStatusPill.esm.js +54 -0
  142. package/dist/features/environment/components/InstanceStatusPill.esm.js.map +1 -0
  143. package/dist/features/environment/graph/Diagram.esm.js +143 -0
  144. package/dist/features/environment/graph/Diagram.esm.js.map +1 -0
  145. package/dist/features/environment/graph/DiagramNode.constants.esm.js +5 -0
  146. package/dist/features/environment/graph/DiagramNode.constants.esm.js.map +1 -0
  147. package/dist/features/environment/graph/DiagramNode.esm.js +221 -0
  148. package/dist/features/environment/graph/DiagramNode.esm.js.map +1 -0
  149. package/dist/features/environment/graph/NodeMeta.esm.js +182 -0
  150. package/dist/features/environment/graph/NodeMeta.esm.js.map +1 -0
  151. package/dist/features/environment/graph/NodeVersionBadges.esm.js +150 -0
  152. package/dist/features/environment/graph/NodeVersionBadges.esm.js.map +1 -0
  153. package/dist/features/environment/graph/diagramFactory.esm.js +151 -0
  154. package/dist/features/environment/graph/diagramFactory.esm.js.map +1 -0
  155. package/dist/features/environment/graph/handles/ExpandableHandleWrapper.esm.js +174 -0
  156. package/dist/features/environment/graph/handles/ExpandableHandleWrapper.esm.js.map +1 -0
  157. package/dist/features/environment/graph/handles/NodeHandle.esm.js +45 -0
  158. package/dist/features/environment/graph/handles/NodeHandle.esm.js.map +1 -0
  159. package/dist/features/environment/graph/handles/NodeHandleTooltip.esm.js +134 -0
  160. package/dist/features/environment/graph/handles/NodeHandleTooltip.esm.js.map +1 -0
  161. package/dist/features/environment/graph/handles/handleTypes.esm.js +170 -0
  162. package/dist/features/environment/graph/handles/handleTypes.esm.js.map +1 -0
  163. package/dist/features/environment/graph/handles/useAnimationFrameSync.esm.js +19 -0
  164. package/dist/features/environment/graph/handles/useAnimationFrameSync.esm.js.map +1 -0
  165. package/dist/features/environment/graph/handles/useRadialPositions.esm.js +37 -0
  166. package/dist/features/environment/graph/handles/useRadialPositions.esm.js.map +1 -0
  167. package/dist/features/environment/graph/handles/useTransitionLifecycle.esm.js +19 -0
  168. package/dist/features/environment/graph/handles/useTransitionLifecycle.esm.js.map +1 -0
  169. package/dist/features/environment/graph/hasUndeployedPlan.esm.js +43 -0
  170. package/dist/features/environment/graph/hasUndeployedPlan.esm.js.map +1 -0
  171. package/dist/features/environment/graph/queries.esm.js +103 -0
  172. package/dist/features/environment/graph/queries.esm.js.map +1 -0
  173. package/dist/features/environment/graph/useDiagramSnapshot.esm.js +43 -0
  174. package/dist/features/environment/graph/useDiagramSnapshot.esm.js.map +1 -0
  175. package/dist/features/environment/realtime/RealtimeProvider.esm.js +43 -0
  176. package/dist/features/environment/realtime/RealtimeProvider.esm.js.map +1 -0
  177. package/dist/features/environment/realtime/queries.esm.js +76 -0
  178. package/dist/features/environment/realtime/queries.esm.js.map +1 -0
  179. package/dist/features/environment/realtime/useLiveRelayQuery.esm.js +36 -0
  180. package/dist/features/environment/realtime/useLiveRelayQuery.esm.js.map +1 -0
  181. package/dist/features/project/ProjectDetailsPage.esm.js +101 -0
  182. package/dist/features/project/ProjectDetailsPage.esm.js.map +1 -0
  183. package/dist/features/project/tabs/ComponentsTab.esm.js +149 -0
  184. package/dist/features/project/tabs/ComponentsTab.esm.js.map +1 -0
  185. package/dist/features/project/tabs/EnvStatus.esm.js +149 -0
  186. package/dist/features/project/tabs/EnvStatus.esm.js.map +1 -0
  187. package/dist/features/project/tabs/EnvironmentsTab.esm.js +199 -0
  188. package/dist/features/project/tabs/EnvironmentsTab.esm.js.map +1 -0
  189. package/dist/features/project/tabs/OverviewTab.esm.js +420 -0
  190. package/dist/features/project/tabs/OverviewTab.esm.js.map +1 -0
  191. package/dist/features/projects/ProjectsListPage.esm.js +50 -0
  192. package/dist/features/projects/ProjectsListPage.esm.js.map +1 -0
  193. package/dist/features/projects/ProjectsListPageLazy.esm.js +12 -0
  194. package/dist/features/projects/ProjectsListPageLazy.esm.js.map +1 -0
  195. package/dist/features/projects/projectColumns.esm.js +38 -0
  196. package/dist/features/projects/projectColumns.esm.js.map +1 -0
  197. package/dist/features/projects/useProjects.esm.js +48 -0
  198. package/dist/features/projects/useProjects.esm.js.map +1 -0
  199. package/dist/features/repo/DeploymentLogsDrawer.esm.js +213 -0
  200. package/dist/features/repo/DeploymentLogsDrawer.esm.js.map +1 -0
  201. package/dist/features/repo/DeploymentLogsDrawer.loading.esm.js +43 -0
  202. package/dist/features/repo/DeploymentLogsDrawer.loading.esm.js.map +1 -0
  203. package/dist/features/repo/FileTree.esm.js +179 -0
  204. package/dist/features/repo/FileTree.esm.js.map +1 -0
  205. package/dist/features/repo/FileViewer.esm.js +115 -0
  206. package/dist/features/repo/FileViewer.esm.js.map +1 -0
  207. package/dist/features/repo/FileViewer.helpers.esm.js +54 -0
  208. package/dist/features/repo/FileViewer.helpers.esm.js.map +1 -0
  209. package/dist/features/repo/RepoDetailsPage.esm.js +127 -0
  210. package/dist/features/repo/RepoDetailsPage.esm.js.map +1 -0
  211. package/dist/features/repo/RepoEmptyState.esm.js +58 -0
  212. package/dist/features/repo/RepoEmptyState.esm.js.map +1 -0
  213. package/dist/features/repo/RepoNoVersionsState.esm.js +29 -0
  214. package/dist/features/repo/RepoNoVersionsState.esm.js.map +1 -0
  215. package/dist/features/repo/RepoTabHeader.esm.js +30 -0
  216. package/dist/features/repo/RepoTabHeader.esm.js.map +1 -0
  217. package/dist/features/repo/RepoTabLayout.esm.js +18 -0
  218. package/dist/features/repo/RepoTabLayout.esm.js.map +1 -0
  219. package/dist/features/repo/RepoVersionSelect.esm.js +176 -0
  220. package/dist/features/repo/RepoVersionSelect.esm.js.map +1 -0
  221. package/dist/features/repo/ViewDeploymentDetailsDialog.esm.js +427 -0
  222. package/dist/features/repo/ViewDeploymentDetailsDialog.esm.js.map +1 -0
  223. package/dist/features/repo/deploymentHelpers.esm.js +74 -0
  224. package/dist/features/repo/deploymentHelpers.esm.js.map +1 -0
  225. package/dist/features/repo/fileTreeHelpers.esm.js +45 -0
  226. package/dist/features/repo/fileTreeHelpers.esm.js.map +1 -0
  227. package/dist/features/repo/flattenParams.esm.js +23 -0
  228. package/dist/features/repo/flattenParams.esm.js.map +1 -0
  229. package/dist/features/repo/queries.esm.js +239 -0
  230. package/dist/features/repo/queries.esm.js.map +1 -0
  231. package/dist/features/repo/repoFilter.esm.js +9 -0
  232. package/dist/features/repo/repoFilter.esm.js.map +1 -0
  233. package/dist/features/repo/repoTabs.esm.js +22 -0
  234. package/dist/features/repo/repoTabs.esm.js.map +1 -0
  235. package/dist/features/repo/resolveVersion.esm.js +22 -0
  236. package/dist/features/repo/resolveVersion.esm.js.map +1 -0
  237. package/dist/features/repo/tabs/DeploymentRow.esm.js +201 -0
  238. package/dist/features/repo/tabs/DeploymentRow.esm.js.map +1 -0
  239. package/dist/features/repo/tabs/DeploymentsTab.esm.js +188 -0
  240. package/dist/features/repo/tabs/DeploymentsTab.esm.js.map +1 -0
  241. package/dist/features/repo/tabs/DeploymentsTab.helpers.esm.js +46 -0
  242. package/dist/features/repo/tabs/DeploymentsTab.helpers.esm.js.map +1 -0
  243. package/dist/features/repo/tabs/DeploymentsTab.loading.esm.js +37 -0
  244. package/dist/features/repo/tabs/DeploymentsTab.loading.esm.js.map +1 -0
  245. package/dist/features/repo/tabs/FilesTab.esm.js +142 -0
  246. package/dist/features/repo/tabs/FilesTab.esm.js.map +1 -0
  247. package/dist/features/repo/tabs/InstanceRow.esm.js +121 -0
  248. package/dist/features/repo/tabs/InstanceRow.esm.js.map +1 -0
  249. package/dist/features/repo/tabs/InstancesTab.esm.js +147 -0
  250. package/dist/features/repo/tabs/InstancesTab.esm.js.map +1 -0
  251. package/dist/features/repo/tabs/InstancesTab.helpers.esm.js +44 -0
  252. package/dist/features/repo/tabs/InstancesTab.helpers.esm.js.map +1 -0
  253. package/dist/features/repo/tabs/InstancesTab.loading.esm.js +33 -0
  254. package/dist/features/repo/tabs/InstancesTab.loading.esm.js.map +1 -0
  255. package/dist/features/repo/tabs/OverviewTab.esm.js +77 -0
  256. package/dist/features/repo/tabs/OverviewTab.esm.js.map +1 -0
  257. package/dist/features/repo/tabs/PermissionsTab.esm.js +56 -0
  258. package/dist/features/repo/tabs/PermissionsTab.esm.js.map +1 -0
  259. package/dist/features/repo/tabs/VersionsTab.esm.js +152 -0
  260. package/dist/features/repo/tabs/VersionsTab.esm.js.map +1 -0
  261. package/dist/features/repo/useInfiniteRelayList.esm.js +92 -0
  262. package/dist/features/repo/useInfiniteRelayList.esm.js.map +1 -0
  263. package/dist/features/repo/useInfiniteScroll.esm.js +21 -0
  264. package/dist/features/repo/useInfiniteScroll.esm.js.map +1 -0
  265. package/dist/features/repos/ReposListPage.esm.js +53 -0
  266. package/dist/features/repos/ReposListPage.esm.js.map +1 -0
  267. package/dist/features/repos/queries.esm.js +40 -0
  268. package/dist/features/repos/queries.esm.js.map +1 -0
  269. package/dist/features/repos/repoColumns.esm.js +121 -0
  270. package/dist/features/repos/repoColumns.esm.js.map +1 -0
  271. package/dist/features/repos/useRepos.esm.js +22 -0
  272. package/dist/features/repos/useRepos.esm.js.map +1 -0
  273. package/dist/features/resource/OriginChip.esm.js +42 -0
  274. package/dist/features/resource/OriginChip.esm.js.map +1 -0
  275. package/dist/features/resource/ResourceDetailsPage.esm.js +167 -0
  276. package/dist/features/resource/ResourceDetailsPage.esm.js.map +1 -0
  277. package/dist/features/resource/queries.esm.js +141 -0
  278. package/dist/features/resource/queries.esm.js.map +1 -0
  279. package/dist/features/resource/tabs/GeneralTab.esm.js +247 -0
  280. package/dist/features/resource/tabs/GeneralTab.esm.js.map +1 -0
  281. package/dist/features/resource/tabs/GeneralTab.loading.esm.js +76 -0
  282. package/dist/features/resource/tabs/GeneralTab.loading.esm.js.map +1 -0
  283. package/dist/features/resource/tabs/PermissionsTab.esm.js +57 -0
  284. package/dist/features/resource/tabs/PermissionsTab.esm.js.map +1 -0
  285. package/dist/features/resource/tabs/SettingsTabLayout.esm.js +18 -0
  286. package/dist/features/resource/tabs/SettingsTabLayout.esm.js.map +1 -0
  287. package/dist/features/resource/tabs/TabHeader.esm.js +30 -0
  288. package/dist/features/resource/tabs/TabHeader.esm.js.map +1 -0
  289. package/dist/features/resource/tabs/UsagePanel.esm.js +35 -0
  290. package/dist/features/resource/tabs/UsagePanel.esm.js.map +1 -0
  291. package/dist/features/resource/tabs/UsageTab.esm.js +91 -0
  292. package/dist/features/resource/tabs/UsageTab.esm.js.map +1 -0
  293. package/dist/features/resource/tabs/UsageTab.helpers.esm.js +168 -0
  294. package/dist/features/resource/tabs/UsageTab.helpers.esm.js.map +1 -0
  295. package/dist/features/resources/ResourcesEmptyState.esm.js +148 -0
  296. package/dist/features/resources/ResourcesEmptyState.esm.js.map +1 -0
  297. package/dist/features/resources/ResourcesListPage.esm.js +115 -0
  298. package/dist/features/resources/ResourcesListPage.esm.js.map +1 -0
  299. package/dist/features/resources/queries.esm.js +50 -0
  300. package/dist/features/resources/queries.esm.js.map +1 -0
  301. package/dist/features/resources/resourceColumns.esm.js +158 -0
  302. package/dist/features/resources/resourceColumns.esm.js.map +1 -0
  303. package/dist/features/resources/resourceConstants.esm.js +7 -0
  304. package/dist/features/resources/resourceConstants.esm.js.map +1 -0
  305. package/dist/features/resources/toResourceRow.esm.js +29 -0
  306. package/dist/features/resources/toResourceRow.esm.js.map +1 -0
  307. package/dist/hooks/useAuthedSvg.esm.js +34 -0
  308. package/dist/hooks/useAuthedSvg.esm.js.map +1 -0
  309. package/dist/hooks/useCursorPagination.esm.js +40 -0
  310. package/dist/hooks/useCursorPagination.esm.js.map +1 -0
  311. package/dist/hooks/useMassdriverSubscription.esm.js +61 -0
  312. package/dist/hooks/useMassdriverSubscription.esm.js.map +1 -0
  313. package/dist/hooks/usePaginatedRelayQuery.esm.js +68 -0
  314. package/dist/hooks/usePaginatedRelayQuery.esm.js.map +1 -0
  315. package/dist/index.d.ts +256 -0
  316. package/dist/index.esm.js +8 -0
  317. package/dist/index.esm.js.map +1 -0
  318. package/dist/internalRoutes.esm.js +29 -0
  319. package/dist/internalRoutes.esm.js.map +1 -0
  320. package/dist/plugin.esm.js +57 -0
  321. package/dist/plugin.esm.js.map +1 -0
  322. package/dist/queries.esm.js +54 -0
  323. package/dist/queries.esm.js.map +1 -0
  324. package/dist/routes.esm.js +6 -0
  325. package/dist/routes.esm.js.map +1 -0
  326. package/dist/shell/MassdriverHeader.esm.js +37 -0
  327. package/dist/shell/MassdriverHeader.esm.js.map +1 -0
  328. package/dist/shell/MassdriverShell.esm.js +30 -0
  329. package/dist/shell/MassdriverShell.esm.js.map +1 -0
  330. package/dist/theme/MassdriverThemeScope.esm.js +30 -0
  331. package/dist/theme/MassdriverThemeScope.esm.js.map +1 -0
  332. package/dist/theme/ThemeModeContext.esm.js +35 -0
  333. package/dist/theme/ThemeModeContext.esm.js.map +1 -0
  334. package/dist/theme/muiClassNameAudit.esm.js +11 -0
  335. package/dist/theme/muiClassNameAudit.esm.js.map +1 -0
  336. package/dist/useInstances.esm.js +39 -0
  337. package/dist/useInstances.esm.js.map +1 -0
  338. package/dist/utils/attributes.esm.js +28 -0
  339. package/dist/utils/attributes.esm.js.map +1 -0
  340. package/dist/utils/conditions.esm.js +20 -0
  341. package/dist/utils/conditions.esm.js.map +1 -0
  342. package/dist/utils/formatRelativeTime.esm.js +40 -0
  343. package/dist/utils/formatRelativeTime.esm.js.map +1 -0
  344. package/dist/utils/instanceStatuses.esm.js +74 -0
  345. package/dist/utils/instanceStatuses.esm.js.map +1 -0
  346. package/package.json +92 -0
@@ -0,0 +1,188 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useState, useMemo } from 'react';
3
+ import { useSearchParams } from 'react-router-dom';
4
+ import Alert from '@massdriver/ui/Alert';
5
+ import Box from '@massdriver/ui/Box';
6
+ import LoadingIndicator from '@massdriver/ui/LoadingIndicator';
7
+ import Select, { MenuItem } from '@massdriver/ui/Select';
8
+ import FilterListIcon from '@massdriver/ui/icons/FilterListIcon';
9
+ import HistoryIcon from '@massdriver/ui/icons/HistoryIcon';
10
+ import SortIcon from '@massdriver/ui/icons/SortIcon';
11
+ import stylin from '@massdriver/ui/stylin';
12
+ import { RepoEmptyState } from '../RepoEmptyState.esm.js';
13
+ import { RepoNoVersionsState } from '../RepoNoVersionsState.esm.js';
14
+ import { RepoTabHeader } from '../RepoTabHeader.esm.js';
15
+ import { RepoTabLayout } from '../RepoTabLayout.esm.js';
16
+ import { buildRepoVersionFilter } from '../repoFilter.esm.js';
17
+ import { ALL_VERSIONS } from '../resolveVersion.esm.js';
18
+ import { REPO_DEPLOYMENTS_QUERY } from '../queries.esm.js';
19
+ import { useInfiniteRelayList } from '../useInfiniteRelayList.esm.js';
20
+ import { useInfiniteScroll } from '../useInfiniteScroll.esm.js';
21
+ import { DeploymentRow } from './DeploymentRow.esm.js';
22
+ import { DeploymentsTabLoading } from './DeploymentsTab.loading.esm.js';
23
+ import { DEFAULT_SORT_VALUE, DEFAULT_STATUS_VALUE, DEFAULT_ACTION_VALUE, sortValueToInput, filterValue, ACTION_OPTIONS, STATUS_OPTIONS, SORT_OPTIONS } from './DeploymentsTab.helpers.esm.js';
24
+ import '@mui/material/Chip';
25
+ import '@mui/material/Drawer';
26
+ import '@mui/material/OutlinedInput';
27
+ import { selectClasses } from '@mui/material/Select';
28
+ import '@mui/material/ToggleButton';
29
+
30
+ const DeploymentsTab = ({
31
+ repoId,
32
+ version,
33
+ hasNoVersions
34
+ }) => {
35
+ const [sortValue, setSortValue] = useState(DEFAULT_SORT_VALUE);
36
+ const [statusValue, setStatusValue] = useState(DEFAULT_STATUS_VALUE);
37
+ const [actionValue, setActionValue] = useState(DEFAULT_ACTION_VALUE);
38
+ const [, setSearchParams] = useSearchParams();
39
+ const versionScoped = version !== ALL_VERSIONS;
40
+ const setParam = (key, value) => setSearchParams(
41
+ (prev) => {
42
+ const next = new URLSearchParams(prev);
43
+ next.set(key, value);
44
+ return next;
45
+ },
46
+ { replace: false }
47
+ );
48
+ const onViewDetails = (deploymentId) => setParam("deployment", deploymentId);
49
+ const onViewLogs = (deploymentId) => setParam("logs", deploymentId);
50
+ const sort = useMemo(() => sortValueToInput(sortValue), [sortValue]);
51
+ const status = useMemo(() => filterValue(statusValue), [statusValue]);
52
+ const action = useMemo(() => filterValue(actionValue), [actionValue]);
53
+ const versionFilter = buildRepoVersionFilter(repoId, version);
54
+ const filter = versionFilter ? {
55
+ ...versionFilter,
56
+ ...status ? { status: { eq: status } } : {},
57
+ ...action ? { action: { eq: action } } : {}
58
+ } : void 0;
59
+ const { items, loading, loadingMore, error, hasMore, onLoadMore } = useInfiniteRelayList(REPO_DEPLOYMENTS_QUERY, {
60
+ responseKey: "deployments",
61
+ variables: { filter, sort },
62
+ pageSize: 20,
63
+ skip: hasNoVersions
64
+ });
65
+ const sentinelRef = useInfiniteScroll({
66
+ onLoadMore,
67
+ hasMore,
68
+ loading: loading || loadingMore
69
+ });
70
+ if (hasNoVersions) {
71
+ return /* @__PURE__ */ jsx(RepoNoVersionsState, { tabLabel: "deployments" });
72
+ }
73
+ const description = versionScoped ? "Deployments stamped with this bundle version, across every instance in your organization." : "Deployments of this bundle across every instance in your organization.";
74
+ return /* @__PURE__ */ jsxs(RepoTabLayout, { children: [
75
+ /* @__PURE__ */ jsx(RepoTabHeader, { title: "Deployments", description }),
76
+ /* @__PURE__ */ jsxs(Controls, { children: [
77
+ /* @__PURE__ */ jsxs(ControlGroup, { children: [
78
+ /* @__PURE__ */ jsx(FilterListIcon, { fontSize: "small" }),
79
+ /* @__PURE__ */ jsx(
80
+ ControlSelect,
81
+ {
82
+ value: actionValue,
83
+ onChange: (event) => setActionValue(event.target.value),
84
+ size: "small",
85
+ variant: "standard",
86
+ InputProps: { disableUnderline: true },
87
+ "aria-label": "Filter by action",
88
+ children: ACTION_OPTIONS.map((option) => /* @__PURE__ */ jsx(MenuItem, { value: option.value, children: option.label }, option.value))
89
+ }
90
+ )
91
+ ] }),
92
+ /* @__PURE__ */ jsxs(ControlGroup, { children: [
93
+ /* @__PURE__ */ jsx(FilterListIcon, { fontSize: "small" }),
94
+ /* @__PURE__ */ jsx(
95
+ ControlSelect,
96
+ {
97
+ value: statusValue,
98
+ onChange: (event) => setStatusValue(event.target.value),
99
+ size: "small",
100
+ variant: "standard",
101
+ InputProps: { disableUnderline: true },
102
+ "aria-label": "Filter by deployment status",
103
+ children: STATUS_OPTIONS.map((option) => /* @__PURE__ */ jsx(MenuItem, { value: option.value, children: option.label }, option.value))
104
+ }
105
+ )
106
+ ] }),
107
+ /* @__PURE__ */ jsxs(ControlGroup, { children: [
108
+ /* @__PURE__ */ jsx(SortIcon, { fontSize: "small" }),
109
+ /* @__PURE__ */ jsx(
110
+ ControlSelect,
111
+ {
112
+ value: sortValue,
113
+ onChange: (event) => setSortValue(event.target.value),
114
+ size: "small",
115
+ variant: "standard",
116
+ InputProps: { disableUnderline: true },
117
+ "aria-label": "Sort deployments",
118
+ children: SORT_OPTIONS.map((option) => /* @__PURE__ */ jsx(MenuItem, { value: option.value, children: option.label }, option.value))
119
+ }
120
+ )
121
+ ] })
122
+ ] }),
123
+ error ? /* @__PURE__ */ jsx(Alert, { severity: "error", children: String(error.message ?? error) }) : loading && items.length === 0 ? /* @__PURE__ */ jsx(DeploymentsTabLoading, {}) : items.length === 0 ? /* @__PURE__ */ jsx(
124
+ RepoEmptyState,
125
+ {
126
+ icon: /* @__PURE__ */ jsx(HistoryIcon, {}),
127
+ title: "No deployments",
128
+ description: versionScoped ? "No deployments match these filters for this bundle version." : "No deployments match these filters for this bundle."
129
+ }
130
+ ) : /* @__PURE__ */ jsxs(List, { children: [
131
+ items.map((deployment) => /* @__PURE__ */ jsx(
132
+ DeploymentRow,
133
+ {
134
+ deployment,
135
+ onViewLogs,
136
+ onViewDetails
137
+ },
138
+ deployment.id
139
+ )),
140
+ /* @__PURE__ */ jsx(Sentinel, { ref: sentinelRef }),
141
+ loadingMore ? /* @__PURE__ */ jsx(LoadingMoreRow, { children: /* @__PURE__ */ jsx(LoadingIndicator, { size: 24, delay: 0 }) }) : null
142
+ ] })
143
+ ] });
144
+ };
145
+ const Controls = stylin(Box)(({ theme }) => ({
146
+ display: "flex",
147
+ alignItems: "center",
148
+ gap: theme.spacing(2),
149
+ flexWrap: "wrap",
150
+ paddingBottom: theme.spacing(0.5),
151
+ borderBottom: `1px solid ${theme.palette.divider}`
152
+ }));
153
+ const ControlGroup = stylin(Box)(({ theme }) => ({
154
+ display: "flex",
155
+ alignItems: "center",
156
+ gap: theme.spacing(0.75),
157
+ color: theme.palette.text.secondary,
158
+ "& > svg": {
159
+ color: theme.palette.text.disabled
160
+ }
161
+ }));
162
+ const ControlSelect = stylin(Select)(({ theme }) => ({
163
+ [`& .${selectClasses.select}`]: {
164
+ fontSize: theme.typography.body2.fontSize,
165
+ padding: theme.spacing(0.25, 0.5),
166
+ paddingRight: `${theme.spacing(3)} !important`,
167
+ color: theme.palette.text.primary,
168
+ borderRadius: 1
169
+ }
170
+ }));
171
+ const List = stylin(Box)(({ theme }) => ({
172
+ display: "flex",
173
+ flexDirection: "column",
174
+ gap: theme.spacing(1.5)
175
+ }));
176
+ const Sentinel = stylin("div")({
177
+ height: 1,
178
+ width: "100%"
179
+ });
180
+ const LoadingMoreRow = stylin(Box)(({ theme }) => ({
181
+ display: "flex",
182
+ alignItems: "center",
183
+ justifyContent: "center",
184
+ padding: theme.spacing(1.5)
185
+ }));
186
+
187
+ export { DeploymentsTab };
188
+ //# sourceMappingURL=DeploymentsTab.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeploymentsTab.esm.js","sources":["../../../../src/features/repo/tabs/DeploymentsTab.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport { useSearchParams } from 'react-router-dom';\nimport Alert from '@massdriver/ui/Alert';\nimport Box from '@massdriver/ui/Box';\nimport LoadingIndicator from '@massdriver/ui/LoadingIndicator';\nimport Select, { MenuItem } from '@massdriver/ui/Select';\nimport FilterListIcon from '@massdriver/ui/icons/FilterListIcon';\nimport HistoryIcon from '@massdriver/ui/icons/HistoryIcon';\nimport SortIcon from '@massdriver/ui/icons/SortIcon';\nimport stylin from '@massdriver/ui/stylin';\nimport { RepoEmptyState } from '../RepoEmptyState';\nimport { RepoNoVersionsState } from '../RepoNoVersionsState';\nimport { RepoTabHeader } from '../RepoTabHeader';\nimport { RepoTabLayout } from '../RepoTabLayout';\nimport { buildRepoVersionFilter } from '../repoFilter';\nimport { ALL_VERSIONS } from '../resolveVersion';\nimport { REPO_DEPLOYMENTS_QUERY } from '../queries';\nimport type { RepoTabProps } from '../RepoDetailsPage';\nimport type { RepoDeployment } from '../types';\nimport { useInfiniteRelayList } from '../useInfiniteRelayList';\nimport { useInfiniteScroll } from '../useInfiniteScroll';\nimport { DeploymentRow } from './DeploymentRow';\nimport { DeploymentsTabLoading } from './DeploymentsTab.loading';\nimport {\n ACTION_OPTIONS,\n DEFAULT_ACTION_VALUE,\n DEFAULT_SORT_VALUE,\n DEFAULT_STATUS_VALUE,\n SORT_OPTIONS,\n STATUS_OPTIONS,\n filterValue,\n sortValueToInput,\n} from './DeploymentsTab.helpers';\nimport { selectClasses } from '../../../theme/muiClasses';\n\n// Ported from apps/web/features/repos/sections/DeploymentsTab/ (container + view\n// merged into one component, matching this plugin's single-file tab style). The\n// web app's infinite-scroll card list is reproduced here over the relay via\n// useInfiniteRelayList + an IntersectionObserver sentinel. Rows open the in-place\n// ViewDeploymentDetailsDialog / DeploymentLogsDrawer (mounted at RepoDetailsPage\n// level) by setting the same `deployment` / `logs` URL params the web uses.\nexport const DeploymentsTab = ({\n repoId,\n version,\n hasNoVersions,\n}: RepoTabProps) => {\n const [sortValue, setSortValue] = useState(DEFAULT_SORT_VALUE);\n const [statusValue, setStatusValue] = useState(DEFAULT_STATUS_VALUE);\n const [actionValue, setActionValue] = useState(DEFAULT_ACTION_VALUE);\n const [, setSearchParams] = useSearchParams();\n const versionScoped = version !== ALL_VERSIONS;\n\n const setParam = (key: string, value: string) =>\n setSearchParams(\n prev => {\n const next = new URLSearchParams(prev);\n next.set(key, value);\n return next;\n },\n { replace: false },\n );\n const onViewDetails = (deploymentId: string) =>\n setParam('deployment', deploymentId);\n const onViewLogs = (deploymentId: string) => setParam('logs', deploymentId);\n\n const sort = useMemo(() => sortValueToInput(sortValue), [sortValue]);\n const status = useMemo(() => filterValue(statusValue), [statusValue]);\n const action = useMemo(() => filterValue(actionValue), [actionValue]);\n\n const versionFilter = buildRepoVersionFilter(repoId, version);\n const filter = versionFilter\n ? {\n ...versionFilter,\n ...(status ? { status: { eq: status } } : {}),\n ...(action ? { action: { eq: action } } : {}),\n }\n : undefined;\n\n const { items, loading, loadingMore, error, hasMore, onLoadMore } =\n useInfiniteRelayList<RepoDeployment>(REPO_DEPLOYMENTS_QUERY, {\n responseKey: 'deployments',\n variables: { filter, sort },\n pageSize: 20,\n skip: hasNoVersions,\n });\n\n const sentinelRef = useInfiniteScroll({\n onLoadMore,\n hasMore,\n loading: loading || loadingMore,\n });\n\n if (hasNoVersions) {\n return <RepoNoVersionsState tabLabel=\"deployments\" />;\n }\n\n const description = versionScoped\n ? 'Deployments stamped with this bundle version, across every instance in your organization.'\n : 'Deployments of this bundle across every instance in your organization.';\n\n return (\n <RepoTabLayout>\n <RepoTabHeader title=\"Deployments\" description={description} />\n <Controls>\n <ControlGroup>\n <FilterListIcon fontSize=\"small\" />\n <ControlSelect\n value={actionValue}\n onChange={(event: { target: { value: string } }) =>\n setActionValue(event.target.value)\n }\n size=\"small\"\n variant=\"standard\"\n InputProps={{ disableUnderline: true }}\n aria-label=\"Filter by action\"\n >\n {ACTION_OPTIONS.map(option => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </ControlSelect>\n </ControlGroup>\n <ControlGroup>\n <FilterListIcon fontSize=\"small\" />\n <ControlSelect\n value={statusValue}\n onChange={(event: { target: { value: string } }) =>\n setStatusValue(event.target.value)\n }\n size=\"small\"\n variant=\"standard\"\n InputProps={{ disableUnderline: true }}\n aria-label=\"Filter by deployment status\"\n >\n {STATUS_OPTIONS.map(option => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </ControlSelect>\n </ControlGroup>\n <ControlGroup>\n <SortIcon fontSize=\"small\" />\n <ControlSelect\n value={sortValue}\n onChange={(event: { target: { value: string } }) =>\n setSortValue(event.target.value)\n }\n size=\"small\"\n variant=\"standard\"\n InputProps={{ disableUnderline: true }}\n aria-label=\"Sort deployments\"\n >\n {SORT_OPTIONS.map(option => (\n <MenuItem key={option.value} value={option.value}>\n {option.label}\n </MenuItem>\n ))}\n </ControlSelect>\n </ControlGroup>\n </Controls>\n {error ? (\n <Alert severity=\"error\">{String(error.message ?? error)}</Alert>\n ) : loading && items.length === 0 ? (\n <DeploymentsTabLoading />\n ) : items.length === 0 ? (\n <RepoEmptyState\n icon={<HistoryIcon />}\n title=\"No deployments\"\n description={\n versionScoped\n ? 'No deployments match these filters for this bundle version.'\n : 'No deployments match these filters for this bundle.'\n }\n />\n ) : (\n <List>\n {items.map(deployment => (\n <DeploymentRow\n key={deployment.id}\n deployment={deployment}\n onViewLogs={onViewLogs}\n onViewDetails={onViewDetails}\n />\n ))}\n <Sentinel ref={sentinelRef} />\n {loadingMore ? (\n <LoadingMoreRow>\n <LoadingIndicator size={24} delay={0} />\n </LoadingMoreRow>\n ) : null}\n </List>\n )}\n </RepoTabLayout>\n );\n};\n\nconst Controls = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(2),\n flexWrap: 'wrap',\n paddingBottom: theme.spacing(0.5),\n borderBottom: `1px solid ${theme.palette.divider}`,\n}));\n\nconst ControlGroup = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(0.75),\n color: theme.palette.text.secondary,\n '& > svg': {\n color: theme.palette.text.disabled,\n },\n}));\n\nconst ControlSelect = stylin(Select)(({ theme }: { theme: any }) => ({\n [`& .${selectClasses.select}`]: {\n fontSize: theme.typography.body2.fontSize,\n padding: theme.spacing(0.25, 0.5),\n paddingRight: `${theme.spacing(3)} !important`,\n color: theme.palette.text.primary,\n borderRadius: 1,\n },\n}));\n\nconst List = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1.5),\n}));\n\nconst Sentinel = stylin('div')({\n height: 1,\n width: '100%',\n});\n\nconst LoadingMoreRow = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: theme.spacing(1.5),\n}));\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyCO,MAAM,iBAAiB,CAAC;AAAA,EAC7B,MAAA;AAAA,EACA,OAAA;AAAA,EACA;AACF,CAAA,KAAoB;AAClB,EAAA,MAAM,CAAC,SAAA,EAAW,YAAY,CAAA,GAAI,SAAS,kBAAkB,CAAA;AAC7D,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,oBAAoB,CAAA;AACnE,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,oBAAoB,CAAA;AACnE,EAAA,MAAM,GAAG,eAAe,CAAA,GAAI,eAAA,EAAgB;AAC5C,EAAA,MAAM,gBAAgB,OAAA,KAAY,YAAA;AAElC,EAAA,MAAM,QAAA,GAAW,CAAC,GAAA,EAAa,KAAA,KAC7B,eAAA;AAAA,IACE,CAAA,IAAA,KAAQ;AACN,MAAA,MAAM,IAAA,GAAO,IAAI,eAAA,CAAgB,IAAI,CAAA;AACrC,MAAA,IAAA,CAAK,GAAA,CAAI,KAAK,KAAK,CAAA;AACnB,MAAA,OAAO,IAAA;AAAA,IACT,CAAA;AAAA,IACA,EAAE,SAAS,KAAA;AAAM,GACnB;AACF,EAAA,MAAM,aAAA,GAAgB,CAAC,YAAA,KACrB,QAAA,CAAS,cAAc,YAAY,CAAA;AACrC,EAAA,MAAM,UAAA,GAAa,CAAC,YAAA,KAAyB,QAAA,CAAS,QAAQ,YAAY,CAAA;AAE1E,EAAA,MAAM,IAAA,GAAO,QAAQ,MAAM,gBAAA,CAAiB,SAAS,CAAA,EAAG,CAAC,SAAS,CAAC,CAAA;AACnE,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAM,WAAA,CAAY,WAAW,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AACpE,EAAA,MAAM,MAAA,GAAS,QAAQ,MAAM,WAAA,CAAY,WAAW,CAAA,EAAG,CAAC,WAAW,CAAC,CAAA;AAEpE,EAAA,MAAM,aAAA,GAAgB,sBAAA,CAAuB,MAAA,EAAQ,OAAO,CAAA;AAC5D,EAAA,MAAM,SAAS,aAAA,GACX;AAAA,IACE,GAAG,aAAA;AAAA,IACH,GAAI,SAAS,EAAE,MAAA,EAAQ,EAAE,EAAA,EAAI,MAAA,EAAO,EAAE,GAAI,EAAC;AAAA,IAC3C,GAAI,SAAS,EAAE,MAAA,EAAQ,EAAE,EAAA,EAAI,MAAA,EAAO,EAAE,GAAI;AAAC,GAC7C,GACA,MAAA;AAEJ,EAAA,MAAM,EAAE,OAAO,OAAA,EAAS,WAAA,EAAa,OAAO,OAAA,EAAS,UAAA,EAAW,GAC9D,oBAAA,CAAqC,sBAAA,EAAwB;AAAA,IAC3D,WAAA,EAAa,aAAA;AAAA,IACb,SAAA,EAAW,EAAE,MAAA,EAAQ,IAAA,EAAK;AAAA,IAC1B,QAAA,EAAU,EAAA;AAAA,IACV,IAAA,EAAM;AAAA,GACP,CAAA;AAEH,EAAA,MAAM,cAAc,iBAAA,CAAkB;AAAA,IACpC,UAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAS,OAAA,IAAW;AAAA,GACrB,CAAA;AAED,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,uBAAO,GAAA,CAAC,mBAAA,EAAA,EAAoB,QAAA,EAAS,aAAA,EAAc,CAAA;AAAA,EACrD;AAEA,EAAA,MAAM,WAAA,GAAc,gBAChB,2FAAA,GACA,wEAAA;AAEJ,EAAA,4BACG,aAAA,EAAA,EACC,QAAA,EAAA;AAAA,oBAAA,GAAA,CAAC,aAAA,EAAA,EAAc,KAAA,EAAM,aAAA,EAAc,WAAA,EAA0B,CAAA;AAAA,yBAC5D,QAAA,EAAA,EACC,QAAA,EAAA;AAAA,sBAAA,IAAA,CAAC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,UAAS,OAAA,EAAQ,CAAA;AAAA,wBACjC,GAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO,WAAA;AAAA,YACP,UAAU,CAAC,KAAA,KACT,cAAA,CAAe,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,YAEnC,IAAA,EAAK,OAAA;AAAA,YACL,OAAA,EAAQ,UAAA;AAAA,YACR,UAAA,EAAY,EAAE,gBAAA,EAAkB,IAAA,EAAK;AAAA,YACrC,YAAA,EAAW,kBAAA;AAAA,YAEV,QAAA,EAAA,cAAA,CAAe,GAAA,CAAI,CAAA,MAAA,qBAClB,GAAA,CAAC,QAAA,EAAA,EAA4B,KAAA,EAAO,MAAA,CAAO,KAAA,EACxC,QAAA,EAAA,MAAA,CAAO,KAAA,EAAA,EADK,MAAA,CAAO,KAEtB,CACD;AAAA;AAAA;AACH,OAAA,EACF,CAAA;AAAA,2BACC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,cAAA,EAAA,EAAe,UAAS,OAAA,EAAQ,CAAA;AAAA,wBACjC,GAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO,WAAA;AAAA,YACP,UAAU,CAAC,KAAA,KACT,cAAA,CAAe,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,YAEnC,IAAA,EAAK,OAAA;AAAA,YACL,OAAA,EAAQ,UAAA;AAAA,YACR,UAAA,EAAY,EAAE,gBAAA,EAAkB,IAAA,EAAK;AAAA,YACrC,YAAA,EAAW,6BAAA;AAAA,YAEV,QAAA,EAAA,cAAA,CAAe,GAAA,CAAI,CAAA,MAAA,qBAClB,GAAA,CAAC,QAAA,EAAA,EAA4B,KAAA,EAAO,MAAA,CAAO,KAAA,EACxC,QAAA,EAAA,MAAA,CAAO,KAAA,EAAA,EADK,MAAA,CAAO,KAEtB,CACD;AAAA;AAAA;AACH,OAAA,EACF,CAAA;AAAA,2BACC,YAAA,EAAA,EACC,QAAA,EAAA;AAAA,wBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,UAAS,OAAA,EAAQ,CAAA;AAAA,wBAC3B,GAAA;AAAA,UAAC,aAAA;AAAA,UAAA;AAAA,YACC,KAAA,EAAO,SAAA;AAAA,YACP,UAAU,CAAC,KAAA,KACT,YAAA,CAAa,KAAA,CAAM,OAAO,KAAK,CAAA;AAAA,YAEjC,IAAA,EAAK,OAAA;AAAA,YACL,OAAA,EAAQ,UAAA;AAAA,YACR,UAAA,EAAY,EAAE,gBAAA,EAAkB,IAAA,EAAK;AAAA,YACrC,YAAA,EAAW,kBAAA;AAAA,YAEV,QAAA,EAAA,YAAA,CAAa,GAAA,CAAI,CAAA,MAAA,qBAChB,GAAA,CAAC,QAAA,EAAA,EAA4B,KAAA,EAAO,MAAA,CAAO,KAAA,EACxC,QAAA,EAAA,MAAA,CAAO,KAAA,EAAA,EADK,MAAA,CAAO,KAEtB,CACD;AAAA;AAAA;AACH,OAAA,EACF;AAAA,KAAA,EACF,CAAA;AAAA,IACC,KAAA,uBACE,KAAA,EAAA,EAAM,QAAA,EAAS,SAAS,QAAA,EAAA,MAAA,CAAO,KAAA,CAAM,WAAW,KAAK,CAAA,EAAE,IACtD,OAAA,IAAW,KAAA,CAAM,WAAW,CAAA,mBAC9B,GAAA,CAAC,yBAAsB,CAAA,GACrB,KAAA,CAAM,WAAW,CAAA,mBACnB,GAAA;AAAA,MAAC,cAAA;AAAA,MAAA;AAAA,QACC,IAAA,sBAAO,WAAA,EAAA,EAAY,CAAA;AAAA,QACnB,KAAA,EAAM,gBAAA;AAAA,QACN,WAAA,EACE,gBACI,6DAAA,GACA;AAAA;AAAA,KAER,wBAEC,IAAA,EAAA,EACE,QAAA,EAAA;AAAA,MAAA,KAAA,CAAM,IAAI,CAAA,UAAA,qBACT,GAAA;AAAA,QAAC,aAAA;AAAA,QAAA;AAAA,UAEC,UAAA;AAAA,UACA,UAAA;AAAA,UACA;AAAA,SAAA;AAAA,QAHK,UAAA,CAAW;AAAA,OAKnB,CAAA;AAAA,sBACD,GAAA,CAAC,QAAA,EAAA,EAAS,GAAA,EAAK,WAAA,EAAa,CAAA;AAAA,MAC3B,WAAA,mBACC,GAAA,CAAC,cAAA,EAAA,EACC,QAAA,kBAAA,GAAA,CAAC,gBAAA,EAAA,EAAiB,MAAM,EAAA,EAAI,KAAA,EAAO,CAAA,EAAG,CAAA,EACxC,CAAA,GACE;AAAA,KAAA,EACN;AAAA,GAAA,EAEJ,CAAA;AAEJ;AAEA,MAAM,WAAW,MAAA,CAAO,GAAG,EAAE,CAAC,EAAE,OAAM,MAAuB;AAAA,EAC3D,OAAA,EAAS,MAAA;AAAA,EACT,UAAA,EAAY,QAAA;AAAA,EACZ,GAAA,EAAK,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,EACpB,QAAA,EAAU,MAAA;AAAA,EACV,aAAA,EAAe,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AAAA,EAChC,YAAA,EAAc,CAAA,UAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA;AAClD,CAAA,CAAE,CAAA;AAEF,MAAM,eAAe,MAAA,CAAO,GAAG,EAAE,CAAC,EAAE,OAAM,MAAuB;AAAA,EAC/D,OAAA,EAAS,MAAA;AAAA,EACT,UAAA,EAAY,QAAA;AAAA,EACZ,GAAA,EAAK,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA;AAAA,EACvB,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,SAAA;AAAA,EAC1B,SAAA,EAAW;AAAA,IACT,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK;AAAA;AAE9B,CAAA,CAAE,CAAA;AAEF,MAAM,gBAAgB,MAAA,CAAO,MAAM,EAAE,CAAC,EAAE,OAAM,MAAuB;AAAA,EACnE,CAAC,CAAA,GAAA,EAAM,aAAA,CAAc,MAAM,EAAE,GAAG;AAAA,IAC9B,QAAA,EAAU,KAAA,CAAM,UAAA,CAAW,KAAA,CAAM,QAAA;AAAA,IACjC,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA;AAAA,IAChC,YAAA,EAAc,CAAA,EAAG,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAC,CAAA,WAAA,CAAA;AAAA,IACjC,KAAA,EAAO,KAAA,CAAM,OAAA,CAAQ,IAAA,CAAK,OAAA;AAAA,IAC1B,YAAA,EAAc;AAAA;AAElB,CAAA,CAAE,CAAA;AAEF,MAAM,OAAO,MAAA,CAAO,GAAG,EAAE,CAAC,EAAE,OAAM,MAAuB;AAAA,EACvD,OAAA,EAAS,MAAA;AAAA,EACT,aAAA,EAAe,QAAA;AAAA,EACf,GAAA,EAAK,KAAA,CAAM,OAAA,CAAQ,GAAG;AACxB,CAAA,CAAE,CAAA;AAEF,MAAM,QAAA,GAAW,MAAA,CAAO,KAAK,CAAA,CAAE;AAAA,EAC7B,MAAA,EAAQ,CAAA;AAAA,EACR,KAAA,EAAO;AACT,CAAC,CAAA;AAED,MAAM,iBAAiB,MAAA,CAAO,GAAG,EAAE,CAAC,EAAE,OAAM,MAAuB;AAAA,EACjE,OAAA,EAAS,MAAA;AAAA,EACT,UAAA,EAAY,QAAA;AAAA,EACZ,cAAA,EAAgB,QAAA;AAAA,EAChB,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,GAAG;AAC5B,CAAA,CAAE,CAAA;;;;"}
@@ -0,0 +1,46 @@
1
+ const STATUS_OPTIONS = [
2
+ { value: "ALL", label: "All statuses" },
3
+ { value: "RUNNING", label: "Running" },
4
+ { value: "PENDING", label: "Pending" },
5
+ { value: "COMPLETED", label: "Completed" },
6
+ { value: "FAILED", label: "Failed" },
7
+ { value: "PROPOSED", label: "Proposed" },
8
+ { value: "APPROVED", label: "Approved" },
9
+ { value: "REJECTED", label: "Rejected" },
10
+ { value: "ABORTED", label: "Aborted" }
11
+ ];
12
+ const DEFAULT_STATUS_VALUE = "ALL";
13
+ const ACTION_OPTIONS = [
14
+ { value: "ALL", label: "All actions" },
15
+ { value: "PROVISION", label: "Provision" },
16
+ { value: "DECOMMISSION", label: "Decommission" },
17
+ { value: "PLAN", label: "Plan" }
18
+ ];
19
+ const DEFAULT_ACTION_VALUE = "ALL";
20
+ const filterValue = (value) => value === "ALL" || !value ? null : value;
21
+ const SORT_OPTIONS = [
22
+ { value: "UPDATED_AT_DESC", label: "Last activity (newest)" },
23
+ { value: "UPDATED_AT_ASC", label: "Last activity (oldest)" },
24
+ { value: "CREATED_AT_DESC", label: "Created (newest)" },
25
+ { value: "CREATED_AT_ASC", label: "Created (oldest)" },
26
+ { value: "STATUS_ASC", label: "Status (A\u2013Z)" }
27
+ ];
28
+ const DEFAULT_SORT_VALUE = "UPDATED_AT_DESC";
29
+ const sortValueToInput = (value) => {
30
+ switch (value) {
31
+ case "UPDATED_AT_ASC":
32
+ return { field: "UPDATED_AT", order: "ASC" };
33
+ case "CREATED_AT_DESC":
34
+ return { field: "CREATED_AT", order: "DESC" };
35
+ case "CREATED_AT_ASC":
36
+ return { field: "CREATED_AT", order: "ASC" };
37
+ case "STATUS_ASC":
38
+ return { field: "STATUS", order: "ASC" };
39
+ case "UPDATED_AT_DESC":
40
+ default:
41
+ return { field: "UPDATED_AT", order: "DESC" };
42
+ }
43
+ };
44
+
45
+ export { ACTION_OPTIONS, DEFAULT_ACTION_VALUE, DEFAULT_SORT_VALUE, DEFAULT_STATUS_VALUE, SORT_OPTIONS, STATUS_OPTIONS, filterValue, sortValueToInput };
46
+ //# sourceMappingURL=DeploymentsTab.helpers.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeploymentsTab.helpers.esm.js","sources":["../../../../src/features/repo/tabs/DeploymentsTab.helpers.ts"],"sourcesContent":["// Ported from apps/web/features/repos/sections/DeploymentsTab/DeploymentsTab.helpers.js.\n\nexport const STATUS_OPTIONS = [\n { value: 'ALL', label: 'All statuses' },\n { value: 'RUNNING', label: 'Running' },\n { value: 'PENDING', label: 'Pending' },\n { value: 'COMPLETED', label: 'Completed' },\n { value: 'FAILED', label: 'Failed' },\n { value: 'PROPOSED', label: 'Proposed' },\n { value: 'APPROVED', label: 'Approved' },\n { value: 'REJECTED', label: 'Rejected' },\n { value: 'ABORTED', label: 'Aborted' },\n];\n\nexport const DEFAULT_STATUS_VALUE = 'ALL';\n\nexport const ACTION_OPTIONS = [\n { value: 'ALL', label: 'All actions' },\n { value: 'PROVISION', label: 'Provision' },\n { value: 'DECOMMISSION', label: 'Decommission' },\n { value: 'PLAN', label: 'Plan' },\n];\n\nexport const DEFAULT_ACTION_VALUE = 'ALL';\n\nexport const filterValue = (value: string): string | null =>\n value === 'ALL' || !value ? null : value;\n\n// UPDATED_AT tracks the most recent change to a deployment record (status\n// transitions, log compaction); CREATED_AT is when the deployment was enqueued.\nexport const SORT_OPTIONS = [\n { value: 'UPDATED_AT_DESC', label: 'Last activity (newest)' },\n { value: 'UPDATED_AT_ASC', label: 'Last activity (oldest)' },\n { value: 'CREATED_AT_DESC', label: 'Created (newest)' },\n { value: 'CREATED_AT_ASC', label: 'Created (oldest)' },\n { value: 'STATUS_ASC', label: 'Status (A–Z)' },\n];\n\nexport const DEFAULT_SORT_VALUE = 'UPDATED_AT_DESC';\n\nexport interface SortInput {\n field: string;\n order: 'ASC' | 'DESC';\n}\n\nexport const sortValueToInput = (value: string): SortInput => {\n switch (value) {\n case 'UPDATED_AT_ASC':\n return { field: 'UPDATED_AT', order: 'ASC' };\n case 'CREATED_AT_DESC':\n return { field: 'CREATED_AT', order: 'DESC' };\n case 'CREATED_AT_ASC':\n return { field: 'CREATED_AT', order: 'ASC' };\n case 'STATUS_ASC':\n return { field: 'STATUS', order: 'ASC' };\n case 'UPDATED_AT_DESC':\n default:\n return { field: 'UPDATED_AT', order: 'DESC' };\n }\n};\n"],"names":[],"mappings":"AAEO,MAAM,cAAA,GAAiB;AAAA,EAC5B,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,cAAA,EAAe;AAAA,EACtC,EAAE,KAAA,EAAO,SAAA,EAAW,KAAA,EAAO,SAAA,EAAU;AAAA,EACrC,EAAE,KAAA,EAAO,SAAA,EAAW,KAAA,EAAO,SAAA,EAAU;AAAA,EACrC,EAAE,KAAA,EAAO,WAAA,EAAa,KAAA,EAAO,WAAA,EAAY;AAAA,EACzC,EAAE,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,QAAA,EAAS;AAAA,EACnC,EAAE,KAAA,EAAO,UAAA,EAAY,KAAA,EAAO,UAAA,EAAW;AAAA,EACvC,EAAE,KAAA,EAAO,UAAA,EAAY,KAAA,EAAO,UAAA,EAAW;AAAA,EACvC,EAAE,KAAA,EAAO,UAAA,EAAY,KAAA,EAAO,UAAA,EAAW;AAAA,EACvC,EAAE,KAAA,EAAO,SAAA,EAAW,KAAA,EAAO,SAAA;AAC7B;AAEO,MAAM,oBAAA,GAAuB;AAE7B,MAAM,cAAA,GAAiB;AAAA,EAC5B,EAAE,KAAA,EAAO,KAAA,EAAO,KAAA,EAAO,aAAA,EAAc;AAAA,EACrC,EAAE,KAAA,EAAO,WAAA,EAAa,KAAA,EAAO,WAAA,EAAY;AAAA,EACzC,EAAE,KAAA,EAAO,cAAA,EAAgB,KAAA,EAAO,cAAA,EAAe;AAAA,EAC/C,EAAE,KAAA,EAAO,MAAA,EAAQ,KAAA,EAAO,MAAA;AAC1B;AAEO,MAAM,oBAAA,GAAuB;AAE7B,MAAM,cAAc,CAAC,KAAA,KAC1B,UAAU,KAAA,IAAS,CAAC,QAAQ,IAAA,GAAO;AAI9B,MAAM,YAAA,GAAe;AAAA,EAC1B,EAAE,KAAA,EAAO,iBAAA,EAAmB,KAAA,EAAO,wBAAA,EAAyB;AAAA,EAC5D,EAAE,KAAA,EAAO,gBAAA,EAAkB,KAAA,EAAO,wBAAA,EAAyB;AAAA,EAC3D,EAAE,KAAA,EAAO,iBAAA,EAAmB,KAAA,EAAO,kBAAA,EAAmB;AAAA,EACtD,EAAE,KAAA,EAAO,gBAAA,EAAkB,KAAA,EAAO,kBAAA,EAAmB;AAAA,EACrD,EAAE,KAAA,EAAO,YAAA,EAAc,KAAA,EAAO,mBAAA;AAChC;AAEO,MAAM,kBAAA,GAAqB;AAO3B,MAAM,gBAAA,GAAmB,CAAC,KAAA,KAA6B;AAC5D,EAAA,QAAQ,KAAA;AAAO,IACb,KAAK,gBAAA;AACH,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,EAAc,KAAA,EAAO,KAAA,EAAM;AAAA,IAC7C,KAAK,iBAAA;AACH,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,EAAc,KAAA,EAAO,MAAA,EAAO;AAAA,IAC9C,KAAK,gBAAA;AACH,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,EAAc,KAAA,EAAO,KAAA,EAAM;AAAA,IAC7C,KAAK,YAAA;AACH,MAAA,OAAO,EAAE,KAAA,EAAO,QAAA,EAAU,KAAA,EAAO,KAAA,EAAM;AAAA,IACzC,KAAK,iBAAA;AAAA,IACL;AACE,MAAA,OAAO,EAAE,KAAA,EAAO,YAAA,EAAc,KAAA,EAAO,MAAA,EAAO;AAAA;AAElD;;;;"}
@@ -0,0 +1,37 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import Box from '@massdriver/ui/Box';
3
+ import Skeleton from '@massdriver/ui/Skeleton';
4
+ import stylin from '@massdriver/ui/stylin';
5
+
6
+ const ROW_COUNT = 4;
7
+ const DeploymentsTabLoading = () => /* @__PURE__ */ jsx(List, { children: Array.from({ length: ROW_COUNT }).map((_, index) => /* @__PURE__ */ jsxs(RowSkeleton, { children: [
8
+ /* @__PURE__ */ jsx(Skeleton, { variant: "circular", width: 18, height: 18 }),
9
+ /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: 80 }),
10
+ /* @__PURE__ */ jsx(Skeleton, { variant: "rounded", width: 60, height: 20 }),
11
+ /* @__PURE__ */ jsx(Spacer, {}),
12
+ /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: 80 }),
13
+ /* @__PURE__ */ jsx(Sub, { children: /* @__PURE__ */ jsx(Skeleton, { variant: "text", width: "40%" }) })
14
+ ] }, index)) });
15
+ const List = stylin(Box)(({ theme }) => ({
16
+ display: "flex",
17
+ flexDirection: "column",
18
+ gap: theme.spacing(1.5)
19
+ }));
20
+ const RowSkeleton = stylin(Box)(({ theme }) => ({
21
+ display: "grid",
22
+ gridTemplateColumns: "auto auto auto 1fr auto",
23
+ alignItems: "center",
24
+ rowGap: theme.spacing(0.5),
25
+ columnGap: theme.spacing(1),
26
+ padding: theme.spacing(1.5),
27
+ borderRadius: 1,
28
+ border: `1px solid ${theme.palette.divider}`,
29
+ backgroundColor: theme.palette.background.paper
30
+ }));
31
+ const Spacer = stylin(Box)({});
32
+ const Sub = stylin(Box)({
33
+ gridColumn: "1 / -1"
34
+ });
35
+
36
+ export { DeploymentsTabLoading };
37
+ //# sourceMappingURL=DeploymentsTab.loading.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DeploymentsTab.loading.esm.js","sources":["../../../../src/features/repo/tabs/DeploymentsTab.loading.tsx"],"sourcesContent":["import Box from '@massdriver/ui/Box';\nimport Skeleton from '@massdriver/ui/Skeleton';\nimport stylin from '@massdriver/ui/stylin';\n\n// Ported from apps/web/features/repos/sections/DeploymentsTab/DeploymentsTab.loading.js.\nconst ROW_COUNT = 4;\n\nexport const DeploymentsTabLoading = () => (\n <List>\n {Array.from({ length: ROW_COUNT }).map((_, index) => (\n <RowSkeleton key={index}>\n <Skeleton variant=\"circular\" width={18} height={18} />\n <Skeleton variant=\"text\" width={80} />\n <Skeleton variant=\"rounded\" width={60} height={20} />\n <Spacer />\n <Skeleton variant=\"text\" width={80} />\n <Sub>\n <Skeleton variant=\"text\" width=\"40%\" />\n </Sub>\n </RowSkeleton>\n ))}\n </List>\n);\n\nexport default DeploymentsTabLoading;\n\nconst List = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(1.5),\n}));\n\nconst RowSkeleton = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'grid',\n gridTemplateColumns: 'auto auto auto 1fr auto',\n alignItems: 'center',\n rowGap: theme.spacing(0.5),\n columnGap: theme.spacing(1),\n padding: theme.spacing(1.5),\n borderRadius: 1,\n border: `1px solid ${theme.palette.divider}`,\n backgroundColor: theme.palette.background.paper,\n}));\n\nconst Spacer = stylin(Box)({});\n\nconst Sub = stylin(Box)({\n gridColumn: '1 / -1',\n});\n"],"names":[],"mappings":";;;;;AAKA,MAAM,SAAA,GAAY,CAAA;AAEX,MAAM,wBAAwB,sBACnC,GAAA,CAAC,IAAA,EAAA,EACE,QAAA,EAAA,KAAA,CAAM,KAAK,EAAE,MAAA,EAAQ,SAAA,EAAW,EAAE,GAAA,CAAI,CAAC,CAAA,EAAG,KAAA,0BACxC,WAAA,EAAA,EACC,QAAA,EAAA;AAAA,kBAAA,GAAA,CAAC,YAAS,OAAA,EAAQ,UAAA,EAAW,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAA,EAAI,CAAA;AAAA,kBACpD,GAAA,CAAC,QAAA,EAAA,EAAS,OAAA,EAAQ,MAAA,EAAO,OAAO,EAAA,EAAI,CAAA;AAAA,sBACnC,QAAA,EAAA,EAAS,OAAA,EAAQ,WAAU,KAAA,EAAO,EAAA,EAAI,QAAQ,EAAA,EAAI,CAAA;AAAA,sBAClD,MAAA,EAAA,EAAO,CAAA;AAAA,kBACR,GAAA,CAAC,QAAA,EAAA,EAAS,OAAA,EAAQ,MAAA,EAAO,OAAO,EAAA,EAAI,CAAA;AAAA,kBACpC,GAAA,CAAC,OACC,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,SAAQ,MAAA,EAAO,KAAA,EAAM,OAAM,CAAA,EACvC;AAAA,CAAA,EAAA,EARgB,KASlB,CACD,CAAA,EACH;AAKF,MAAM,OAAO,MAAA,CAAO,GAAG,EAAE,CAAC,EAAE,OAAM,MAAuB;AAAA,EACvD,OAAA,EAAS,MAAA;AAAA,EACT,aAAA,EAAe,QAAA;AAAA,EACf,GAAA,EAAK,KAAA,CAAM,OAAA,CAAQ,GAAG;AACxB,CAAA,CAAE,CAAA;AAEF,MAAM,cAAc,MAAA,CAAO,GAAG,EAAE,CAAC,EAAE,OAAM,MAAuB;AAAA,EAC9D,OAAA,EAAS,MAAA;AAAA,EACT,mBAAA,EAAqB,yBAAA;AAAA,EACrB,UAAA,EAAY,QAAA;AAAA,EACZ,MAAA,EAAQ,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AAAA,EACzB,SAAA,EAAW,KAAA,CAAM,OAAA,CAAQ,CAAC,CAAA;AAAA,EAC1B,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AAAA,EAC1B,YAAA,EAAc,CAAA;AAAA,EACd,MAAA,EAAQ,CAAA,UAAA,EAAa,KAAA,CAAM,OAAA,CAAQ,OAAO,CAAA,CAAA;AAAA,EAC1C,eAAA,EAAiB,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW;AAC5C,CAAA,CAAE,CAAA;AAEF,MAAM,MAAA,GAAS,MAAA,CAAO,GAAG,CAAA,CAAE,EAAE,CAAA;AAE7B,MAAM,GAAA,GAAM,MAAA,CAAO,GAAG,CAAA,CAAE;AAAA,EACtB,UAAA,EAAY;AACd,CAAC,CAAA;;;;"}
@@ -0,0 +1,142 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { useCallback, useMemo } from 'react';
3
+ import { useApi } from '@backstage/frontend-plugin-api';
4
+ import { useSearchParams } from 'react-router-dom';
5
+ import Alert from '@massdriver/ui/Alert';
6
+ import Box from '@massdriver/ui/Box';
7
+ import LoadingIndicator from '@massdriver/ui/LoadingIndicator';
8
+ import HistoryIcon from '@massdriver/ui/icons/HistoryIcon';
9
+ import stylin from '@massdriver/ui/stylin';
10
+ import useAsync from 'react-use/esm/useAsync';
11
+ import { massdriverApiRef } from '../../../api.esm.js';
12
+ import { RepoEmptyState } from '../RepoEmptyState.esm.js';
13
+ import { RepoNoVersionsState } from '../RepoNoVersionsState.esm.js';
14
+ import { FileTree } from '../FileTree.esm.js';
15
+ import { FileViewer } from '../FileViewer.esm.js';
16
+ import { REPO_TAG_FILES_QUERY } from '../queries.esm.js';
17
+ import { resolveSelectedVersion } from '../resolveVersion.esm.js';
18
+
19
+ const MAX_PAGES = 100;
20
+ const PAGE_LIMIT = 100;
21
+ const FilesTab = ({
22
+ repoId,
23
+ version,
24
+ hasNoVersions,
25
+ repo
26
+ }) => {
27
+ const api = useApi(massdriverApiRef);
28
+ const [searchParams, setSearchParams] = useSearchParams();
29
+ const selectedPath = searchParams.get("file") ?? "";
30
+ const onSelectPath = useCallback(
31
+ (nextPath) => {
32
+ setSearchParams(
33
+ (prev) => {
34
+ const next = new URLSearchParams(prev);
35
+ if (nextPath) next.set("file", nextPath);
36
+ else next.delete("file");
37
+ return next;
38
+ },
39
+ { replace: false }
40
+ );
41
+ },
42
+ [setSearchParams]
43
+ );
44
+ const resolvedVersion = resolveSelectedVersion(version, repo);
45
+ const isResolutionMissing = Boolean(repo) && !resolvedVersion && !hasNoVersions;
46
+ const { value, loading, error } = useAsync(async () => {
47
+ if (hasNoVersions || isResolutionMissing || !repoId || !resolvedVersion) {
48
+ return [];
49
+ }
50
+ const files2 = [];
51
+ let cursor = { limit: PAGE_LIMIT };
52
+ for (let page = 0; page < MAX_PAGES; page++) {
53
+ const data = await api.query(REPO_TAG_FILES_QUERY, {
54
+ repoId,
55
+ version: resolvedVersion,
56
+ cursor
57
+ });
58
+ const filesPage = data?.ociRepo?.tags?.items?.[0]?.files;
59
+ files2.push(...(filesPage?.items ?? []).filter(Boolean));
60
+ const next = filesPage?.cursor?.next;
61
+ if (!next) break;
62
+ cursor = { limit: PAGE_LIMIT, next };
63
+ }
64
+ return files2;
65
+ }, [api, repoId, resolvedVersion, hasNoVersions, isResolutionMissing]);
66
+ const files = useMemo(() => value ?? [], [value]);
67
+ const selectedFile = useMemo(
68
+ () => files.find((file) => file.name === selectedPath) ?? null,
69
+ [files, selectedPath]
70
+ );
71
+ if (hasNoVersions) {
72
+ return /* @__PURE__ */ jsx(RepoNoVersionsState, { tabLabel: "files" });
73
+ }
74
+ if (isResolutionMissing) {
75
+ return /* @__PURE__ */ jsx(
76
+ RepoEmptyState,
77
+ {
78
+ icon: /* @__PURE__ */ jsx(HistoryIcon, {}),
79
+ title: "Files unavailable",
80
+ description: "We couldn't resolve a version to load files for. Pick a different version above."
81
+ }
82
+ );
83
+ }
84
+ if (loading) {
85
+ return /* @__PURE__ */ jsx(Centered, { children: /* @__PURE__ */ jsx(LoadingIndicator, {}) });
86
+ }
87
+ if (error) {
88
+ return /* @__PURE__ */ jsx(Padded, { children: /* @__PURE__ */ jsx(Alert, { severity: "error", children: String(error.message ?? error) }) });
89
+ }
90
+ return /* @__PURE__ */ jsxs(Layout, { children: [
91
+ /* @__PURE__ */ jsx(TreePane, { children: /* @__PURE__ */ jsx(
92
+ FileTree,
93
+ {
94
+ files,
95
+ selectedPath,
96
+ onSelectPath
97
+ }
98
+ ) }),
99
+ /* @__PURE__ */ jsx(ViewerPane, { children: /* @__PURE__ */ jsx(FileViewer, { file: selectedFile }) })
100
+ ] });
101
+ };
102
+ const Layout = stylin(Box)(({ theme }) => ({
103
+ display: "grid",
104
+ gridTemplateColumns: "280px 1fr",
105
+ height: "calc(100vh - 220px)",
106
+ minHeight: 400,
107
+ borderTop: `1px solid ${theme.palette.divider}`,
108
+ [theme.breakpoints.down("md")]: {
109
+ gridTemplateColumns: "1fr",
110
+ gridTemplateRows: "minmax(180px, 30vh) 1fr",
111
+ height: "auto"
112
+ }
113
+ }));
114
+ const TreePane = stylin(Box)(({ theme }) => ({
115
+ borderRight: `1px solid ${theme.palette.divider}`,
116
+ backgroundColor: theme.palette.background.paper,
117
+ overflow: "hidden",
118
+ display: "flex",
119
+ flexDirection: "column",
120
+ minHeight: 0,
121
+ [theme.breakpoints.down("md")]: {
122
+ borderRight: "none",
123
+ borderBottom: `1px solid ${theme.palette.divider}`
124
+ }
125
+ }));
126
+ const ViewerPane = stylin(Box)({
127
+ minHeight: 0,
128
+ overflow: "hidden",
129
+ display: "flex",
130
+ flexDirection: "column"
131
+ });
132
+ const Centered = stylin(Box)(({ theme }) => ({
133
+ display: "flex",
134
+ justifyContent: "center",
135
+ padding: theme.spacing(6)
136
+ }));
137
+ const Padded = stylin(Box)(({ theme }) => ({
138
+ padding: theme.spacing(3)
139
+ }));
140
+
141
+ export { FilesTab };
142
+ //# sourceMappingURL=FilesTab.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FilesTab.esm.js","sources":["../../../../src/features/repo/tabs/FilesTab.tsx"],"sourcesContent":["import { useCallback, useMemo } from 'react';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport { useSearchParams } from 'react-router-dom';\nimport Alert from '@massdriver/ui/Alert';\nimport Box from '@massdriver/ui/Box';\nimport LoadingIndicator from '@massdriver/ui/LoadingIndicator';\nimport HistoryIcon from '@massdriver/ui/icons/HistoryIcon';\nimport stylin from '@massdriver/ui/stylin';\nimport useAsync from 'react-use/esm/useAsync';\nimport { massdriverApiRef } from '../../../api';\nimport { RepoEmptyState } from '../RepoEmptyState';\nimport { RepoNoVersionsState } from '../RepoNoVersionsState';\nimport { FileTree } from '../FileTree';\nimport { FileViewer } from '../FileViewer';\nimport { REPO_TAG_FILES_QUERY } from '../queries';\nimport { resolveSelectedVersion } from '../resolveVersion';\nimport type { RepoTabProps } from '../RepoDetailsPage';\nimport type { RepoFile } from '../types';\n\nconst MAX_PAGES = 100;\nconst PAGE_LIMIT = 100;\n\ninterface FilesQueryResult {\n ociRepo: {\n tags?: {\n items?: Array<{\n tag: string;\n files?: {\n cursor?: { next?: string | null } | null;\n items?: Array<RepoFile | null> | null;\n } | null;\n } | null> | null;\n } | null;\n } | null;\n}\n\n// Ported from apps/web/features/repos/sections/FilesTab/ + components/FileViewer.\n//\n// DIVERGENCE: the web app stores the selected file path in a URL catch-all\n// segment (`/files/<path>`). This plugin's route is\n// `repositories/:repoId/:version/:tab` with no catch-all, so the selected file\n// lives in a `?file=` search param instead — deep-linking still works. File\n// contents are fetched through the backend content proxy (see FileViewer), so\n// the real in-app viewer is fully functional here.\nexport const FilesTab = ({\n repoId,\n version,\n hasNoVersions,\n repo,\n}: RepoTabProps) => {\n const api = useApi(massdriverApiRef);\n const [searchParams, setSearchParams] = useSearchParams();\n const selectedPath = searchParams.get('file') ?? '';\n\n const onSelectPath = useCallback(\n (nextPath: string) => {\n setSearchParams(\n prev => {\n const next = new URLSearchParams(prev);\n if (nextPath) next.set('file', nextPath);\n else next.delete('file');\n return next;\n },\n { replace: false },\n );\n },\n [setSearchParams],\n );\n\n const resolvedVersion = resolveSelectedVersion(version, repo);\n const isResolutionMissing =\n Boolean(repo) && !resolvedVersion && !hasNoVersions;\n\n const { value, loading, error } = useAsync(async () => {\n if (hasNoVersions || isResolutionMissing || !repoId || !resolvedVersion) {\n return [] as RepoFile[];\n }\n const files: RepoFile[] = [];\n let cursor: { limit: number; next?: string } = { limit: PAGE_LIMIT };\n for (let page = 0; page < MAX_PAGES; page++) {\n const data = (await api.query(REPO_TAG_FILES_QUERY, {\n repoId,\n version: resolvedVersion,\n cursor,\n })) as FilesQueryResult;\n const filesPage = data?.ociRepo?.tags?.items?.[0]?.files;\n files.push(...((filesPage?.items ?? []).filter(Boolean) as RepoFile[]));\n const next = filesPage?.cursor?.next;\n if (!next) break;\n cursor = { limit: PAGE_LIMIT, next };\n }\n return files;\n }, [api, repoId, resolvedVersion, hasNoVersions, isResolutionMissing]);\n\n const files = useMemo(() => value ?? [], [value]);\n const selectedFile = useMemo(\n () => files.find(file => file.name === selectedPath) ?? null,\n [files, selectedPath],\n );\n\n if (hasNoVersions) {\n return <RepoNoVersionsState tabLabel=\"files\" />;\n }\n\n if (isResolutionMissing) {\n return (\n <RepoEmptyState\n icon={<HistoryIcon />}\n title=\"Files unavailable\"\n description=\"We couldn't resolve a version to load files for. Pick a different version above.\"\n />\n );\n }\n\n if (loading) {\n return (\n <Centered>\n <LoadingIndicator />\n </Centered>\n );\n }\n\n if (error) {\n return (\n <Padded>\n <Alert severity=\"error\">{String(error.message ?? error)}</Alert>\n </Padded>\n );\n }\n\n return (\n <Layout>\n <TreePane>\n <FileTree\n files={files}\n selectedPath={selectedPath}\n onSelectPath={onSelectPath}\n />\n </TreePane>\n <ViewerPane>\n <FileViewer file={selectedFile} />\n </ViewerPane>\n </Layout>\n );\n};\n\nconst Layout = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'grid',\n gridTemplateColumns: '280px 1fr',\n height: 'calc(100vh - 220px)',\n minHeight: 400,\n borderTop: `1px solid ${theme.palette.divider}`,\n [theme.breakpoints.down('md')]: {\n gridTemplateColumns: '1fr',\n gridTemplateRows: 'minmax(180px, 30vh) 1fr',\n height: 'auto',\n },\n}));\n\nconst TreePane = stylin(Box)(({ theme }: { theme: any }) => ({\n borderRight: `1px solid ${theme.palette.divider}`,\n backgroundColor: theme.palette.background.paper,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\n minHeight: 0,\n [theme.breakpoints.down('md')]: {\n borderRight: 'none',\n borderBottom: `1px solid ${theme.palette.divider}`,\n },\n}));\n\nconst ViewerPane = stylin(Box)({\n minHeight: 0,\n overflow: 'hidden',\n display: 'flex',\n flexDirection: 'column',\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(3),\n}));\n"],"names":["files"],"mappings":"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"}
@@ -0,0 +1,121 @@
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { parseInstanceId } from '@massdriver/backstage-plugin-common';
3
+ import Box from '@massdriver/ui/Box';
4
+ import Typography from '@massdriver/ui/Typography';
5
+ import stylin from '@massdriver/ui/stylin';
6
+ import { InstanceStatusPill } from '../../../components/InstanceStatusPill.esm.js';
7
+ import { RouterLinkAdapter } from '../../../components/RouterLinkAdapter.esm.js';
8
+ import VersionBadge from '../../../components/VersionBadge.esm.js';
9
+ import { formatRelativeTime } from '../../../utils/formatRelativeTime.esm.js';
10
+ import { internalRoutes } from '../../../internalRoutes.esm.js';
11
+ import { formatCost } from './InstancesTab.helpers.esm.js';
12
+
13
+ const InstanceRow = ({ instance }) => {
14
+ const { projectId, scopedEnvironmentId, scopedComponentId } = parseInstanceId(
15
+ instance.id
16
+ );
17
+ const href = internalRoutes.instance(
18
+ projectId,
19
+ scopedEnvironmentId,
20
+ scopedComponentId
21
+ );
22
+ const projectName = instance.component?.project?.name ?? "\u2014";
23
+ const environmentName = instance.environment?.name ?? "\u2014";
24
+ const displayVersion = instance.deployedVersion ?? instance.resolvedVersion ?? instance.version;
25
+ const cost = formatCost(instance.cost?.lastMonth, { fallback: null });
26
+ const updated = formatRelativeTime(instance.updatedAt);
27
+ return /* @__PURE__ */ jsxs(Card, { component: RouterLinkAdapter, href, children: [
28
+ /* @__PURE__ */ jsxs(Header, { children: [
29
+ /* @__PURE__ */ jsx(InstanceStatusPill, { status: instance.status }),
30
+ /* @__PURE__ */ jsx(Name, { title: instance.id, children: instance.id }),
31
+ displayVersion ? /* @__PURE__ */ jsx(VersionBadge, { version: displayVersion }) : null
32
+ ] }),
33
+ /* @__PURE__ */ jsxs(Meta, { variant: "caption", children: [
34
+ /* @__PURE__ */ jsxs(Group, { children: [
35
+ /* @__PURE__ */ jsx("strong", { children: projectName }),
36
+ /* @__PURE__ */ jsx(Sep, { children: "/" }),
37
+ /* @__PURE__ */ jsx("span", { children: environmentName })
38
+ ] }),
39
+ /* @__PURE__ */ jsx(Dot, { children: "\xB7" }),
40
+ /* @__PURE__ */ jsxs("span", { children: [
41
+ "Updated ",
42
+ updated
43
+ ] }),
44
+ cost ? /* @__PURE__ */ jsxs(Fragment, { children: [
45
+ /* @__PURE__ */ jsx(Dot, { children: "\xB7" }),
46
+ /* @__PURE__ */ jsxs(CostText, { children: [
47
+ cost,
48
+ " last month"
49
+ ] })
50
+ ] }) : null
51
+ ] })
52
+ ] });
53
+ };
54
+ const Card = stylin(Box)(({ theme }) => ({
55
+ display: "flex",
56
+ flexDirection: "column",
57
+ gap: theme.spacing(0.5),
58
+ padding: theme.spacing(1.25, 1.5),
59
+ borderRadius: 1,
60
+ border: `1px solid ${theme.palette.divider}`,
61
+ backgroundColor: theme.palette.background.paper,
62
+ color: "inherit",
63
+ textDecoration: "none",
64
+ transition: "background-color 120ms ease, border-color 120ms ease",
65
+ "&:hover": {
66
+ backgroundColor: theme.palette.action.hover,
67
+ borderColor: theme.palette.divider
68
+ },
69
+ "&:focus-visible": {
70
+ outline: `2px solid ${theme.palette.primary.main}`,
71
+ outlineOffset: 2
72
+ }
73
+ }));
74
+ const Header = stylin(Box)(({ theme }) => ({
75
+ display: "flex",
76
+ alignItems: "center",
77
+ gap: theme.spacing(1),
78
+ flexWrap: "wrap",
79
+ minWidth: 0
80
+ }));
81
+ const Name = stylin(Typography)(({ theme }) => ({
82
+ fontSize: theme.typography.pxToRem(14),
83
+ fontWeight: 600,
84
+ color: theme.palette.text.primary,
85
+ minWidth: 0,
86
+ overflow: "hidden",
87
+ textOverflow: "ellipsis",
88
+ whiteSpace: "nowrap",
89
+ flex: "1 1 auto"
90
+ }));
91
+ const Meta = stylin(Typography)(({ theme }) => ({
92
+ color: theme.palette.text.secondary,
93
+ display: "flex",
94
+ flexWrap: "wrap",
95
+ alignItems: "center",
96
+ gap: theme.spacing(0.5),
97
+ minWidth: 0
98
+ }));
99
+ const Group = stylin("span")(({ theme }) => ({
100
+ display: "inline-flex",
101
+ alignItems: "center",
102
+ gap: theme.spacing(0.5),
103
+ minWidth: 0,
104
+ color: theme.palette.text.secondary,
105
+ "& strong": {
106
+ color: theme.palette.text.primary,
107
+ fontWeight: 500
108
+ }
109
+ }));
110
+ const Sep = stylin("span")(({ theme }) => ({
111
+ color: theme.palette.text.disabled
112
+ }));
113
+ const Dot = stylin("span")(({ theme }) => ({
114
+ color: theme.palette.text.disabled
115
+ }));
116
+ const CostText = stylin("span")({
117
+ fontVariantNumeric: "tabular-nums"
118
+ });
119
+
120
+ export { InstanceRow };
121
+ //# sourceMappingURL=InstanceRow.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InstanceRow.esm.js","sources":["../../../../src/features/repo/tabs/InstanceRow.tsx"],"sourcesContent":["import { parseInstanceId } from '@massdriver/backstage-plugin-common';\nimport Box from '@massdriver/ui/Box';\nimport Typography from '@massdriver/ui/Typography';\nimport stylin from '@massdriver/ui/stylin';\nimport { InstanceStatusPill } from '../../../components/InstanceStatusPill';\nimport { RouterLinkAdapter } from '../../../components/RouterLinkAdapter';\nimport VersionBadge from '../../../components/VersionBadge';\nimport { formatRelativeTime } from '../../../utils/formatRelativeTime';\nimport { internalRoutes } from '../../../internalRoutes';\nimport type { RepoInstance } from '../types';\nimport { formatCost } from './InstancesTab.helpers';\n\n// Ported from apps/web/features/repos/sections/InstancesTab/InstanceRow.js. The\n// whole card is a link to the instance drawer. The web renders the plain\n// (static) InstanceStatusPill here too — the live, latest-deployment-aware pill\n// is only used inside the environment graph — so `status={instance.status}` is\n// the faithful equivalent (differs only while a deployment is actively running).\nexport const InstanceRow = ({ instance }: { instance: RepoInstance }) => {\n const { projectId, scopedEnvironmentId, scopedComponentId } = parseInstanceId(\n instance.id,\n );\n const href = internalRoutes.instance(\n projectId,\n scopedEnvironmentId,\n scopedComponentId,\n );\n const projectName = instance.component?.project?.name ?? '—';\n const environmentName = instance.environment?.name ?? '—';\n const displayVersion =\n instance.deployedVersion ?? instance.resolvedVersion ?? instance.version;\n const cost = formatCost(instance.cost?.lastMonth, { fallback: null });\n const updated = formatRelativeTime(instance.updatedAt);\n\n return (\n <Card component={RouterLinkAdapter} href={href}>\n <Header>\n <InstanceStatusPill status={instance.status} />\n <Name title={instance.id}>{instance.id}</Name>\n {displayVersion ? <VersionBadge version={displayVersion} /> : null}\n </Header>\n <Meta variant=\"caption\">\n <Group>\n <strong>{projectName}</strong>\n <Sep>/</Sep>\n <span>{environmentName}</span>\n </Group>\n <Dot>·</Dot>\n <span>Updated {updated}</span>\n {cost ? (\n <>\n <Dot>·</Dot>\n <CostText>{cost} last month</CostText>\n </>\n ) : null}\n </Meta>\n </Card>\n );\n};\n\nexport default InstanceRow;\n\nconst Card = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(0.5),\n padding: theme.spacing(1.25, 1.5),\n borderRadius: 1,\n border: `1px solid ${theme.palette.divider}`,\n backgroundColor: theme.palette.background.paper,\n color: 'inherit',\n textDecoration: 'none',\n transition: 'background-color 120ms ease, border-color 120ms ease',\n '&:hover': {\n backgroundColor: theme.palette.action.hover,\n borderColor: theme.palette.divider,\n },\n '&:focus-visible': {\n outline: `2px solid ${theme.palette.primary.main}`,\n outlineOffset: 2,\n },\n}));\n\nconst Header = 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 Name = stylin(Typography)(({ theme }: { theme: any }) => ({\n fontSize: theme.typography.pxToRem(14),\n fontWeight: 600,\n color: theme.palette.text.primary,\n minWidth: 0,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n flex: '1 1 auto',\n}));\n\nconst Meta = stylin(Typography)(({ theme }: { theme: any }) => ({\n color: theme.palette.text.secondary,\n display: 'flex',\n flexWrap: 'wrap',\n alignItems: 'center',\n gap: theme.spacing(0.5),\n minWidth: 0,\n}));\n\nconst Group = stylin('span')(({ theme }: { theme: any }) => ({\n display: 'inline-flex',\n alignItems: 'center',\n gap: theme.spacing(0.5),\n minWidth: 0,\n color: theme.palette.text.secondary,\n '& strong': {\n color: theme.palette.text.primary,\n fontWeight: 500,\n },\n}));\n\nconst Sep = stylin('span')(({ theme }: { theme: any }) => ({\n color: theme.palette.text.disabled,\n}));\n\nconst Dot = stylin('span')(({ theme }: { theme: any }) => ({\n color: theme.palette.text.disabled,\n}));\n\nconst CostText = stylin('span')({\n fontVariantNumeric: 'tabular-nums',\n});\n"],"names":[],"mappings":"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"}