@burdenoff/microfe-planmagnet 2026.930.25 → 2026.1001.2

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 (314) hide show
  1. package/dist/_virtual/__vite-browser-external.js +9 -0
  2. package/dist/_virtual/__vite-browser-external.js.map +1 -0
  3. package/dist/_virtual/_rolldown/runtime.js +5 -2
  4. package/dist/index.js +3 -1
  5. package/dist/node_modules/fflate/esm/browser.js +554 -0
  6. package/dist/node_modules/fflate/esm/browser.js.map +1 -0
  7. package/dist/node_modules/jszip/dist/jszip.min.js +3038 -0
  8. package/dist/node_modules/jszip/dist/jszip.min.js.map +1 -0
  9. package/dist/node_modules/pptxgenjs/dist/pptxgen.es.js +2151 -0
  10. package/dist/node_modules/pptxgenjs/dist/pptxgen.es.js.map +1 -0
  11. package/dist/node_modules/write-excel-file/browser/index.js +3 -0
  12. package/dist/node_modules/write-excel-file/modules/export/convertFileContentToUint8ArrayBrowser.js +13 -0
  13. package/dist/node_modules/write-excel-file/modules/export/convertFileContentToUint8ArrayBrowser.js.map +1 -0
  14. package/dist/node_modules/write-excel-file/modules/export/convertFilesContentToUint8Arrays.js +21 -0
  15. package/dist/node_modules/write-excel-file/modules/export/convertFilesContentToUint8Arrays.js.map +1 -0
  16. package/dist/node_modules/write-excel-file/modules/export/downloadBlob.js +11 -0
  17. package/dist/node_modules/write-excel-file/modules/export/downloadBlob.js.map +1 -0
  18. package/dist/node_modules/write-excel-file/modules/export/writeXlsxFileBrowser.js +23 -0
  19. package/dist/node_modules/write-excel-file/modules/export/writeXlsxFileBrowser.js.map +1 -0
  20. package/dist/node_modules/write-excel-file/modules/export/writeXlsxFileUniversal.js +22 -0
  21. package/dist/node_modules/write-excel-file/modules/export/writeXlsxFileUniversal.js.map +1 -0
  22. package/dist/node_modules/write-excel-file/modules/getSheetData/getSheetData.js +18 -0
  23. package/dist/node_modules/write-excel-file/modules/getSheetData/getSheetData.js.map +1 -0
  24. package/dist/node_modules/write-excel-file/modules/xlsx/features/conditionalFormatting.js +131 -0
  25. package/dist/node_modules/write-excel-file/modules/xlsx/features/conditionalFormatting.js.map +1 -0
  26. package/dist/node_modules/write-excel-file/modules/xlsx/features/images.js +188 -0
  27. package/dist/node_modules/write-excel-file/modules/xlsx/features/images.js.map +1 -0
  28. package/dist/node_modules/write-excel-file/modules/xlsx/features/stickyRowsOrColumns.js +52 -0
  29. package/dist/node_modules/write-excel-file/modules/xlsx/features/stickyRowsOrColumns.js.map +1 -0
  30. package/dist/node_modules/write-excel-file/modules/xlsx/files/_Content_Types_.xml.js +18 -0
  31. package/dist/node_modules/write-excel-file/modules/xlsx/files/_Content_Types_.xml.js.map +1 -0
  32. package/dist/node_modules/write-excel-file/modules/xlsx/files/drawing.xml.js +18 -0
  33. package/dist/node_modules/write-excel-file/modules/xlsx/files/drawing.xml.js.map +1 -0
  34. package/dist/node_modules/write-excel-file/modules/xlsx/files/drawing.xml.rels.js +17 -0
  35. package/dist/node_modules/write-excel-file/modules/xlsx/files/drawing.xml.rels.js.map +1 -0
  36. package/dist/node_modules/write-excel-file/modules/xlsx/files/rels.js +11 -0
  37. package/dist/node_modules/write-excel-file/modules/xlsx/files/rels.js.map +1 -0
  38. package/dist/node_modules/write-excel-file/modules/xlsx/files/sharedStrings.xml.js +42 -0
  39. package/dist/node_modules/write-excel-file/modules/xlsx/files/sharedStrings.xml.js.map +1 -0
  40. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/cell.js +102 -0
  41. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/cell.js.map +1 -0
  42. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/column.js +17 -0
  43. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/column.js.map +1 -0
  44. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/columns.js +15 -0
  45. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/columns.js.map +1 -0
  46. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/drawingReference.js +8 -0
  47. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/drawingReference.js.map +1 -0
  48. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/helpers/getCellStyleProperties.js +71 -0
  49. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/helpers/getCellStyleProperties.js.map +1 -0
  50. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/mergedCellsDescription.js +56 -0
  51. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/mergedCellsDescription.js.map +1 -0
  52. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/pageMargins.js +15 -0
  53. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/pageMargins.js.map +1 -0
  54. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/pageSetup.js +13 -0
  55. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/pageSetup.js.map +1 -0
  56. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/processMergedCells.js +44 -0
  57. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/processMergedCells.js.map +1 -0
  58. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/row.js +123 -0
  59. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/row.js.map +1 -0
  60. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheet.xml.js +41 -0
  61. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheet.xml.js.map +1 -0
  62. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheetData.js +11 -0
  63. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheetData.js.map +1 -0
  64. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheetViews.js +17 -0
  65. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheetViews.js.map +1 -0
  66. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml.rels.js +20 -0
  67. package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml.rels.js.map +1 -0
  68. package/dist/node_modules/write-excel-file/modules/xlsx/files/styles.xml.js +77 -0
  69. package/dist/node_modules/write-excel-file/modules/xlsx/files/styles.xml.js.map +1 -0
  70. package/dist/node_modules/write-excel-file/modules/xlsx/files/workbook.xml.js +22 -0
  71. package/dist/node_modules/write-excel-file/modules/xlsx/files/workbook.xml.js.map +1 -0
  72. package/dist/node_modules/write-excel-file/modules/xlsx/files/workbook.xml.rels.js +13 -0
  73. package/dist/node_modules/write-excel-file/modules/xlsx/files/workbook.xml.rels.js.map +1 -0
  74. package/dist/node_modules/write-excel-file/modules/xlsx/generateXlsxFileContents.js +242 -0
  75. package/dist/node_modules/write-excel-file/modules/xlsx/generateXlsxFileContents.js.map +1 -0
  76. package/dist/node_modules/write-excel-file/modules/xlsx/getFeatures.js +29 -0
  77. package/dist/node_modules/write-excel-file/modules/xlsx/getFeatures.js.map +1 -0
  78. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/convertDateToSerialNumber.js +9 -0
  79. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/convertDateToSerialNumber.js.map +1 -0
  80. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getAdditionalContent.js +42 -0
  81. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getAdditionalContent.js.map +1 -0
  82. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getElementXml.js +43 -0
  83. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getElementXml.js.map +1 -0
  84. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getWrittenFiles.js +93 -0
  85. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getWrittenFiles.js.map +1 -0
  86. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/transformContent.js +39 -0
  87. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/transformContent.js.map +1 -0
  88. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getAlignmentXml.js +17 -0
  89. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getAlignmentXml.js.map +1 -0
  90. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getBorderXml.js +29 -0
  91. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getBorderXml.js.map +1 -0
  92. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getCellAddress.js +14 -0
  93. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getCellAddress.js.map +1 -0
  94. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFileExtensionForContentType.js +11 -0
  95. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFileExtensionForContentType.js.map +1 -0
  96. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFillXml.js +14 -0
  97. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFillXml.js.map +1 -0
  98. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFontXml.js +12 -0
  99. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFontXml.js.map +1 -0
  100. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getOrderOfSiblings.js +24 -0
  101. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getOrderOfSiblings.js.map +1 -0
  102. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getXlsxColorForHexColor.js +9 -0
  103. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getXlsxColorForHexColor.js.map +1 -0
  104. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasAlignment.js +9 -0
  105. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasAlignment.js.map +1 -0
  106. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasBorder.js +9 -0
  107. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasBorder.js.map +1 -0
  108. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasFill.js +9 -0
  109. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasFill.js.map +1 -0
  110. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasFont.js +9 -0
  111. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasFont.js.map +1 -0
  112. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/isCellObject.js +9 -0
  113. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/isCellObject.js.map +1 -0
  114. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/isObject.js +9 -0
  115. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/isObject.js.map +1 -0
  116. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/orderOfSiblings.js +27 -0
  117. package/dist/node_modules/write-excel-file/modules/xlsx/helpers/orderOfSiblings.js.map +1 -0
  118. package/dist/node_modules/write-excel-file/modules/xlsx/initializeSharedStrings.js +17 -0
  119. package/dist/node_modules/write-excel-file/modules/xlsx/initializeSharedStrings.js.map +1 -0
  120. package/dist/node_modules/write-excel-file/modules/xlsx/initializeSheets.js +74 -0
  121. package/dist/node_modules/write-excel-file/modules/xlsx/initializeSheets.js.map +1 -0
  122. package/dist/node_modules/write-excel-file/modules/xlsx/initializeStyles.js +138 -0
  123. package/dist/node_modules/write-excel-file/modules/xlsx/initializeStyles.js.map +1 -0
  124. package/dist/node_modules/write-excel-file/modules/xlsx/validateSheetData.js +40 -0
  125. package/dist/node_modules/write-excel-file/modules/xlsx/validateSheetData.js.map +1 -0
  126. package/dist/node_modules/write-excel-file/modules/xlsx/validateSheetName.js +11 -0
  127. package/dist/node_modules/write-excel-file/modules/xlsx/validateSheetName.js.map +1 -0
  128. package/dist/node_modules/write-excel-file/modules/xml/appendMarkupInsideElement.js +9 -0
  129. package/dist/node_modules/write-excel-file/modules/xml/appendMarkupInsideElement.js.map +1 -0
  130. package/dist/node_modules/write-excel-file/modules/xml/applyEnclosingElementOffset.js +9 -0
  131. package/dist/node_modules/write-excel-file/modules/xml/applyEnclosingElementOffset.js.map +1 -0
  132. package/dist/node_modules/write-excel-file/modules/xml/escapeXmlSpecialCharacters.js +12 -0
  133. package/dist/node_modules/write-excel-file/modules/xml/escapeXmlSpecialCharacters.js.map +1 -0
  134. package/dist/node_modules/write-excel-file/modules/xml/findElement.js +12 -0
  135. package/dist/node_modules/write-excel-file/modules/xml/findElement.js.map +1 -0
  136. package/dist/node_modules/write-excel-file/modules/xml/findElementInsideElement.js +12 -0
  137. package/dist/node_modules/write-excel-file/modules/xml/findElementInsideElement.js.map +1 -0
  138. package/dist/node_modules/write-excel-file/modules/xml/findElementsNonRecursive_.js +41 -0
  139. package/dist/node_modules/write-excel-file/modules/xml/findElementsNonRecursive_.js.map +1 -0
  140. package/dist/node_modules/write-excel-file/modules/xml/getAttributesString.js +14 -0
  141. package/dist/node_modules/write-excel-file/modules/xml/getAttributesString.js.map +1 -0
  142. package/dist/node_modules/write-excel-file/modules/xml/getChildElements.js +42 -0
  143. package/dist/node_modules/write-excel-file/modules/xml/getChildElements.js.map +1 -0
  144. package/dist/node_modules/write-excel-file/modules/xml/getClosingTagMarkup.js +8 -0
  145. package/dist/node_modules/write-excel-file/modules/xml/getClosingTagMarkup.js.map +1 -0
  146. package/dist/node_modules/write-excel-file/modules/xml/getMarkupInsideElement.js +8 -0
  147. package/dist/node_modules/write-excel-file/modules/xml/getMarkupInsideElement.js.map +1 -0
  148. package/dist/node_modules/write-excel-file/modules/xml/getOpeningTagMarkup.js +9 -0
  149. package/dist/node_modules/write-excel-file/modules/xml/getOpeningTagMarkup.js.map +1 -0
  150. package/dist/node_modules/write-excel-file/modules/xml/getSelfClosingTagMarkup.js +9 -0
  151. package/dist/node_modules/write-excel-file/modules/xml/getSelfClosingTagMarkup.js.map +1 -0
  152. package/dist/node_modules/write-excel-file/modules/xml/insertElementMarkupAccordingToOrderOfSiblings.js +64 -0
  153. package/dist/node_modules/write-excel-file/modules/xml/insertElementMarkupAccordingToOrderOfSiblings.js.map +1 -0
  154. package/dist/node_modules/write-excel-file/modules/xml/prependMarkupInsideElement.js +9 -0
  155. package/dist/node_modules/write-excel-file/modules/xml/prependMarkupInsideElement.js.map +1 -0
  156. package/dist/node_modules/write-excel-file/modules/xml/removeInvalidXmlCharacters.js +9 -0
  157. package/dist/node_modules/write-excel-file/modules/xml/removeInvalidXmlCharacters.js.map +1 -0
  158. package/dist/node_modules/write-excel-file/modules/xml/replaceElement.js +8 -0
  159. package/dist/node_modules/write-excel-file/modules/xml/replaceElement.js.map +1 -0
  160. package/dist/node_modules/write-excel-file/modules/xml/sanitizeAttributeName.js +10 -0
  161. package/dist/node_modules/write-excel-file/modules/xml/sanitizeAttributeName.js.map +1 -0
  162. package/dist/node_modules/write-excel-file/modules/xml/sanitizeAttributeValue.js +11 -0
  163. package/dist/node_modules/write-excel-file/modules/xml/sanitizeAttributeValue.js.map +1 -0
  164. package/dist/node_modules/write-excel-file/modules/xml/sanitizeTextContent.js +11 -0
  165. package/dist/node_modules/write-excel-file/modules/xml/sanitizeTextContent.js.map +1 -0
  166. package/dist/node_modules/write-excel-file/modules/xml/setMarkupInsideElement.js +8 -0
  167. package/dist/node_modules/write-excel-file/modules/xml/setMarkupInsideElement.js.map +1 -0
  168. package/dist/node_modules/write-excel-file/modules/zip/zipToArrayBuffer.js +18 -0
  169. package/dist/node_modules/write-excel-file/modules/zip/zipToArrayBuffer.js.map +1 -0
  170. package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
  171. package/dist/planmagnet/PlanMagnetRoot.js +160 -147
  172. package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
  173. package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
  174. package/dist/planmagnet/PlanMagnetRoutes.js +126 -106
  175. package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
  176. package/dist/planmagnet/comments/CommentThread.js +36 -36
  177. package/dist/planmagnet/comments/RoadmapComments.js +21 -21
  178. package/dist/planmagnet/controls/AutomationRuleControls.js +24 -24
  179. package/dist/planmagnet/controls/FeatureControls.js +60 -60
  180. package/dist/planmagnet/controls/Pickers.d.ts +10 -0
  181. package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
  182. package/dist/planmagnet/controls/Pickers.js +75 -27
  183. package/dist/planmagnet/controls/Pickers.js.map +1 -1
  184. package/dist/planmagnet/controls/SyncControls.js +59 -59
  185. package/dist/planmagnet/discussion/WorkItemDiscussionPanel.js +15 -15
  186. package/dist/planmagnet/docs/DocSuggestionsPanel.js +12 -12
  187. package/dist/planmagnet/docs/DocVersionCompare.js +3 -3
  188. package/dist/planmagnet/forecast/DeliveryForecastCard.d.ts +12 -0
  189. package/dist/planmagnet/forecast/DeliveryForecastCard.d.ts.map +1 -0
  190. package/dist/planmagnet/forecast/DeliveryForecastCard.js +208 -0
  191. package/dist/planmagnet/forecast/DeliveryForecastCard.js.map +1 -0
  192. package/dist/planmagnet/forecast/ProjectOutlookCard.d.ts +5 -0
  193. package/dist/planmagnet/forecast/ProjectOutlookCard.d.ts.map +1 -0
  194. package/dist/planmagnet/forecast/ProjectOutlookCard.js +190 -0
  195. package/dist/planmagnet/forecast/ProjectOutlookCard.js.map +1 -0
  196. package/dist/planmagnet/forecast/ProjectRiskSummaryCard.d.ts +5 -0
  197. package/dist/planmagnet/forecast/ProjectRiskSummaryCard.d.ts.map +1 -0
  198. package/dist/planmagnet/forecast/ProjectRiskSummaryCard.js +99 -0
  199. package/dist/planmagnet/forecast/ProjectRiskSummaryCard.js.map +1 -0
  200. package/dist/planmagnet/forecast/ResourceForecastCard.d.ts +8 -0
  201. package/dist/planmagnet/forecast/ResourceForecastCard.d.ts.map +1 -0
  202. package/dist/planmagnet/forecast/ResourceForecastCard.js +185 -0
  203. package/dist/planmagnet/forecast/ResourceForecastCard.js.map +1 -0
  204. package/dist/planmagnet/forecast/riskFlags.d.ts +35 -0
  205. package/dist/planmagnet/forecast/riskFlags.d.ts.map +1 -0
  206. package/dist/planmagnet/forecast/riskFlags.js +37 -0
  207. package/dist/planmagnet/forecast/riskFlags.js.map +1 -0
  208. package/dist/planmagnet/index.d.ts +2 -0
  209. package/dist/planmagnet/index.d.ts.map +1 -1
  210. package/dist/planmagnet/index.js +2 -0
  211. package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.d.ts.map +1 -1
  212. package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js +216 -182
  213. package/dist/planmagnet/pages/AnalyticsAnalyticsPagePage.js.map +1 -1
  214. package/dist/planmagnet/pages/AutomationAutomationRuleDetailPagePage.js +11 -11
  215. package/dist/planmagnet/pages/AutomationCreateAutomationRulePagePage.js +4 -4
  216. package/dist/planmagnet/pages/DocsDocDetailPagePage.js +163 -163
  217. package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
  218. package/dist/planmagnet/pages/IntegrationsNewSyncPagePage.js +165 -165
  219. package/dist/planmagnet/pages/IntegrationsNewSyncPagePage.js.map +1 -1
  220. package/dist/planmagnet/pages/ProjectsAtRiskPagePage.d.ts +2 -0
  221. package/dist/planmagnet/pages/ProjectsAtRiskPagePage.d.ts.map +1 -0
  222. package/dist/planmagnet/pages/ProjectsAtRiskPagePage.js +234 -0
  223. package/dist/planmagnet/pages/ProjectsAtRiskPagePage.js.map +1 -0
  224. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
  225. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +206 -182
  226. package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
  227. package/dist/planmagnet/pages/ReportsCreateReportPagePage.d.ts +6 -0
  228. package/dist/planmagnet/pages/ReportsCreateReportPagePage.d.ts.map +1 -1
  229. package/dist/planmagnet/pages/ReportsCreateReportPagePage.js +5 -177
  230. package/dist/planmagnet/pages/ReportsCreateReportPagePage.js.map +1 -1
  231. package/dist/planmagnet/pages/ReportsEditReportPagePage.d.ts +3 -0
  232. package/dist/planmagnet/pages/ReportsEditReportPagePage.d.ts.map +1 -0
  233. package/dist/planmagnet/pages/ReportsEditReportPagePage.js +15 -0
  234. package/dist/planmagnet/pages/ReportsEditReportPagePage.js.map +1 -0
  235. package/dist/planmagnet/pages/ReportsReportPagePage.d.ts +7 -0
  236. package/dist/planmagnet/pages/ReportsReportPagePage.d.ts.map +1 -0
  237. package/dist/planmagnet/pages/ReportsReportPagePage.js +226 -0
  238. package/dist/planmagnet/pages/ReportsReportPagePage.js.map +1 -0
  239. package/dist/planmagnet/pages/ReportsReportsPagePage.d.ts.map +1 -1
  240. package/dist/planmagnet/pages/ReportsReportsPagePage.js +224 -496
  241. package/dist/planmagnet/pages/ReportsReportsPagePage.js.map +1 -1
  242. package/dist/planmagnet/pages/TeamTeamDetailPagePage.d.ts.map +1 -1
  243. package/dist/planmagnet/pages/TeamTeamDetailPagePage.js +88 -83
  244. package/dist/planmagnet/pages/TeamTeamDetailPagePage.js.map +1 -1
  245. package/dist/planmagnet/pages/analytics/SprintDeliveryCards.d.ts.map +1 -1
  246. package/dist/planmagnet/pages/analytics/SprintDeliveryCards.js +139 -112
  247. package/dist/planmagnet/pages/analytics/SprintDeliveryCards.js.map +1 -1
  248. package/dist/planmagnet/pages/analytics/StatusFlowCard.js +21 -21
  249. package/dist/planmagnet/product/ProductControls.js +91 -91
  250. package/dist/planmagnet/reports/ExportMenu.d.ts +9 -0
  251. package/dist/planmagnet/reports/ExportMenu.d.ts.map +1 -0
  252. package/dist/planmagnet/reports/ExportMenu.js +116 -0
  253. package/dist/planmagnet/reports/ExportMenu.js.map +1 -0
  254. package/dist/planmagnet/reports/PrintReportView.d.ts +24 -0
  255. package/dist/planmagnet/reports/PrintReportView.d.ts.map +1 -0
  256. package/dist/planmagnet/reports/PrintReportView.js +75 -0
  257. package/dist/planmagnet/reports/PrintReportView.js.map +1 -0
  258. package/dist/planmagnet/reports/ReportBuilderCanvas.d.ts +8 -0
  259. package/dist/planmagnet/reports/ReportBuilderCanvas.d.ts.map +1 -0
  260. package/dist/planmagnet/reports/ReportBuilderCanvas.js +261 -0
  261. package/dist/planmagnet/reports/ReportBuilderCanvas.js.map +1 -0
  262. package/dist/planmagnet/reports/ReportBuilderPage.d.ts +5 -0
  263. package/dist/planmagnet/reports/ReportBuilderPage.d.ts.map +1 -0
  264. package/dist/planmagnet/reports/ReportBuilderPage.js +198 -0
  265. package/dist/planmagnet/reports/ReportBuilderPage.js.map +1 -0
  266. package/dist/planmagnet/reports/ReportRunHistory.d.ts +8 -0
  267. package/dist/planmagnet/reports/ReportRunHistory.d.ts.map +1 -0
  268. package/dist/planmagnet/reports/ReportRunHistory.js +63 -0
  269. package/dist/planmagnet/reports/ReportRunHistory.js.map +1 -0
  270. package/dist/planmagnet/reports/ReportWidgetRenderer.d.ts +7 -0
  271. package/dist/planmagnet/reports/ReportWidgetRenderer.d.ts.map +1 -0
  272. package/dist/planmagnet/reports/ReportWidgetRenderer.js +251 -0
  273. package/dist/planmagnet/reports/ReportWidgetRenderer.js.map +1 -0
  274. package/dist/planmagnet/reports/SchedulesPanel.d.ts +4 -0
  275. package/dist/planmagnet/reports/SchedulesPanel.d.ts.map +1 -0
  276. package/dist/planmagnet/reports/SchedulesPanel.js +457 -0
  277. package/dist/planmagnet/reports/SchedulesPanel.js.map +1 -0
  278. package/dist/planmagnet/reports/ShareDialog.d.ts +5 -0
  279. package/dist/planmagnet/reports/ShareDialog.d.ts.map +1 -0
  280. package/dist/planmagnet/reports/ShareDialog.js +234 -0
  281. package/dist/planmagnet/reports/ShareDialog.js.map +1 -0
  282. package/dist/planmagnet/reports/SharedReportPage.d.ts +4 -0
  283. package/dist/planmagnet/reports/SharedReportPage.d.ts.map +1 -0
  284. package/dist/planmagnet/reports/SharedReportPage.js +180 -0
  285. package/dist/planmagnet/reports/SharedReportPage.js.map +1 -0
  286. package/dist/planmagnet/reports/WidgetEditorDialog.d.ts +10 -0
  287. package/dist/planmagnet/reports/WidgetEditorDialog.d.ts.map +1 -0
  288. package/dist/planmagnet/reports/WidgetEditorDialog.js +220 -0
  289. package/dist/planmagnet/reports/WidgetEditorDialog.js.map +1 -0
  290. package/dist/planmagnet/reports/reportExportPptx.d.ts +4 -0
  291. package/dist/planmagnet/reports/reportExportPptx.d.ts.map +1 -0
  292. package/dist/planmagnet/reports/reportExportPptx.js +118 -0
  293. package/dist/planmagnet/reports/reportExportPptx.js.map +1 -0
  294. package/dist/planmagnet/reports/reportExportXlsx.d.ts +4 -0
  295. package/dist/planmagnet/reports/reportExportXlsx.d.ts.map +1 -0
  296. package/dist/planmagnet/reports/reportExportXlsx.js +42 -0
  297. package/dist/planmagnet/reports/reportExportXlsx.js.map +1 -0
  298. package/dist/planmagnet/reports/reportGraphql.d.ts +28 -0
  299. package/dist/planmagnet/reports/reportGraphql.d.ts.map +1 -0
  300. package/dist/planmagnet/reports/reportGraphql.js +360 -0
  301. package/dist/planmagnet/reports/reportGraphql.js.map +1 -0
  302. package/dist/planmagnet/reports/reportModel.d.ts +198 -0
  303. package/dist/planmagnet/reports/reportModel.d.ts.map +1 -0
  304. package/dist/planmagnet/reports/reportModel.js +328 -0
  305. package/dist/planmagnet/reports/reportModel.js.map +1 -0
  306. package/dist/planmagnet/reports/sharedReportRoute.d.ts +15 -0
  307. package/dist/planmagnet/reports/sharedReportRoute.d.ts.map +1 -0
  308. package/dist/planmagnet/reports/sharedReportRoute.js +9 -0
  309. package/dist/planmagnet/reports/sharedReportRoute.js.map +1 -0
  310. package/dist/planmagnet/roadmaps/RoadmapControls.js +60 -60
  311. package/dist/planmagnet/roadmaps/RoadmapNowNextLater.js +30 -30
  312. package/dist/planmagnet/roadmaps/RoadmapReviewPanel.js +21 -21
  313. package/dist/planmagnet/roadmaps/RoadmapVersionsPanel.js +22 -22
  314. package/package.json +6 -4
@@ -1 +1 @@
1
- {"version":3,"file":"ReportsReportsPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ReportsReportsPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport {\n Badge,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { BarChart3, ShieldCheck, TrendingUp, Users } from 'lucide-react';\nimport {\n Bar,\n BarChart,\n CartesianGrid,\n Legend,\n ReferenceLine,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from 'recharts';\nimport { usePlanMagnet } from '../providers/PlanMagnetProvider';\nimport { CycleTimeCard } from './analytics/DeliveryHealthCards';\n\n/**\n * Reports (BOFF-8048). Until this ticket, Reports had no saved-report model and no report runner, so the page said\n * so and pointed at Analytics instead (BOFF-7967). Every panel here is query-driven — it reads numbers the server\n * already computes (velocity, cycle time, throughput, release readiness) — with ZERO client-side row fabrication.\n * That property is the entire point: this page previously invented rows (\"Velocity Report\", \"Burndown\", …) with\n * made-up schedules and run counts, which is exactly what must never come back (see git history / BOFF-7967).\n *\n * `planmagnetThroughput` ships with the BOFF-8048 backend PR — until it deploys and the schema is re-pulled,\n * `bun run validate:schema` fails on the Throughput panel's query below (expected; not a regression in the other\n * three panels, which reuse queries that already exist and are already validated: planmagnetVelocity,\n * planmagnetCycleTime — via <CycleTimeCard>, planmagnetTeamVelocity and planmagnetReleaseReadiness).\n */\n\nconst GET_REPORTS_PROJECTS = gql`\n query GetReportsProjects($workspaceId: ID!) {\n planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n }\n }\n }\n`;\n\nconst GET_REPORTS_VELOCITY = gql`\n query GetReportsVelocity($workspaceId: ID!, $projectId: ID!, $trailingSprintCount: Int) {\n planmagnetVelocity(\n workspaceId: $workspaceId\n projectId: $projectId\n trailingSprintCount: $trailingSprintCount\n ) {\n projectId\n averageVelocity\n forecastNextSprintPoints\n sprints {\n sprintId\n sprintName\n sequenceNumber\n completedPoints\n completedCount\n plannedPoints\n }\n }\n }\n`;\n\n// New with BOFF-8048 — see the file-header note on schema-drift.\nconst GET_REPORTS_THROUGHPUT = gql`\n query GetReportsThroughput(\n $workspaceId: ID!\n $projectId: ID!\n $bucket: PlanmagnetThroughputBucket\n ) {\n planmagnetThroughput(workspaceId: $workspaceId, projectId: $projectId, bucket: $bucket) {\n projectId\n bucket\n startDate\n endDate\n points {\n periodStart\n completedCount\n completedPoints\n }\n }\n }\n`;\n\nconst GET_REPORTS_TEAMS = gql`\n query GetReportsTeams($workspaceId: ID!) {\n planmagnetTeams(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n }\n }\n }\n`;\n\nconst GET_REPORTS_TEAM_VELOCITY = gql`\n query GetReportsTeamVelocity($workspaceId: ID!, $teamId: ID!, $trailingSprintCount: Int) {\n planmagnetTeamVelocity(\n workspaceId: $workspaceId\n teamId: $teamId\n trailingSprintCount: $trailingSprintCount\n ) {\n teamId\n averageVelocity\n forecastNextSprintPoints\n sprints {\n sprintId\n sprintName\n sequenceNumber\n completedCount\n completedPoints\n plannedPoints\n byProject {\n projectId\n projectName\n count\n points\n }\n }\n }\n }\n`;\n\nconst GET_REPORTS_RELEASES = gql`\n query GetReportsReleases($workspaceId: ID!, $projectId: String) {\n planmagnetReleases(\n workspaceId: $workspaceId\n filter: { projectId: $projectId }\n pagination: { first: 50 }\n ) {\n items {\n id\n name\n status\n plannedDate\n }\n totalCount\n }\n }\n`;\n\nconst GET_RELEASE_READINESS = gql`\n query GetReportsReleaseReadiness($releaseId: ID!) {\n planmagnetReleaseReadiness(releaseId: $releaseId) {\n releaseId\n doneItems\n totalItems\n blockers {\n workItem {\n id\n key\n title\n }\n }\n }\n }\n`;\n\n// Non-terminal: still worth watching for readiness. RELEASED/ROLLED_BACK/CANCELLED are done stories, not upcoming.\nconst OPEN_RELEASE_STATUSES = new Set(['DRAFT', 'PLANNING', 'IN_PROGRESS', 'STAGING', 'READY']);\n\ninterface ProjectNode {\n id: string;\n name: string;\n}\n\ninterface VelocitySprintPoint {\n sprintId: string;\n sprintName: string;\n sequenceNumber: number;\n completedPoints: number;\n completedCount: number;\n plannedPoints: number | null;\n}\n\ninterface ReleaseNode {\n id: string;\n name: string;\n status: string;\n plannedDate: string | null;\n}\n\nfunction formatPeriod(iso: string): string {\n const d = new Date(iso);\n return `${d.getUTCMonth() + 1}/${d.getUTCDate()}`;\n}\n\n/** One release's readiness — its own query, independent of the others (§4.2.3: a handful of cards, no batching). */\nfunction ReleaseReadinessCard({ release }: { release: ReleaseNode }) {\n const { t } = useI18n();\n const { data, loading, error } = useQuery<{\n planmagnetReleaseReadiness: {\n releaseId: string;\n doneItems: number;\n totalItems: number;\n blockers: { workItem: { id: string; key: string; title: string } }[];\n };\n }>(GET_RELEASE_READINESS, { variables: { releaseId: release.id } });\n\n const readiness = data?.planmagnetReleaseReadiness;\n const percent =\n readiness && readiness.totalItems > 0\n ? Math.round((readiness.doneItems / readiness.totalItems) * 100)\n : null;\n const ready = readiness\n ? readiness.doneItems >= readiness.totalItems && readiness.blockers.length === 0\n : null;\n\n return (\n <Card data-testid={`release-readiness-${release.id}`}>\n <CardHeader>\n <CardTitle className=\"flex items-center justify-between text-sm\">\n <span>{release.name}</span>\n <Badge variant=\"outline\">{enumTitleCase(release.status)}</Badge>\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {loading ? (\n <p className=\"text-sm text-muted-foreground\">\n {t('planmagnet.reports.loading', 'Loading…')}\n </p>\n ) : error ? (\n <p className=\"text-sm text-destructive\">\n {t('planmagnet.reports.readiness.error', 'Readiness could not be loaded')}\n </p>\n ) : !readiness ? null : (\n <>\n <p className=\"text-sm\">\n <span className=\"font-semibold\">{readiness.doneItems}</span> /{' '}\n <span className=\"text-muted-foreground\">{readiness.totalItems}</span>{' '}\n {t('planmagnet.reports.readiness.itemsDone', 'items done')}\n {percent !== null && <span className=\"text-muted-foreground\"> ({percent}%)</span>}\n </p>\n <Badge variant={ready ? 'success' : 'warning'}>\n {ready\n ? t('planmagnet.reports.readiness.ready', 'Ready')\n : t('planmagnet.reports.readiness.notReady', 'Not ready')}\n </Badge>\n {readiness.blockers.length > 0 && (\n <p className=\"text-xs text-muted-foreground\">\n {t('planmagnet.reports.readiness.blockers', '{{count}} blocker(s)', {\n count: readiness.blockers.length,\n })}\n </p>\n )}\n </>\n )}\n </CardContent>\n </Card>\n );\n}\n\nfunction enumTitleCase(value: string): string {\n const words = value.toLowerCase().replace(/_/g, ' ');\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\nfunction ProjectReportsPanels({\n workspaceId,\n projectId,\n}: {\n workspaceId?: string | null;\n projectId: string;\n}) {\n const { t } = useI18n();\n\n const { data: velocityData, loading: velocityLoading } = useQuery<{\n planmagnetVelocity: {\n averageVelocity: number;\n forecastNextSprintPoints: number;\n sprints: VelocitySprintPoint[];\n };\n }>(GET_REPORTS_VELOCITY, {\n variables: { workspaceId, projectId, trailingSprintCount: 10 },\n skip: !workspaceId || !projectId,\n });\n\n const {\n data: throughputData,\n loading: throughputLoading,\n error: throughputError,\n } = useQuery<{\n planmagnetThroughput: {\n points: { periodStart: string; completedCount: number; completedPoints: number }[];\n };\n }>(GET_REPORTS_THROUGHPUT, {\n variables: { workspaceId, projectId, bucket: 'WEEK' },\n skip: !workspaceId || !projectId,\n });\n\n const { data: releasesData } = useQuery<{\n planmagnetReleases: { items: ReleaseNode[]; totalCount: number };\n }>(GET_REPORTS_RELEASES, {\n variables: { workspaceId, projectId },\n skip: !workspaceId || !projectId,\n });\n\n const velocity = velocityData?.planmagnetVelocity;\n const velocityChartData =\n velocity?.sprints.map((s) => ({\n name: s.sprintName,\n completed: s.completedPoints,\n planned: s.plannedPoints ?? undefined,\n })) ?? [];\n const avgVelocity = velocity ? Math.round(velocity.averageVelocity) : 0;\n\n const throughputChartData =\n throughputData?.planmagnetThroughput.points.map((p) => ({\n period: formatPeriod(p.periodStart),\n count: p.completedCount,\n points: p.completedPoints,\n })) ?? [];\n\n const upcomingReleases = (releasesData?.planmagnetReleases.items ?? []).filter((r) =>\n OPEN_RELEASE_STATUSES.has(r.status)\n );\n\n return (\n <div className=\"space-y-6\">\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <TrendingUp className=\"h-4 w-4\" />\n {t('planmagnet.reports.velocity.title', 'Sprint Velocity')} (\n {velocityChartData.length} {t('planmagnet.reports.velocity.sprints', 'sprints')})\n </CardTitle>\n </CardHeader>\n <CardContent>\n {velocityLoading ? (\n <div className=\"flex justify-center py-12\">\n <div className=\"animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n ) : velocityChartData.length > 0 ? (\n // recharts' `fill`/`stroke` render as literal SVG paint attributes, not Tailwind classNames — they\n // cannot consume semantic bg-*/text-* tokens. Same accepted exception as\n // AnalyticsAnalyticsPagePage.tsx's CFD_STATUS_COLORS (lint warns, does not error, here and there).\n <ResponsiveContainer width=\"100%\" height={220}>\n <BarChart data={velocityChartData}>\n <CartesianGrid strokeDasharray=\"3 3\" opacity={0.2} />\n <XAxis dataKey=\"name\" tick={{ fontSize: 11 }} />\n <YAxis tick={{ fontSize: 11 }} allowDecimals={false} />\n <Tooltip />\n <Legend wrapperStyle={{ fontSize: 12 }} />\n <Bar\n dataKey=\"planned\"\n name={t('planmagnet.reports.velocity.planned', 'Planned')}\n fill=\"#cbd5e1\"\n />\n <Bar\n dataKey=\"completed\"\n name={t('planmagnet.reports.velocity.completed', 'Completed')}\n fill=\"#6366f1\"\n />\n <ReferenceLine y={avgVelocity} stroke=\"#22c55e\" strokeDasharray=\"4 4\" />\n </BarChart>\n </ResponsiveContainer>\n ) : (\n <p className=\"text-sm text-muted-foreground py-8 text-center\">\n {t(\n 'planmagnet.reports.velocity.empty',\n 'No completed sprints yet for this project'\n )}\n </p>\n )}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <BarChart3 className=\"h-4 w-4\" />\n {t('planmagnet.reports.throughput.title', 'Throughput')}\n </CardTitle>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'planmagnet.reports.throughput.subtitle',\n 'Work items completed per week, trailing 12 weeks.'\n )}\n </p>\n </CardHeader>\n <CardContent>\n {throughputLoading ? (\n <div className=\"flex justify-center py-12\">\n <div className=\"animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n ) : throughputError ? (\n <p className=\"text-sm text-muted-foreground py-8 text-center\">\n {t(\n 'planmagnet.reports.throughput.unavailable',\n 'Throughput is not available yet for this workspace.'\n )}\n </p>\n ) : throughputChartData.length > 0 ? (\n <ResponsiveContainer width=\"100%\" height={220}>\n <BarChart data={throughputChartData}>\n <CartesianGrid strokeDasharray=\"3 3\" opacity={0.2} />\n <XAxis dataKey=\"period\" tick={{ fontSize: 11 }} />\n <YAxis tick={{ fontSize: 11 }} allowDecimals={false} />\n <Tooltip />\n <Legend wrapperStyle={{ fontSize: 12 }} />\n <Bar\n dataKey=\"count\"\n name={t('planmagnet.reports.throughput.items', 'Items done')}\n fill=\"#0ea5e9\"\n />\n <Bar\n dataKey=\"points\"\n name={t('planmagnet.reports.throughput.points', 'Points done')}\n fill=\"#a855f7\"\n />\n </BarChart>\n </ResponsiveContainer>\n ) : (\n <p className=\"text-sm text-muted-foreground py-8 text-center\">\n {t('planmagnet.reports.throughput.empty', 'No work completed in this project yet')}\n </p>\n )}\n </CardContent>\n </Card>\n </div>\n\n <CycleTimeCard workspaceId={workspaceId} projectId={projectId} />\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <ShieldCheck className=\"h-4 w-4\" />\n {t('planmagnet.reports.readiness.title', 'Release readiness')}\n </CardTitle>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'planmagnet.reports.readiness.subtitle',\n 'Open releases for this project, and what still blocks each.'\n )}\n </p>\n </CardHeader>\n <CardContent>\n {upcomingReleases.length === 0 ? (\n <p className=\"text-sm text-muted-foreground py-4 text-center\">\n {t('planmagnet.reports.readiness.empty', 'No open releases for this project')}\n </p>\n ) : (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\">\n {upcomingReleases.map((release) => (\n <ReleaseReadinessCard key={release.id} release={release} />\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n );\n}\n\nfunction TeamReportsPanel({ workspaceId }: { workspaceId?: string | null }) {\n const { t } = useI18n();\n const [teamId, setTeamId] = useState('');\n\n const { data: teamsData } = useQuery<{\n planmagnetTeams: { items: { id: string; name: string }[] };\n }>(GET_REPORTS_TEAMS, { variables: { workspaceId }, skip: !workspaceId });\n const teams = teamsData?.planmagnetTeams.items ?? [];\n const effectiveTeamId = teamId || teams[0]?.id || '';\n\n const { data, loading } = useQuery<{\n planmagnetTeamVelocity: {\n averageVelocity: number;\n forecastNextSprintPoints: number;\n sprints: {\n sprintId: string;\n sprintName: string;\n completedPoints: number;\n plannedPoints: number | null;\n }[];\n };\n }>(GET_REPORTS_TEAM_VELOCITY, {\n variables: { workspaceId, teamId: effectiveTeamId, trailingSprintCount: 10 },\n skip: !workspaceId || !effectiveTeamId,\n });\n\n const velocity = data?.planmagnetTeamVelocity;\n const chartData =\n velocity?.sprints.map((s) => ({\n name: s.sprintName,\n completed: s.completedPoints,\n planned: s.plannedPoints ?? undefined,\n })) ?? [];\n\n if (teams.length === 0) {\n return (\n <p className=\"text-sm text-muted-foreground py-8 text-center\">\n {t(\n 'planmagnet.reports.team.empty',\n 'No teams in this workspace yet — create one under Teams.'\n )}\n </p>\n );\n }\n\n return (\n <div className=\"space-y-4\">\n <Select value={effectiveTeamId} onValueChange={setTeamId}>\n <SelectTrigger className=\"h-8 w-56\">\n <SelectValue placeholder={t('planmagnet.reports.team.pick', 'Select team')} />\n </SelectTrigger>\n <SelectContent>\n {teams.map((team) => (\n <SelectItem key={team.id} value={team.id}>\n {team.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Users className=\"h-4 w-4\" />\n {t('planmagnet.reports.team.velocityTitle', 'Team velocity')} ({chartData.length}{' '}\n {t('planmagnet.reports.velocity.sprints', 'sprints')})\n </CardTitle>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'planmagnet.reports.team.velocitySubtitle',\n 'Whole-team completed points across the trailing 10 completed team sprints (BOFF-8044 per-project split, no double counting).'\n )}\n </p>\n </CardHeader>\n <CardContent>\n {loading ? (\n <div className=\"flex justify-center py-12\">\n <div className=\"animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n ) : chartData.length > 0 ? (\n <ResponsiveContainer width=\"100%\" height={220}>\n <BarChart data={chartData}>\n <CartesianGrid strokeDasharray=\"3 3\" opacity={0.2} />\n <XAxis dataKey=\"name\" tick={{ fontSize: 11 }} />\n <YAxis tick={{ fontSize: 11 }} allowDecimals={false} />\n <Tooltip />\n <Legend wrapperStyle={{ fontSize: 12 }} />\n <Bar\n dataKey=\"planned\"\n name={t('planmagnet.reports.velocity.planned', 'Planned')}\n fill=\"#cbd5e1\"\n />\n <Bar\n dataKey=\"completed\"\n name={t('planmagnet.reports.velocity.completed', 'Completed')}\n fill=\"#6366f1\"\n />\n </BarChart>\n </ResponsiveContainer>\n ) : (\n <p className=\"text-sm text-muted-foreground py-8 text-center\">\n {t('planmagnet.reports.team.velocityEmpty', 'No completed team sprints yet')}\n </p>\n )}\n </CardContent>\n </Card>\n </div>\n );\n}\n\nexport function ReportsReportsPagePage() {\n const { workspaceId } = usePlanMagnet();\n const { t } = useI18n();\n const [selectedProjectId, setSelectedProjectId] = useState('');\n\n const { data, loading, error } = useQuery<{ planmagnetProjects: { items: ProjectNode[] } }>(\n GET_REPORTS_PROJECTS,\n { variables: { workspaceId }, skip: !workspaceId }\n );\n\n const projects = data?.planmagnetProjects.items ?? [];\n const effectiveProjectId = selectedProjectId || projects[0]?.id || '';\n const effectiveProjectName = projects.find((p) => p.id === effectiveProjectId)?.name ?? '';\n\n // Only before the first load: a refetch must not blank the page.\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"p-6 text-destructive\">\n {t('planmagnet.reports.errorLoading', 'Reports could not be loaded')}: {error.message}\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold flex items-center gap-2\">\n <BarChart3 className=\"h-6 w-6\" />\n {t('planmagnet.reports.title', 'Reports')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'planmagnet.reports.subtitle',\n 'Delivery numbers computed on the server — velocity, cycle time, throughput and release readiness.'\n )}\n </p>\n </div>\n\n {projects.length === 0 ? (\n <Card>\n <CardContent className=\"py-12 text-center text-sm text-muted-foreground\">\n {t('planmagnet.reports.noProjects', 'No projects in this workspace yet.')}\n </CardContent>\n </Card>\n ) : (\n <Tabs defaultValue=\"project\">\n <div className=\"flex flex-col sm:flex-row gap-3 items-start sm:items-center sm:justify-between\">\n <TabsList>\n <TabsTrigger value=\"project\" data-testid=\"reports-tab-project\">\n {t('planmagnet.reports.tabs.project', 'Project')}\n </TabsTrigger>\n <TabsTrigger value=\"team\" data-testid=\"reports-tab-team\">\n {t('planmagnet.reports.tabs.team', 'Team')}\n </TabsTrigger>\n </TabsList>\n <Select value={effectiveProjectId} onValueChange={setSelectedProjectId}>\n <SelectTrigger className=\"h-8 w-56\" data-testid=\"reports-project-select\">\n <SelectValue placeholder={t('planmagnet.reports.pickProject', 'Select project')} />\n </SelectTrigger>\n <SelectContent>\n {projects.map((p) => (\n <SelectItem key={p.id} value={p.id}>\n {p.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <TabsContent value=\"project\" className=\"mt-4\">\n {effectiveProjectId ? (\n <ProjectReportsPanels workspaceId={workspaceId} projectId={effectiveProjectId} />\n ) : (\n <p className=\"text-sm text-muted-foreground py-8 text-center\">\n {t('planmagnet.reports.pickProjectHint', 'Select a project to see its report.')}\n </p>\n )}\n {effectiveProjectName && (\n <p className=\"sr-only\" data-testid=\"reports-current-project\">\n {effectiveProjectName}\n </p>\n )}\n </TabsContent>\n <TabsContent value=\"team\" className=\"mt-4\">\n <TeamReportsPanel workspaceId={workspaceId} />\n </TabsContent>\n </Tabs>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ReportsReportsPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ReportsReportsPagePage.tsx"],"sourcesContent":["import { useDeferredValue, useState } from 'react';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Input,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { BarChart3, LayoutTemplate, Plus } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath, rowLinkProps, stopRowActivation } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { ConfirmButton, ErrorLine } from '../controls/ConfirmButton';\nimport { mutationErrorMessage } from '../utils/graphqlErrors';\nimport { LEAVES_PAGE_CONTEXT, throwOnError } from '../utils/mutationResult';\nimport {\n CREATE_REPORT,\n DELETE_REPORT,\n DUPLICATE_REPORT,\n LIST_REPORTS,\n LIST_REPORT_TEMPLATES,\n} from '../reports/reportGraphql';\nimport type { ReportSummary, ReportTemplate } from '../reports/reportModel';\n\n/**\n * Reports (ANR-13, replacing BOFF-8048's stand-in — see git history: this page used to say Reports had no\n * saved-report model and point at Analytics instead, since Save ran no mutation. It now does: a saved report\n * is a named, ownable, shareable, schedulable set of widgets over the same real analytics/work-item data\n * Analytics already reads directly — this page is the list + template gallery in front of it, not a parallel\n * feature.\n */\n\nfunction ReportRow({\n report,\n isOwner,\n onDuplicate,\n onDelete,\n}: {\n report: ReportSummary;\n isOwner: boolean;\n onDuplicate: (id: string) => void;\n onDelete: (id: string) => void;\n}) {\n const navigate = usePlanMagnetNavigate();\n const open = () => navigate(detailPath('/reports/report-page', report.id));\n return (\n <div\n {...rowLinkProps(open, report.name)}\n className=\"flex items-center justify-between gap-3 rounded-md border border-border p-3\"\n data-testid=\"report-list-item\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium\">{report.name}</p>\n {report.description && (\n <p className=\"truncate text-xs text-muted-foreground\">{report.description}</p>\n )}\n <p className=\"mt-0.5 text-xs text-muted-foreground\">\n <Badge\n variant={report.visibility === 'WORKSPACE' ? 'secondary' : 'outline'}\n className=\"mr-1.5\"\n >\n {report.visibility === 'WORKSPACE' ? 'Workspace' : 'Private'}\n </Badge>\n Owned by <PersonName id={report.ownerId} /> · Updated{' '}\n {new Date(report.updatedAt).toLocaleDateString()}\n </p>\n </div>\n <div className=\"flex shrink-0 items-center gap-1.5\" onClick={stopRowActivation}>\n <Button size=\"sm\" variant=\"outline\" onClick={() => onDuplicate(report.id)}>\n Duplicate\n </Button>\n {isOwner && (\n <ConfirmButton\n label=\"Delete\"\n icon={null}\n title={`Delete \"${report.name}\"?`}\n description=\"Its runs, shares and schedules are deleted too. This cannot be undone.\"\n confirmLabel=\"Delete\"\n destructive\n variant=\"outline\"\n disabled={false}\n onConfirm={() => onDelete(report.id)}\n />\n )}\n </div>\n </div>\n );\n}\n\nfunction ReportListTab({ mine }: { mine: boolean }) {\n const { workspaceId, currentUser } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [search, setSearch] = useState('');\n const deferredSearch = useDeferredValue(search.trim());\n const [error, setError] = useState<string | null>(null);\n\n const variables = {\n workspaceId: workspaceId ?? '',\n filter: { mine: mine || undefined, search: deferredSearch || undefined },\n pagination: { first: 50 },\n };\n const {\n data,\n loading,\n error: queryError,\n } = useQuery<{\n planmagnetReports: { items: ReportSummary[]; totalCount: number };\n }>(LIST_REPORTS, { variables, skip: !workspaceId });\n const [duplicateReport] = useMutation(DUPLICATE_REPORT, {\n refetchQueries: [{ query: LIST_REPORTS, variables }],\n });\n const [deleteReport] = useMutation(DELETE_REPORT, {\n refetchQueries: [{ query: LIST_REPORTS, variables }],\n });\n\n const items = mine\n ? (data?.planmagnetReports.items ?? [])\n : (data?.planmagnetReports.items ?? []).filter((r) => r.visibility === 'WORKSPACE');\n\n const duplicate = async (id: string) => {\n setError(null);\n try {\n const result = await throwOnError(duplicateReport({ variables: { id } }));\n const copy = (result.data as { planmagnetDuplicateReport?: { id: string } } | undefined)\n ?.planmagnetDuplicateReport;\n if (copy) navigate(detailPath('/reports/edit-report-page', copy.id));\n } catch (e) {\n setError(mutationErrorMessage(e, 'This report could not be duplicated.'));\n }\n };\n const remove = async (id: string) => {\n setError(null);\n try {\n await throwOnError(deleteReport({ variables: { id } }));\n } catch (e) {\n setError(mutationErrorMessage(e, 'This report could not be deleted.'));\n }\n };\n\n return (\n <div className=\"space-y-3\">\n <Input\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search reports\"\n aria-label=\"Search reports\"\n className=\"max-w-sm\"\n />\n {error && <ErrorLine message={error} />}\n {queryError ? (\n <p className=\"text-sm text-destructive\">\n Reports could not be loaded: {queryError.message}\n </p>\n ) : loading && !data ? (\n <p className=\"py-8 text-center text-sm text-muted-foreground\">Loading…</p>\n ) : items.length === 0 ? (\n <p className=\"py-8 text-center text-sm text-muted-foreground\">\n {mine ? 'You have no reports yet.' : 'No workspace-visible reports yet.'}\n </p>\n ) : (\n <div className=\"space-y-2\">\n {items.map((report) => (\n <ReportRow\n key={report.id}\n report={report}\n isOwner={!!currentUser?.id && currentUser.id === report.ownerId}\n onDuplicate={(id) => void duplicate(id)}\n onDelete={(id) => void remove(id)}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction TemplateGallery() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const { data, loading, error } = useQuery<{ planmagnetReportTemplates: ReportTemplate[] }>(\n LIST_REPORT_TEMPLATES\n );\n const [createReport, { loading: creating }] = useMutation(CREATE_REPORT);\n const [busyKey, setBusyKey] = useState<string | null>(null);\n const [createError, setCreateError] = useState<string | null>(null);\n\n const startFromTemplate = async (template: ReportTemplate) => {\n if (!workspaceId) return;\n setCreateError(null);\n setBusyKey(template.key);\n try {\n const result = await throwOnError(\n createReport({\n variables: {\n workspaceId,\n input: {\n name: template.name,\n description: template.description,\n templateKey: template.key,\n visibility: 'PRIVATE',\n definition: template.definition,\n },\n },\n context: LEAVES_PAGE_CONTEXT,\n })\n );\n const id = (result.data as { planmagnetCreateReport?: { id: string } } | undefined)\n ?.planmagnetCreateReport?.id;\n // Template widgets ship with empty params (project/sprint/team/date range) — the builder is where those\n // get filled in before the report is ever run.\n if (id) navigate(detailPath('/reports/edit-report-page', id));\n } catch (e) {\n setCreateError(\n mutationErrorMessage(e, 'This report could not be created from the template.')\n );\n } finally {\n setBusyKey(null);\n }\n };\n\n if (loading && !data)\n return <p className=\"py-8 text-center text-sm text-muted-foreground\">Loading…</p>;\n if (error) return <p className=\"text-sm text-destructive\">Templates could not be loaded.</p>;\n const templates = data?.planmagnetReportTemplates ?? [];\n\n return (\n <div className=\"space-y-3\">\n {createError && <ErrorLine message={createError} />}\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {templates.map((template) => (\n <Card key={template.key} data-testid=\"report-template\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-sm\">\n <LayoutTemplate className=\"h-4 w-4\" />\n {template.name}\n </CardTitle>\n <CardDescription>{template.description}</CardDescription>\n </CardHeader>\n <CardContent>\n <p className=\"mb-3 text-xs text-muted-foreground\">\n {template.definition.widgets.length} widget\n {template.definition.widgets.length === 1 ? '' : 's'}\n </p>\n <Button\n size=\"sm\"\n className=\"w-full\"\n disabled={creating}\n onClick={() => void startFromTemplate(template)}\n >\n {busyKey === template.key ? 'Creating…' : 'Start from template'}\n </Button>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n );\n}\n\nexport function ReportsReportsPagePage() {\n const { t } = useI18n();\n const navigate = usePlanMagnetNavigate();\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <h1 className=\"flex items-center gap-2 text-2xl font-semibold\">\n <BarChart3 className=\"h-6 w-6\" />\n {t('planmagnet.reports.title', 'Reports')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'planmagnet.reports.subtitle',\n 'Build, run, share and schedule reports over your PlanMagnet data.'\n )}\n </p>\n </div>\n <Button\n size=\"sm\"\n onClick={() => navigate('/reports/create-report-page')}\n data-testid=\"report-new\"\n >\n <Plus className=\"mr-1 h-4 w-4\" />\n {t('planmagnet.reports.newBlank', 'New blank report')}\n </Button>\n </div>\n\n <Tabs defaultValue=\"mine\">\n <TabsList>\n <TabsTrigger value=\"mine\" data-testid=\"report-list\">\n My reports\n </TabsTrigger>\n <TabsTrigger value=\"workspace\">Workspace</TabsTrigger>\n <TabsTrigger value=\"templates\">Templates</TabsTrigger>\n </TabsList>\n <TabsContent value=\"mine\" className=\"mt-4\">\n <ReportListTab mine={true} />\n </TabsContent>\n <TabsContent value=\"workspace\" className=\"mt-4\">\n <ReportListTab mine={false} />\n </TabsContent>\n <TabsContent value=\"templates\" className=\"mt-4\">\n <TemplateGallery />\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"TeamTeamDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TeamTeamDetailPagePage.tsx"],"names":[],"mappings":"AA2FA,wBAAgB,sBAAsB,4CAqLrC"}
1
+ {"version":3,"file":"TeamTeamDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TeamTeamDetailPagePage.tsx"],"names":[],"mappings":"AA4FA,wBAAgB,sBAAsB,4CAwLrC"}
@@ -4,14 +4,15 @@ import { ROW_LINK_CLASS as r, detailPath as i, rowLinkProps as a } from "../util
4
4
  import { useEntityId as o } from "../hooks/useEntityId.js";
5
5
  import { PlanMagnetNotFoundPage as s } from "./NotFoundPage.js";
6
6
  import { NewSprintDialog as c } from "../sprints/SprintControls.js";
7
- import { TeamHeaderActions as l, TeamMembersPanel as u, TeamProjectsPanel as d } from "../team/TeamControls.js";
8
- import { Gauge as f, UserRound as p, Users as m, Zap as h } from "lucide-react";
9
- import { gql as g } from "@apollo/client";
10
- import { useQuery as _ } from "@apollo/client/react";
11
- import { jsx as v, jsxs as y } from "react/jsx-runtime";
12
- import { Badge as b, Card as x, CardContent as S, CardHeader as C, CardTitle as w } from "@burdenoff/fe-libs/ui";
7
+ import { ResourceForecastCard as l } from "../forecast/ResourceForecastCard.js";
8
+ import { TeamHeaderActions as u, TeamMembersPanel as d, TeamProjectsPanel as f } from "../team/TeamControls.js";
9
+ import { Gauge as p, UserRound as m, Users as h, Zap as g } from "lucide-react";
10
+ import { gql as _ } from "@apollo/client";
11
+ import { useQuery as v } from "@apollo/client/react";
12
+ import { jsx as y, jsxs as b } from "react/jsx-runtime";
13
+ import { Badge as x, Card as S, CardContent as C, CardHeader as w, CardTitle as T } from "@burdenoff/fe-libs/ui";
13
14
  //#region src/planmagnet/pages/TeamTeamDetailPagePage.tsx
14
- var T = g`
15
+ var E = _`
15
16
  query GetTeamDetail($id: ID!) {
16
17
  planmagnetTeam(id: $id) {
17
18
  id
@@ -31,7 +32,7 @@ var T = g`
31
32
  }
32
33
  }
33
34
  }
34
- `, E = g`
35
+ `, D = _`
35
36
  query GetTeamSprints($workspaceId: ID!, $filter: PlanmagnetSprintFilter) {
36
37
  planmagnetSprints(workspaceId: $workspaceId, filter: $filter, pagination: { first: 50 }) {
37
38
  items {
@@ -51,149 +52,153 @@ var T = g`
51
52
  totalCount
52
53
  }
53
54
  }
54
- `, D = {
55
+ `, O = {
55
56
  PLANNING: "bg-blue-100 text-blue-800",
56
57
  ACTIVE: "bg-green-100 text-green-800",
57
58
  REVIEW: "bg-purple-100 text-purple-800",
58
59
  COMPLETED: "bg-gray-100 text-gray-800",
59
60
  CANCELLED: "bg-red-100 text-red-800"
60
61
  };
61
- function O() {
62
- let g = o("teamId"), { workspaceId: O } = e(), k = t(), { data: A, loading: j, error: M } = _(T, {
63
- variables: { id: g },
64
- skip: !g
65
- }), { data: N, loading: P } = _(E, {
62
+ function k() {
63
+ let _ = o("teamId"), { workspaceId: k } = e(), A = t(), { data: j, loading: M, error: N } = v(E, {
64
+ variables: { id: _ },
65
+ skip: !_
66
+ }), { data: P, loading: F } = v(D, {
66
67
  variables: {
67
- workspaceId: O ?? "",
68
- filter: { teamId: g }
68
+ workspaceId: k ?? "",
69
+ filter: { teamId: _ }
69
70
  },
70
- skip: !g || !O
71
+ skip: !_ || !k
71
72
  });
72
- if (!g) return /* @__PURE__ */ v("div", {
73
+ if (!_) return /* @__PURE__ */ y("div", {
73
74
  className: "p-6 text-muted-foreground",
74
75
  children: "No team selected. Open one from the list."
75
76
  });
76
- if (j && !A) return /* @__PURE__ */ v("div", {
77
+ if (M && !j) return /* @__PURE__ */ y("div", {
77
78
  className: "flex items-center justify-center p-12",
78
- children: /* @__PURE__ */ v("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
79
+ children: /* @__PURE__ */ y("div", { className: "animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full" })
79
80
  });
80
- if (M) return /* @__PURE__ */ y("div", {
81
+ if (N) return /* @__PURE__ */ b("div", {
81
82
  className: "p-6 text-destructive",
82
- children: ["Error loading team: ", M.message]
83
+ children: ["Error loading team: ", N.message]
83
84
  });
84
- let F = A?.planmagnetTeam;
85
- if (!F) return /* @__PURE__ */ v(s, {});
86
- let I = N?.planmagnetSprints.items ?? [];
87
- return /* @__PURE__ */ y("div", {
85
+ let I = j?.planmagnetTeam;
86
+ if (!I) return /* @__PURE__ */ y(s, {});
87
+ let L = P?.planmagnetSprints.items ?? [];
88
+ return /* @__PURE__ */ b("div", {
88
89
  className: "space-y-6 p-6",
89
90
  children: [
90
- /* @__PURE__ */ y("div", {
91
+ /* @__PURE__ */ b("div", {
91
92
  className: "flex items-start justify-between gap-4",
92
- children: [/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ y("div", {
93
+ children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ b("div", {
93
94
  className: "flex items-center gap-2",
94
- children: [/* @__PURE__ */ v(m, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ v("h1", {
95
+ children: [/* @__PURE__ */ y(h, { className: "h-5 w-5 text-primary" }), /* @__PURE__ */ y("h1", {
95
96
  className: "text-2xl font-semibold",
96
- children: F.name
97
+ children: I.name
97
98
  })]
98
- }), /* @__PURE__ */ v("p", {
99
+ }), /* @__PURE__ */ y("p", {
99
100
  className: "text-sm text-muted-foreground mt-1",
100
- children: F.description ?? "No description"
101
- })] }), /* @__PURE__ */ v(l, {
102
- teamId: F.id,
103
- name: F.name
101
+ children: I.description ?? "No description"
102
+ })] }), /* @__PURE__ */ y(u, {
103
+ teamId: I.id,
104
+ name: I.name
104
105
  })]
105
106
  }),
106
- /* @__PURE__ */ y("div", {
107
+ /* @__PURE__ */ b("div", {
107
108
  className: "grid grid-cols-2 md:grid-cols-4 gap-4",
108
109
  children: [
109
- /* @__PURE__ */ v(x, { children: /* @__PURE__ */ y(S, {
110
+ /* @__PURE__ */ y(S, { children: /* @__PURE__ */ b(C, {
110
111
  className: "pt-4",
111
- children: [/* @__PURE__ */ y("div", {
112
+ children: [/* @__PURE__ */ b("div", {
112
113
  className: "flex items-center gap-2 text-muted-foreground text-xs",
113
- children: [/* @__PURE__ */ v(p, { className: "h-4 w-4" }), "Lead"]
114
- }), /* @__PURE__ */ v("p", {
114
+ children: [/* @__PURE__ */ y(m, { className: "h-4 w-4" }), "Lead"]
115
+ }), /* @__PURE__ */ y("p", {
115
116
  className: "text-sm font-bold mt-1 truncate",
116
- children: F.leadId ? /* @__PURE__ */ v(n, { id: F.leadId }) : "No lead"
117
+ children: I.leadId ? /* @__PURE__ */ y(n, { id: I.leadId }) : "No lead"
117
118
  })]
118
119
  }) }),
119
- /* @__PURE__ */ v(x, { children: /* @__PURE__ */ y(S, {
120
+ /* @__PURE__ */ y(S, { children: /* @__PURE__ */ b(C, {
120
121
  className: "pt-4",
121
- children: [/* @__PURE__ */ y("div", {
122
+ children: [/* @__PURE__ */ b("div", {
122
123
  className: "flex items-center gap-2 text-muted-foreground text-xs",
123
- children: [/* @__PURE__ */ v(f, { className: "h-4 w-4" }), "Capacity"]
124
- }), /* @__PURE__ */ v("p", {
124
+ children: [/* @__PURE__ */ y(p, { className: "h-4 w-4" }), "Capacity"]
125
+ }), /* @__PURE__ */ y("p", {
125
126
  className: "text-xl font-bold mt-1",
126
- children: F.capacity ?? "—"
127
+ children: I.capacity ?? "—"
127
128
  })]
128
129
  }) }),
129
- /* @__PURE__ */ v(x, { children: /* @__PURE__ */ y(S, {
130
+ /* @__PURE__ */ y(S, { children: /* @__PURE__ */ b(C, {
130
131
  className: "pt-4",
131
- children: [/* @__PURE__ */ y("div", {
132
+ children: [/* @__PURE__ */ b("div", {
132
133
  className: "flex items-center gap-2 text-muted-foreground text-xs",
133
- children: [/* @__PURE__ */ v(m, { className: "h-4 w-4" }), "Members"]
134
- }), /* @__PURE__ */ v("p", {
134
+ children: [/* @__PURE__ */ y(h, { className: "h-4 w-4" }), "Members"]
135
+ }), /* @__PURE__ */ y("p", {
135
136
  className: "text-xl font-bold mt-1",
136
- children: F.members.length
137
+ children: I.members.length
137
138
  })]
138
139
  }) }),
139
- /* @__PURE__ */ v(x, { children: /* @__PURE__ */ y(S, {
140
+ /* @__PURE__ */ y(S, { children: /* @__PURE__ */ b(C, {
140
141
  className: "pt-4",
141
- children: [/* @__PURE__ */ y("div", {
142
+ children: [/* @__PURE__ */ b("div", {
142
143
  className: "flex items-center gap-2 text-muted-foreground text-xs",
143
- children: [/* @__PURE__ */ v(h, { className: "h-4 w-4" }), "Team sprints"]
144
- }), /* @__PURE__ */ v("p", {
144
+ children: [/* @__PURE__ */ y(g, { className: "h-4 w-4" }), "Team sprints"]
145
+ }), /* @__PURE__ */ y("p", {
145
146
  className: "text-xl font-bold mt-1",
146
- children: N?.planmagnetSprints.totalCount ?? (P ? "—" : I.length)
147
+ children: P?.planmagnetSprints.totalCount ?? (F ? "—" : L.length)
147
148
  })]
148
149
  }) })
149
150
  ]
150
151
  }),
151
- /* @__PURE__ */ y("div", {
152
+ /* @__PURE__ */ b("div", {
152
153
  className: "grid grid-cols-1 lg:grid-cols-2 gap-6",
153
- children: [/* @__PURE__ */ y(x, { children: [/* @__PURE__ */ v(C, { children: /* @__PURE__ */ v(w, { children: "Members" }) }), /* @__PURE__ */ v(S, { children: /* @__PURE__ */ v(u, {
154
- teamId: F.id,
155
- members: F.members
156
- }) })] }), /* @__PURE__ */ y(x, { children: [/* @__PURE__ */ v(C, { children: /* @__PURE__ */ v(w, { children: "Projects" }) }), /* @__PURE__ */ v(S, { children: /* @__PURE__ */ v(d, {
157
- teamId: F.id,
158
- projects: F.projects
154
+ children: [/* @__PURE__ */ b(S, { children: [/* @__PURE__ */ y(w, { children: /* @__PURE__ */ y(T, { children: "Members" }) }), /* @__PURE__ */ y(C, { children: /* @__PURE__ */ y(d, {
155
+ teamId: I.id,
156
+ members: I.members
157
+ }) })] }), /* @__PURE__ */ b(S, { children: [/* @__PURE__ */ y(w, { children: /* @__PURE__ */ y(T, { children: "Projects" }) }), /* @__PURE__ */ y(C, { children: /* @__PURE__ */ y(f, {
158
+ teamId: I.id,
159
+ projects: I.projects
159
160
  }) })] })]
160
161
  }),
161
- /* @__PURE__ */ y(x, { children: [/* @__PURE__ */ y(C, {
162
+ /* @__PURE__ */ y(l, {
163
+ workspaceId: k,
164
+ teamId: I.id
165
+ }),
166
+ /* @__PURE__ */ b(S, { children: [/* @__PURE__ */ b(w, {
162
167
  className: "flex flex-row items-center justify-between space-y-0",
163
- children: [/* @__PURE__ */ v(w, { children: "Sprints" }), /* @__PURE__ */ v(c, {
168
+ children: [/* @__PURE__ */ y(T, { children: "Sprints" }), /* @__PURE__ */ y(c, {
164
169
  initialScope: "team",
165
- initialTeamId: F.id,
166
- onCreated: (e) => k(i("/projects/planning-detail-page", e))
170
+ initialTeamId: I.id,
171
+ onCreated: (e) => A(i("/projects/planning-detail-page", e))
167
172
  })]
168
- }), /* @__PURE__ */ y(S, {
173
+ }), /* @__PURE__ */ b(C, {
169
174
  className: "space-y-2",
170
175
  children: [
171
- P && I.length === 0 && /* @__PURE__ */ v("p", {
176
+ F && L.length === 0 && /* @__PURE__ */ y("p", {
172
177
  className: "text-sm text-muted-foreground text-center py-4",
173
178
  children: "Loading sprints…"
174
179
  }),
175
- !P && I.length === 0 && /* @__PURE__ */ v("p", {
180
+ !F && L.length === 0 && /* @__PURE__ */ y("p", {
176
181
  className: "text-sm text-muted-foreground text-center py-4",
177
182
  children: "No sprints yet. A team sprint can only include work items from this team's projects."
178
183
  }),
179
- I.map((e) => {
184
+ L.map((e) => {
180
185
  let t = e.workItems.reduce((e, t) => e + (t.storyPoints ?? 0), 0), n = e.workItems.filter((e) => e.status === "DONE").reduce((e, t) => e + (t.storyPoints ?? 0), 0);
181
- return /* @__PURE__ */ y("div", {
182
- ...a(() => k(i("/projects/planning-detail-page", e.id)), e.name),
186
+ return /* @__PURE__ */ b("div", {
187
+ ...a(() => A(i("/projects/planning-detail-page", e.id)), e.name),
183
188
  className: `flex items-center justify-between border rounded-md p-2.5 ${r}`,
184
- children: [/* @__PURE__ */ y("div", { children: [/* @__PURE__ */ v("p", {
189
+ children: [/* @__PURE__ */ b("div", { children: [/* @__PURE__ */ y("p", {
185
190
  className: "text-sm font-medium",
186
191
  children: e.name
187
- }), e.goal && /* @__PURE__ */ v("p", {
192
+ }), e.goal && /* @__PURE__ */ y("p", {
188
193
  className: "text-xs text-muted-foreground",
189
194
  children: e.goal
190
- })] }), /* @__PURE__ */ y("div", {
195
+ })] }), /* @__PURE__ */ b("div", {
191
196
  className: "flex items-center gap-2",
192
- children: [/* @__PURE__ */ v("span", {
197
+ children: [/* @__PURE__ */ y("span", {
193
198
  className: "text-xs text-muted-foreground",
194
199
  children: e.status === "COMPLETED" && e.velocity != null ? `${e.velocity} pts velocity` : `${n}/${t} pts`
195
- }), /* @__PURE__ */ v("span", {
196
- className: `text-xs px-2 py-0.5 rounded-full capitalize ${D[e.status] ?? "bg-gray-100"}`,
200
+ }), /* @__PURE__ */ y("span", {
201
+ className: `text-xs px-2 py-0.5 rounded-full capitalize ${O[e.status] ?? "bg-gray-100"}`,
197
202
  children: e.status.toLowerCase().replace("_", " ")
198
203
  })]
199
204
  })]
@@ -201,17 +206,17 @@ function O() {
201
206
  })
202
207
  ]
203
208
  })] }),
204
- /* @__PURE__ */ y("p", {
209
+ /* @__PURE__ */ b("p", {
205
210
  className: "text-xs text-muted-foreground",
206
- children: ["Created ", /* @__PURE__ */ v(b, {
211
+ children: ["Created ", /* @__PURE__ */ y(x, {
207
212
  variant: "outline",
208
- children: new Date(F.createdAt).toLocaleDateString()
213
+ children: new Date(I.createdAt).toLocaleDateString()
209
214
  })]
210
215
  })
211
216
  ]
212
217
  });
213
218
  }
214
219
  //#endregion
215
- export { O as TeamTeamDetailPagePage };
220
+ export { k as TeamTeamDetailPagePage };
216
221
 
217
222
  //# sourceMappingURL=TeamTeamDetailPagePage.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"TeamTeamDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TeamTeamDetailPagePage.tsx"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Badge, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Users, UserRound, Gauge, Zap } from 'lucide-react';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { ROW_LINK_CLASS, detailPath, rowLinkProps } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { TeamHeaderActions, TeamMembersPanel, TeamProjectsPanel } from '../team/TeamControls';\nimport { NewSprintDialog } from '../sprints/SprintControls';\nimport { PlanMagnetNotFoundPage } from './NotFoundPage';\n\n/**\n * Team detail (BOFF-8044): members, lead, capacity, projects, and the team's own sprints\n * (sprints whose scope is this team, never a project — sprint scope is PROJECT xor TEAM).\n */\n\nconst GET_TEAM_DETAIL = gql`\n query GetTeamDetail($id: ID!) {\n planmagnetTeam(id: $id) {\n id\n name\n description\n leadId\n capacity\n createdAt\n members {\n id\n actorId\n }\n projects {\n id\n name\n key\n }\n }\n }\n`;\n\nconst GET_TEAM_SPRINTS = gql`\n query GetTeamSprints($workspaceId: ID!, $filter: PlanmagnetSprintFilter) {\n planmagnetSprints(workspaceId: $workspaceId, filter: $filter, pagination: { first: 50 }) {\n items {\n id\n name\n status\n goal\n velocity\n startDate\n endDate\n workItems {\n id\n status\n storyPoints\n }\n }\n totalCount\n }\n }\n`;\n\ninterface TeamDetail {\n id: string;\n name: string;\n description: string | null;\n leadId: string | null;\n capacity: number | null;\n createdAt: string;\n members: { id: string; actorId: string }[];\n projects: { id: string; name: string; key: string }[];\n}\n\ninterface TeamSprintNode {\n id: string;\n name: string;\n status: string;\n goal: string | null;\n velocity: number | null;\n startDate: string | null;\n endDate: string | null;\n workItems: { id: string; status: string; storyPoints: number | null }[];\n}\n\nconst statusColor: Record<string, string> = {\n PLANNING: 'bg-blue-100 text-blue-800',\n ACTIVE: 'bg-green-100 text-green-800',\n REVIEW: 'bg-purple-100 text-purple-800',\n COMPLETED: 'bg-gray-100 text-gray-800',\n CANCELLED: 'bg-red-100 text-red-800',\n};\n\nexport function TeamTeamDetailPagePage() {\n const teamId = useEntityId('teamId');\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n\n const { data, loading, error } = useQuery<{ planmagnetTeam: TeamDetail | null }>(\n GET_TEAM_DETAIL,\n { variables: { id: teamId }, skip: !teamId }\n );\n const { data: sprintData, loading: sprintsLoading } = useQuery<{\n planmagnetSprints: { items: TeamSprintNode[]; totalCount: number };\n }>(GET_TEAM_SPRINTS, {\n variables: { workspaceId: workspaceId ?? '', filter: { teamId } },\n skip: !teamId || !workspaceId,\n });\n\n if (!teamId) {\n return (\n <div className=\"p-6 text-muted-foreground\">No team selected. Open one from the list.</div>\n );\n }\n // Only before the first load: a refetch must not blank the page (it\n // unmounts every component on it and loses their state).\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n if (error) {\n return <div className=\"p-6 text-destructive\">Error loading team: {error.message}</div>;\n }\n\n const team = data?.planmagnetTeam;\n // Deleted, unauthorized or an unknown id all read back the same way (no cross-tenant existence\n // leak) — the real 404 page, not an inline message and not a same-URL redirect (H5).\n if (!team) return <PlanMagnetNotFoundPage />;\n\n const sprints = sprintData?.planmagnetSprints.items ?? [];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-start justify-between gap-4\">\n <div>\n <div className=\"flex items-center gap-2\">\n <Users className=\"h-5 w-5 text-primary\" />\n <h1 className=\"text-2xl font-semibold\">{team.name}</h1>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {team.description ?? 'No description'}\n </p>\n </div>\n <TeamHeaderActions teamId={team.id} name={team.name} />\n </div>\n\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <UserRound className=\"h-4 w-4\" />\n Lead\n </div>\n <p className=\"text-sm font-bold mt-1 truncate\">\n {team.leadId ? <PersonName id={team.leadId} /> : 'No lead'}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Gauge className=\"h-4 w-4\" />\n Capacity\n </div>\n <p className=\"text-xl font-bold mt-1\">{team.capacity ?? '—'}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Users className=\"h-4 w-4\" />\n Members\n </div>\n <p className=\"text-xl font-bold mt-1\">{team.members.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Zap className=\"h-4 w-4\" />\n Team sprints\n </div>\n <p className=\"text-xl font-bold mt-1\">\n {sprintData?.planmagnetSprints.totalCount ?? (sprintsLoading ? '—' : sprints.length)}\n </p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n <Card>\n <CardHeader>\n <CardTitle>Members</CardTitle>\n </CardHeader>\n <CardContent>\n <TeamMembersPanel teamId={team.id} members={team.members} />\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Projects</CardTitle>\n </CardHeader>\n <CardContent>\n <TeamProjectsPanel teamId={team.id} projects={team.projects} />\n </CardContent>\n </Card>\n </div>\n\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0\">\n <CardTitle>Sprints</CardTitle>\n <NewSprintDialog\n initialScope=\"team\"\n initialTeamId={team.id}\n onCreated={(id) => navigate(detailPath('/projects/planning-detail-page', id))}\n />\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {sprintsLoading && sprints.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-4\">Loading sprints…</p>\n )}\n {!sprintsLoading && sprints.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-4\">\n No sprints yet. A team sprint can only include work items from this team&apos;s\n projects.\n </p>\n )}\n {sprints.map((sprint) => {\n const totalPoints = sprint.workItems.reduce(\n (sum, wi) => sum + (wi.storyPoints ?? 0),\n 0\n );\n const donePoints = sprint.workItems\n .filter((wi) => wi.status === 'DONE')\n .reduce((sum, wi) => sum + (wi.storyPoints ?? 0), 0);\n return (\n <div\n key={sprint.id}\n {...rowLinkProps(\n () => navigate(detailPath('/projects/planning-detail-page', sprint.id)),\n sprint.name\n )}\n className={`flex items-center justify-between border rounded-md p-2.5 ${ROW_LINK_CLASS}`}\n >\n <div>\n <p className=\"text-sm font-medium\">{sprint.name}</p>\n {sprint.goal && <p className=\"text-xs text-muted-foreground\">{sprint.goal}</p>}\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">\n {sprint.status === 'COMPLETED' && sprint.velocity != null\n ? `${sprint.velocity} pts velocity`\n : `${donePoints}/${totalPoints} pts`}\n </span>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[sprint.status] ?? 'bg-gray-100'}`}\n >\n {sprint.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n </div>\n );\n })}\n </CardContent>\n </Card>\n\n <p className=\"text-xs text-muted-foreground\">\n Created <Badge variant=\"outline\">{new Date(team.createdAt).toLocaleDateString()}</Badge>\n </p>\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"TeamTeamDetailPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/TeamTeamDetailPagePage.tsx"],"sourcesContent":["import { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport { Badge, Card, CardContent, CardHeader, CardTitle } from '@burdenoff/fe-libs/ui';\nimport { Users, UserRound, Gauge, Zap } from 'lucide-react';\nimport { useEntityId } from '../hooks/useEntityId';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { ROW_LINK_CLASS, detailPath, rowLinkProps } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { TeamHeaderActions, TeamMembersPanel, TeamProjectsPanel } from '../team/TeamControls';\nimport { NewSprintDialog } from '../sprints/SprintControls';\nimport { PlanMagnetNotFoundPage } from './NotFoundPage';\nimport { ResourceForecastCard } from '../forecast/ResourceForecastCard';\n\n/**\n * Team detail (BOFF-8044): members, lead, capacity, projects, and the team's own sprints\n * (sprints whose scope is this team, never a project — sprint scope is PROJECT xor TEAM).\n */\n\nconst GET_TEAM_DETAIL = gql`\n query GetTeamDetail($id: ID!) {\n planmagnetTeam(id: $id) {\n id\n name\n description\n leadId\n capacity\n createdAt\n members {\n id\n actorId\n }\n projects {\n id\n name\n key\n }\n }\n }\n`;\n\nconst GET_TEAM_SPRINTS = gql`\n query GetTeamSprints($workspaceId: ID!, $filter: PlanmagnetSprintFilter) {\n planmagnetSprints(workspaceId: $workspaceId, filter: $filter, pagination: { first: 50 }) {\n items {\n id\n name\n status\n goal\n velocity\n startDate\n endDate\n workItems {\n id\n status\n storyPoints\n }\n }\n totalCount\n }\n }\n`;\n\ninterface TeamDetail {\n id: string;\n name: string;\n description: string | null;\n leadId: string | null;\n capacity: number | null;\n createdAt: string;\n members: { id: string; actorId: string }[];\n projects: { id: string; name: string; key: string }[];\n}\n\ninterface TeamSprintNode {\n id: string;\n name: string;\n status: string;\n goal: string | null;\n velocity: number | null;\n startDate: string | null;\n endDate: string | null;\n workItems: { id: string; status: string; storyPoints: number | null }[];\n}\n\nconst statusColor: Record<string, string> = {\n PLANNING: 'bg-blue-100 text-blue-800',\n ACTIVE: 'bg-green-100 text-green-800',\n REVIEW: 'bg-purple-100 text-purple-800',\n COMPLETED: 'bg-gray-100 text-gray-800',\n CANCELLED: 'bg-red-100 text-red-800',\n};\n\nexport function TeamTeamDetailPagePage() {\n const teamId = useEntityId('teamId');\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n\n const { data, loading, error } = useQuery<{ planmagnetTeam: TeamDetail | null }>(\n GET_TEAM_DETAIL,\n { variables: { id: teamId }, skip: !teamId }\n );\n const { data: sprintData, loading: sprintsLoading } = useQuery<{\n planmagnetSprints: { items: TeamSprintNode[]; totalCount: number };\n }>(GET_TEAM_SPRINTS, {\n variables: { workspaceId: workspaceId ?? '', filter: { teamId } },\n skip: !teamId || !workspaceId,\n });\n\n if (!teamId) {\n return (\n <div className=\"p-6 text-muted-foreground\">No team selected. Open one from the list.</div>\n );\n }\n // Only before the first load: a refetch must not blank the page (it\n // unmounts every component on it and loses their state).\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n if (error) {\n return <div className=\"p-6 text-destructive\">Error loading team: {error.message}</div>;\n }\n\n const team = data?.planmagnetTeam;\n // Deleted, unauthorized or an unknown id all read back the same way (no cross-tenant existence\n // leak) — the real 404 page, not an inline message and not a same-URL redirect (H5).\n if (!team) return <PlanMagnetNotFoundPage />;\n\n const sprints = sprintData?.planmagnetSprints.items ?? [];\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-start justify-between gap-4\">\n <div>\n <div className=\"flex items-center gap-2\">\n <Users className=\"h-5 w-5 text-primary\" />\n <h1 className=\"text-2xl font-semibold\">{team.name}</h1>\n </div>\n <p className=\"text-sm text-muted-foreground mt-1\">\n {team.description ?? 'No description'}\n </p>\n </div>\n <TeamHeaderActions teamId={team.id} name={team.name} />\n </div>\n\n <div className=\"grid grid-cols-2 md:grid-cols-4 gap-4\">\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <UserRound className=\"h-4 w-4\" />\n Lead\n </div>\n <p className=\"text-sm font-bold mt-1 truncate\">\n {team.leadId ? <PersonName id={team.leadId} /> : 'No lead'}\n </p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Gauge className=\"h-4 w-4\" />\n Capacity\n </div>\n <p className=\"text-xl font-bold mt-1\">{team.capacity ?? '—'}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Users className=\"h-4 w-4\" />\n Members\n </div>\n <p className=\"text-xl font-bold mt-1\">{team.members.length}</p>\n </CardContent>\n </Card>\n <Card>\n <CardContent className=\"pt-4\">\n <div className=\"flex items-center gap-2 text-muted-foreground text-xs\">\n <Zap className=\"h-4 w-4\" />\n Team sprints\n </div>\n <p className=\"text-xl font-bold mt-1\">\n {sprintData?.planmagnetSprints.totalCount ?? (sprintsLoading ? '—' : sprints.length)}\n </p>\n </CardContent>\n </Card>\n </div>\n\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n <Card>\n <CardHeader>\n <CardTitle>Members</CardTitle>\n </CardHeader>\n <CardContent>\n <TeamMembersPanel teamId={team.id} members={team.members} />\n </CardContent>\n </Card>\n <Card>\n <CardHeader>\n <CardTitle>Projects</CardTitle>\n </CardHeader>\n <CardContent>\n <TeamProjectsPanel teamId={team.id} projects={team.projects} />\n </CardContent>\n </Card>\n </div>\n\n {/* ANR-11: capacity vs. this team's own open backlog, across its live member projects. */}\n <ResourceForecastCard workspaceId={workspaceId} teamId={team.id} />\n\n <Card>\n <CardHeader className=\"flex flex-row items-center justify-between space-y-0\">\n <CardTitle>Sprints</CardTitle>\n <NewSprintDialog\n initialScope=\"team\"\n initialTeamId={team.id}\n onCreated={(id) => navigate(detailPath('/projects/planning-detail-page', id))}\n />\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {sprintsLoading && sprints.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-4\">Loading sprints…</p>\n )}\n {!sprintsLoading && sprints.length === 0 && (\n <p className=\"text-sm text-muted-foreground text-center py-4\">\n No sprints yet. A team sprint can only include work items from this team&apos;s\n projects.\n </p>\n )}\n {sprints.map((sprint) => {\n const totalPoints = sprint.workItems.reduce(\n (sum, wi) => sum + (wi.storyPoints ?? 0),\n 0\n );\n const donePoints = sprint.workItems\n .filter((wi) => wi.status === 'DONE')\n .reduce((sum, wi) => sum + (wi.storyPoints ?? 0), 0);\n return (\n <div\n key={sprint.id}\n {...rowLinkProps(\n () => navigate(detailPath('/projects/planning-detail-page', sprint.id)),\n sprint.name\n )}\n className={`flex items-center justify-between border rounded-md p-2.5 ${ROW_LINK_CLASS}`}\n >\n <div>\n <p className=\"text-sm font-medium\">{sprint.name}</p>\n {sprint.goal && <p className=\"text-xs text-muted-foreground\">{sprint.goal}</p>}\n </div>\n <div className=\"flex items-center gap-2\">\n <span className=\"text-xs text-muted-foreground\">\n {sprint.status === 'COMPLETED' && sprint.velocity != null\n ? `${sprint.velocity} pts velocity`\n : `${donePoints}/${totalPoints} pts`}\n </span>\n <span\n className={`text-xs px-2 py-0.5 rounded-full capitalize ${statusColor[sprint.status] ?? 'bg-gray-100'}`}\n >\n {sprint.status.toLowerCase().replace('_', ' ')}\n </span>\n </div>\n </div>\n );\n })}\n </CardContent>\n </Card>\n\n <p className=\"text-xs text-muted-foreground\">\n Created <Badge variant=\"outline\">{new Date(team.createdAt).toLocaleDateString()}</Badge>\n </p>\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"SprintDeliveryCards.d.ts","sourceRoot":"","sources":["../../../../src/planmagnet/pages/analytics/SprintDeliveryCards.tsx"],"names":[],"mappings":"AAkGA,wBAAgB,kBAAkB,CAAC,EACjC,WAAW,EACX,QAAQ,GACT,EAAE;IACD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB,2CA2EA;AAED,wBAAgB,kBAAkB,CAAC,EACjC,WAAW,EACX,SAAS,EACT,mBAAuB,GACxB,EAAE;IACD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,2CA6FA"}
1
+ {"version":3,"file":"SprintDeliveryCards.d.ts","sourceRoot":"","sources":["../../../../src/planmagnet/pages/analytics/SprintDeliveryCards.tsx"],"names":[],"mappings":"AA0GA,wBAAgB,kBAAkB,CAAC,EACjC,WAAW,EACX,QAAQ,GACT,EAAE;IACD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,QAAQ,EAAE,MAAM,CAAC;CAClB,2CA2EA;AAED,wBAAgB,kBAAkB,CAAC,EACjC,WAAW,EACX,SAAS,EACT,mBAAuB,GACxB,EAAE;IACD,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,SAAS,EAAE,MAAM,CAAC;IAClB,mBAAmB,CAAC,EAAE,MAAM,CAAC;CAC9B,2CAgIA"}