@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
@@ -0,0 +1,116 @@
1
+ import { mutationErrorMessage as e } from "../utils/graphqlErrors.js";
2
+ import { EXPORT_REPORT_RUN as t } from "./reportGraphql.js";
3
+ import { useState as n } from "react";
4
+ import { Download as r, Printer as i } from "lucide-react";
5
+ import { useApolloClient as a } from "@apollo/client/react";
6
+ import { jsx as o, jsxs as s } from "react/jsx-runtime";
7
+ import { Button as c, DropdownMenu as l, DropdownMenuContent as u, DropdownMenuItem as d, DropdownMenuLabel as f, DropdownMenuSeparator as p, DropdownMenuTrigger as m } from "@burdenoff/fe-libs/ui";
8
+ //#region src/planmagnet/reports/ExportMenu.tsx
9
+ function h(e) {
10
+ return e.toLowerCase().trim().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "") || "report";
11
+ }
12
+ function g(e, t, n) {
13
+ let r = new Blob([n], { type: t || "text/plain;charset=utf-8" }), i = URL.createObjectURL(r), a = document.createElement("a");
14
+ a.href = i, a.download = e, document.body.appendChild(a), a.click(), a.remove(), URL.revokeObjectURL(i);
15
+ }
16
+ function _({ reportName: _, widgets: v, run: y, onPrint: b }) {
17
+ let x = a(), [S, C] = n(null), [w, T] = n(null), E = `${h(_)}-${(/* @__PURE__ */ new Date()).toISOString().slice(0, 10)}`, D = !y, O = async (n) => {
18
+ if (y) {
19
+ C(n), T(null);
20
+ try {
21
+ let e = await x.query({
22
+ query: t,
23
+ variables: {
24
+ runId: y.id,
25
+ format: n
26
+ },
27
+ fetchPolicy: "network-only"
28
+ });
29
+ if (e.error) throw e.error;
30
+ let r = e.data?.planmagnetExportReportRun;
31
+ if (!r) throw Error("The export could not be generated.");
32
+ g(r.filename, r.contentType, r.content);
33
+ } catch (t) {
34
+ T(e(t, "The export failed."));
35
+ } finally {
36
+ C(null);
37
+ }
38
+ }
39
+ }, k = async () => {
40
+ if (y) {
41
+ C("XLSX"), T(null);
42
+ try {
43
+ let { exportReportRunToXlsx: e } = await import("./reportExportXlsx.js");
44
+ await e(v, y, E);
45
+ } catch (t) {
46
+ T(e(t, "The Excel export failed."));
47
+ } finally {
48
+ C(null);
49
+ }
50
+ }
51
+ }, A = async () => {
52
+ if (y) {
53
+ C("PPTX"), T(null);
54
+ try {
55
+ let { exportReportRunToPptx: e } = await import("./reportExportPptx.js");
56
+ await e(v, y, E, _);
57
+ } catch (t) {
58
+ T(e(t, "The PowerPoint export failed."));
59
+ } finally {
60
+ C(null);
61
+ }
62
+ }
63
+ };
64
+ return /* @__PURE__ */ s("div", {
65
+ className: "flex items-center gap-2",
66
+ children: [/* @__PURE__ */ s(l, { children: [/* @__PURE__ */ o(m, {
67
+ asChild: !0,
68
+ children: /* @__PURE__ */ s(c, {
69
+ size: "sm",
70
+ variant: "outline",
71
+ disabled: D,
72
+ "data-testid": "report-export",
73
+ children: [/* @__PURE__ */ o(r, { className: "mr-1 h-4 w-4" }), S ? `Exporting ${S}…` : "Export"]
74
+ })
75
+ }), /* @__PURE__ */ s(u, {
76
+ align: "end",
77
+ children: [
78
+ /* @__PURE__ */ o(f, { children: "Data" }),
79
+ /* @__PURE__ */ o(d, {
80
+ onSelect: () => void O("CSV"),
81
+ children: "CSV"
82
+ }),
83
+ /* @__PURE__ */ o(d, {
84
+ onSelect: () => void O("JSON"),
85
+ children: "JSON"
86
+ }),
87
+ /* @__PURE__ */ o(d, {
88
+ onSelect: () => void O("XML"),
89
+ children: "XML"
90
+ }),
91
+ /* @__PURE__ */ o(p, {}),
92
+ /* @__PURE__ */ o(f, { children: "Documents" }),
93
+ /* @__PURE__ */ o(d, {
94
+ onSelect: () => void k(),
95
+ children: "Excel (.xlsx)"
96
+ }),
97
+ /* @__PURE__ */ o(d, {
98
+ onSelect: () => void A(),
99
+ children: "PowerPoint (.pptx)"
100
+ }),
101
+ /* @__PURE__ */ s(d, {
102
+ onSelect: b,
103
+ children: [/* @__PURE__ */ o(i, { className: "mr-1 h-3.5 w-3.5" }), "PDF (print)"]
104
+ })
105
+ ]
106
+ })] }), w && /* @__PURE__ */ o("span", {
107
+ role: "alert",
108
+ className: "text-xs text-destructive",
109
+ children: w
110
+ })]
111
+ });
112
+ }
113
+ //#endregion
114
+ export { _ as ExportMenu };
115
+
116
+ //# sourceMappingURL=ExportMenu.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportMenu.js","names":[],"sources":["../../../src/planmagnet/reports/ExportMenu.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { useApolloClient } from '@apollo/client/react';\nimport {\n Button,\n DropdownMenu,\n DropdownMenuContent,\n DropdownMenuItem,\n DropdownMenuLabel,\n DropdownMenuSeparator,\n DropdownMenuTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { Download, Printer } from 'lucide-react';\nimport { mutationErrorMessage } from '../utils/graphqlErrors';\nimport { EXPORT_REPORT_RUN } from './reportGraphql';\nimport type { ReportExportFormat, ReportRun, ReportWidget } from './reportModel';\n\n/**\n * Export a run (ANR-16). CSV/JSON/XML are rendered server-side (`planmagnetExportReportRun`) and downloaded as\n * given. Excel/PowerPoint are built client-side from the same already-fetched run, via a dynamic `import()` so\n * `write-excel-file`/`pptxgenjs` only ever load when actually used. PDF is a print-optimised view + the\n * browser's own \"Save as PDF\" (`onPrint`) — no PDF library.\n */\n\nfunction slugify(name: string): string {\n return (\n name\n .toLowerCase()\n .trim()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-+|-+$/g, '') || 'report'\n );\n}\n\nfunction downloadTextFile(filename: string, contentType: string, content: string): void {\n const blob = new Blob([content], { type: contentType || 'text/plain;charset=utf-8' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = filename;\n document.body.appendChild(link);\n link.click();\n link.remove();\n URL.revokeObjectURL(url);\n}\n\nexport function ExportMenu({\n reportName,\n widgets,\n run,\n onPrint,\n}: {\n reportName: string;\n widgets: ReportWidget[];\n run: ReportRun | null;\n onPrint: () => void;\n}) {\n const client = useApolloClient();\n const [busy, setBusy] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const fileNameBase = `${slugify(reportName)}-${new Date().toISOString().slice(0, 10)}`;\n const disabled = !run;\n\n const exportServerFormat = async (format: ReportExportFormat) => {\n if (!run) return;\n setBusy(format);\n setError(null);\n try {\n const result = await client.query<{\n planmagnetExportReportRun: { filename: string; contentType: string; content: string };\n }>({\n query: EXPORT_REPORT_RUN,\n variables: { runId: run.id, format },\n fetchPolicy: 'network-only',\n });\n if (result.error) throw result.error;\n const file = result.data?.planmagnetExportReportRun;\n if (!file) throw new Error('The export could not be generated.');\n downloadTextFile(file.filename, file.contentType, file.content);\n } catch (e) {\n setError(mutationErrorMessage(e, 'The export failed.'));\n } finally {\n setBusy(null);\n }\n };\n\n const exportXlsx = async () => {\n if (!run) return;\n setBusy('XLSX');\n setError(null);\n try {\n const { exportReportRunToXlsx } = await import('./reportExportXlsx');\n await exportReportRunToXlsx(widgets, run, fileNameBase);\n } catch (e) {\n setError(mutationErrorMessage(e, 'The Excel export failed.'));\n } finally {\n setBusy(null);\n }\n };\n\n const exportPptx = async () => {\n if (!run) return;\n setBusy('PPTX');\n setError(null);\n try {\n const { exportReportRunToPptx } = await import('./reportExportPptx');\n await exportReportRunToPptx(widgets, run, fileNameBase, reportName);\n } catch (e) {\n setError(mutationErrorMessage(e, 'The PowerPoint export failed.'));\n } finally {\n setBusy(null);\n }\n };\n\n return (\n <div className=\"flex items-center gap-2\">\n <DropdownMenu>\n <DropdownMenuTrigger asChild>\n <Button size=\"sm\" variant=\"outline\" disabled={disabled} data-testid=\"report-export\">\n <Download className=\"mr-1 h-4 w-4\" />\n {busy ? `Exporting ${busy}…` : 'Export'}\n </Button>\n </DropdownMenuTrigger>\n <DropdownMenuContent align=\"end\">\n <DropdownMenuLabel>Data</DropdownMenuLabel>\n <DropdownMenuItem onSelect={() => void exportServerFormat('CSV')}>CSV</DropdownMenuItem>\n <DropdownMenuItem onSelect={() => void exportServerFormat('JSON')}>JSON</DropdownMenuItem>\n <DropdownMenuItem onSelect={() => void exportServerFormat('XML')}>XML</DropdownMenuItem>\n <DropdownMenuSeparator />\n <DropdownMenuLabel>Documents</DropdownMenuLabel>\n <DropdownMenuItem onSelect={() => void exportXlsx()}>Excel (.xlsx)</DropdownMenuItem>\n <DropdownMenuItem onSelect={() => void exportPptx()}>PowerPoint (.pptx)</DropdownMenuItem>\n <DropdownMenuItem onSelect={onPrint}>\n <Printer className=\"mr-1 h-3.5 w-3.5\" />\n PDF (print)\n </DropdownMenuItem>\n </DropdownMenuContent>\n </DropdownMenu>\n {error && (\n <span role=\"alert\" className=\"text-xs text-destructive\">\n {error}\n </span>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import { ReportWidget, WidgetRunResult } from './reportModel';
2
+
3
+ /**
4
+ * The print-optimised view (ANR-16's PDF export — a print stylesheet, not a PDF library: `window.print()` lets
5
+ * the browser's own "Save as PDF" do the rendering). Reused by both the in-app Export ▸ PDF flow
6
+ * (`ReportsReportPagePage.tsx`, the owner's own widgets/results) and the public `SharedReportPage` (a synthetic
7
+ * `CHART`-typed widget per result, since a share's snapshot carries no widget title/type — see that file).
8
+ *
9
+ * The toolbar (`print:hidden`) never appears in the printed/PDF output, only on screen. The watermark, when
10
+ * set, is `aria-hidden` (decorative) but rendered both on screen and in print via a fixed, tiled overlay —
11
+ * never only in a `@media print` block this package cannot ship (Tailwind utility classes only, per this
12
+ * repo's design constraints).
13
+ */
14
+ export declare function PrintReportView({ reportName, generatedAt, watermark, widgets, results, onClose, onPrintNow, }: {
15
+ reportName: string;
16
+ generatedAt: string;
17
+ watermark?: string | null;
18
+ widgets: ReportWidget[];
19
+ results: Map<string, WidgetRunResult>;
20
+ /** Omit for the public shared view, which has no "back to the builder" to return to. */
21
+ onClose?: () => void;
22
+ onPrintNow: () => void;
23
+ }): import("react/jsx-runtime").JSX.Element;
24
+ //# sourceMappingURL=PrintReportView.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PrintReportView.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/reports/PrintReportView.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAEnE;;;;;;;;;;GAUG;AACH,wBAAgB,eAAe,CAAC,EAC9B,UAAU,EACV,WAAW,EACX,SAAS,EACT,OAAO,EACP,OAAO,EACP,OAAO,EACP,UAAU,GACX,EAAE;IACD,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;IACtC,wFAAwF;IACxF,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB,2CA+DA"}
@@ -0,0 +1,75 @@
1
+ import { ReportWidgetRenderer as e } from "./ReportWidgetRenderer.js";
2
+ import { Printer as t, X as n } from "lucide-react";
3
+ import { jsx as r, jsxs as i } from "react/jsx-runtime";
4
+ import { Button as a } from "@burdenoff/fe-libs/ui";
5
+ //#region src/planmagnet/reports/PrintReportView.tsx
6
+ function o({ reportName: o, generatedAt: s, watermark: c, widgets: l, results: u, onClose: d, onPrintNow: f }) {
7
+ return /* @__PURE__ */ i("div", {
8
+ className: "relative mx-auto max-w-4xl bg-background p-6 text-foreground",
9
+ "data-testid": "print-report-view",
10
+ children: [
11
+ c && /* @__PURE__ */ r("div", {
12
+ "aria-hidden": !0,
13
+ className: "pointer-events-none fixed inset-0 z-50 flex flex-wrap content-around justify-around gap-16 overflow-hidden opacity-10 print:opacity-20",
14
+ children: Array.from({ length: 24 }, (e, t) => /* @__PURE__ */ r("span", {
15
+ className: "whitespace-nowrap rotate-[-30deg] text-2xl font-semibold text-foreground",
16
+ children: c
17
+ }, t))
18
+ }),
19
+ /* @__PURE__ */ i("div", {
20
+ className: "mb-4 flex items-center justify-between gap-2 print:hidden",
21
+ children: [/* @__PURE__ */ r("p", {
22
+ className: "text-xs text-muted-foreground",
23
+ children: "Use your browser’s print dialog to save this as a PDF."
24
+ }), /* @__PURE__ */ i("div", {
25
+ className: "flex gap-2",
26
+ children: [/* @__PURE__ */ i(a, {
27
+ size: "sm",
28
+ onClick: f,
29
+ "data-testid": "print-report-now",
30
+ children: [/* @__PURE__ */ r(t, { className: "mr-1 h-4 w-4" }), "Print / Save as PDF"]
31
+ }), d && /* @__PURE__ */ i(a, {
32
+ size: "sm",
33
+ variant: "outline",
34
+ onClick: d,
35
+ children: [/* @__PURE__ */ r(n, { className: "mr-1 h-4 w-4" }), "Close"]
36
+ })]
37
+ })]
38
+ }),
39
+ /* @__PURE__ */ i("header", {
40
+ className: "mb-6 border-b border-border pb-4",
41
+ children: [
42
+ /* @__PURE__ */ r("p", {
43
+ className: "text-xs font-semibold uppercase tracking-wide text-primary",
44
+ children: "PlanMagnet"
45
+ }),
46
+ /* @__PURE__ */ r("h1", {
47
+ className: "text-2xl font-bold",
48
+ children: o
49
+ }),
50
+ /* @__PURE__ */ i("p", {
51
+ className: "text-sm text-muted-foreground",
52
+ children: ["Generated ", new Date(s).toLocaleString()]
53
+ })
54
+ ]
55
+ }),
56
+ /* @__PURE__ */ r("div", {
57
+ className: "space-y-6",
58
+ children: l.map((t) => /* @__PURE__ */ i("section", {
59
+ className: "break-inside-avoid rounded-md border border-border p-4",
60
+ children: [t.type !== "TEXT" && /* @__PURE__ */ r("h2", {
61
+ className: "mb-2 text-base font-semibold",
62
+ children: t.title
63
+ }), /* @__PURE__ */ r(e, {
64
+ widget: t,
65
+ runResult: u.get(t.id)
66
+ })]
67
+ }, t.id))
68
+ })
69
+ ]
70
+ });
71
+ }
72
+ //#endregion
73
+ export { o as PrintReportView };
74
+
75
+ //# sourceMappingURL=PrintReportView.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PrintReportView.js","names":[],"sources":["../../../src/planmagnet/reports/PrintReportView.tsx"],"sourcesContent":["import { Button } from '@burdenoff/fe-libs/ui';\nimport { Printer, X } from 'lucide-react';\nimport { ReportWidgetRenderer } from './ReportWidgetRenderer';\nimport type { ReportWidget, WidgetRunResult } from './reportModel';\n\n/**\n * The print-optimised view (ANR-16's PDF export — a print stylesheet, not a PDF library: `window.print()` lets\n * the browser's own \"Save as PDF\" do the rendering). Reused by both the in-app Export ▸ PDF flow\n * (`ReportsReportPagePage.tsx`, the owner's own widgets/results) and the public `SharedReportPage` (a synthetic\n * `CHART`-typed widget per result, since a share's snapshot carries no widget title/type — see that file).\n *\n * The toolbar (`print:hidden`) never appears in the printed/PDF output, only on screen. The watermark, when\n * set, is `aria-hidden` (decorative) but rendered both on screen and in print via a fixed, tiled overlay —\n * never only in a `@media print` block this package cannot ship (Tailwind utility classes only, per this\n * repo's design constraints).\n */\nexport function PrintReportView({\n reportName,\n generatedAt,\n watermark,\n widgets,\n results,\n onClose,\n onPrintNow,\n}: {\n reportName: string;\n generatedAt: string;\n watermark?: string | null;\n widgets: ReportWidget[];\n results: Map<string, WidgetRunResult>;\n /** Omit for the public shared view, which has no \"back to the builder\" to return to. */\n onClose?: () => void;\n onPrintNow: () => void;\n}) {\n return (\n <div\n className=\"relative mx-auto max-w-4xl bg-background p-6 text-foreground\"\n data-testid=\"print-report-view\"\n >\n {watermark && (\n <div\n aria-hidden={true}\n className=\"pointer-events-none fixed inset-0 z-50 flex flex-wrap content-around justify-around gap-16 overflow-hidden opacity-10 print:opacity-20\"\n >\n {Array.from({ length: 24 }, (_, i) => (\n <span\n key={i}\n className=\"whitespace-nowrap rotate-[-30deg] text-2xl font-semibold text-foreground\"\n >\n {watermark}\n </span>\n ))}\n </div>\n )}\n\n <div className=\"mb-4 flex items-center justify-between gap-2 print:hidden\">\n <p className=\"text-xs text-muted-foreground\">\n Use your browser&rsquo;s print dialog to save this as a PDF.\n </p>\n <div className=\"flex gap-2\">\n <Button size=\"sm\" onClick={onPrintNow} data-testid=\"print-report-now\">\n <Printer className=\"mr-1 h-4 w-4\" />\n Print / Save as PDF\n </Button>\n {onClose && (\n <Button size=\"sm\" variant=\"outline\" onClick={onClose}>\n <X className=\"mr-1 h-4 w-4\" />\n Close\n </Button>\n )}\n </div>\n </div>\n\n <header className=\"mb-6 border-b border-border pb-4\">\n <p className=\"text-xs font-semibold uppercase tracking-wide text-primary\">PlanMagnet</p>\n <h1 className=\"text-2xl font-bold\">{reportName}</h1>\n <p className=\"text-sm text-muted-foreground\">\n Generated {new Date(generatedAt).toLocaleString()}\n </p>\n </header>\n\n <div className=\"space-y-6\">\n {widgets.map((widget) => (\n <section\n key={widget.id}\n className=\"break-inside-avoid rounded-md border border-border p-4\"\n >\n {widget.type !== 'TEXT' && (\n <h2 className=\"mb-2 text-base font-semibold\">{widget.title}</h2>\n )}\n <ReportWidgetRenderer widget={widget} runResult={results.get(widget.id)} />\n </section>\n ))}\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;AAgBA,SAAgB,EAAgB,EAC9B,eACA,gBACA,cACA,YACA,YACA,YACA,iBAUC;AACD,QACE,kBAAC,OAAD;EACE,WAAU;EACV,eAAY;YAFd;GAIG,KACC,kBAAC,OAAD;IACE,eAAa;IACb,WAAU;cAET,MAAM,KAAK,EAAE,QAAQ,IAAI,GAAG,GAAG,MAC9B,kBAAC,QAAD;KAEE,WAAU;eAET;KACI,EAJA,EAIA,CACP;IACE,CAAA;GAGR,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,KAAD;KAAG,WAAU;eAAgC;KAEzC,CAAA,EACJ,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD;MAAQ,MAAK;MAAK,SAAS;MAAY,eAAY;gBAAnD,CACE,kBAAC,GAAD,EAAS,WAAU,gBAAiB,CAAA,EAAA,sBAE7B;SACR,KACC,kBAAC,GAAD;MAAQ,MAAK;MAAK,SAAQ;MAAU,SAAS;gBAA7C,CACE,kBAAC,GAAD,EAAG,WAAU,gBAAiB,CAAA,EAAA,QAEvB;QAEP;OACF;;GAEN,kBAAC,UAAD;IAAQ,WAAU;cAAlB;KACE,kBAAC,KAAD;MAAG,WAAU;gBAA6D;MAAc,CAAA;KACxF,kBAAC,MAAD;MAAI,WAAU;gBAAsB;MAAgB,CAAA;KACpD,kBAAC,KAAD;MAAG,WAAU;gBAAb,CAA6C,cAChC,IAAI,KAAK,EAAY,CAAC,gBAAgB,CAC/C;;KACG;;GAET,kBAAC,OAAD;IAAK,WAAU;cACZ,EAAQ,KAAK,MACZ,kBAAC,WAAD;KAEE,WAAU;eAFZ,CAIG,EAAO,SAAS,UACf,kBAAC,MAAD;MAAI,WAAU;gBAAgC,EAAO;MAAW,CAAA,EAElE,kBAAC,GAAD;MAA8B;MAAQ,WAAW,EAAQ,IAAI,EAAO,GAAG;MAAI,CAAA,CACnE;OAPH,EAAO,GAOJ,CACV;IACE,CAAA;GACF"}
@@ -0,0 +1,8 @@
1
+ import { FieldError, ReportWidget } from './reportModel';
2
+
3
+ export declare function ReportBuilderCanvas({ widgets, onChange, errors, }: {
4
+ widgets: ReportWidget[];
5
+ onChange: (widgets: ReportWidget[]) => void;
6
+ errors: FieldError[];
7
+ }): import("react/jsx-runtime").JSX.Element;
8
+ //# sourceMappingURL=ReportBuilderCanvas.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReportBuilderCanvas.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/reports/ReportBuilderCanvas.tsx"],"names":[],"mappings":"AAIA,OAAO,EAOL,KAAK,UAAU,EACf,KAAK,YAAY,EAElB,MAAM,eAAe,CAAC;AA8OvB,wBAAgB,mBAAmB,CAAC,EAClC,OAAO,EACP,QAAQ,EACR,MAAM,GACP,EAAE;IACD,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,OAAO,EAAE,YAAY,EAAE,KAAK,IAAI,CAAC;IAC5C,MAAM,EAAE,UAAU,EAAE,CAAC;CACtB,2CAsGA"}
@@ -0,0 +1,261 @@
1
+ import { PARAM_LABELS as e, REPORT_SOURCE_SPECS as t, repackWidgets as n, widgetIndexFromField as r } from "./reportModel.js";
2
+ import { WidgetEditorDialog as i } from "./WidgetEditorDialog.js";
3
+ import { useState as a } from "react";
4
+ import { ArrowDown as o, ArrowUp as s, GripVertical as c, Minus as l, Pencil as u, Plus as d, Trash2 as f } from "lucide-react";
5
+ import { jsx as p, jsxs as m } from "react/jsx-runtime";
6
+ import { Badge as h, Button as g } from "@burdenoff/fe-libs/ui";
7
+ //#region src/planmagnet/reports/ReportBuilderCanvas.tsx
8
+ var _ = [
9
+ "projectId",
10
+ "sprintId",
11
+ "teamId",
12
+ "from",
13
+ "to",
14
+ "limit"
15
+ ];
16
+ function v(e, t, n) {
17
+ if (n < 0 || n >= e.length) return e;
18
+ let r = e.slice(), [i] = r.splice(t, 1);
19
+ return i === void 0 ? e : (r.splice(n, 0, i), r);
20
+ }
21
+ function y(t) {
22
+ let n = _.filter((e) => {
23
+ let n = t.params[e];
24
+ return n != null && n !== "";
25
+ }).map((n) => {
26
+ let r = t.params[n], i = n === "from" || n === "to" ? String(r).slice(0, 10) : String(r);
27
+ return `${e[n]}: ${i}`;
28
+ });
29
+ return n.length ? n.join(" · ") : null;
30
+ }
31
+ function b({ widget: e, index: n, total: i, errors: l, onEdit: d, onRemove: _, onMoveUp: v, onMoveDown: b, onResize: S, onDragStart: C, onDropBefore: w }) {
32
+ let [T, E] = a(!1), D = l.filter((e) => r(e.field) === n);
33
+ return /* @__PURE__ */ p("div", {
34
+ style: { width: `${e.layout.w / 12 * 100}%` },
35
+ className: "p-1.5",
36
+ "data-testid": "report-widget",
37
+ children: /* @__PURE__ */ m("div", {
38
+ draggable: !0,
39
+ onDragStart: C,
40
+ onDragOver: (e) => {
41
+ e.preventDefault(), E(!0);
42
+ },
43
+ onDragLeave: () => E(!1),
44
+ onDrop: (e) => {
45
+ E(!1), w(e);
46
+ },
47
+ className: `flex h-full flex-col gap-2 rounded-md border bg-background p-3 ${T ? "ring-2 ring-primary" : "border-border"} ${D.length ? "border-destructive" : ""}`,
48
+ children: [
49
+ /* @__PURE__ */ m("div", {
50
+ className: "flex items-start justify-between gap-2",
51
+ children: [/* @__PURE__ */ m("div", {
52
+ className: "flex min-w-0 items-start gap-1.5",
53
+ children: [/* @__PURE__ */ p(c, {
54
+ className: "mt-0.5 h-4 w-4 shrink-0 cursor-grab text-muted-foreground",
55
+ "aria-hidden": !0
56
+ }), /* @__PURE__ */ m("div", {
57
+ className: "min-w-0",
58
+ children: [/* @__PURE__ */ p("p", {
59
+ className: "truncate text-sm font-medium",
60
+ title: e.title,
61
+ children: e.title
62
+ }), /* @__PURE__ */ m("div", {
63
+ className: "mt-0.5 flex flex-wrap items-center gap-1",
64
+ children: [/* @__PURE__ */ p(h, {
65
+ variant: "outline",
66
+ className: "text-[10px]",
67
+ children: e.type
68
+ }), e.type !== "TEXT" && /* @__PURE__ */ p(h, {
69
+ variant: "secondary",
70
+ className: "text-[10px]",
71
+ children: t[e.source].label
72
+ })]
73
+ })]
74
+ })]
75
+ }), /* @__PURE__ */ m("div", {
76
+ className: "flex shrink-0 items-center gap-0.5",
77
+ draggable: !1,
78
+ onMouseDown: (e) => e.stopPropagation(),
79
+ onDragStart: (e) => e.stopPropagation(),
80
+ children: [
81
+ /* @__PURE__ */ p(g, {
82
+ size: "sm",
83
+ variant: "outline",
84
+ className: "h-7 w-7 p-0",
85
+ "aria-label": "Move widget earlier",
86
+ disabled: n === 0,
87
+ onClick: v,
88
+ children: /* @__PURE__ */ p(s, { className: "h-3.5 w-3.5" })
89
+ }),
90
+ /* @__PURE__ */ p(g, {
91
+ size: "sm",
92
+ variant: "outline",
93
+ className: "h-7 w-7 p-0",
94
+ "aria-label": "Move widget later",
95
+ disabled: n === i - 1,
96
+ onClick: b,
97
+ children: /* @__PURE__ */ p(o, { className: "h-3.5 w-3.5" })
98
+ }),
99
+ /* @__PURE__ */ p(g, {
100
+ size: "sm",
101
+ variant: "outline",
102
+ className: "h-7 w-7 p-0",
103
+ "aria-label": `Edit ${e.title}`,
104
+ onClick: d,
105
+ children: /* @__PURE__ */ p(u, { className: "h-3.5 w-3.5" })
106
+ }),
107
+ /* @__PURE__ */ p(g, {
108
+ size: "sm",
109
+ variant: "outline",
110
+ className: "h-7 w-7 p-0",
111
+ "aria-label": `Remove ${e.title}`,
112
+ onClick: _,
113
+ children: /* @__PURE__ */ p(f, { className: "h-3.5 w-3.5" })
114
+ })
115
+ ]
116
+ })]
117
+ }),
118
+ e.type !== "TEXT" && y(e) && /* @__PURE__ */ p("p", {
119
+ className: "text-xs text-muted-foreground",
120
+ children: y(e)
121
+ }),
122
+ /* @__PURE__ */ m("div", {
123
+ className: "mt-auto flex flex-wrap items-center gap-3 border-t border-border pt-2 text-xs text-muted-foreground",
124
+ draggable: !1,
125
+ onMouseDown: (e) => e.stopPropagation(),
126
+ onDragStart: (e) => e.stopPropagation(),
127
+ children: [/* @__PURE__ */ p(x, {
128
+ label: "Width",
129
+ value: e.layout.w,
130
+ min: 1,
131
+ max: 12,
132
+ onChange: (e) => S({ w: e })
133
+ }), /* @__PURE__ */ p(x, {
134
+ label: "Height",
135
+ value: e.layout.h,
136
+ min: 1,
137
+ max: 12,
138
+ onChange: (e) => S({ h: e })
139
+ })]
140
+ }),
141
+ D.length > 0 && /* @__PURE__ */ p("ul", {
142
+ className: "space-y-0.5 text-xs text-destructive",
143
+ role: "alert",
144
+ children: D.map((e) => /* @__PURE__ */ p("li", { children: e.message }, e.field))
145
+ })
146
+ ]
147
+ })
148
+ });
149
+ }
150
+ function x({ label: e, value: t, min: n, max: r, onChange: i }) {
151
+ return /* @__PURE__ */ m("div", {
152
+ className: "flex items-center gap-1",
153
+ children: [
154
+ /* @__PURE__ */ p("span", { children: e }),
155
+ /* @__PURE__ */ p(g, {
156
+ size: "sm",
157
+ variant: "outline",
158
+ className: "h-6 w-6 p-0",
159
+ "aria-label": `Decrease ${e.toLowerCase()}`,
160
+ disabled: t <= n,
161
+ onClick: () => i(Math.max(n, t - 1)),
162
+ children: /* @__PURE__ */ p(l, { className: "h-3 w-3" })
163
+ }),
164
+ /* @__PURE__ */ p("span", {
165
+ className: "w-4 text-center tabular-nums",
166
+ children: t
167
+ }),
168
+ /* @__PURE__ */ p(g, {
169
+ size: "sm",
170
+ variant: "outline",
171
+ className: "h-6 w-6 p-0",
172
+ "aria-label": `Increase ${e.toLowerCase()}`,
173
+ disabled: t >= r,
174
+ onClick: () => i(Math.min(r, t + 1)),
175
+ children: /* @__PURE__ */ p(d, { className: "h-3 w-3" })
176
+ })
177
+ ]
178
+ });
179
+ }
180
+ function S({ widgets: e, onChange: t, errors: o }) {
181
+ let [s, c] = a(!1), [l, u] = a(null), [f, _] = a(null), y = (e) => t(n(e)), x = () => {
182
+ u(null), c(!0);
183
+ }, S = (e) => {
184
+ u(e), c(!0);
185
+ }, C = (t) => {
186
+ y(l === null ? [...e, t] : e.map((e, n) => n === l ? t : e));
187
+ }, w = o.filter((e) => r(e.field) === null);
188
+ return /* @__PURE__ */ m("div", {
189
+ className: "space-y-3",
190
+ children: [
191
+ /* @__PURE__ */ m("div", {
192
+ className: "flex items-center justify-between",
193
+ children: [/* @__PURE__ */ m("div", {
194
+ className: "flex items-center gap-2",
195
+ children: [/* @__PURE__ */ p("h2", {
196
+ className: "text-sm font-semibold",
197
+ children: "Widgets"
198
+ }), /* @__PURE__ */ m(h, {
199
+ variant: e.length > 24 ? "destructive" : "outline",
200
+ children: [
201
+ e.length,
202
+ " / ",
203
+ 24
204
+ ]
205
+ })]
206
+ }), /* @__PURE__ */ m(g, {
207
+ size: "sm",
208
+ onClick: x,
209
+ disabled: e.length >= 24,
210
+ "data-testid": "report-add-widget-trigger",
211
+ children: [/* @__PURE__ */ p(d, { className: "mr-1 h-4 w-4" }), "Add widget"]
212
+ })]
213
+ }),
214
+ w.length > 0 && /* @__PURE__ */ p("ul", {
215
+ className: "space-y-0.5 text-sm text-destructive",
216
+ role: "alert",
217
+ children: w.map((e) => /* @__PURE__ */ p("li", { children: e.message }, e.field))
218
+ }),
219
+ e.length === 0 ? /* @__PURE__ */ p("div", {
220
+ className: "rounded-md border border-dashed border-border p-8 text-center text-sm text-muted-foreground",
221
+ children: "No widgets yet. Add one to start building this report."
222
+ }) : /* @__PURE__ */ p("div", {
223
+ className: "flex flex-wrap",
224
+ "data-testid": "report-builder",
225
+ children: e.map((t, n) => /* @__PURE__ */ p(b, {
226
+ widget: t,
227
+ index: n,
228
+ total: e.length,
229
+ errors: o,
230
+ onEdit: () => S(n),
231
+ onRemove: () => y(e.filter((e, t) => t !== n)),
232
+ onMoveUp: () => y(v(e, n, n - 1)),
233
+ onMoveDown: () => y(v(e, n, n + 1)),
234
+ onResize: (t) => y(e.map((e, r) => r === n ? {
235
+ ...e,
236
+ layout: {
237
+ ...e.layout,
238
+ ...t
239
+ }
240
+ } : e)),
241
+ onDragStart: (e) => {
242
+ _(n), e.dataTransfer.effectAllowed = "move", e.dataTransfer.setData("text/plain", t.id);
243
+ },
244
+ onDropBefore: (t) => {
245
+ t.preventDefault(), !(f === null || f === n) && (y(v(e, f, n)), _(null));
246
+ }
247
+ }, t.id))
248
+ }),
249
+ /* @__PURE__ */ p(i, {
250
+ open: s,
251
+ onOpenChange: c,
252
+ widget: l === null ? null : e[l] ?? null,
253
+ onSave: C
254
+ })
255
+ ]
256
+ });
257
+ }
258
+ //#endregion
259
+ export { S as ReportBuilderCanvas };
260
+
261
+ //# sourceMappingURL=ReportBuilderCanvas.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReportBuilderCanvas.js","names":[],"sources":["../../../src/planmagnet/reports/ReportBuilderCanvas.tsx"],"sourcesContent":["import { useState, type DragEvent } from 'react';\nimport { Badge, Button } from '@burdenoff/fe-libs/ui';\nimport { ArrowDown, ArrowUp, GripVertical, Minus, Pencil, Plus, Trash2 } from 'lucide-react';\nimport { WidgetEditorDialog } from './WidgetEditorDialog';\nimport {\n GRID_COLUMNS,\n MAX_WIDGETS,\n PARAM_LABELS,\n REPORT_SOURCE_SPECS,\n repackWidgets,\n widgetIndexFromField,\n type FieldError,\n type ReportWidget,\n type WidgetParamKey,\n} from './reportModel';\n\n/**\n * The builder's 12-column grid canvas (ANR-13). There is no free-form drag-to-position: a widget's place comes\n * from its order in the list (reordered by drag-and-drop or the keyboard up/down buttons) and its own width,\n * packed left-to-right with wraparound (`packLayout` in `reportModel.ts`) — the same rule the flex-wrap layout\n * below renders visually, so the canvas preview and the persisted `layout` never disagree, and every layout\n * this UI can produce already satisfies the server's grid bounds.\n */\n\nconst PARAM_KEYS_ORDER: WidgetParamKey[] = [\n 'projectId',\n 'sprintId',\n 'teamId',\n 'from',\n 'to',\n 'limit',\n];\n\nfunction moveItem<T>(list: T[], from: number, to: number): T[] {\n if (to < 0 || to >= list.length) return list;\n const next = list.slice();\n const [item] = next.splice(from, 1);\n if (item === undefined) return list;\n next.splice(to, 0, item);\n return next;\n}\n\nfunction paramSummary(widget: ReportWidget): string | null {\n const parts = PARAM_KEYS_ORDER.filter((key) => {\n const value = widget.params[key];\n return value !== undefined && value !== null && value !== '';\n }).map((key) => {\n const value = widget.params[key];\n const text = key === 'from' || key === 'to' ? String(value).slice(0, 10) : String(value);\n return `${PARAM_LABELS[key]}: ${text}`;\n });\n return parts.length ? parts.join(' · ') : null;\n}\n\nfunction WidgetCard({\n widget,\n index,\n total,\n errors,\n onEdit,\n onRemove,\n onMoveUp,\n onMoveDown,\n onResize,\n onDragStart,\n onDropBefore,\n}: {\n widget: ReportWidget;\n index: number;\n total: number;\n errors: FieldError[];\n onEdit: () => void;\n onRemove: () => void;\n onMoveUp: () => void;\n onMoveDown: () => void;\n onResize: (dims: Partial<{ w: number; h: number }>) => void;\n onDragStart: (event: DragEvent<HTMLDivElement>) => void;\n onDropBefore: (event: DragEvent<HTMLDivElement>) => void;\n}) {\n const [dragOver, setDragOver] = useState(false);\n const cardErrors = errors.filter((e) => widgetIndexFromField(e.field) === index);\n\n return (\n <div\n style={{ width: `${(widget.layout.w / GRID_COLUMNS) * 100}%` }}\n className=\"p-1.5\"\n data-testid=\"report-widget\"\n >\n <div\n draggable\n onDragStart={onDragStart}\n onDragOver={(e) => {\n e.preventDefault();\n setDragOver(true);\n }}\n onDragLeave={() => setDragOver(false)}\n onDrop={(e) => {\n setDragOver(false);\n onDropBefore(e);\n }}\n className={`flex h-full flex-col gap-2 rounded-md border bg-background p-3 ${\n dragOver ? 'ring-2 ring-primary' : 'border-border'\n } ${cardErrors.length ? 'border-destructive' : ''}`}\n >\n <div className=\"flex items-start justify-between gap-2\">\n <div className=\"flex min-w-0 items-start gap-1.5\">\n <GripVertical\n className=\"mt-0.5 h-4 w-4 shrink-0 cursor-grab text-muted-foreground\"\n aria-hidden={true}\n />\n <div className=\"min-w-0\">\n <p className=\"truncate text-sm font-medium\" title={widget.title}>\n {widget.title}\n </p>\n <div className=\"mt-0.5 flex flex-wrap items-center gap-1\">\n <Badge variant=\"outline\" className=\"text-[10px]\">\n {widget.type}\n </Badge>\n {widget.type !== 'TEXT' && (\n <Badge variant=\"secondary\" className=\"text-[10px]\">\n {REPORT_SOURCE_SPECS[widget.source].label}\n </Badge>\n )}\n </div>\n </div>\n </div>\n <div\n className=\"flex shrink-0 items-center gap-0.5\"\n draggable={false}\n onMouseDown={(e) => e.stopPropagation()}\n onDragStart={(e) => e.stopPropagation()}\n >\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-7 w-7 p-0\"\n aria-label=\"Move widget earlier\"\n disabled={index === 0}\n onClick={onMoveUp}\n >\n <ArrowUp className=\"h-3.5 w-3.5\" />\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-7 w-7 p-0\"\n aria-label=\"Move widget later\"\n disabled={index === total - 1}\n onClick={onMoveDown}\n >\n <ArrowDown className=\"h-3.5 w-3.5\" />\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-7 w-7 p-0\"\n aria-label={`Edit ${widget.title}`}\n onClick={onEdit}\n >\n <Pencil className=\"h-3.5 w-3.5\" />\n </Button>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-7 w-7 p-0\"\n aria-label={`Remove ${widget.title}`}\n onClick={onRemove}\n >\n <Trash2 className=\"h-3.5 w-3.5\" />\n </Button>\n </div>\n </div>\n\n {widget.type !== 'TEXT' && paramSummary(widget) && (\n <p className=\"text-xs text-muted-foreground\">{paramSummary(widget)}</p>\n )}\n\n <div\n className=\"mt-auto flex flex-wrap items-center gap-3 border-t border-border pt-2 text-xs text-muted-foreground\"\n draggable={false}\n onMouseDown={(e) => e.stopPropagation()}\n onDragStart={(e) => e.stopPropagation()}\n >\n <SizeStepper\n label=\"Width\"\n value={widget.layout.w}\n min={1}\n max={GRID_COLUMNS}\n onChange={(w) => onResize({ w })}\n />\n <SizeStepper\n label=\"Height\"\n value={widget.layout.h}\n min={1}\n max={GRID_COLUMNS}\n onChange={(h) => onResize({ h })}\n />\n </div>\n\n {cardErrors.length > 0 && (\n <ul className=\"space-y-0.5 text-xs text-destructive\" role=\"alert\">\n {cardErrors.map((e) => (\n <li key={e.field}>{e.message}</li>\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n}\n\nfunction SizeStepper({\n label,\n value,\n min,\n max,\n onChange,\n}: {\n label: string;\n value: number;\n min: number;\n max: number;\n onChange: (value: number) => void;\n}) {\n return (\n <div className=\"flex items-center gap-1\">\n <span>{label}</span>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-6 w-6 p-0\"\n aria-label={`Decrease ${label.toLowerCase()}`}\n disabled={value <= min}\n onClick={() => onChange(Math.max(min, value - 1))}\n >\n <Minus className=\"h-3 w-3\" />\n </Button>\n <span className=\"w-4 text-center tabular-nums\">{value}</span>\n <Button\n size=\"sm\"\n variant=\"outline\"\n className=\"h-6 w-6 p-0\"\n aria-label={`Increase ${label.toLowerCase()}`}\n disabled={value >= max}\n onClick={() => onChange(Math.min(max, value + 1))}\n >\n <Plus className=\"h-3 w-3\" />\n </Button>\n </div>\n );\n}\n\nexport function ReportBuilderCanvas({\n widgets,\n onChange,\n errors,\n}: {\n widgets: ReportWidget[];\n onChange: (widgets: ReportWidget[]) => void;\n errors: FieldError[];\n}) {\n const [editorOpen, setEditorOpen] = useState(false);\n const [editingIndex, setEditingIndex] = useState<number | null>(null);\n const [dragIndex, setDragIndex] = useState<number | null>(null);\n\n const apply = (next: ReportWidget[]) => onChange(repackWidgets(next));\n\n const openAdd = () => {\n setEditingIndex(null);\n setEditorOpen(true);\n };\n const openEdit = (index: number) => {\n setEditingIndex(index);\n setEditorOpen(true);\n };\n\n const handleSave = (widget: ReportWidget) => {\n if (editingIndex === null) {\n apply([...widgets, widget]);\n } else {\n apply(widgets.map((w, i) => (i === editingIndex ? widget : w)));\n }\n };\n\n const reportLevelErrors = errors.filter((e) => widgetIndexFromField(e.field) === null);\n\n return (\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div className=\"flex items-center gap-2\">\n <h2 className=\"text-sm font-semibold\">Widgets</h2>\n <Badge variant={widgets.length > MAX_WIDGETS ? 'destructive' : 'outline'}>\n {widgets.length} / {MAX_WIDGETS}\n </Badge>\n </div>\n <Button\n size=\"sm\"\n onClick={openAdd}\n disabled={widgets.length >= MAX_WIDGETS}\n data-testid=\"report-add-widget-trigger\"\n >\n <Plus className=\"mr-1 h-4 w-4\" />\n Add widget\n </Button>\n </div>\n\n {reportLevelErrors.length > 0 && (\n <ul className=\"space-y-0.5 text-sm text-destructive\" role=\"alert\">\n {reportLevelErrors.map((e) => (\n <li key={e.field}>{e.message}</li>\n ))}\n </ul>\n )}\n\n {widgets.length === 0 ? (\n <div className=\"rounded-md border border-dashed border-border p-8 text-center text-sm text-muted-foreground\">\n No widgets yet. Add one to start building this report.\n </div>\n ) : (\n <div className=\"flex flex-wrap\" data-testid=\"report-builder\">\n {widgets.map((widget, index) => (\n <WidgetCard\n key={widget.id}\n widget={widget}\n index={index}\n total={widgets.length}\n errors={errors}\n onEdit={() => openEdit(index)}\n onRemove={() => apply(widgets.filter((_, i) => i !== index))}\n onMoveUp={() => apply(moveItem(widgets, index, index - 1))}\n onMoveDown={() => apply(moveItem(widgets, index, index + 1))}\n onResize={(dims) =>\n apply(\n widgets.map((w, i) =>\n i === index ? { ...w, layout: { ...w.layout, ...dims } } : w\n )\n )\n }\n onDragStart={(e) => {\n setDragIndex(index);\n e.dataTransfer.effectAllowed = 'move';\n e.dataTransfer.setData('text/plain', widget.id);\n }}\n onDropBefore={(e) => {\n e.preventDefault();\n if (dragIndex === null || dragIndex === index) return;\n apply(moveItem(widgets, dragIndex, index));\n setDragIndex(null);\n }}\n />\n ))}\n </div>\n )}\n\n <WidgetEditorDialog\n open={editorOpen}\n onOpenChange={setEditorOpen}\n widget={editingIndex === null ? null : (widgets[editingIndex] ?? null)}\n onSave={handleSave}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;AAwBA,IAAM,IAAqC;CACzC;CACA;CACA;CACA;CACA;CACA;CACD;AAED,SAAS,EAAY,GAAW,GAAc,GAAiB;AAC7D,KAAI,IAAK,KAAK,KAAM,EAAK,OAAQ,QAAO;CACxC,IAAM,IAAO,EAAK,OAAO,EACnB,CAAC,KAAQ,EAAK,OAAO,GAAM,EAAE;AAGnC,QAFI,MAAS,KAAA,IAAkB,KAC/B,EAAK,OAAO,GAAI,GAAG,EAAK,EACjB;;AAGT,SAAS,EAAa,GAAqC;CACzD,IAAM,IAAQ,EAAiB,QAAQ,MAAQ;EAC7C,IAAM,IAAQ,EAAO,OAAO;AAC5B,SAAO,KAAiC,QAAQ,MAAU;GAC1D,CAAC,KAAK,MAAQ;EACd,IAAM,IAAQ,EAAO,OAAO,IACtB,IAAO,MAAQ,UAAU,MAAQ,OAAO,OAAO,EAAM,CAAC,MAAM,GAAG,GAAG,GAAG,OAAO,EAAM;AACxF,SAAO,GAAG,EAAa,GAAK,IAAI;GAChC;AACF,QAAO,EAAM,SAAS,EAAM,KAAK,MAAM,GAAG;;AAG5C,SAAS,EAAW,EAClB,WACA,UACA,UACA,WACA,WACA,aACA,aACA,eACA,aACA,gBACA,mBAaC;CACD,IAAM,CAAC,GAAU,KAAe,EAAS,GAAM,EACzC,IAAa,EAAO,QAAQ,MAAM,EAAqB,EAAE,MAAM,KAAK,EAAM;AAEhF,QACE,kBAAC,OAAD;EACE,OAAO,EAAE,OAAO,GAAI,EAAO,OAAO,IAAA,KAAoB,IAAI,IAAI;EAC9D,WAAU;EACV,eAAY;YAEZ,kBAAC,OAAD;GACE,WAAA;GACa;GACb,aAAa,MAAM;AAEjB,IADA,EAAE,gBAAgB,EAClB,EAAY,GAAK;;GAEnB,mBAAmB,EAAY,GAAM;GACrC,SAAS,MAAM;AAEb,IADA,EAAY,GAAM,EAClB,EAAa,EAAE;;GAEjB,WAAW,kEACT,IAAW,wBAAwB,gBACpC,GAAG,EAAW,SAAS,uBAAuB;aAdjD;IAgBE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,GAAD;OACE,WAAU;OACV,eAAa;OACb,CAAA,EACF,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,KAAD;QAAG,WAAU;QAA+B,OAAO,EAAO;kBACvD,EAAO;QACN,CAAA,EACJ,kBAAC,OAAD;QAAK,WAAU;kBAAf,CACE,kBAAC,GAAD;SAAO,SAAQ;SAAU,WAAU;mBAChC,EAAO;SACF,CAAA,EACP,EAAO,SAAS,UACf,kBAAC,GAAD;SAAO,SAAQ;SAAY,WAAU;mBAClC,EAAoB,EAAO,QAAQ;SAC9B,CAAA,CAEN;UACF;SACF;SACN,kBAAC,OAAD;MACE,WAAU;MACV,WAAW;MACX,cAAc,MAAM,EAAE,iBAAiB;MACvC,cAAc,MAAM,EAAE,iBAAiB;gBAJzC;OAME,kBAAC,GAAD;QACE,MAAK;QACL,SAAQ;QACR,WAAU;QACV,cAAW;QACX,UAAU,MAAU;QACpB,SAAS;kBAET,kBAAC,GAAD,EAAS,WAAU,eAAgB,CAAA;QAC5B,CAAA;OACT,kBAAC,GAAD;QACE,MAAK;QACL,SAAQ;QACR,WAAU;QACV,cAAW;QACX,UAAU,MAAU,IAAQ;QAC5B,SAAS;kBAET,kBAAC,GAAD,EAAW,WAAU,eAAgB,CAAA;QAC9B,CAAA;OACT,kBAAC,GAAD;QACE,MAAK;QACL,SAAQ;QACR,WAAU;QACV,cAAY,QAAQ,EAAO;QAC3B,SAAS;kBAET,kBAAC,GAAD,EAAQ,WAAU,eAAgB,CAAA;QAC3B,CAAA;OACT,kBAAC,GAAD;QACE,MAAK;QACL,SAAQ;QACR,WAAU;QACV,cAAY,UAAU,EAAO;QAC7B,SAAS;kBAET,kBAAC,GAAD,EAAQ,WAAU,eAAgB,CAAA;QAC3B,CAAA;OACL;QACF;;IAEL,EAAO,SAAS,UAAU,EAAa,EAAO,IAC7C,kBAAC,KAAD;KAAG,WAAU;eAAiC,EAAa,EAAO;KAAK,CAAA;IAGzE,kBAAC,OAAD;KACE,WAAU;KACV,WAAW;KACX,cAAc,MAAM,EAAE,iBAAiB;KACvC,cAAc,MAAM,EAAE,iBAAiB;eAJzC,CAME,kBAAC,GAAD;MACE,OAAM;MACN,OAAO,EAAO,OAAO;MACrB,KAAK;MACL,KAAA;MACA,WAAW,MAAM,EAAS,EAAE,MAAG,CAAC;MAChC,CAAA,EACF,kBAAC,GAAD;MACE,OAAM;MACN,OAAO,EAAO,OAAO;MACrB,KAAK;MACL,KAAA;MACA,WAAW,MAAM,EAAS,EAAE,MAAG,CAAC;MAChC,CAAA,CACE;;IAEL,EAAW,SAAS,KACnB,kBAAC,MAAD;KAAI,WAAU;KAAuC,MAAK;eACvD,EAAW,KAAK,MACf,kBAAC,MAAD,EAAA,UAAmB,EAAE,SAAa,EAAzB,EAAE,MAAuB,CAClC;KACC,CAAA;IAEH;;EACF,CAAA;;AAIV,SAAS,EAAY,EACnB,UACA,UACA,QACA,QACA,eAOC;AACD,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,QAAD,EAAA,UAAO,GAAa,CAAA;GACpB,kBAAC,GAAD;IACE,MAAK;IACL,SAAQ;IACR,WAAU;IACV,cAAY,YAAY,EAAM,aAAa;IAC3C,UAAU,KAAS;IACnB,eAAe,EAAS,KAAK,IAAI,GAAK,IAAQ,EAAE,CAAC;cAEjD,kBAAC,GAAD,EAAO,WAAU,WAAY,CAAA;IACtB,CAAA;GACT,kBAAC,QAAD;IAAM,WAAU;cAAgC;IAAa,CAAA;GAC7D,kBAAC,GAAD;IACE,MAAK;IACL,SAAQ;IACR,WAAU;IACV,cAAY,YAAY,EAAM,aAAa;IAC3C,UAAU,KAAS;IACnB,eAAe,EAAS,KAAK,IAAI,GAAK,IAAQ,EAAE,CAAC;cAEjD,kBAAC,GAAD,EAAM,WAAU,WAAY,CAAA;IACrB,CAAA;GACL;;;AAIV,SAAgB,EAAoB,EAClC,YACA,aACA,aAKC;CACD,IAAM,CAAC,GAAY,KAAiB,EAAS,GAAM,EAC7C,CAAC,GAAc,KAAmB,EAAwB,KAAK,EAC/D,CAAC,GAAW,KAAgB,EAAwB,KAAK,EAEzD,KAAS,MAAyB,EAAS,EAAc,EAAK,CAAC,EAE/D,UAAgB;AAEpB,EADA,EAAgB,KAAK,EACrB,EAAc,GAAK;IAEf,KAAY,MAAkB;AAElC,EADA,EAAgB,EAAM,EACtB,EAAc,GAAK;IAGf,KAAc,MAAyB;AAC3C,EACE,EADE,MAAiB,OACb,CAAC,GAAG,GAAS,EAAO,GAEpB,EAAQ,KAAK,GAAG,MAAO,MAAM,IAAe,IAAS,EAAG,CAAC;IAI7D,IAAoB,EAAO,QAAQ,MAAM,EAAqB,EAAE,MAAM,KAAK,KAAK;AAEtF,QACE,kBAAC,OAAD;EAAK,WAAU;YAAf;GACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,MAAD;MAAI,WAAU;gBAAwB;MAAY,CAAA,EAClD,kBAAC,GAAD;MAAO,SAAS,EAAQ,SAAA,KAAuB,gBAAgB;gBAA/D;OACG,EAAQ;OAAO;;OACV;QACJ;QACN,kBAAC,GAAD;KACE,MAAK;KACL,SAAS;KACT,UAAU,EAAQ,UAAA;KAClB,eAAY;eAJd,CAME,kBAAC,GAAD,EAAM,WAAU,gBAAiB,CAAA,EAAA,aAE1B;OACL;;GAEL,EAAkB,SAAS,KAC1B,kBAAC,MAAD;IAAI,WAAU;IAAuC,MAAK;cACvD,EAAkB,KAAK,MACtB,kBAAC,MAAD,EAAA,UAAmB,EAAE,SAAa,EAAzB,EAAE,MAAuB,CAClC;IACC,CAAA;GAGN,EAAQ,WAAW,IAClB,kBAAC,OAAD;IAAK,WAAU;cAA8F;IAEvG,CAAA,GAEN,kBAAC,OAAD;IAAK,WAAU;IAAiB,eAAY;cACzC,EAAQ,KAAK,GAAQ,MACpB,kBAAC,GAAD;KAEU;KACD;KACP,OAAO,EAAQ;KACP;KACR,cAAc,EAAS,EAAM;KAC7B,gBAAgB,EAAM,EAAQ,QAAQ,GAAG,MAAM,MAAM,EAAM,CAAC;KAC5D,gBAAgB,EAAM,EAAS,GAAS,GAAO,IAAQ,EAAE,CAAC;KAC1D,kBAAkB,EAAM,EAAS,GAAS,GAAO,IAAQ,EAAE,CAAC;KAC5D,WAAW,MACT,EACE,EAAQ,KAAK,GAAG,MACd,MAAM,IAAQ;MAAE,GAAG;MAAG,QAAQ;OAAE,GAAG,EAAE;OAAQ,GAAG;OAAM;MAAE,GAAG,EAC5D,CACF;KAEH,cAAc,MAAM;AAGlB,MAFA,EAAa,EAAM,EACnB,EAAE,aAAa,gBAAgB,QAC/B,EAAE,aAAa,QAAQ,cAAc,EAAO,GAAG;;KAEjD,eAAe,MAAM;AACnB,QAAE,gBAAgB,EACd,QAAc,QAAQ,MAAc,OACxC,EAAM,EAAS,GAAS,GAAW,EAAM,CAAC,EAC1C,EAAa,KAAK;;KAEpB,EA3BK,EAAO,GA2BZ,CACF;IACE,CAAA;GAGR,kBAAC,GAAD;IACE,MAAM;IACN,cAAc;IACd,QAAQ,MAAiB,OAAO,OAAQ,EAAQ,MAAiB;IACjE,QAAQ;IACR,CAAA;GACE"}
@@ -0,0 +1,5 @@
1
+ export declare function ReportBuilderPage({ mode, reportId, }: {
2
+ mode: 'create' | 'edit';
3
+ reportId?: string;
4
+ }): import("react/jsx-runtime").JSX.Element;
5
+ //# sourceMappingURL=ReportBuilderPage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ReportBuilderPage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/reports/ReportBuilderPage.tsx"],"names":[],"mappings":"AA2PA,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,QAAQ,GACT,EAAE;IACD,IAAI,EAAE,QAAQ,GAAG,MAAM,CAAC;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,2CAqCA"}