@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,57 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { alpha } from '@massdriver/ui/theme';
3
+ import Box from '@massdriver/ui/Box';
4
+ import Tooltip from '@massdriver/ui/Tooltip';
5
+ import LockIcon from '@massdriver/ui/icons/LockIcon';
6
+ import stylin from '@massdriver/ui/stylin';
7
+
8
+ const SEMVER_RE = /^\d+\.\d+\.\d+(?:[-+].+)?$/;
9
+ const isPinnedVersion = (version) => Boolean(version && SEMVER_RE.test(version));
10
+ const VersionBadge = ({
11
+ version,
12
+ showPinnedWarning,
13
+ className
14
+ }) => {
15
+ const pinned = isPinnedVersion(version);
16
+ const showWarning = Boolean(showPinnedWarning) && pinned;
17
+ const displayVersion = pinned ? `v${version}` : version;
18
+ return /* @__PURE__ */ jsx(
19
+ Tooltip,
20
+ {
21
+ arrow: true,
22
+ enterDelay: 600,
23
+ enterNextDelay: 600,
24
+ title: showWarning ? "This instance's version is pinned and won't update automatically. Consider using a release channel to keep it current." : "",
25
+ children: /* @__PURE__ */ jsxs(BadgeRoot, { pinned, className, children: [
26
+ pinned && /* @__PURE__ */ jsx(PinnedIcon, {}),
27
+ /* @__PURE__ */ jsx(VersionText, { children: displayVersion })
28
+ ] })
29
+ }
30
+ );
31
+ };
32
+ const BadgeRoot = stylin(Box, ["pinned"])(
33
+ ({ theme, pinned }) => ({
34
+ display: "inline-flex",
35
+ alignItems: "center",
36
+ gap: theme.spacing(0.5),
37
+ padding: theme.spacing(0.25, 0.75),
38
+ borderRadius: 1,
39
+ lineHeight: 1,
40
+ backgroundColor: pinned ? alpha(theme.palette.warning.main, 0.12) : theme.palette.background.field,
41
+ color: pinned ? theme.palette.warning.main : theme.palette.text.secondary,
42
+ border: `1px solid ${pinned ? alpha(theme.palette.warning.main, 0.3) : theme.palette.divider}`
43
+ })
44
+ );
45
+ const PinnedIcon = stylin(LockIcon)({
46
+ fontSize: 12
47
+ });
48
+ const VersionText = stylin("span")(({ theme }) => ({
49
+ fontSize: theme.typography.pxToRem(12),
50
+ fontWeight: 500,
51
+ color: "inherit",
52
+ lineHeight: 1,
53
+ fontFamily: theme.typography.fontFamilyMono
54
+ }));
55
+
56
+ export { VersionBadge as default };
57
+ //# sourceMappingURL=VersionBadge.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VersionBadge.esm.js","sources":["../../src/components/VersionBadge.tsx"],"sourcesContent":["import { alpha } from '@massdriver/ui/theme';\nimport Box from '@massdriver/ui/Box';\nimport Tooltip from '@massdriver/ui/Tooltip';\nimport LockIcon from '@massdriver/ui/icons/LockIcon';\nimport stylin from '@massdriver/ui/stylin';\n\n// A pinned version is a concrete semver (e.g. \"1.2.3\"); release-channel names\n// (e.g. \"latest\", \"stable\") are not. Inlined to avoid a `semver` dependency.\nconst SEMVER_RE = /^\\d+\\.\\d+\\.\\d+(?:[-+].+)?$/;\nconst isPinnedVersion = (version?: string | null): boolean =>\n Boolean(version && SEMVER_RE.test(version));\n\n/** Version chip with a pinned-version lock warning. Read-only port. */\nconst VersionBadge = ({\n version,\n showPinnedWarning,\n className,\n}: {\n version?: string | null;\n showPinnedWarning?: boolean;\n className?: string;\n}) => {\n const pinned = isPinnedVersion(version);\n const showWarning = Boolean(showPinnedWarning) && pinned;\n const displayVersion = pinned ? `v${version}` : version;\n\n return (\n <Tooltip\n arrow\n enterDelay={600}\n enterNextDelay={600}\n title={\n showWarning\n ? \"This instance's version is pinned and won't update automatically. Consider using a release channel to keep it current.\"\n : ''\n }\n >\n <BadgeRoot pinned={pinned} className={className}>\n {pinned && <PinnedIcon />}\n <VersionText>{displayVersion}</VersionText>\n </BadgeRoot>\n </Tooltip>\n );\n};\n\nconst BadgeRoot = stylin(Box, ['pinned'])(\n ({ theme, pinned }: { theme: any; pinned: boolean }) => ({\n display: 'inline-flex',\n alignItems: 'center',\n gap: theme.spacing(0.5),\n padding: theme.spacing(0.25, 0.75),\n borderRadius: 1,\n lineHeight: 1,\n backgroundColor: pinned\n ? alpha(theme.palette.warning.main, 0.12)\n : theme.palette.background.field,\n color: pinned ? theme.palette.warning.main : theme.palette.text.secondary,\n border: `1px solid ${\n pinned ? alpha(theme.palette.warning.main, 0.3) : theme.palette.divider\n }`,\n }),\n);\n\nconst PinnedIcon = stylin(LockIcon)({\n fontSize: 12,\n});\n\nconst VersionText = stylin('span')(({ theme }: { theme: any }) => ({\n fontSize: theme.typography.pxToRem(12),\n fontWeight: 500,\n color: 'inherit',\n lineHeight: 1,\n fontFamily: theme.typography.fontFamilyMono,\n}));\n\nexport default VersionBadge;\n"],"names":[],"mappings":";;;;;;;AAQA,MAAM,SAAA,GAAY,4BAAA;AAClB,MAAM,eAAA,GAAkB,CAAC,OAAA,KACvB,OAAA,CAAQ,WAAW,SAAA,CAAU,IAAA,CAAK,OAAO,CAAC,CAAA;AAG5C,MAAM,eAAe,CAAC;AAAA,EACpB,OAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACF,CAAA,KAIM;AACJ,EAAA,MAAM,MAAA,GAAS,gBAAgB,OAAO,CAAA;AACtC,EAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,iBAAiB,CAAA,IAAK,MAAA;AAClD,EAAA,MAAM,cAAA,GAAiB,MAAA,GAAS,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA,GAAK,OAAA;AAEhD,EAAA,uBACE,GAAA;AAAA,IAAC,OAAA;AAAA,IAAA;AAAA,MACC,KAAA,EAAK,IAAA;AAAA,MACL,UAAA,EAAY,GAAA;AAAA,MACZ,cAAA,EAAgB,GAAA;AAAA,MAChB,KAAA,EACE,cACI,wHAAA,GACA,EAAA;AAAA,MAGN,QAAA,kBAAA,IAAA,CAAC,SAAA,EAAA,EAAU,MAAA,EAAgB,SAAA,EACxB,QAAA,EAAA;AAAA,QAAA,MAAA,wBAAW,UAAA,EAAA,EAAW,CAAA;AAAA,wBACvB,GAAA,CAAC,eAAa,QAAA,EAAA,cAAA,EAAe;AAAA,OAAA,EAC/B;AAAA;AAAA,GACF;AAEJ;AAEA,MAAM,SAAA,GAAY,MAAA,CAAO,GAAA,EAAK,CAAC,QAAQ,CAAC,CAAA;AAAA,EACtC,CAAC,EAAE,KAAA,EAAO,MAAA,EAAO,MAAwC;AAAA,IACvD,OAAA,EAAS,aAAA;AAAA,IACT,UAAA,EAAY,QAAA;AAAA,IACZ,GAAA,EAAK,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AAAA,IACtB,OAAA,EAAS,KAAA,CAAM,OAAA,CAAQ,IAAA,EAAM,IAAI,CAAA;AAAA,IACjC,YAAA,EAAc,CAAA;AAAA,IACd,UAAA,EAAY,CAAA;AAAA,IACZ,eAAA,EAAiB,MAAA,GACb,KAAA,CAAM,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,IAAA,EAAM,IAAI,CAAA,GACtC,KAAA,CAAM,OAAA,CAAQ,UAAA,CAAW,KAAA;AAAA,IAC7B,KAAA,EAAO,SAAS,KAAA,CAAM,OAAA,CAAQ,QAAQ,IAAA,GAAO,KAAA,CAAM,QAAQ,IAAA,CAAK,SAAA;AAAA,IAChE,MAAA,EAAQ,CAAA,UAAA,EACN,MAAA,GAAS,KAAA,CAAM,KAAA,CAAM,OAAA,CAAQ,OAAA,CAAQ,IAAA,EAAM,GAAG,CAAA,GAAI,KAAA,CAAM,OAAA,CAAQ,OAClE,CAAA;AAAA,GACF;AACF,CAAA;AAEA,MAAM,UAAA,GAAa,MAAA,CAAO,QAAQ,CAAA,CAAE;AAAA,EAClC,QAAA,EAAU;AACZ,CAAC,CAAA;AAED,MAAM,cAAc,MAAA,CAAO,MAAM,EAAE,CAAC,EAAE,OAAM,MAAuB;AAAA,EACjE,QAAA,EAAU,KAAA,CAAM,UAAA,CAAW,OAAA,CAAQ,EAAE,CAAA;AAAA,EACrC,UAAA,EAAY,GAAA;AAAA,EACZ,KAAA,EAAO,SAAA;AAAA,EACP,UAAA,EAAY,CAAA;AAAA,EACZ,UAAA,EAAY,MAAM,UAAA,CAAW;AAC/B,CAAA,CAAE,CAAA;;;;"}
@@ -0,0 +1,56 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { col } from '@massdriver/ui/DataList';
3
+ import DeleteOutlineIcon from '@massdriver/ui/icons/DeleteOutlineIcon';
4
+ import { ConditionsCell } from './ConditionsCell.esm.js';
5
+
6
+ const dateFormatter = new Intl.DateTimeFormat(void 0, {
7
+ year: "numeric",
8
+ month: "short",
9
+ day: "numeric",
10
+ timeZone: "UTC"
11
+ });
12
+ const formatGrantCreatedAt = (value) => {
13
+ if (!value) return "--";
14
+ const date = new Date(value);
15
+ return Number.isNaN(date.getTime()) ? "--" : dateFormatter.format(date);
16
+ };
17
+ const mapGrantToRow = (grant) => ({
18
+ id: grant.id,
19
+ action: grant.action,
20
+ recipientConditions: grant.recipientConditions,
21
+ createdAt: formatGrantCreatedAt(grant.createdAt)
22
+ });
23
+ const renderRecipientsCell = (_value, row) => /* @__PURE__ */ jsx(ConditionsCell, { conditions: row.recipientConditions });
24
+ const buildGrantColumns = ({
25
+ manageUrl
26
+ }) => [
27
+ col.text("action", "Action", {
28
+ flex: 1,
29
+ minWidth: 140,
30
+ sortable: false
31
+ }),
32
+ col.custom("recipientConditions", "Recipients", renderRecipientsCell, {
33
+ flex: 3,
34
+ minWidth: 240,
35
+ sortable: false,
36
+ searchable: false
37
+ }),
38
+ col.text("createdAt", "Created", {
39
+ flex: 1,
40
+ minWidth: 140,
41
+ sortable: false
42
+ }),
43
+ col.actions([
44
+ {
45
+ icon: /* @__PURE__ */ jsx(DeleteOutlineIcon, { fontSize: "small" }),
46
+ tooltip: "Remove in Massdriver",
47
+ href: () => manageUrl,
48
+ target: "_blank",
49
+ rel: "noopener noreferrer",
50
+ color: "error"
51
+ }
52
+ ])
53
+ ];
54
+
55
+ export { buildGrantColumns, formatGrantCreatedAt, mapGrantToRow };
56
+ //# sourceMappingURL=grantColumns.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grantColumns.esm.js","sources":["../../src/components/grantColumns.tsx"],"sourcesContent":["import { col } from '@massdriver/ui/DataList';\nimport DeleteOutlineIcon from '@massdriver/ui/icons/DeleteOutlineIcon';\nimport { ConditionsCell } from './ConditionsCell';\n\n// Ported from apps/web/shared/grants/permissionColumns.js. The web app's\n// Remove action mutates, so here it deep-links out to the entity's Permissions\n// tab in the Massdriver web app instead (read-only parity: clear mutation\n// buttons link out rather than rendering disabled).\n\nconst dateFormatter = new Intl.DateTimeFormat(undefined, {\n year: 'numeric',\n month: 'short',\n day: 'numeric',\n timeZone: 'UTC',\n});\n\nexport const formatGrantCreatedAt = (value: string | null | undefined) => {\n if (!value) return '--';\n const date = new Date(value);\n return Number.isNaN(date.getTime()) ? '--' : dateFormatter.format(date);\n};\n\n/** A grant as returned by the API's `grants { items }` selections. */\nexport interface Grant {\n id: string;\n action: string;\n recipientConditions?: unknown;\n createdAt?: string | null;\n}\n\nexport interface GrantRow {\n id: string;\n action: string;\n recipientConditions?: unknown;\n createdAt: string;\n}\n\nexport const mapGrantToRow = (grant: Grant): GrantRow => ({\n id: grant.id,\n action: grant.action,\n recipientConditions: grant.recipientConditions,\n createdAt: formatGrantCreatedAt(grant.createdAt),\n});\n\nconst renderRecipientsCell = (_value: unknown, row: GrantRow) => (\n <ConditionsCell conditions={row.recipientConditions} />\n);\n\nexport const buildGrantColumns = ({\n manageUrl,\n}: {\n /** Web-app URL of the entity's Permissions tab, where grants are removed. */\n manageUrl: string;\n}) => [\n col.text('action', 'Action', {\n flex: 1,\n minWidth: 140,\n sortable: false,\n }),\n col.custom('recipientConditions', 'Recipients', renderRecipientsCell, {\n flex: 3,\n minWidth: 240,\n sortable: false,\n searchable: false,\n }),\n col.text('createdAt', 'Created', {\n flex: 1,\n minWidth: 140,\n sortable: false,\n }),\n col.actions([\n {\n icon: <DeleteOutlineIcon fontSize=\"small\" />,\n tooltip: 'Remove in Massdriver',\n href: () => manageUrl,\n target: '_blank',\n rel: 'noopener noreferrer',\n color: 'error',\n },\n ]),\n];\n"],"names":[],"mappings":";;;;;AASA,MAAM,aAAA,GAAgB,IAAI,IAAA,CAAK,cAAA,CAAe,MAAA,EAAW;AAAA,EACvD,IAAA,EAAM,SAAA;AAAA,EACN,KAAA,EAAO,OAAA;AAAA,EACP,GAAA,EAAK,SAAA;AAAA,EACL,QAAA,EAAU;AACZ,CAAC,CAAA;AAEM,MAAM,oBAAA,GAAuB,CAAC,KAAA,KAAqC;AACxE,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,KAAK,CAAA;AAC3B,EAAA,OAAO,MAAA,CAAO,MAAM,IAAA,CAAK,OAAA,EAAS,CAAA,GAAI,IAAA,GAAO,aAAA,CAAc,MAAA,CAAO,IAAI,CAAA;AACxE;AAiBO,MAAM,aAAA,GAAgB,CAAC,KAAA,MAA4B;AAAA,EACxD,IAAI,KAAA,CAAM,EAAA;AAAA,EACV,QAAQ,KAAA,CAAM,MAAA;AAAA,EACd,qBAAqB,KAAA,CAAM,mBAAA;AAAA,EAC3B,SAAA,EAAW,oBAAA,CAAqB,KAAA,CAAM,SAAS;AACjD,CAAA;AAEA,MAAM,oBAAA,GAAuB,CAAC,MAAA,EAAiB,GAAA,yBAC5C,cAAA,EAAA,EAAe,UAAA,EAAY,IAAI,mBAAA,EAAqB,CAAA;AAGhD,MAAM,oBAAoB,CAAC;AAAA,EAChC;AACF,CAAA,KAGM;AAAA,EACJ,GAAA,CAAI,IAAA,CAAK,QAAA,EAAU,QAAA,EAAU;AAAA,IAC3B,IAAA,EAAM,CAAA;AAAA,IACN,QAAA,EAAU,GAAA;AAAA,IACV,QAAA,EAAU;AAAA,GACX,CAAA;AAAA,EACD,GAAA,CAAI,MAAA,CAAO,qBAAA,EAAuB,YAAA,EAAc,oBAAA,EAAsB;AAAA,IACpE,IAAA,EAAM,CAAA;AAAA,IACN,QAAA,EAAU,GAAA;AAAA,IACV,QAAA,EAAU,KAAA;AAAA,IACV,UAAA,EAAY;AAAA,GACb,CAAA;AAAA,EACD,GAAA,CAAI,IAAA,CAAK,WAAA,EAAa,SAAA,EAAW;AAAA,IAC/B,IAAA,EAAM,CAAA;AAAA,IACN,QAAA,EAAU,GAAA;AAAA,IACV,QAAA,EAAU;AAAA,GACX,CAAA;AAAA,EACD,IAAI,OAAA,CAAQ;AAAA,IACV;AAAA,MACE,IAAA,kBAAM,GAAA,CAAC,iBAAA,EAAA,EAAkB,QAAA,EAAS,OAAA,EAAQ,CAAA;AAAA,MAC1C,OAAA,EAAS,sBAAA;AAAA,MACT,MAAM,MAAM,SAAA;AAAA,MACZ,MAAA,EAAQ,QAAA;AAAA,MACR,GAAA,EAAK,qBAAA;AAAA,MACL,KAAA,EAAO;AAAA;AACT,GACD;AACH;;;;"}
@@ -0,0 +1,7 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import SvgIcon from '@material-ui/core/SvgIcon';
3
+
4
+ const BundleIcon = (props) => /* @__PURE__ */ jsx(SvgIcon, { viewBox: "0 0 24 24", ...props, children: /* @__PURE__ */ jsx("path", { d: "M18.961 6.828l-6.961 4.027-6.961-4.027 6.456-3.689c0.112-0.064 0.232-0.105 0.355-0.124 0.218-0.034 0.445 0.003 0.654 0.124zM11.526 22.961c0.141 0.076 0.303 0.119 0.474 0.119 0.173 0 0.336-0.044 0.478-0.121 0.356-0.058 0.701-0.18 1.017-0.36l7.001-4.001c0.618-0.357 1.060-0.897 1.299-1.514 0.133-0.342 0.202-0.707 0.205-1.084v-8c0-0.478-0.113-0.931-0.314-1.334-0.022-0.071-0.052-0.14-0.091-0.207-0.046-0.079-0.1-0.149-0.162-0.21-0.031-0.043-0.064-0.086-0.097-0.127-0.23-0.286-0.512-0.528-0.831-0.715l-7.009-4.005c-0.61-0.352-1.3-0.465-1.954-0.364-0.363 0.057-0.715 0.179-1.037 0.363l-7.001 4.001c-0.383 0.221-0.699 0.513-0.941 0.85-0.060 0.060-0.114 0.13-0.159 0.207-0.039 0.068-0.070 0.138-0.092 0.21-0.040 0.080-0.076 0.163-0.108 0.246-0.132 0.343-0.201 0.708-0.204 1.078v8.007c0.001 0.71 0.248 1.363 0.664 1.878 0.23 0.286 0.512 0.528 0.831 0.715l7.009 4.005c0.324 0.187 0.67 0.307 1.022 0.362zM11 12.587v7.991l-6.495-3.711c-0.111-0.065-0.207-0.148-0.285-0.245-0.139-0.172-0.22-0.386-0.22-0.622v-7.462zM13 20.578v-7.991l7-4.049v7.462c-0.001 0.121-0.025 0.246-0.070 0.362-0.080 0.206-0.225 0.384-0.426 0.5z" }) });
5
+
6
+ export { BundleIcon };
7
+ //# sourceMappingURL=BundleIcon.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"BundleIcon.esm.js","sources":["../../../src/components/icons/BundleIcon.tsx"],"sourcesContent":["import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';\n\n// Local copy of @massdriver/ui/icons/BundleIcon rendered with MUI v4 SvgIcon.\n// This icon is reachable from the package root (via MassdriverSidebarItem),\n// which Backstage `require()`s eagerly at app boot — importing it from\n// `@massdriver/ui` would pull the whole `@mui/material` barrel into the boot\n// graph and freeze v5 class-name constants before Backstage configures its\n// `v5-` prefix (see .claude/rules/styling-and-theme.md).\nexport const BundleIcon = (props: SvgIconProps) => (\n <SvgIcon viewBox=\"0 0 24 24\" {...props}>\n <path d=\"M18.961 6.828l-6.961 4.027-6.961-4.027 6.456-3.689c0.112-0.064 0.232-0.105 0.355-0.124 0.218-0.034 0.445 0.003 0.654 0.124zM11.526 22.961c0.141 0.076 0.303 0.119 0.474 0.119 0.173 0 0.336-0.044 0.478-0.121 0.356-0.058 0.701-0.18 1.017-0.36l7.001-4.001c0.618-0.357 1.060-0.897 1.299-1.514 0.133-0.342 0.202-0.707 0.205-1.084v-8c0-0.478-0.113-0.931-0.314-1.334-0.022-0.071-0.052-0.14-0.091-0.207-0.046-0.079-0.1-0.149-0.162-0.21-0.031-0.043-0.064-0.086-0.097-0.127-0.23-0.286-0.512-0.528-0.831-0.715l-7.009-4.005c-0.61-0.352-1.3-0.465-1.954-0.364-0.363 0.057-0.715 0.179-1.037 0.363l-7.001 4.001c-0.383 0.221-0.699 0.513-0.941 0.85-0.060 0.060-0.114 0.13-0.159 0.207-0.039 0.068-0.070 0.138-0.092 0.21-0.040 0.080-0.076 0.163-0.108 0.246-0.132 0.343-0.201 0.708-0.204 1.078v8.007c0.001 0.71 0.248 1.363 0.664 1.878 0.23 0.286 0.512 0.528 0.831 0.715l7.009 4.005c0.324 0.187 0.67 0.307 1.022 0.362zM11 12.587v7.991l-6.495-3.711c-0.111-0.065-0.207-0.148-0.285-0.245-0.139-0.172-0.22-0.386-0.22-0.622v-7.462zM13 20.578v-7.991l7-4.049v7.462c-0.001 0.121-0.025 0.246-0.070 0.362-0.080 0.206-0.225 0.384-0.426 0.5z\" />\n </SvgIcon>\n);\n"],"names":[],"mappings":";;;AAQO,MAAM,UAAA,GAAa,CAAC,KAAA,qBACzB,GAAA,CAAC,OAAA,EAAA,EAAQ,OAAA,EAAQ,WAAA,EAAa,GAAG,KAAA,EAC/B,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,slCAAqlC,CAAA,EAC/lC;;;;"}
@@ -0,0 +1,7 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import SvgIcon from '@material-ui/core/SvgIcon';
3
+
4
+ const FolderOutlinedIcon = (props) => /* @__PURE__ */ jsx(SvgIcon, { viewBox: "0 0 24 24", ...props, children: /* @__PURE__ */ jsx("path", { d: "m9.17 6 2 2H20v10H4V6zM10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8z" }) });
5
+
6
+ export { FolderOutlinedIcon };
7
+ //# sourceMappingURL=FolderOutlinedIcon.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FolderOutlinedIcon.esm.js","sources":["../../../src/components/icons/FolderOutlinedIcon.tsx"],"sourcesContent":["import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';\n\n// Local copy of @mui/icons-material FolderOutlined (what\n// @massdriver/ui/icons/FolderOutlinedIcon re-exports), rendered with MUI v4\n// SvgIcon so the eagerly-required package root never evaluates @mui/material.\n// See BundleIcon.tsx for the full rationale.\nexport const FolderOutlinedIcon = (props: SvgIconProps) => (\n <SvgIcon viewBox=\"0 0 24 24\" {...props}>\n <path d=\"m9.17 6 2 2H20v10H4V6zM10 4H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2h-8z\" />\n </SvgIcon>\n);\n"],"names":[],"mappings":";;;AAMO,MAAM,kBAAA,GAAqB,CAAC,KAAA,qBACjC,GAAA,CAAC,OAAA,EAAA,EAAQ,OAAA,EAAQ,WAAA,EAAa,GAAG,KAAA,EAC/B,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,gHAA+G,CAAA,EACzH;;;;"}
@@ -0,0 +1,7 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import SvgIcon from '@material-ui/core/SvgIcon';
3
+
4
+ const TokenIcon = (props) => /* @__PURE__ */ jsx(SvgIcon, { viewBox: "0 0 24 24", ...props, children: /* @__PURE__ */ jsx("path", { d: "M19.97 6.43 12 2 4.03 6.43 9.1 9.24C9.83 8.48 10.86 8 12 8s2.17.48 2.9 1.24zM10 12c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2m1 9.44L3 17V8.14l5.13 2.85c-.09.32-.13.66-.13 1.01 0 1.86 1.27 3.43 3 3.87zm2 0v-5.57c1.73-.44 3-2.01 3-3.87 0-.35-.04-.69-.13-1.01L21 8.14V17z" }) });
5
+
6
+ export { TokenIcon };
7
+ //# sourceMappingURL=TokenIcon.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TokenIcon.esm.js","sources":["../../../src/components/icons/TokenIcon.tsx"],"sourcesContent":["import SvgIcon, { SvgIconProps } from '@material-ui/core/SvgIcon';\n\n// Local copy of @mui/icons-material Token (what @massdriver/ui/icons/TokenIcon\n// re-exports), rendered with MUI v4 SvgIcon so the eagerly-required package\n// root never evaluates @mui/material. See BundleIcon.tsx for the full\n// rationale.\nexport const TokenIcon = (props: SvgIconProps) => (\n <SvgIcon viewBox=\"0 0 24 24\" {...props}>\n <path d=\"M19.97 6.43 12 2 4.03 6.43 9.1 9.24C9.83 8.48 10.86 8 12 8s2.17.48 2.9 1.24zM10 12c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2m1 9.44L3 17V8.14l5.13 2.85c-.09.32-.13.66-.13 1.01 0 1.86 1.27 3.43 3 3.87zm2 0v-5.57c1.73-.44 3-2.01 3-3.87 0-.35-.04-.69-.13-1.01L21 8.14V17z\" />\n </SvgIcon>\n);\n"],"names":[],"mappings":";;;AAMO,MAAM,SAAA,GAAY,CAAC,KAAA,qBACxB,GAAA,CAAC,OAAA,EAAA,EAAQ,OAAA,EAAQ,WAAA,EAAa,GAAG,KAAA,EAC/B,QAAA,kBAAA,GAAA,CAAC,MAAA,EAAA,EAAK,CAAA,EAAE,+QAA8Q,CAAA,EACxR;;;;"}
@@ -0,0 +1,23 @@
1
+ import { ANNOTATION_INSTANCE_ID, ANNOTATION_ORG_ID, ANNOTATION_ENVIRONMENT_ID, ANNOTATION_PROJECT_ID } from '@massdriver/backstage-plugin-common';
2
+
3
+ const annotation = (entity, key) => entity.metadata.annotations?.[key];
4
+ const getMassdriverScope = (entity) => {
5
+ const orgId = annotation(entity, ANNOTATION_ORG_ID);
6
+ const instanceId = annotation(entity, ANNOTATION_INSTANCE_ID);
7
+ if (instanceId) {
8
+ return { kind: "instance", instanceId, orgId };
9
+ }
10
+ const environmentId = annotation(entity, ANNOTATION_ENVIRONMENT_ID);
11
+ if (environmentId) {
12
+ return { kind: "environment", environmentId, orgId };
13
+ }
14
+ const projectId = annotation(entity, ANNOTATION_PROJECT_ID);
15
+ if (projectId) {
16
+ return { kind: "project", projectId, orgId };
17
+ }
18
+ return void 0;
19
+ };
20
+ const isMassdriverEntity = (entity) => Boolean(getMassdriverScope(entity));
21
+
22
+ export { getMassdriverScope, isMassdriverEntity };
23
+ //# sourceMappingURL=entity.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity.esm.js","sources":["../src/entity.ts"],"sourcesContent":["import { Entity } from '@backstage/catalog-model';\nimport {\n ANNOTATION_ENVIRONMENT_ID,\n ANNOTATION_INSTANCE_ID,\n ANNOTATION_ORG_ID,\n ANNOTATION_PROJECT_ID,\n} from '@massdriver/backstage-plugin-common';\n\n/** The Massdriver resource an entity maps to. */\nexport type MassdriverScope =\n | { kind: 'project'; projectId: string; orgId?: string }\n | { kind: 'environment'; environmentId: string; orgId?: string }\n | { kind: 'instance'; instanceId: string; orgId?: string };\n\nconst annotation = (entity: Entity, key: string): string | undefined =>\n entity.metadata.annotations?.[key];\n\n/**\n * Resolve which Massdriver resource an entity represents from its annotations.\n * Instance is most specific, then environment, then project.\n */\nexport const getMassdriverScope = (\n entity: Entity,\n): MassdriverScope | undefined => {\n const orgId = annotation(entity, ANNOTATION_ORG_ID);\n const instanceId = annotation(entity, ANNOTATION_INSTANCE_ID);\n if (instanceId) {\n return { kind: 'instance', instanceId, orgId };\n }\n const environmentId = annotation(entity, ANNOTATION_ENVIRONMENT_ID);\n if (environmentId) {\n return { kind: 'environment', environmentId, orgId };\n }\n const projectId = annotation(entity, ANNOTATION_PROJECT_ID);\n if (projectId) {\n return { kind: 'project', projectId, orgId };\n }\n return undefined;\n};\n\n/** True when the entity carries any Massdriver annotation. */\nexport const isMassdriverEntity = (entity: Entity): boolean =>\n Boolean(getMassdriverScope(entity));\n"],"names":[],"mappings":";;AAcA,MAAM,aAAa,CAAC,MAAA,EAAgB,QAClC,MAAA,CAAO,QAAA,CAAS,cAAc,GAAG,CAAA;AAM5B,MAAM,kBAAA,GAAqB,CAChC,MAAA,KACgC;AAChC,EAAA,MAAM,KAAA,GAAQ,UAAA,CAAW,MAAA,EAAQ,iBAAiB,CAAA;AAClD,EAAA,MAAM,UAAA,GAAa,UAAA,CAAW,MAAA,EAAQ,sBAAsB,CAAA;AAC5D,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,OAAO,EAAE,IAAA,EAAM,UAAA,EAAY,UAAA,EAAY,KAAA,EAAM;AAAA,EAC/C;AACA,EAAA,MAAM,aAAA,GAAgB,UAAA,CAAW,MAAA,EAAQ,yBAAyB,CAAA;AAClE,EAAA,IAAI,aAAA,EAAe;AACjB,IAAA,OAAO,EAAE,IAAA,EAAM,aAAA,EAAe,aAAA,EAAe,KAAA,EAAM;AAAA,EACrD;AACA,EAAA,MAAM,SAAA,GAAY,UAAA,CAAW,MAAA,EAAQ,qBAAqB,CAAA;AAC1D,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,OAAO,EAAE,IAAA,EAAM,SAAA,EAAW,SAAA,EAAW,KAAA,EAAM;AAAA,EAC7C;AACA,EAAA,OAAO,MAAA;AACT;AAGO,MAAM,qBAAqB,CAAC,MAAA,KACjC,OAAA,CAAQ,kBAAA,CAAmB,MAAM,CAAC;;;;"}
@@ -0,0 +1,115 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { useState, useEffect, useMemo } from 'react';
3
+ import { useApi } from '@backstage/frontend-plugin-api';
4
+ import useAsync from 'react-use/esm/useAsync';
5
+ import { Dialog, DialogTitle, DialogActions, DialogContent } from '@massdriver/ui/Dialog';
6
+ import Box from '@massdriver/ui/Box';
7
+ import Button from '@massdriver/ui/Button';
8
+ import Alert from '@massdriver/ui/Alert';
9
+ import LoadingIndicator from '@massdriver/ui/LoadingIndicator';
10
+ import stylin from '@massdriver/ui/stylin';
11
+ import { massdriverApiRef } from '../../../api.esm.js';
12
+ import { SelectStep } from './SelectStep.esm.js';
13
+ import { ResultsStep } from './ResultsStep.esm.js';
14
+ import flattenDeploymentComparison from './flattenDeploymentComparison.esm.js';
15
+ import { DEPLOYMENTS_BY_INSTANCE_QUERY, COMPARE_DEPLOYMENTS_QUERY } from './queries.esm.js';
16
+
17
+ const CompareDeploymentsDialog = ({
18
+ open,
19
+ onClose,
20
+ instanceId
21
+ }) => {
22
+ const api = useApi(massdriverApiRef);
23
+ const [step, setStep] = useState("select");
24
+ const [source, setSource] = useState(null);
25
+ const [target, setTarget] = useState(null);
26
+ useEffect(() => {
27
+ if (open) {
28
+ setSource(null);
29
+ setTarget(null);
30
+ setStep("select");
31
+ }
32
+ }, [open]);
33
+ const deploymentsAsync = useAsync(async () => {
34
+ if (!open || !instanceId) return [];
35
+ const data = await api.query(DEPLOYMENTS_BY_INSTANCE_QUERY, {
36
+ filter: { instanceId: { eq: instanceId } }
37
+ });
38
+ return (data.deployments?.items ?? []).filter(Boolean);
39
+ }, [api, open, instanceId]);
40
+ const deployments = useMemo(
41
+ () => deploymentsAsync.value ?? [],
42
+ [deploymentsAsync.value]
43
+ );
44
+ const positionMap = useMemo(() => {
45
+ const ascending = [...deployments].sort(
46
+ (left, right) => String(left.createdAt ?? "").localeCompare(String(right.createdAt ?? ""))
47
+ );
48
+ const map = /* @__PURE__ */ new Map();
49
+ ascending.forEach((deployment, index) => map.set(deployment.id, index + 1));
50
+ return map;
51
+ }, [deployments]);
52
+ const runCompare = step === "results" && Boolean(source) && Boolean(target);
53
+ const compareAsync = useAsync(async () => {
54
+ if (!runCompare) return null;
55
+ const data = await api.query(COMPARE_DEPLOYMENTS_QUERY, {
56
+ sourceId: source.id,
57
+ targetId: target.id
58
+ });
59
+ return data.compareDeployments;
60
+ }, [api, runCompare, source?.id, target?.id]);
61
+ const rows = useMemo(
62
+ () => flattenDeploymentComparison(compareAsync.value),
63
+ [compareAsync.value]
64
+ );
65
+ const handleCompare = () => {
66
+ if (!source || !target || source.id === target.id) return;
67
+ setStep("results");
68
+ };
69
+ const handleSwap = () => {
70
+ setSource(target);
71
+ setTarget(source);
72
+ };
73
+ return /* @__PURE__ */ jsxs(Dialog, { open, onClose, maxWidth: "lg", fullWidth: true, children: [
74
+ /* @__PURE__ */ jsx(DialogTitle, { children: "Compare Deployments" }),
75
+ /* @__PURE__ */ jsx(Body, { children: runCompare ? compareAsync.loading ? /* @__PURE__ */ jsx(Centered, { children: /* @__PURE__ */ jsx(LoadingIndicator, {}) }) : compareAsync.error ? /* @__PURE__ */ jsx(Centered, { children: /* @__PURE__ */ jsx(Alert, { severity: "error", children: String(compareAsync.error.message ?? compareAsync.error) }) }) : /* @__PURE__ */ jsx(
76
+ ResultsStep,
77
+ {
78
+ rows,
79
+ source,
80
+ target,
81
+ sourcePosition: positionMap.get(source.id),
82
+ targetPosition: positionMap.get(target.id),
83
+ onChangeSelection: () => setStep("select")
84
+ }
85
+ ) : deploymentsAsync.loading ? /* @__PURE__ */ jsx(Centered, { children: /* @__PURE__ */ jsx(LoadingIndicator, {}) }) : deploymentsAsync.error ? /* @__PURE__ */ jsx(Centered, { children: /* @__PURE__ */ jsx(Alert, { severity: "error", children: String(deploymentsAsync.error.message ?? deploymentsAsync.error) }) }) : /* @__PURE__ */ jsx(
86
+ SelectStep,
87
+ {
88
+ source,
89
+ target,
90
+ deployments,
91
+ positionMap,
92
+ onSourceChange: setSource,
93
+ onTargetChange: setTarget,
94
+ onSwap: handleSwap,
95
+ onCompare: handleCompare
96
+ }
97
+ ) }),
98
+ /* @__PURE__ */ jsx(DialogActions, { children: /* @__PURE__ */ jsx(Button, { variant: "text", onClick: onClose, children: "Close" }) })
99
+ ] });
100
+ };
101
+ const Body = stylin(DialogContent)(({ theme }) => ({
102
+ display: "flex",
103
+ flexDirection: "column",
104
+ minHeight: theme.spacing(60)
105
+ }));
106
+ const Centered = stylin(Box)(({ theme }) => ({
107
+ flex: 1,
108
+ display: "flex",
109
+ alignItems: "center",
110
+ justifyContent: "center",
111
+ padding: theme.spacing(6)
112
+ }));
113
+
114
+ export { CompareDeploymentsDialog, CompareDeploymentsDialog as default };
115
+ //# sourceMappingURL=CompareDeploymentsDialog.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CompareDeploymentsDialog.esm.js","sources":["../../../../src/features/environment/CompareDeploymentsDialog/CompareDeploymentsDialog.tsx"],"sourcesContent":["import { useEffect, useMemo, useState } from 'react';\nimport { useApi } from '@backstage/frontend-plugin-api';\nimport useAsync from 'react-use/esm/useAsync';\nimport {\n Dialog,\n DialogActions,\n DialogContent,\n DialogTitle,\n} from '@massdriver/ui/Dialog';\nimport Box from '@massdriver/ui/Box';\nimport Button from '@massdriver/ui/Button';\nimport Alert from '@massdriver/ui/Alert';\nimport LoadingIndicator from '@massdriver/ui/LoadingIndicator';\nimport stylin from '@massdriver/ui/stylin';\nimport { massdriverApiRef } from '../../../api';\nimport SelectStep from './SelectStep';\nimport ResultsStep from './ResultsStep';\nimport flattenDeploymentComparison from './flattenDeploymentComparison';\nimport {\n COMPARE_DEPLOYMENTS_QUERY,\n DEPLOYMENTS_BY_INSTANCE_QUERY,\n type CompareDeploymentsResult,\n} from './queries';\nimport type { Deployment } from '../InstanceDrawer/types';\n\n/**\n * Read-only deployment comparison dialog. Two steps: pick source + target\n * (SelectStep), then view the flattened param/version diff (ResultsStep). No\n * mutations — the web app's URL-param + infinite-scroll pickers are replaced\n * with local `useState` and a capped, in-memory deployment list.\n */\nexport const CompareDeploymentsDialog = ({\n open,\n onClose,\n instanceId,\n}: {\n open: boolean;\n onClose: () => void;\n instanceId: string | null;\n}) => {\n const api = useApi(massdriverApiRef);\n const [step, setStep] = useState<'select' | 'results'>('select');\n const [source, setSource] = useState<Deployment | null>(null);\n const [target, setTarget] = useState<Deployment | null>(null);\n\n useEffect(() => {\n if (open) {\n setSource(null);\n setTarget(null);\n setStep('select');\n }\n }, [open]);\n\n const deploymentsAsync = useAsync(async () => {\n if (!open || !instanceId) return [] as Deployment[];\n const data = (await api.query(DEPLOYMENTS_BY_INSTANCE_QUERY, {\n filter: { instanceId: { eq: instanceId } },\n })) as { deployments: { items?: (Deployment | null)[] | null } | null };\n return (data.deployments?.items ?? []).filter(Boolean) as Deployment[];\n }, [api, open, instanceId]);\n\n const deployments = useMemo(\n () => deploymentsAsync.value ?? [],\n [deploymentsAsync.value],\n );\n\n // Position numbers run oldest → newest (oldest = 1), independent of the list's\n // display order, so \"#N\" stays stable regardless of sort.\n const positionMap = useMemo(() => {\n const ascending = [...deployments].sort((left, right) =>\n String(left.createdAt ?? '').localeCompare(String(right.createdAt ?? '')),\n );\n const map = new Map<string, number>();\n ascending.forEach((deployment, index) => map.set(deployment.id, index + 1));\n return map;\n }, [deployments]);\n\n const runCompare = step === 'results' && Boolean(source) && Boolean(target);\n\n const compareAsync = useAsync(async () => {\n if (!runCompare) return null;\n const data = (await api.query(COMPARE_DEPLOYMENTS_QUERY, {\n sourceId: source!.id,\n targetId: target!.id,\n })) as CompareDeploymentsResult;\n return data.compareDeployments;\n }, [api, runCompare, source?.id, target?.id]);\n\n const rows = useMemo(\n () => flattenDeploymentComparison(compareAsync.value),\n [compareAsync.value],\n );\n\n const handleCompare = () => {\n if (!source || !target || source.id === target.id) return;\n setStep('results');\n };\n\n const handleSwap = () => {\n setSource(target);\n setTarget(source);\n };\n\n return (\n <Dialog open={open} onClose={onClose} maxWidth=\"lg\" fullWidth>\n <DialogTitle>Compare Deployments</DialogTitle>\n <Body>\n {runCompare ? (\n compareAsync.loading ? (\n <Centered>\n <LoadingIndicator />\n </Centered>\n ) : compareAsync.error ? (\n <Centered>\n <Alert severity=\"error\">\n {String(compareAsync.error.message ?? compareAsync.error)}\n </Alert>\n </Centered>\n ) : (\n <ResultsStep\n rows={rows}\n source={source}\n target={target}\n sourcePosition={positionMap.get(source!.id)}\n targetPosition={positionMap.get(target!.id)}\n onChangeSelection={() => setStep('select')}\n />\n )\n ) : deploymentsAsync.loading ? (\n <Centered>\n <LoadingIndicator />\n </Centered>\n ) : deploymentsAsync.error ? (\n <Centered>\n <Alert severity=\"error\">\n {String(deploymentsAsync.error.message ?? deploymentsAsync.error)}\n </Alert>\n </Centered>\n ) : (\n <SelectStep\n source={source}\n target={target}\n deployments={deployments}\n positionMap={positionMap}\n onSourceChange={setSource}\n onTargetChange={setTarget}\n onSwap={handleSwap}\n onCompare={handleCompare}\n />\n )}\n </Body>\n <DialogActions>\n <Button variant=\"text\" onClick={onClose}>\n Close\n </Button>\n </DialogActions>\n </Dialog>\n );\n};\n\nexport default CompareDeploymentsDialog;\n\nconst Body = stylin(DialogContent)(({ theme }: { theme: any }) => ({\n display: 'flex',\n flexDirection: 'column',\n minHeight: theme.spacing(60),\n}));\n\nconst Centered = stylin(Box)(({ theme }: { theme: any }) => ({\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n padding: theme.spacing(6),\n}));\n"],"names":[],"mappings":"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"}
@@ -0,0 +1,165 @@
1
+ import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
2
+ import { useState, useMemo } from 'react';
3
+ import Box from '@massdriver/ui/Box';
4
+ import Typography from '@massdriver/ui/Typography';
5
+ import Switch from '@massdriver/ui/Switch';
6
+ import Alert from '@massdriver/ui/Alert';
7
+ import Button from '@massdriver/ui/Button';
8
+ import DataList from '@massdriver/ui/DataList';
9
+ import stylin from '@massdriver/ui/stylin';
10
+ import ChevronLeftIcon from '@massdriver/ui/icons/ChevronLeftIcon';
11
+ import { buildCompareColumns } from './compareColumns.esm.js';
12
+ import { truncateDeploymentId } from '../InstanceDrawer/helpers.esm.js';
13
+
14
+ const labelFor = (deployment, position) => {
15
+ if (!deployment) return "";
16
+ const id = truncateDeploymentId(deployment.id);
17
+ return position != null ? `#${position} \xB7 ${id}` : id;
18
+ };
19
+ const ResultsStep = ({
20
+ rows,
21
+ source,
22
+ target,
23
+ sourcePosition,
24
+ targetPosition,
25
+ onChangeSelection
26
+ }) => {
27
+ const [hideEqual, setHideEqual] = useState(true);
28
+ const filteredRows = useMemo(
29
+ () => hideEqual ? rows.filter((row) => row.status !== "equal") : rows,
30
+ [rows, hideEqual]
31
+ );
32
+ const columns = useMemo(
33
+ () => buildCompareColumns({
34
+ leftLabel: labelFor(source, sourcePosition),
35
+ rightLabel: labelFor(target, targetPosition)
36
+ }),
37
+ [source, target, sourcePosition, targetPosition]
38
+ );
39
+ const differingCount = useMemo(
40
+ () => rows.filter((row) => row.status !== "equal").length,
41
+ [rows]
42
+ );
43
+ const allEqual = rows.length > 0 && differingCount === 0;
44
+ return /* @__PURE__ */ jsxs(Root, { children: [
45
+ /* @__PURE__ */ jsxs(HeaderBar, { children: [
46
+ /* @__PURE__ */ jsx(
47
+ BackButton,
48
+ {
49
+ variant: "text",
50
+ size: "small",
51
+ startIcon: /* @__PURE__ */ jsx(ChevronLeftIcon, {}),
52
+ onClick: onChangeSelection,
53
+ children: "Change selection"
54
+ }
55
+ ),
56
+ /* @__PURE__ */ jsxs(Title, { children: [
57
+ /* @__PURE__ */ jsx(DeploymentLabel, { children: labelFor(source, sourcePosition) }),
58
+ /* @__PURE__ */ jsx(ArrowText, { children: "\u2194" }),
59
+ /* @__PURE__ */ jsx(DeploymentLabel, { children: labelFor(target, targetPosition) })
60
+ ] }),
61
+ /* @__PURE__ */ jsx(HeaderSpacer, {})
62
+ ] }),
63
+ /* @__PURE__ */ jsxs(SummaryRow, { children: [
64
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: allEqual ? "No differences." : /* @__PURE__ */ jsxs(Fragment, { children: [
65
+ /* @__PURE__ */ jsx(Strong, { children: differingCount }),
66
+ " ",
67
+ differingCount === 1 ? "difference" : "differences"
68
+ ] }) }),
69
+ /* @__PURE__ */ jsx(ToolbarActions, { children: /* @__PURE__ */ jsxs(SwitchLabel, { children: [
70
+ /* @__PURE__ */ jsx(
71
+ Switch,
72
+ {
73
+ size: "small",
74
+ checked: hideEqual,
75
+ onChange: (event) => setHideEqual(event.target.checked)
76
+ }
77
+ ),
78
+ /* @__PURE__ */ jsx(Typography, { variant: "body2", color: "text.secondary", children: "Hide identical" })
79
+ ] }) })
80
+ ] }),
81
+ allEqual ? /* @__PURE__ */ jsx(Alert, { severity: "success", variant: "outlined", children: "These deployments are identical." }) : null,
82
+ allEqual && hideEqual ? null : /* @__PURE__ */ jsx(
83
+ DataList,
84
+ {
85
+ rows: filteredRows,
86
+ columns,
87
+ searchable: true,
88
+ searchPlaceholder: "Search path\u2026",
89
+ defaultSort: { field: "path", direction: "asc" },
90
+ defaultPageSize: 20,
91
+ variant: "outlined",
92
+ size: "small",
93
+ emptyMessage: 'No fields match the current filters. Try clearing the search or toggling "Hide identical".'
94
+ }
95
+ )
96
+ ] });
97
+ };
98
+ const Root = stylin(Box)(({ theme }) => ({
99
+ display: "flex",
100
+ flexDirection: "column",
101
+ gap: theme.spacing(2),
102
+ flex: 1
103
+ }));
104
+ const HeaderBar = stylin(Box)(({ theme }) => ({
105
+ display: "flex",
106
+ alignItems: "center",
107
+ gap: theme.spacing(2),
108
+ paddingBottom: theme.spacing(1.5),
109
+ borderBottom: `1px solid ${theme.palette.divider}`
110
+ }));
111
+ const BackButton = stylin(Button)(({ theme }) => ({
112
+ color: theme.palette.text.secondary,
113
+ flexShrink: 0
114
+ }));
115
+ const Title = stylin(Box)(({ theme }) => ({
116
+ flex: 1,
117
+ display: "flex",
118
+ alignItems: "center",
119
+ justifyContent: "center",
120
+ gap: theme.spacing(1.5)
121
+ }));
122
+ const DeploymentLabel = stylin("span")(({ theme }) => ({
123
+ fontFamily: theme.typography.fontFamilyMono,
124
+ fontSize: theme.typography.h6.fontSize,
125
+ fontWeight: 600,
126
+ color: theme.palette.text.primary,
127
+ maxWidth: theme.spacing(40),
128
+ whiteSpace: "nowrap",
129
+ overflow: "hidden",
130
+ textOverflow: "ellipsis"
131
+ }));
132
+ const ArrowText = stylin("span")(({ theme }) => ({
133
+ color: theme.palette.text.disabled,
134
+ fontSize: theme.typography.h6.fontSize
135
+ }));
136
+ const HeaderSpacer = stylin(Box)(({ theme }) => ({
137
+ width: theme.spacing(20),
138
+ flexShrink: 0
139
+ }));
140
+ const SummaryRow = stylin(Box)(({ theme }) => ({
141
+ display: "flex",
142
+ alignItems: "center",
143
+ justifyContent: "space-between",
144
+ gap: theme.spacing(2),
145
+ flexWrap: "wrap"
146
+ }));
147
+ const Strong = stylin("span")(({ theme }) => ({
148
+ color: theme.palette.text.primary,
149
+ fontWeight: 600
150
+ }));
151
+ const ToolbarActions = stylin(Box)(({ theme }) => ({
152
+ display: "flex",
153
+ alignItems: "center",
154
+ gap: theme.spacing(1.5),
155
+ flexWrap: "wrap"
156
+ }));
157
+ const SwitchLabel = stylin(Box)(({ theme }) => ({
158
+ display: "flex",
159
+ alignItems: "center",
160
+ gap: theme.spacing(0.5),
161
+ userSelect: "none"
162
+ }));
163
+
164
+ export { ResultsStep, ResultsStep as default };
165
+ //# sourceMappingURL=ResultsStep.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ResultsStep.esm.js","sources":["../../../../src/features/environment/CompareDeploymentsDialog/ResultsStep.tsx"],"sourcesContent":["import { useMemo, useState } from 'react';\nimport Box from '@massdriver/ui/Box';\nimport Typography from '@massdriver/ui/Typography';\nimport Switch from '@massdriver/ui/Switch';\nimport Alert from '@massdriver/ui/Alert';\nimport Button from '@massdriver/ui/Button';\nimport DataList from '@massdriver/ui/DataList';\nimport stylin from '@massdriver/ui/stylin';\nimport ChevronLeftIcon from '@massdriver/ui/icons/ChevronLeftIcon';\nimport buildCompareColumns from './compareColumns';\nimport type { DeploymentComparisonRow } from './flattenDeploymentComparison';\nimport { truncateDeploymentId } from '../InstanceDrawer/helpers';\nimport type { Deployment } from '../InstanceDrawer/types';\n\nconst labelFor = (\n deployment?: Deployment | null,\n position?: number,\n): string => {\n if (!deployment) return '';\n const id = truncateDeploymentId(deployment.id);\n return position != null ? `#${position} · ${id}` : id;\n};\n\n/** Step 2 of the deployment compare flow: the flattened diff as a DataList. */\nexport const ResultsStep = ({\n rows,\n source,\n target,\n sourcePosition,\n targetPosition,\n onChangeSelection,\n}: {\n rows: DeploymentComparisonRow[];\n source: Deployment | null;\n target: Deployment | null;\n sourcePosition?: number;\n targetPosition?: number;\n onChangeSelection: () => void;\n}) => {\n const [hideEqual, setHideEqual] = useState(true);\n\n const filteredRows = useMemo(\n () => (hideEqual ? rows.filter(row => row.status !== 'equal') : rows),\n [rows, hideEqual],\n );\n\n const columns = useMemo(\n () =>\n buildCompareColumns({\n leftLabel: labelFor(source, sourcePosition),\n rightLabel: labelFor(target, targetPosition),\n }),\n [source, target, sourcePosition, targetPosition],\n );\n\n const differingCount = useMemo(\n () => rows.filter(row => row.status !== 'equal').length,\n [rows],\n );\n const allEqual = rows.length > 0 && differingCount === 0;\n\n return (\n <Root>\n <HeaderBar>\n <BackButton\n variant=\"text\"\n size=\"small\"\n startIcon={<ChevronLeftIcon />}\n onClick={onChangeSelection}\n >\n Change selection\n </BackButton>\n <Title>\n <DeploymentLabel>{labelFor(source, sourcePosition)}</DeploymentLabel>\n <ArrowText>↔</ArrowText>\n <DeploymentLabel>{labelFor(target, targetPosition)}</DeploymentLabel>\n </Title>\n <HeaderSpacer />\n </HeaderBar>\n\n <SummaryRow>\n <Typography variant=\"body2\" color=\"text.secondary\">\n {allEqual ? (\n 'No differences.'\n ) : (\n <>\n <Strong>{differingCount}</Strong>{' '}\n {differingCount === 1 ? 'difference' : 'differences'}\n </>\n )}\n </Typography>\n <ToolbarActions>\n <SwitchLabel>\n <Switch\n size=\"small\"\n checked={hideEqual}\n onChange={(event: any) => setHideEqual(event.target.checked)}\n />\n <Typography variant=\"body2\" color=\"text.secondary\">\n Hide identical\n </Typography>\n </SwitchLabel>\n </ToolbarActions>\n </SummaryRow>\n\n {allEqual ? (\n <Alert severity=\"success\" variant=\"outlined\">\n These deployments are identical.\n </Alert>\n ) : null}\n\n {allEqual && hideEqual ? null : (\n <DataList\n rows={filteredRows}\n columns={columns}\n searchable\n searchPlaceholder=\"Search path…\"\n defaultSort={{ field: 'path', direction: 'asc' }}\n defaultPageSize={20}\n variant=\"outlined\"\n size=\"small\"\n emptyMessage='No fields match the current filters. Try clearing the search or toggling \"Hide identical\".'\n />\n )}\n </Root>\n );\n};\n\nexport default ResultsStep;\n\nconst Root = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n flexDirection: 'column',\n gap: theme.spacing(2),\n flex: 1,\n}));\n\nconst HeaderBar = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(2),\n paddingBottom: theme.spacing(1.5),\n borderBottom: `1px solid ${theme.palette.divider}`,\n}));\n\nconst BackButton = stylin(Button)(({ theme }: { theme: any }) => ({\n color: theme.palette.text.secondary,\n flexShrink: 0,\n}));\n\nconst Title = stylin(Box)(({ theme }: { theme: any }) => ({\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'center',\n gap: theme.spacing(1.5),\n}));\n\nconst DeploymentLabel = stylin('span')(({ theme }: { theme: any }) => ({\n fontFamily: theme.typography.fontFamilyMono,\n fontSize: theme.typography.h6.fontSize,\n fontWeight: 600,\n color: theme.palette.text.primary,\n maxWidth: theme.spacing(40),\n whiteSpace: 'nowrap',\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n}));\n\nconst ArrowText = stylin('span')(({ theme }: { theme: any }) => ({\n color: theme.palette.text.disabled,\n fontSize: theme.typography.h6.fontSize,\n}));\n\nconst HeaderSpacer = stylin(Box)(({ theme }: { theme: any }) => ({\n width: theme.spacing(20),\n flexShrink: 0,\n}));\n\nconst SummaryRow = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n alignItems: 'center',\n justifyContent: 'space-between',\n gap: theme.spacing(2),\n flexWrap: 'wrap',\n}));\n\nconst Strong = stylin('span')(({ theme }: { theme: any }) => ({\n color: theme.palette.text.primary,\n fontWeight: 600,\n}));\n\nconst ToolbarActions = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(1.5),\n flexWrap: 'wrap',\n}));\n\nconst SwitchLabel = stylin(Box)(({ theme }: { theme: any }) => ({\n display: 'flex',\n alignItems: 'center',\n gap: theme.spacing(0.5),\n userSelect: 'none',\n}));\n"],"names":[],"mappings":"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"}