@burdenoff/microfe-planmagnet 2026.930.25 → 2026.1001.1

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 (258) 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 +154 -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 +122 -106
  175. package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
  176. package/dist/planmagnet/controls/Pickers.d.ts +10 -0
  177. package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
  178. package/dist/planmagnet/controls/Pickers.js +75 -27
  179. package/dist/planmagnet/controls/Pickers.js.map +1 -1
  180. package/dist/planmagnet/index.d.ts +2 -0
  181. package/dist/planmagnet/index.d.ts.map +1 -1
  182. package/dist/planmagnet/index.js +2 -0
  183. package/dist/planmagnet/pages/ReportsCreateReportPagePage.d.ts +6 -0
  184. package/dist/planmagnet/pages/ReportsCreateReportPagePage.d.ts.map +1 -1
  185. package/dist/planmagnet/pages/ReportsCreateReportPagePage.js +5 -177
  186. package/dist/planmagnet/pages/ReportsCreateReportPagePage.js.map +1 -1
  187. package/dist/planmagnet/pages/ReportsEditReportPagePage.d.ts +3 -0
  188. package/dist/planmagnet/pages/ReportsEditReportPagePage.d.ts.map +1 -0
  189. package/dist/planmagnet/pages/ReportsEditReportPagePage.js +15 -0
  190. package/dist/planmagnet/pages/ReportsEditReportPagePage.js.map +1 -0
  191. package/dist/planmagnet/pages/ReportsReportPagePage.d.ts +7 -0
  192. package/dist/planmagnet/pages/ReportsReportPagePage.d.ts.map +1 -0
  193. package/dist/planmagnet/pages/ReportsReportPagePage.js +226 -0
  194. package/dist/planmagnet/pages/ReportsReportPagePage.js.map +1 -0
  195. package/dist/planmagnet/pages/ReportsReportsPagePage.d.ts.map +1 -1
  196. package/dist/planmagnet/pages/ReportsReportsPagePage.js +224 -496
  197. package/dist/planmagnet/pages/ReportsReportsPagePage.js.map +1 -1
  198. package/dist/planmagnet/reports/ExportMenu.d.ts +9 -0
  199. package/dist/planmagnet/reports/ExportMenu.d.ts.map +1 -0
  200. package/dist/planmagnet/reports/ExportMenu.js +116 -0
  201. package/dist/planmagnet/reports/ExportMenu.js.map +1 -0
  202. package/dist/planmagnet/reports/PrintReportView.d.ts +24 -0
  203. package/dist/planmagnet/reports/PrintReportView.d.ts.map +1 -0
  204. package/dist/planmagnet/reports/PrintReportView.js +75 -0
  205. package/dist/planmagnet/reports/PrintReportView.js.map +1 -0
  206. package/dist/planmagnet/reports/ReportBuilderCanvas.d.ts +8 -0
  207. package/dist/planmagnet/reports/ReportBuilderCanvas.d.ts.map +1 -0
  208. package/dist/planmagnet/reports/ReportBuilderCanvas.js +261 -0
  209. package/dist/planmagnet/reports/ReportBuilderCanvas.js.map +1 -0
  210. package/dist/planmagnet/reports/ReportBuilderPage.d.ts +5 -0
  211. package/dist/planmagnet/reports/ReportBuilderPage.d.ts.map +1 -0
  212. package/dist/planmagnet/reports/ReportBuilderPage.js +198 -0
  213. package/dist/planmagnet/reports/ReportBuilderPage.js.map +1 -0
  214. package/dist/planmagnet/reports/ReportRunHistory.d.ts +8 -0
  215. package/dist/planmagnet/reports/ReportRunHistory.d.ts.map +1 -0
  216. package/dist/planmagnet/reports/ReportRunHistory.js +63 -0
  217. package/dist/planmagnet/reports/ReportRunHistory.js.map +1 -0
  218. package/dist/planmagnet/reports/ReportWidgetRenderer.d.ts +7 -0
  219. package/dist/planmagnet/reports/ReportWidgetRenderer.d.ts.map +1 -0
  220. package/dist/planmagnet/reports/ReportWidgetRenderer.js +251 -0
  221. package/dist/planmagnet/reports/ReportWidgetRenderer.js.map +1 -0
  222. package/dist/planmagnet/reports/SchedulesPanel.d.ts +4 -0
  223. package/dist/planmagnet/reports/SchedulesPanel.d.ts.map +1 -0
  224. package/dist/planmagnet/reports/SchedulesPanel.js +457 -0
  225. package/dist/planmagnet/reports/SchedulesPanel.js.map +1 -0
  226. package/dist/planmagnet/reports/ShareDialog.d.ts +5 -0
  227. package/dist/planmagnet/reports/ShareDialog.d.ts.map +1 -0
  228. package/dist/planmagnet/reports/ShareDialog.js +234 -0
  229. package/dist/planmagnet/reports/ShareDialog.js.map +1 -0
  230. package/dist/planmagnet/reports/SharedReportPage.d.ts +4 -0
  231. package/dist/planmagnet/reports/SharedReportPage.d.ts.map +1 -0
  232. package/dist/planmagnet/reports/SharedReportPage.js +180 -0
  233. package/dist/planmagnet/reports/SharedReportPage.js.map +1 -0
  234. package/dist/planmagnet/reports/WidgetEditorDialog.d.ts +10 -0
  235. package/dist/planmagnet/reports/WidgetEditorDialog.d.ts.map +1 -0
  236. package/dist/planmagnet/reports/WidgetEditorDialog.js +220 -0
  237. package/dist/planmagnet/reports/WidgetEditorDialog.js.map +1 -0
  238. package/dist/planmagnet/reports/reportExportPptx.d.ts +4 -0
  239. package/dist/planmagnet/reports/reportExportPptx.d.ts.map +1 -0
  240. package/dist/planmagnet/reports/reportExportPptx.js +118 -0
  241. package/dist/planmagnet/reports/reportExportPptx.js.map +1 -0
  242. package/dist/planmagnet/reports/reportExportXlsx.d.ts +4 -0
  243. package/dist/planmagnet/reports/reportExportXlsx.d.ts.map +1 -0
  244. package/dist/planmagnet/reports/reportExportXlsx.js +42 -0
  245. package/dist/planmagnet/reports/reportExportXlsx.js.map +1 -0
  246. package/dist/planmagnet/reports/reportGraphql.d.ts +28 -0
  247. package/dist/planmagnet/reports/reportGraphql.d.ts.map +1 -0
  248. package/dist/planmagnet/reports/reportGraphql.js +360 -0
  249. package/dist/planmagnet/reports/reportGraphql.js.map +1 -0
  250. package/dist/planmagnet/reports/reportModel.d.ts +198 -0
  251. package/dist/planmagnet/reports/reportModel.d.ts.map +1 -0
  252. package/dist/planmagnet/reports/reportModel.js +328 -0
  253. package/dist/planmagnet/reports/reportModel.js.map +1 -0
  254. package/dist/planmagnet/reports/sharedReportRoute.d.ts +14 -0
  255. package/dist/planmagnet/reports/sharedReportRoute.d.ts.map +1 -0
  256. package/dist/planmagnet/reports/sharedReportRoute.js +9 -0
  257. package/dist/planmagnet/reports/sharedReportRoute.js.map +1 -0
  258. package/package.json +6 -4
@@ -0,0 +1,220 @@
1
+ import { PARAM_LABELS as e, REPORT_SOURCE_SPECS as t, SOURCE_GROUPS as n, WIDGET_TYPES as r, newWidgetId as i } from "./reportModel.js";
2
+ import { ProjectSelect as a, SprintSelect as o, TeamSelect as s } from "../controls/Pickers.js";
3
+ import { useId as c, useState as l } from "react";
4
+ import { Fragment as u, jsx as d, jsxs as f } from "react/jsx-runtime";
5
+ import { Button as p, Input as m, ResponsiveDialog as h, ResponsiveDialogContent as g, ResponsiveDialogDescription as _, ResponsiveDialogFooter as v, ResponsiveDialogHeader as y, ResponsiveDialogTitle as b, Select as x, SelectContent as S, SelectGroup as C, SelectItem as w, SelectLabel as T, SelectTrigger as E, SelectValue as D } from "@burdenoff/fe-libs/ui";
6
+ //#region src/planmagnet/reports/WidgetEditorDialog.tsx
7
+ var O = {
8
+ KPI: "KPI tiles",
9
+ CHART: "Chart",
10
+ TABLE: "Table",
11
+ TEXT: "Section header (no data)"
12
+ };
13
+ function k(e, n) {
14
+ let r = new Set(t[e].allowedParams), i = {};
15
+ return r.has("projectId") && n.projectId && (i.projectId = n.projectId), r.has("sprintId") && n.sprintId && (i.sprintId = n.sprintId), r.has("teamId") && n.teamId && (i.teamId = n.teamId), r.has("from") && n.from && (i.from = n.from), r.has("to") && n.to && (i.to = n.to), r.has("limit") && n.limit && (i.limit = n.limit), i;
16
+ }
17
+ function A({ widget: h, onCancel: g, onSave: A }) {
18
+ let j = c(), [M, N] = l(h?.type ?? "TABLE"), [P, F] = l(h?.source ?? "WORK_ITEMS"), [I, L] = l(h?.title ?? t.WORK_ITEMS.label), [R, z] = l(h?.params ?? {}), [B, V] = l(!1), H = t[P], U = B && !I.trim(), W = B && R.limit !== void 0 && R.limit !== null && (!Number.isInteger(R.limit) || R.limit < 1), G = I.trim().length > 0 && !W, K = (e) => {
19
+ F(e), z((t) => k(e, t)), L((n) => !h && (n === "" || n === H.label) ? t[e].label : n);
20
+ }, q = (e, t) => {
21
+ z((n) => ({
22
+ ...n,
23
+ [e]: t
24
+ }));
25
+ };
26
+ return /* @__PURE__ */ f(u, { children: [
27
+ /* @__PURE__ */ f(y, { children: [/* @__PURE__ */ d(b, { children: h ? "Edit widget" : "Add widget" }), /* @__PURE__ */ d(_, { children: "Choose what this widget shows. Only the fields its data source reads are asked for." })] }),
28
+ /* @__PURE__ */ f("div", {
29
+ className: "space-y-4",
30
+ children: [
31
+ /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
32
+ htmlFor: `${j}-type`,
33
+ className: "text-sm font-medium",
34
+ children: "Widget type"
35
+ }), /* @__PURE__ */ f(x, {
36
+ value: M,
37
+ onValueChange: (e) => N(e),
38
+ children: [/* @__PURE__ */ d(E, {
39
+ id: `${j}-type`,
40
+ className: "mt-1",
41
+ children: /* @__PURE__ */ d(D, {})
42
+ }), /* @__PURE__ */ d(S, { children: r.map((e) => /* @__PURE__ */ d(w, {
43
+ value: e,
44
+ children: O[e]
45
+ }, e)) })]
46
+ })] }),
47
+ M !== "TEXT" && /* @__PURE__ */ f("div", { children: [
48
+ /* @__PURE__ */ d("label", {
49
+ htmlFor: `${j}-source`,
50
+ className: "text-sm font-medium",
51
+ children: "Data source"
52
+ }),
53
+ /* @__PURE__ */ f(x, {
54
+ value: P,
55
+ onValueChange: (e) => K(e),
56
+ children: [/* @__PURE__ */ d(E, {
57
+ id: `${j}-source`,
58
+ className: "mt-1",
59
+ children: /* @__PURE__ */ d(D, {})
60
+ }), /* @__PURE__ */ d(S, { children: n.map(({ group: e, sources: n }) => /* @__PURE__ */ f(C, { children: [/* @__PURE__ */ d(T, { children: e }), n.map((e) => /* @__PURE__ */ d(w, {
61
+ value: e,
62
+ children: t[e].label
63
+ }, e))] }, e)) })]
64
+ }),
65
+ /* @__PURE__ */ d("p", {
66
+ className: "mt-1 text-xs text-muted-foreground",
67
+ children: H.description
68
+ })
69
+ ] }),
70
+ /* @__PURE__ */ f("div", { children: [
71
+ /* @__PURE__ */ d("label", {
72
+ htmlFor: `${j}-title`,
73
+ className: "text-sm font-medium",
74
+ children: "Title"
75
+ }),
76
+ /* @__PURE__ */ d(m, {
77
+ id: `${j}-title`,
78
+ className: "mt-1",
79
+ value: I,
80
+ onChange: (e) => L(e.target.value),
81
+ "aria-invalid": U
82
+ }),
83
+ U && /* @__PURE__ */ d("p", {
84
+ className: "mt-1 text-xs text-destructive",
85
+ children: "Give this widget a title."
86
+ })
87
+ ] }),
88
+ M !== "TEXT" && H.allowedParams.length > 0 && /* @__PURE__ */ f("fieldset", {
89
+ className: "space-y-3 rounded-md border border-border p-3",
90
+ children: [
91
+ /* @__PURE__ */ d("legend", {
92
+ className: "px-1 text-xs font-medium text-muted-foreground",
93
+ children: "Parameters"
94
+ }),
95
+ H.allowedParams.includes("projectId") && /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
96
+ htmlFor: `${j}-projectId`,
97
+ className: "text-xs font-medium",
98
+ children: e.projectId
99
+ }), /* @__PURE__ */ d(a, {
100
+ id: `${j}-projectId`,
101
+ value: R.projectId ?? "",
102
+ onChange: (e) => q("projectId", e || void 0),
103
+ noneLabel: "Not set"
104
+ })] }),
105
+ H.allowedParams.includes("sprintId") && /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
106
+ htmlFor: `${j}-sprintId`,
107
+ className: "text-xs font-medium",
108
+ children: e.sprintId
109
+ }), /* @__PURE__ */ d(o, {
110
+ id: `${j}-sprintId`,
111
+ projectId: R.projectId ?? void 0,
112
+ value: R.sprintId ?? "",
113
+ onChange: (e) => q("sprintId", e || void 0),
114
+ noneLabel: "Not set"
115
+ })] }),
116
+ H.allowedParams.includes("teamId") && /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
117
+ htmlFor: `${j}-teamId`,
118
+ className: "text-xs font-medium",
119
+ children: e.teamId
120
+ }), /* @__PURE__ */ d(s, {
121
+ id: `${j}-teamId`,
122
+ value: R.teamId ?? "",
123
+ onChange: (e) => q("teamId", e || void 0),
124
+ noneLabel: "Not set"
125
+ })] }),
126
+ (H.allowedParams.includes("from") || H.allowedParams.includes("to")) && /* @__PURE__ */ f("div", {
127
+ className: "grid grid-cols-2 gap-2",
128
+ children: [H.allowedParams.includes("from") && /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
129
+ htmlFor: `${j}-from`,
130
+ className: "text-xs font-medium",
131
+ children: e.from
132
+ }), /* @__PURE__ */ d(m, {
133
+ id: `${j}-from`,
134
+ type: "date",
135
+ className: "mt-1",
136
+ value: R.from ? R.from.slice(0, 10) : "",
137
+ onChange: (e) => q("from", e.target.value ? `${e.target.value}T00:00:00.000Z` : void 0)
138
+ })] }), H.allowedParams.includes("to") && /* @__PURE__ */ f("div", { children: [/* @__PURE__ */ d("label", {
139
+ htmlFor: `${j}-to`,
140
+ className: "text-xs font-medium",
141
+ children: e.to
142
+ }), /* @__PURE__ */ d(m, {
143
+ id: `${j}-to`,
144
+ type: "date",
145
+ className: "mt-1",
146
+ value: R.to ? R.to.slice(0, 10) : "",
147
+ onChange: (e) => q("to", e.target.value ? `${e.target.value}T23:59:59.999Z` : void 0)
148
+ })] })]
149
+ }),
150
+ H.allowedParams.includes("limit") && /* @__PURE__ */ f("div", { children: [
151
+ /* @__PURE__ */ d("label", {
152
+ htmlFor: `${j}-limit`,
153
+ className: "text-xs font-medium",
154
+ children: e.limit
155
+ }),
156
+ /* @__PURE__ */ d(m, {
157
+ id: `${j}-limit`,
158
+ type: "number",
159
+ min: 1,
160
+ className: "mt-1",
161
+ value: R.limit ?? "",
162
+ "aria-invalid": W,
163
+ onChange: (e) => q("limit", e.target.value === "" ? void 0 : Number(e.target.value))
164
+ }),
165
+ W && /* @__PURE__ */ d("p", {
166
+ className: "mt-1 text-xs text-destructive",
167
+ children: "Limit must be a whole number of 1 or more."
168
+ })
169
+ ] })
170
+ ]
171
+ })
172
+ ]
173
+ }),
174
+ /* @__PURE__ */ f(v, { children: [/* @__PURE__ */ d(p, {
175
+ variant: "outline",
176
+ onClick: g,
177
+ children: "Cancel"
178
+ }), /* @__PURE__ */ d(p, {
179
+ onClick: () => {
180
+ V(!0), !(!I.trim() || W) && A({
181
+ id: h?.id ?? i(),
182
+ type: M,
183
+ title: I.trim(),
184
+ source: P,
185
+ params: R,
186
+ layout: h?.layout ?? {
187
+ x: 0,
188
+ y: 0,
189
+ w: 6,
190
+ h: 4
191
+ }
192
+ });
193
+ },
194
+ disabled: !G,
195
+ "data-testid": "report-save-widget",
196
+ children: h ? "Save widget" : "Add widget"
197
+ })] })
198
+ ] });
199
+ }
200
+ function j({ open: e, onOpenChange: t, widget: n, onSave: r }) {
201
+ return /* @__PURE__ */ d(h, {
202
+ open: e,
203
+ onOpenChange: t,
204
+ children: /* @__PURE__ */ d(g, {
205
+ className: "max-h-[85vh] overflow-y-auto sm:max-w-lg",
206
+ "data-testid": "report-add-widget",
207
+ children: e && /* @__PURE__ */ d(A, {
208
+ widget: n,
209
+ onCancel: () => t(!1),
210
+ onSave: (e) => {
211
+ r(e), t(!1);
212
+ }
213
+ })
214
+ })
215
+ });
216
+ }
217
+ //#endregion
218
+ export { j as WidgetEditorDialog };
219
+
220
+ //# sourceMappingURL=WidgetEditorDialog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WidgetEditorDialog.js","names":[],"sources":["../../../src/planmagnet/reports/WidgetEditorDialog.tsx"],"sourcesContent":["import { useId, useState } from 'react';\nimport {\n Button,\n ResponsiveDialog,\n ResponsiveDialogContent,\n ResponsiveDialogDescription,\n ResponsiveDialogFooter,\n ResponsiveDialogHeader,\n ResponsiveDialogTitle,\n Input,\n Select,\n SelectContent,\n SelectGroup,\n SelectItem,\n SelectLabel,\n SelectTrigger,\n SelectValue,\n} from '@burdenoff/fe-libs/ui';\nimport { ProjectSelect, SprintSelect, TeamSelect } from '../controls/Pickers';\nimport {\n PARAM_LABELS,\n REPORT_SOURCE_SPECS,\n SOURCE_GROUPS,\n WIDGET_TYPES,\n newWidgetId,\n type ReportSource,\n type ReportWidget,\n type WidgetType,\n} from './reportModel';\n\n/**\n * Add/edit one widget's type, source and params (ANR-13). Layout (position/size) is handled by the canvas'\n * own reorder/resize controls, not here — this dialog only ever writes `type`/`title`/`source`/`params`.\n *\n * Params shown are exactly `REPORT_SOURCE_SPECS[source].allowedParams` — switching source drops any param the\n * new source doesn't use, the same normalisation the server's `assertReportDefinition` performs, so what this\n * dialog produces always passes without a round trip.\n *\n * The form's fields (`WidgetEditorForm`) are only ever rendered while `open` is true, so their `useState`\n * initial values — computed straight from `widget`, once, on mount — are always fresh for whichever widget was\n * just opened; there is no effect resyncing them on every `widget`/`open` change (see this file's own\n * `set-state-in-effect` history: this component used to reset its fields via a `useEffect`, which the React\n * Compiler ESLint rule flags as exactly the derived-state anti-pattern the mount/unmount-driven reset here\n * avoids).\n */\n\nconst WIDGET_TYPE_LABELS: Record<WidgetType, string> = {\n KPI: 'KPI tiles',\n CHART: 'Chart',\n TABLE: 'Table',\n TEXT: 'Section header (no data)',\n};\n\nfunction paramsForSource(\n source: ReportSource,\n previous: ReportWidget['params']\n): ReportWidget['params'] {\n const allowed = new Set(REPORT_SOURCE_SPECS[source].allowedParams);\n const next: ReportWidget['params'] = {};\n if (allowed.has('projectId') && previous.projectId) next.projectId = previous.projectId;\n if (allowed.has('sprintId') && previous.sprintId) next.sprintId = previous.sprintId;\n if (allowed.has('teamId') && previous.teamId) next.teamId = previous.teamId;\n if (allowed.has('from') && previous.from) next.from = previous.from;\n if (allowed.has('to') && previous.to) next.to = previous.to;\n if (allowed.has('limit') && previous.limit) next.limit = previous.limit;\n return next;\n}\n\nfunction WidgetEditorForm({\n widget,\n onCancel,\n onSave,\n}: {\n widget: ReportWidget | null;\n onCancel: () => void;\n onSave: (widget: ReportWidget) => void;\n}) {\n const titleId = useId();\n const [type, setType] = useState<WidgetType>(widget?.type ?? 'TABLE');\n const [source, setSource] = useState<ReportSource>(widget?.source ?? 'WORK_ITEMS');\n const [title, setTitle] = useState(widget?.title ?? REPORT_SOURCE_SPECS.WORK_ITEMS.label);\n const [params, setParams] = useState<ReportWidget['params']>(widget?.params ?? {});\n const [touched, setTouched] = useState(false);\n\n const spec = REPORT_SOURCE_SPECS[source];\n const titleInvalid = touched && !title.trim();\n const limitInvalid =\n touched &&\n params.limit !== undefined &&\n params.limit !== null &&\n (!Number.isInteger(params.limit) || params.limit < 1);\n const canSave = title.trim().length > 0 && !limitInvalid;\n\n const handleSourceChange = (next: ReportSource) => {\n setSource(next);\n setParams((prev) => paramsForSource(next, prev));\n // A freshly-typed custom title is kept; an untouched default title follows the source so \"Add widget\" ->\n // pick a source still shows a sensible title without the user having to type one.\n setTitle((prev) =>\n !widget && (prev === '' || prev === spec.label) ? REPORT_SOURCE_SPECS[next].label : prev\n );\n };\n\n const setParam = <K extends keyof ReportWidget['params']>(\n key: K,\n value: ReportWidget['params'][K]\n ) => {\n setParams((prev) => ({ ...prev, [key]: value }));\n };\n\n const handleSave = () => {\n setTouched(true);\n if (!title.trim() || limitInvalid) return;\n const id = widget?.id ?? newWidgetId();\n onSave({\n id,\n type,\n title: title.trim(),\n source,\n params,\n layout: widget?.layout ?? { x: 0, y: 0, w: 6, h: 4 },\n });\n };\n\n return (\n <>\n <ResponsiveDialogHeader>\n <ResponsiveDialogTitle>{widget ? 'Edit widget' : 'Add widget'}</ResponsiveDialogTitle>\n <ResponsiveDialogDescription>\n Choose what this widget shows. Only the fields its data source reads are asked for.\n </ResponsiveDialogDescription>\n </ResponsiveDialogHeader>\n\n <div className=\"space-y-4\">\n <div>\n <label htmlFor={`${titleId}-type`} className=\"text-sm font-medium\">\n Widget type\n </label>\n <Select value={type} onValueChange={(v) => setType(v as WidgetType)}>\n <SelectTrigger id={`${titleId}-type`} className=\"mt-1\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {WIDGET_TYPES.map((t) => (\n <SelectItem key={t} value={t}>\n {WIDGET_TYPE_LABELS[t]}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n {type !== 'TEXT' && (\n <div>\n <label htmlFor={`${titleId}-source`} className=\"text-sm font-medium\">\n Data source\n </label>\n <Select value={source} onValueChange={(v) => handleSourceChange(v as ReportSource)}>\n <SelectTrigger id={`${titleId}-source`} className=\"mt-1\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n {SOURCE_GROUPS.map(({ group, sources }) => (\n <SelectGroup key={group}>\n <SelectLabel>{group}</SelectLabel>\n {sources.map((s) => (\n <SelectItem key={s} value={s}>\n {REPORT_SOURCE_SPECS[s].label}\n </SelectItem>\n ))}\n </SelectGroup>\n ))}\n </SelectContent>\n </Select>\n <p className=\"mt-1 text-xs text-muted-foreground\">{spec.description}</p>\n </div>\n )}\n\n <div>\n <label htmlFor={`${titleId}-title`} className=\"text-sm font-medium\">\n Title\n </label>\n <Input\n id={`${titleId}-title`}\n className=\"mt-1\"\n value={title}\n onChange={(e) => setTitle(e.target.value)}\n aria-invalid={titleInvalid}\n />\n {titleInvalid && (\n <p className=\"mt-1 text-xs text-destructive\">Give this widget a title.</p>\n )}\n </div>\n\n {type !== 'TEXT' && spec.allowedParams.length > 0 && (\n <fieldset className=\"space-y-3 rounded-md border border-border p-3\">\n <legend className=\"px-1 text-xs font-medium text-muted-foreground\">Parameters</legend>\n {spec.allowedParams.includes('projectId') && (\n <div>\n <label htmlFor={`${titleId}-projectId`} className=\"text-xs font-medium\">\n {PARAM_LABELS.projectId}\n </label>\n <ProjectSelect\n id={`${titleId}-projectId`}\n value={params.projectId ?? ''}\n onChange={(v) => setParam('projectId', v || undefined)}\n noneLabel=\"Not set\"\n />\n </div>\n )}\n {spec.allowedParams.includes('sprintId') && (\n <div>\n <label htmlFor={`${titleId}-sprintId`} className=\"text-xs font-medium\">\n {PARAM_LABELS.sprintId}\n </label>\n <SprintSelect\n id={`${titleId}-sprintId`}\n projectId={params.projectId ?? undefined}\n value={params.sprintId ?? ''}\n onChange={(v) => setParam('sprintId', v || undefined)}\n noneLabel=\"Not set\"\n />\n </div>\n )}\n {spec.allowedParams.includes('teamId') && (\n <div>\n <label htmlFor={`${titleId}-teamId`} className=\"text-xs font-medium\">\n {PARAM_LABELS.teamId}\n </label>\n <TeamSelect\n id={`${titleId}-teamId`}\n value={params.teamId ?? ''}\n onChange={(v) => setParam('teamId', v || undefined)}\n noneLabel=\"Not set\"\n />\n </div>\n )}\n {(spec.allowedParams.includes('from') || spec.allowedParams.includes('to')) && (\n <div className=\"grid grid-cols-2 gap-2\">\n {spec.allowedParams.includes('from') && (\n <div>\n <label htmlFor={`${titleId}-from`} className=\"text-xs font-medium\">\n {PARAM_LABELS.from}\n </label>\n <Input\n id={`${titleId}-from`}\n type=\"date\"\n className=\"mt-1\"\n value={params.from ? params.from.slice(0, 10) : ''}\n onChange={(e) =>\n setParam(\n 'from',\n e.target.value ? `${e.target.value}T00:00:00.000Z` : undefined\n )\n }\n />\n </div>\n )}\n {spec.allowedParams.includes('to') && (\n <div>\n <label htmlFor={`${titleId}-to`} className=\"text-xs font-medium\">\n {PARAM_LABELS.to}\n </label>\n <Input\n id={`${titleId}-to`}\n type=\"date\"\n className=\"mt-1\"\n value={params.to ? params.to.slice(0, 10) : ''}\n onChange={(e) =>\n setParam(\n 'to',\n e.target.value ? `${e.target.value}T23:59:59.999Z` : undefined\n )\n }\n />\n </div>\n )}\n </div>\n )}\n {spec.allowedParams.includes('limit') && (\n <div>\n <label htmlFor={`${titleId}-limit`} className=\"text-xs font-medium\">\n {PARAM_LABELS.limit}\n </label>\n <Input\n id={`${titleId}-limit`}\n type=\"number\"\n min={1}\n className=\"mt-1\"\n value={params.limit ?? ''}\n aria-invalid={limitInvalid}\n onChange={(e) =>\n setParam('limit', e.target.value === '' ? undefined : Number(e.target.value))\n }\n />\n {limitInvalid && (\n <p className=\"mt-1 text-xs text-destructive\">\n Limit must be a whole number of 1 or more.\n </p>\n )}\n </div>\n )}\n </fieldset>\n )}\n </div>\n\n <ResponsiveDialogFooter>\n <Button variant=\"outline\" onClick={onCancel}>\n Cancel\n </Button>\n <Button onClick={handleSave} disabled={!canSave} data-testid=\"report-save-widget\">\n {widget ? 'Save widget' : 'Add widget'}\n </Button>\n </ResponsiveDialogFooter>\n </>\n );\n}\n\nexport function WidgetEditorDialog({\n open,\n onOpenChange,\n widget,\n onSave,\n}: {\n open: boolean;\n onOpenChange: (open: boolean) => void;\n /** The widget being edited, or null when adding a new one. */\n widget: ReportWidget | null;\n onSave: (widget: ReportWidget) => void;\n}) {\n return (\n <ResponsiveDialog open={open} onOpenChange={onOpenChange}>\n <ResponsiveDialogContent\n className=\"max-h-[85vh] overflow-y-auto sm:max-w-lg\"\n data-testid=\"report-add-widget\"\n >\n {open && (\n <WidgetEditorForm\n widget={widget}\n onCancel={() => onOpenChange(false)}\n onSave={(saved) => {\n onSave(saved);\n onOpenChange(false);\n }}\n />\n )}\n </ResponsiveDialogContent>\n </ResponsiveDialog>\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { ReportWidget, ReportRun } from './reportModel';
2
+
3
+ export declare function exportReportRunToPptx(widgets: ReportWidget[], run: ReportRun, fileNameBase: string, reportName: string): Promise<void>;
4
+ //# sourceMappingURL=reportExportPptx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reportExportPptx.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/reports/reportExportPptx.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,eAAe,CAAC;AA2DvB,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,YAAY,EAAE,EACvB,GAAG,EAAE,SAAS,EACd,YAAY,EAAE,MAAM,EACpB,UAAU,EAAE,MAAM,GACjB,OAAO,CAAC,IAAI,CAAC,CA8Ff"}
@@ -0,0 +1,118 @@
1
+ import { extractRows as e, humanizeKey as t, scalarFields as n } from "./reportModel.js";
2
+ //#region src/planmagnet/reports/reportExportPptx.ts
3
+ var r = 14, i = 6, a = {
4
+ heading: "4F46E5",
5
+ secondaryText: "666666",
6
+ error: "991B1B",
7
+ tableHeaderFill: "EEF2FF",
8
+ tableBorder: "D1D5DB",
9
+ footer: "999999"
10
+ };
11
+ function o(e) {
12
+ return e == null ? "—" : typeof e == "boolean" ? e ? "Yes" : "No" : typeof e == "number" ? Number.isInteger(e) ? String(e) : e.toFixed(2) : String(e);
13
+ }
14
+ function s(a) {
15
+ if (a && typeof a == "object" && !Array.isArray(a)) {
16
+ let e = n(a);
17
+ if (e.length > 0) return {
18
+ header: ["Field", "Value"],
19
+ rows: e.map(([e, n]) => [t(e), o(n)])
20
+ };
21
+ }
22
+ let s = e(a);
23
+ if (s.length === 0) return {
24
+ header: [],
25
+ rows: []
26
+ };
27
+ let c = [...new Set(s.flatMap((e) => n(e).map(([e]) => e)))].slice(0, i);
28
+ return {
29
+ header: c.map(t),
30
+ rows: s.slice(0, r).map((e) => c.map((t) => o(e[t])))
31
+ };
32
+ }
33
+ async function c(e, t, n, i) {
34
+ let { default: o } = await import("../../node_modules/pptxgenjs/dist/pptxgen.es.js"), c = new o();
35
+ c.layout = "LAYOUT_WIDE", c.author = "PlanMagnet", c.title = i;
36
+ let l = c.addSlide();
37
+ l.addText(i, {
38
+ x: .5,
39
+ y: 1.5,
40
+ w: 9,
41
+ h: 1,
42
+ fontSize: 28,
43
+ bold: !0,
44
+ color: a.heading
45
+ }), l.addText(`Generated ${new Date(t.generatedAt).toLocaleString()}`, {
46
+ x: .5,
47
+ y: 2.4,
48
+ w: 9,
49
+ h: .5,
50
+ fontSize: 14,
51
+ color: a.secondaryText
52
+ });
53
+ for (let n of e) {
54
+ let e = c.addSlide();
55
+ if (e.addText(n.title, {
56
+ x: .4,
57
+ y: .3,
58
+ w: 9.2,
59
+ h: .6,
60
+ fontSize: 20,
61
+ bold: !0,
62
+ color: a.heading
63
+ }), n.type === "TEXT") continue;
64
+ let i = t.widgets.find((e) => e.widgetId === n.id);
65
+ if (!i || i.status !== "OK") {
66
+ e.addText(i?.message ?? "Not available in this run.", {
67
+ x: .4,
68
+ y: 1.2,
69
+ w: 9.2,
70
+ h: 1,
71
+ fontSize: 14,
72
+ color: a.error
73
+ });
74
+ continue;
75
+ }
76
+ let { header: o, rows: l } = s(i.result);
77
+ if (o.length === 0) {
78
+ e.addText("No data.", {
79
+ x: .4,
80
+ y: 1.2,
81
+ w: 9.2,
82
+ h: 1,
83
+ fontSize: 14,
84
+ color: a.secondaryText
85
+ });
86
+ continue;
87
+ }
88
+ e.addTable([o.map((e) => ({
89
+ text: e,
90
+ options: {
91
+ bold: !0,
92
+ fill: { color: a.tableHeaderFill }
93
+ }
94
+ })), ...l.map((e) => e.map((e) => ({ text: e })))], {
95
+ x: .4,
96
+ y: 1.1,
97
+ w: 9.2,
98
+ fontSize: 10,
99
+ border: {
100
+ type: "solid",
101
+ color: a.tableBorder,
102
+ pt: .5
103
+ }
104
+ }), l.length === r && e.addText(`Showing the first ${r} rows.`, {
105
+ x: .4,
106
+ y: 6.8,
107
+ w: 9.2,
108
+ h: .3,
109
+ fontSize: 9,
110
+ color: a.footer
111
+ });
112
+ }
113
+ await c.writeFile({ fileName: `${n}.pptx` });
114
+ }
115
+ //#endregion
116
+ export { c as exportReportRunToPptx };
117
+
118
+ //# sourceMappingURL=reportExportPptx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reportExportPptx.js","names":[],"sources":["../../../src/planmagnet/reports/reportExportPptx.ts"],"sourcesContent":["import {\n extractRows,\n humanizeKey,\n scalarFields,\n type ReportWidget,\n type ReportRun,\n} from './reportModel';\n\n/**\n * PowerPoint export (ANR-16), client-side, straight from an already-fetched `ReportRun` — one slide per\n * widget: its title, then either a small table of its key figures or its row data, capped to fit one slide.\n * Loaded via a dynamic `import()` only when the user actually exports to PowerPoint, so `pptxgenjs` (a large\n * library) never lands in the main bundle.\n */\n\nconst MAX_TABLE_ROWS = 14;\nconst MAX_TABLE_COLUMNS = 6;\n/**\n * The slide deck's own palette. A .pptx is a standalone document, not themed UI: every slide has a white\n * background whatever theme the exporting user had on, and pptxgenjs only accepts sRGB hex. The app's semantic\n * tokens are oklch values that flip under dark mode (primary becomes near-white), so resolving them at export\n * time would put white text on a white slide. These fixed, print-safe values are therefore the deck's palette —\n * kept in this one place so nothing else in the exporter carries a colour literal.\n */\nconst SLIDE_PALETTE = {\n heading: '4F46E5',\n secondaryText: '666666',\n error: '991B1B',\n tableHeaderFill: 'EEF2FF',\n tableBorder: 'D1D5DB',\n footer: '999999',\n} as const;\n\nfunction cellText(value: unknown): string {\n if (value === null || value === undefined) return '—';\n if (typeof value === 'boolean') return value ? 'Yes' : 'No';\n if (typeof value === 'number') return Number.isInteger(value) ? String(value) : value.toFixed(2);\n return String(value);\n}\n\n/** Table rows for one widget's run result: the object's own scalar fields as a 2-column label/value table when\n * it's a single record, otherwise the first `MAX_TABLE_ROWS` data rows with up to `MAX_TABLE_COLUMNS`\n * columns — the same generic shaping `ReportWidgetRenderer.tsx` uses for the in-app table/KPI view. */\nfunction widgetTable(result: unknown): { header: string[]; rows: string[][] } {\n if (result && typeof result === 'object' && !Array.isArray(result)) {\n const fields = scalarFields(result as Record<string, unknown>);\n if (fields.length > 0) {\n return {\n header: ['Field', 'Value'],\n rows: fields.map(([key, value]) => [humanizeKey(key), cellText(value)]),\n };\n }\n }\n const rows = extractRows(result);\n if (rows.length === 0) return { header: [], rows: [] };\n const columns = [...new Set(rows.flatMap((row) => scalarFields(row).map(([key]) => key)))].slice(\n 0,\n MAX_TABLE_COLUMNS\n );\n return {\n header: columns.map(humanizeKey),\n rows: rows.slice(0, MAX_TABLE_ROWS).map((row) => columns.map((c) => cellText(row[c]))),\n };\n}\n\nexport async function exportReportRunToPptx(\n widgets: ReportWidget[],\n run: ReportRun,\n fileNameBase: string,\n reportName: string\n): Promise<void> {\n const { default: PptxGenJS } = await import('pptxgenjs');\n const pres = new PptxGenJS();\n pres.layout = 'LAYOUT_WIDE';\n pres.author = 'PlanMagnet';\n pres.title = reportName;\n\n const cover = pres.addSlide();\n cover.addText(reportName, {\n x: 0.5,\n y: 1.5,\n w: 9,\n h: 1,\n fontSize: 28,\n bold: true,\n color: SLIDE_PALETTE.heading,\n });\n cover.addText(`Generated ${new Date(run.generatedAt).toLocaleString()}`, {\n x: 0.5,\n y: 2.4,\n w: 9,\n h: 0.5,\n fontSize: 14,\n color: SLIDE_PALETTE.secondaryText,\n });\n\n for (const widget of widgets) {\n const slide = pres.addSlide();\n slide.addText(widget.title, {\n x: 0.4,\n y: 0.3,\n w: 9.2,\n h: 0.6,\n fontSize: 20,\n bold: true,\n color: SLIDE_PALETTE.heading,\n });\n\n if (widget.type === 'TEXT') continue;\n\n const runResult = run.widgets.find((w) => w.widgetId === widget.id);\n if (!runResult || runResult.status !== 'OK') {\n slide.addText(runResult?.message ?? 'Not available in this run.', {\n x: 0.4,\n y: 1.2,\n w: 9.2,\n h: 1,\n fontSize: 14,\n color: SLIDE_PALETTE.error,\n });\n continue;\n }\n\n const { header, rows } = widgetTable(runResult.result);\n if (header.length === 0) {\n slide.addText('No data.', {\n x: 0.4,\n y: 1.2,\n w: 9.2,\n h: 1,\n fontSize: 14,\n color: SLIDE_PALETTE.secondaryText,\n });\n continue;\n }\n slide.addTable(\n [\n header.map((text) => ({\n text,\n options: { bold: true, fill: { color: SLIDE_PALETTE.tableHeaderFill } },\n })),\n ...rows.map((row) => row.map((text) => ({ text }))),\n ],\n {\n x: 0.4,\n y: 1.1,\n w: 9.2,\n fontSize: 10,\n border: { type: 'solid', color: SLIDE_PALETTE.tableBorder, pt: 0.5 },\n }\n );\n if (rows.length === MAX_TABLE_ROWS) {\n slide.addText(`Showing the first ${MAX_TABLE_ROWS} rows.`, {\n x: 0.4,\n y: 6.8,\n w: 9.2,\n h: 0.3,\n fontSize: 9,\n color: SLIDE_PALETTE.footer,\n });\n }\n }\n\n await pres.writeFile({ fileName: `${fileNameBase}.pptx` });\n}\n"],"mappings":"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"}
@@ -0,0 +1,4 @@
1
+ import { ReportWidget, ReportRun } from './reportModel';
2
+
3
+ export declare function exportReportRunToXlsx(widgets: ReportWidget[], run: ReportRun, fileNameBase: string): Promise<void>;
4
+ //# sourceMappingURL=reportExportXlsx.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reportExportXlsx.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/reports/reportExportXlsx.ts"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,YAAY,EACjB,KAAK,SAAS,EACf,MAAM,eAAe,CAAC;AAmEvB,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,YAAY,EAAE,EACvB,GAAG,EAAE,SAAS,EACd,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CAQf"}
@@ -0,0 +1,42 @@
1
+ import { extractRows as e, humanizeKey as t, scalarFields as n } from "./reportModel.js";
2
+ //#region src/planmagnet/reports/reportExportXlsx.ts
3
+ var r = 31;
4
+ function i(e, t) {
5
+ return (e.replace(/[\\/?*[\]:]/g, " ").trim() || `Widget ${t + 1}`).slice(0, r);
6
+ }
7
+ function a(e) {
8
+ let t = /* @__PURE__ */ new Map();
9
+ return e.map((e, n) => {
10
+ let a = i(e.title, n), o = t.get(a) ?? 0;
11
+ if (t.set(a, o + 1), o === 0) return a;
12
+ let s = ` (${o + 1})`;
13
+ return `${a.slice(0, r - s.length)}${s}`;
14
+ });
15
+ }
16
+ var o = /^[=+\-@]/;
17
+ function s(e) {
18
+ return o.test(e) ? `'${e}` : e;
19
+ }
20
+ function c(e) {
21
+ return e == null ? null : typeof e == "number" || typeof e == "boolean" ? e : s(String(e));
22
+ }
23
+ function l(r, i) {
24
+ let a = i.widgets.find((e) => e.widgetId === r.id), o = s(r.title);
25
+ if (r.type === "TEXT") return [[o]];
26
+ if (!a || a.status !== "OK") return [[o], [s(a?.message ?? "Not available in this run.")]];
27
+ let l = e(a.result);
28
+ if (l.length === 0) return [[o], ["No data."]];
29
+ let u = [...new Set(l.flatMap((e) => n(e).map(([e]) => e)))].slice(0, 30);
30
+ return [u.map((e) => s(t(e))), ...l.map((e) => u.map((t) => c(e[t])))];
31
+ }
32
+ async function u(e, t, n) {
33
+ let { default: r } = await import("../../node_modules/write-excel-file/browser/index.js"), i = a(e);
34
+ await r(e.map((e, n) => ({
35
+ sheet: i[n],
36
+ data: l(e, t)
37
+ }))).toFile(`${n}.xlsx`);
38
+ }
39
+ //#endregion
40
+ export { u as exportReportRunToXlsx };
41
+
42
+ //# sourceMappingURL=reportExportXlsx.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reportExportXlsx.js","names":[],"sources":["../../../src/planmagnet/reports/reportExportXlsx.ts"],"sourcesContent":["import {\n extractRows,\n humanizeKey,\n scalarFields,\n type ReportWidget,\n type ReportRun,\n} from './reportModel';\n\n/**\n * Excel export (ANR-16), client-side, straight from an already-fetched `ReportRun` — one sheet per widget, the\n * widget's title as the sheet name. Loaded via a dynamic `import()` only when the user actually exports to\n * Excel, so `write-excel-file` never lands in the main bundle. TEXT widgets and ones with no OK data are given\n * a single-cell sheet explaining why, so an export never silently drops a widget the report defines.\n */\n\nconst MAX_SHEET_NAME = 31; // Excel's own limit\n\nfunction sheetName(title: string, index: number): string {\n const cleaned = title.replace(/[\\\\/?*[\\]:]/g, ' ').trim() || `Widget ${index + 1}`;\n return cleaned.slice(0, MAX_SHEET_NAME);\n}\n\nfunction uniqueSheetNames(widgets: ReportWidget[]): string[] {\n const seen = new Map<string, number>();\n return widgets.map((widget, index) => {\n const base = sheetName(widget.title, index);\n const count = seen.get(base) ?? 0;\n seen.set(base, count + 1);\n if (count === 0) return base;\n const suffix = ` (${count + 1})`;\n return `${base.slice(0, MAX_SHEET_NAME - suffix.length)}${suffix}`;\n });\n}\n\ntype XlsxCell = string | number | boolean | null;\ntype XlsxRow = XlsxCell[];\n\n// OWASP CSV/Formula Injection: a cell whose text starts with one of these characters can be read as a\n// live formula (or, via DDE, a command) by some spreadsheet application/version even though this library\n// writes an explicit `String` cell type. Report data is free text entered by any workspace member (work\n// item titles, risk notes, names, …), so every string cell — not just ones sourced from `extractRows` —\n// must be neutralized before it reaches the file. Prefixing with a single quote is the standard mitigation:\n// Excel/Sheets/LibreOffice render it as plain text rather than evaluating the leading character.\nconst FORMULA_TRIGGER = /^[=+\\-@]/;\n\nfunction neutralizeFormula(text: string): string {\n return FORMULA_TRIGGER.test(text) ? `'${text}` : text;\n}\n\nfunction cellValue(value: unknown): XlsxCell {\n if (value === null || value === undefined) return null;\n if (typeof value === 'number' || typeof value === 'boolean') return value;\n return neutralizeFormula(String(value));\n}\n\nfunction widgetSheetData(widget: ReportWidget, run: ReportRun): XlsxRow[] {\n const runResult = run.widgets.find((w) => w.widgetId === widget.id);\n const title = neutralizeFormula(widget.title);\n if (widget.type === 'TEXT') return [[title]];\n if (!runResult || runResult.status !== 'OK') {\n return [[title], [neutralizeFormula(runResult?.message ?? 'Not available in this run.')]];\n }\n const rows = extractRows(runResult.result);\n if (rows.length === 0) return [[title], ['No data.']];\n const columns = [...new Set(rows.flatMap((row) => scalarFields(row).map(([key]) => key)))].slice(\n 0,\n 30\n );\n const header: XlsxRow = columns.map((c) => neutralizeFormula(humanizeKey(c)));\n const body: XlsxRow[] = rows.map((row) => columns.map((c) => cellValue(row[c])));\n return [header, ...body];\n}\n\nexport async function exportReportRunToXlsx(\n widgets: ReportWidget[],\n run: ReportRun,\n fileNameBase: string\n): Promise<void> {\n const { default: writeXlsxFile } = await import('write-excel-file/browser');\n const names = uniqueSheetNames(widgets);\n const sheets = widgets.map((widget, index) => ({\n sheet: names[index],\n data: widgetSheetData(widget, run),\n }));\n await writeXlsxFile(sheets).toFile(`${fileNameBase}.xlsx`);\n}\n"],"mappings":";;AAeA,IAAM,IAAiB;AAEvB,SAAS,EAAU,GAAe,GAAuB;AAEvD,SADgB,EAAM,QAAQ,gBAAgB,IAAI,CAAC,MAAM,IAAI,UAAU,IAAQ,KAChE,MAAM,GAAG,EAAe;;AAGzC,SAAS,EAAiB,GAAmC;CAC3D,IAAM,oBAAO,IAAI,KAAqB;AACtC,QAAO,EAAQ,KAAK,GAAQ,MAAU;EACpC,IAAM,IAAO,EAAU,EAAO,OAAO,EAAM,EACrC,IAAQ,EAAK,IAAI,EAAK,IAAI;AAEhC,MADA,EAAK,IAAI,GAAM,IAAQ,EAAE,EACrB,MAAU,EAAG,QAAO;EACxB,IAAM,IAAS,KAAK,IAAQ,EAAE;AAC9B,SAAO,GAAG,EAAK,MAAM,GAAG,IAAiB,EAAO,OAAO,GAAG;GAC1D;;AAYJ,IAAM,IAAkB;AAExB,SAAS,EAAkB,GAAsB;AAC/C,QAAO,EAAgB,KAAK,EAAK,GAAG,IAAI,MAAS;;AAGnD,SAAS,EAAU,GAA0B;AAG3C,QAFI,KAAU,OAAoC,OAC9C,OAAO,KAAU,YAAY,OAAO,KAAU,YAAkB,IAC7D,EAAkB,OAAO,EAAM,CAAC;;AAGzC,SAAS,EAAgB,GAAsB,GAA2B;CACxE,IAAM,IAAY,EAAI,QAAQ,MAAM,MAAM,EAAE,aAAa,EAAO,GAAG,EAC7D,IAAQ,EAAkB,EAAO,MAAM;AAC7C,KAAI,EAAO,SAAS,OAAQ,QAAO,CAAC,CAAC,EAAM,CAAC;AAC5C,KAAI,CAAC,KAAa,EAAU,WAAW,KACrC,QAAO,CAAC,CAAC,EAAM,EAAE,CAAC,EAAkB,GAAW,WAAW,6BAA6B,CAAC,CAAC;CAE3F,IAAM,IAAO,EAAY,EAAU,OAAO;AAC1C,KAAI,EAAK,WAAW,EAAG,QAAO,CAAC,CAAC,EAAM,EAAE,CAAC,WAAW,CAAC;CACrD,IAAM,IAAU,CAAC,GAAG,IAAI,IAAI,EAAK,SAAS,MAAQ,EAAa,EAAI,CAAC,KAAK,CAAC,OAAS,EAAI,CAAC,CAAC,CAAC,CAAC,MACzF,GACA,GACD;AAGD,QAAO,CAFiB,EAAQ,KAAK,MAAM,EAAkB,EAAY,EAAE,CAAC,CAAC,EAE7D,GADQ,EAAK,KAAK,MAAQ,EAAQ,KAAK,MAAM,EAAU,EAAI,GAAG,CAAC,CAAC,CACxD;;AAG1B,eAAsB,EACpB,GACA,GACA,GACe;CACf,IAAM,EAAE,SAAS,MAAkB,MAAM,OAAO,yDAC1C,IAAQ,EAAiB,EAAQ;AAKvC,OAAM,EAJS,EAAQ,KAAK,GAAQ,OAAW;EAC7C,OAAO,EAAM;EACb,MAAM,EAAgB,GAAQ,EAAI;EACnC,EAAE,CACwB,CAAC,OAAO,GAAG,EAAa,OAAO"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Reports GraphQL documents (ANR-13/14/15/16). Field selections match `graphql/wspace.graphql`'s
3
+ * `Planmagnet*Report*` types exactly — validated by `bun run validate:schema` against
4
+ * `graphql/planmagnet.graphql` + `graphql/planmagnet-gateway-roots.graphql` (see schema-drift.config.json).
5
+ * Selection sets are written out in full in each document rather than shared via `${fragment}` interpolation —
6
+ * `gql` here only ever parses one literal per call (no other file in this package interpolates a sub-document
7
+ * into a `gql` tag), so this follows the same convention.
8
+ */
9
+ export declare const REPORT_SUMMARY_FIELDS_DOC = "\n id\n name\n description\n ownerId\n visibility\n templateKey\n workspaceId\n createdAt\n updatedAt\n";
10
+ export declare const LIST_REPORTS: import('graphql').DocumentNode;
11
+ export declare const GET_REPORT: import('graphql').DocumentNode;
12
+ export declare const LIST_REPORT_TEMPLATES: import('graphql').DocumentNode;
13
+ export declare const CREATE_REPORT: import('graphql').DocumentNode;
14
+ export declare const UPDATE_REPORT: import('graphql').DocumentNode;
15
+ export declare const DELETE_REPORT: import('graphql').DocumentNode;
16
+ export declare const DUPLICATE_REPORT: import('graphql').DocumentNode;
17
+ export declare const RUN_REPORT: import('graphql').DocumentNode;
18
+ export declare const GET_REPORT_RUN: import('graphql').DocumentNode;
19
+ export declare const LIST_REPORT_RUNS: import('graphql').DocumentNode;
20
+ export declare const EXPORT_REPORT_RUN: import('graphql').DocumentNode;
21
+ export declare const LIST_REPORT_SHARES: import('graphql').DocumentNode;
22
+ export declare const CREATE_REPORT_SHARE: import('graphql').DocumentNode;
23
+ export declare const REVOKE_REPORT_SHARE: import('graphql').DocumentNode;
24
+ export declare const LIST_REPORT_SCHEDULES: import('graphql').DocumentNode;
25
+ export declare const CREATE_REPORT_SCHEDULE: import('graphql').DocumentNode;
26
+ export declare const UPDATE_REPORT_SCHEDULE: import('graphql').DocumentNode;
27
+ export declare const DELETE_REPORT_SCHEDULE: import('graphql').DocumentNode;
28
+ //# sourceMappingURL=reportGraphql.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reportGraphql.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/reports/reportGraphql.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AAEH,eAAO,MAAM,yBAAyB,qHAUrC,CAAC;AAEF,eAAO,MAAM,YAAY,gCAyBxB,CAAC;AAEF,eAAO,MAAM,UAAU,gCAoCtB,CAAC;AAEF,eAAO,MAAM,qBAAqB,gCA8BjC,CAAC;AAEF,eAAO,MAAM,aAAa,gCAoCzB,CAAC;AAEF,eAAO,MAAM,aAAa,gCAoCzB,CAAC;AAEF,eAAO,MAAM,aAAa,gCAIzB,CAAC;AAEF,eAAO,MAAM,gBAAgB,gCAc5B,CAAC;AAEF,eAAO,MAAM,UAAU,gCAmBtB,CAAC;AAEF,eAAO,MAAM,cAAc,gCAmB1B,CAAC;AAEF,eAAO,MAAM,gBAAgB,gCAiB5B,CAAC;AAEF,eAAO,MAAM,iBAAiB,gCAQ7B,CAAC;AAEF,eAAO,MAAM,kBAAkB,gCAiB9B,CAAC;AAEF,eAAO,MAAM,mBAAmB,gCAkB/B,CAAC;AAEF,eAAO,MAAM,mBAAmB,gCAI/B,CAAC;AAEF,eAAO,MAAM,qBAAqB,gCAqBjC,CAAC;AAEF,eAAO,MAAM,sBAAsB,gCAwBlC,CAAC;AAEF,eAAO,MAAM,sBAAsB,gCAqBlC,CAAC;AAEF,eAAO,MAAM,sBAAsB,gCAIlC,CAAC"}