@burdenoff/microfe-planmagnet 2026.930.24 → 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.
- package/dist/_virtual/__vite-browser-external.js +9 -0
- package/dist/_virtual/__vite-browser-external.js.map +1 -0
- package/dist/_virtual/_rolldown/runtime.js +5 -2
- package/dist/index.js +3 -1
- package/dist/node_modules/fflate/esm/browser.js +554 -0
- package/dist/node_modules/fflate/esm/browser.js.map +1 -0
- package/dist/node_modules/jszip/dist/jszip.min.js +3038 -0
- package/dist/node_modules/jszip/dist/jszip.min.js.map +1 -0
- package/dist/node_modules/pptxgenjs/dist/pptxgen.es.js +2151 -0
- package/dist/node_modules/pptxgenjs/dist/pptxgen.es.js.map +1 -0
- package/dist/node_modules/write-excel-file/browser/index.js +3 -0
- package/dist/node_modules/write-excel-file/modules/export/convertFileContentToUint8ArrayBrowser.js +13 -0
- package/dist/node_modules/write-excel-file/modules/export/convertFileContentToUint8ArrayBrowser.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/export/convertFilesContentToUint8Arrays.js +21 -0
- package/dist/node_modules/write-excel-file/modules/export/convertFilesContentToUint8Arrays.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/export/downloadBlob.js +11 -0
- package/dist/node_modules/write-excel-file/modules/export/downloadBlob.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/export/writeXlsxFileBrowser.js +23 -0
- package/dist/node_modules/write-excel-file/modules/export/writeXlsxFileBrowser.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/export/writeXlsxFileUniversal.js +22 -0
- package/dist/node_modules/write-excel-file/modules/export/writeXlsxFileUniversal.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/getSheetData/getSheetData.js +18 -0
- package/dist/node_modules/write-excel-file/modules/getSheetData/getSheetData.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/features/conditionalFormatting.js +131 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/features/conditionalFormatting.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/features/images.js +188 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/features/images.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/features/stickyRowsOrColumns.js +52 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/features/stickyRowsOrColumns.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/_Content_Types_.xml.js +18 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/_Content_Types_.xml.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/drawing.xml.js +18 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/drawing.xml.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/drawing.xml.rels.js +17 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/drawing.xml.rels.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/rels.js +11 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/rels.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sharedStrings.xml.js +42 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sharedStrings.xml.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/cell.js +102 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/cell.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/column.js +17 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/column.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/columns.js +15 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/columns.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/drawingReference.js +8 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/drawingReference.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/helpers/getCellStyleProperties.js +71 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/helpers/getCellStyleProperties.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/mergedCellsDescription.js +56 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/mergedCellsDescription.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/pageMargins.js +15 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/pageMargins.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/pageSetup.js +13 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/pageSetup.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/processMergedCells.js +44 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/processMergedCells.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/row.js +123 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/row.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheet.xml.js +41 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheet.xml.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheetData.js +11 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheetData.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheetViews.js +17 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml/sheetViews.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml.rels.js +20 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/sheet.xml.rels.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/styles.xml.js +77 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/styles.xml.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/workbook.xml.js +22 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/workbook.xml.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/workbook.xml.rels.js +13 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/files/workbook.xml.rels.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/generateXlsxFileContents.js +242 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/generateXlsxFileContents.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/getFeatures.js +29 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/getFeatures.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/convertDateToSerialNumber.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/convertDateToSerialNumber.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getAdditionalContent.js +42 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getAdditionalContent.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getElementXml.js +43 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getElementXml.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getWrittenFiles.js +93 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/getWrittenFiles.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/transformContent.js +39 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/features/transformContent.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getAlignmentXml.js +17 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getAlignmentXml.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getBorderXml.js +29 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getBorderXml.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getCellAddress.js +14 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getCellAddress.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFileExtensionForContentType.js +11 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFileExtensionForContentType.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFillXml.js +14 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFillXml.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFontXml.js +12 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getFontXml.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getOrderOfSiblings.js +24 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getOrderOfSiblings.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getXlsxColorForHexColor.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/getXlsxColorForHexColor.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasAlignment.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasAlignment.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasBorder.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasBorder.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasFill.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasFill.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasFont.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/hasFont.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/isCellObject.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/isCellObject.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/isObject.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/isObject.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/orderOfSiblings.js +27 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/helpers/orderOfSiblings.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/initializeSharedStrings.js +17 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/initializeSharedStrings.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/initializeSheets.js +74 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/initializeSheets.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/initializeStyles.js +138 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/initializeStyles.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/validateSheetData.js +40 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/validateSheetData.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/validateSheetName.js +11 -0
- package/dist/node_modules/write-excel-file/modules/xlsx/validateSheetName.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/appendMarkupInsideElement.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xml/appendMarkupInsideElement.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/applyEnclosingElementOffset.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xml/applyEnclosingElementOffset.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/escapeXmlSpecialCharacters.js +12 -0
- package/dist/node_modules/write-excel-file/modules/xml/escapeXmlSpecialCharacters.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/findElement.js +12 -0
- package/dist/node_modules/write-excel-file/modules/xml/findElement.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/findElementInsideElement.js +12 -0
- package/dist/node_modules/write-excel-file/modules/xml/findElementInsideElement.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/findElementsNonRecursive_.js +41 -0
- package/dist/node_modules/write-excel-file/modules/xml/findElementsNonRecursive_.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/getAttributesString.js +14 -0
- package/dist/node_modules/write-excel-file/modules/xml/getAttributesString.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/getChildElements.js +42 -0
- package/dist/node_modules/write-excel-file/modules/xml/getChildElements.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/getClosingTagMarkup.js +8 -0
- package/dist/node_modules/write-excel-file/modules/xml/getClosingTagMarkup.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/getMarkupInsideElement.js +8 -0
- package/dist/node_modules/write-excel-file/modules/xml/getMarkupInsideElement.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/getOpeningTagMarkup.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xml/getOpeningTagMarkup.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/getSelfClosingTagMarkup.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xml/getSelfClosingTagMarkup.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/insertElementMarkupAccordingToOrderOfSiblings.js +64 -0
- package/dist/node_modules/write-excel-file/modules/xml/insertElementMarkupAccordingToOrderOfSiblings.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/prependMarkupInsideElement.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xml/prependMarkupInsideElement.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/removeInvalidXmlCharacters.js +9 -0
- package/dist/node_modules/write-excel-file/modules/xml/removeInvalidXmlCharacters.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/replaceElement.js +8 -0
- package/dist/node_modules/write-excel-file/modules/xml/replaceElement.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/sanitizeAttributeName.js +10 -0
- package/dist/node_modules/write-excel-file/modules/xml/sanitizeAttributeName.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/sanitizeAttributeValue.js +11 -0
- package/dist/node_modules/write-excel-file/modules/xml/sanitizeAttributeValue.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/sanitizeTextContent.js +11 -0
- package/dist/node_modules/write-excel-file/modules/xml/sanitizeTextContent.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/xml/setMarkupInsideElement.js +8 -0
- package/dist/node_modules/write-excel-file/modules/xml/setMarkupInsideElement.js.map +1 -0
- package/dist/node_modules/write-excel-file/modules/zip/zipToArrayBuffer.js +18 -0
- package/dist/node_modules/write-excel-file/modules/zip/zipToArrayBuffer.js.map +1 -0
- package/dist/planmagnet/PlanMagnetRoot.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoot.js +154 -147
- package/dist/planmagnet/PlanMagnetRoot.js.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.d.ts.map +1 -1
- package/dist/planmagnet/PlanMagnetRoutes.js +122 -106
- package/dist/planmagnet/PlanMagnetRoutes.js.map +1 -1
- package/dist/planmagnet/comments/CommentThread.d.ts +8 -1
- package/dist/planmagnet/comments/CommentThread.d.ts.map +1 -1
- package/dist/planmagnet/comments/CommentThread.js +188 -181
- package/dist/planmagnet/comments/CommentThread.js.map +1 -1
- package/dist/planmagnet/comments/TargetComments.d.ts +10 -2
- package/dist/planmagnet/comments/TargetComments.d.ts.map +1 -1
- package/dist/planmagnet/comments/TargetComments.js +10 -8
- package/dist/planmagnet/comments/TargetComments.js.map +1 -1
- package/dist/planmagnet/comments/WorkItemComments.d.ts +7 -1
- package/dist/planmagnet/comments/WorkItemComments.d.ts.map +1 -1
- package/dist/planmagnet/comments/WorkItemComments.js +5 -4
- package/dist/planmagnet/comments/WorkItemComments.js.map +1 -1
- package/dist/planmagnet/controls/Pickers.d.ts +10 -0
- package/dist/planmagnet/controls/Pickers.d.ts.map +1 -1
- package/dist/planmagnet/controls/Pickers.js +75 -27
- package/dist/planmagnet/controls/Pickers.js.map +1 -1
- package/dist/planmagnet/discussion/WorkItemDiscussionPanel.d.ts +8 -0
- package/dist/planmagnet/discussion/WorkItemDiscussionPanel.d.ts.map +1 -0
- package/dist/planmagnet/discussion/WorkItemDiscussionPanel.js +217 -0
- package/dist/planmagnet/discussion/WorkItemDiscussionPanel.js.map +1 -0
- package/dist/planmagnet/docs/DocDiffView.d.ts +26 -0
- package/dist/planmagnet/docs/DocDiffView.d.ts.map +1 -0
- package/dist/planmagnet/docs/DocDiffView.js +52 -0
- package/dist/planmagnet/docs/DocDiffView.js.map +1 -0
- package/dist/planmagnet/docs/DocSuggestionsPanel.d.ts +13 -0
- package/dist/planmagnet/docs/DocSuggestionsPanel.d.ts.map +1 -0
- package/dist/planmagnet/docs/DocSuggestionsPanel.js +308 -0
- package/dist/planmagnet/docs/DocSuggestionsPanel.js.map +1 -0
- package/dist/planmagnet/docs/DocVersionCompare.d.ts +7 -0
- package/dist/planmagnet/docs/DocVersionCompare.d.ts.map +1 -0
- package/dist/planmagnet/docs/DocVersionCompare.js +105 -0
- package/dist/planmagnet/docs/DocVersionCompare.js.map +1 -0
- package/dist/planmagnet/hooks/usePresence.d.ts +39 -0
- package/dist/planmagnet/hooks/usePresence.d.ts.map +1 -0
- package/dist/planmagnet/hooks/usePresence.js +146 -0
- package/dist/planmagnet/hooks/usePresence.js.map +1 -0
- package/dist/planmagnet/index.d.ts +2 -0
- package/dist/planmagnet/index.d.ts.map +1 -1
- package/dist/planmagnet/index.js +2 -0
- package/dist/planmagnet/links/CodeLinksPanel.d.ts +22 -0
- package/dist/planmagnet/links/CodeLinksPanel.d.ts.map +1 -0
- package/dist/planmagnet/links/CodeLinksPanel.js +94 -0
- package/dist/planmagnet/links/CodeLinksPanel.js.map +1 -0
- package/dist/planmagnet/pages/DocsDocDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js +488 -217
- package/dist/planmagnet/pages/DocsDocDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js +136 -130
- package/dist/planmagnet/pages/ProductsRoadmapDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js +205 -196
- package/dist/planmagnet/pages/ProjectsProjectDetailPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ReportsCreateReportPagePage.d.ts +6 -0
- package/dist/planmagnet/pages/ReportsCreateReportPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ReportsCreateReportPagePage.js +5 -177
- package/dist/planmagnet/pages/ReportsCreateReportPagePage.js.map +1 -1
- package/dist/planmagnet/pages/ReportsEditReportPagePage.d.ts +3 -0
- package/dist/planmagnet/pages/ReportsEditReportPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ReportsEditReportPagePage.js +15 -0
- package/dist/planmagnet/pages/ReportsEditReportPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ReportsReportPagePage.d.ts +7 -0
- package/dist/planmagnet/pages/ReportsReportPagePage.d.ts.map +1 -0
- package/dist/planmagnet/pages/ReportsReportPagePage.js +226 -0
- package/dist/planmagnet/pages/ReportsReportPagePage.js.map +1 -0
- package/dist/planmagnet/pages/ReportsReportsPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/ReportsReportsPagePage.js +224 -496
- package/dist/planmagnet/pages/ReportsReportsPagePage.js.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.d.ts.map +1 -1
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js +194 -160
- package/dist/planmagnet/pages/TasksTaskDetailPagePage.js.map +1 -1
- package/dist/planmagnet/presence/PresenceAvatars.d.ts +16 -0
- package/dist/planmagnet/presence/PresenceAvatars.d.ts.map +1 -0
- package/dist/planmagnet/presence/PresenceAvatars.js +56 -0
- package/dist/planmagnet/presence/PresenceAvatars.js.map +1 -0
- package/dist/planmagnet/reports/ExportMenu.d.ts +9 -0
- package/dist/planmagnet/reports/ExportMenu.d.ts.map +1 -0
- package/dist/planmagnet/reports/ExportMenu.js +116 -0
- package/dist/planmagnet/reports/ExportMenu.js.map +1 -0
- package/dist/planmagnet/reports/PrintReportView.d.ts +24 -0
- package/dist/planmagnet/reports/PrintReportView.d.ts.map +1 -0
- package/dist/planmagnet/reports/PrintReportView.js +75 -0
- package/dist/planmagnet/reports/PrintReportView.js.map +1 -0
- package/dist/planmagnet/reports/ReportBuilderCanvas.d.ts +8 -0
- package/dist/planmagnet/reports/ReportBuilderCanvas.d.ts.map +1 -0
- package/dist/planmagnet/reports/ReportBuilderCanvas.js +261 -0
- package/dist/planmagnet/reports/ReportBuilderCanvas.js.map +1 -0
- package/dist/planmagnet/reports/ReportBuilderPage.d.ts +5 -0
- package/dist/planmagnet/reports/ReportBuilderPage.d.ts.map +1 -0
- package/dist/planmagnet/reports/ReportBuilderPage.js +198 -0
- package/dist/planmagnet/reports/ReportBuilderPage.js.map +1 -0
- package/dist/planmagnet/reports/ReportRunHistory.d.ts +8 -0
- package/dist/planmagnet/reports/ReportRunHistory.d.ts.map +1 -0
- package/dist/planmagnet/reports/ReportRunHistory.js +63 -0
- package/dist/planmagnet/reports/ReportRunHistory.js.map +1 -0
- package/dist/planmagnet/reports/ReportWidgetRenderer.d.ts +7 -0
- package/dist/planmagnet/reports/ReportWidgetRenderer.d.ts.map +1 -0
- package/dist/planmagnet/reports/ReportWidgetRenderer.js +251 -0
- package/dist/planmagnet/reports/ReportWidgetRenderer.js.map +1 -0
- package/dist/planmagnet/reports/SchedulesPanel.d.ts +4 -0
- package/dist/planmagnet/reports/SchedulesPanel.d.ts.map +1 -0
- package/dist/planmagnet/reports/SchedulesPanel.js +457 -0
- package/dist/planmagnet/reports/SchedulesPanel.js.map +1 -0
- package/dist/planmagnet/reports/ShareDialog.d.ts +5 -0
- package/dist/planmagnet/reports/ShareDialog.d.ts.map +1 -0
- package/dist/planmagnet/reports/ShareDialog.js +234 -0
- package/dist/planmagnet/reports/ShareDialog.js.map +1 -0
- package/dist/planmagnet/reports/SharedReportPage.d.ts +4 -0
- package/dist/planmagnet/reports/SharedReportPage.d.ts.map +1 -0
- package/dist/planmagnet/reports/SharedReportPage.js +180 -0
- package/dist/planmagnet/reports/SharedReportPage.js.map +1 -0
- package/dist/planmagnet/reports/WidgetEditorDialog.d.ts +10 -0
- package/dist/planmagnet/reports/WidgetEditorDialog.d.ts.map +1 -0
- package/dist/planmagnet/reports/WidgetEditorDialog.js +220 -0
- package/dist/planmagnet/reports/WidgetEditorDialog.js.map +1 -0
- package/dist/planmagnet/reports/reportExportPptx.d.ts +4 -0
- package/dist/planmagnet/reports/reportExportPptx.d.ts.map +1 -0
- package/dist/planmagnet/reports/reportExportPptx.js +118 -0
- package/dist/planmagnet/reports/reportExportPptx.js.map +1 -0
- package/dist/planmagnet/reports/reportExportXlsx.d.ts +4 -0
- package/dist/planmagnet/reports/reportExportXlsx.d.ts.map +1 -0
- package/dist/planmagnet/reports/reportExportXlsx.js +42 -0
- package/dist/planmagnet/reports/reportExportXlsx.js.map +1 -0
- package/dist/planmagnet/reports/reportGraphql.d.ts +28 -0
- package/dist/planmagnet/reports/reportGraphql.d.ts.map +1 -0
- package/dist/planmagnet/reports/reportGraphql.js +360 -0
- package/dist/planmagnet/reports/reportGraphql.js.map +1 -0
- package/dist/planmagnet/reports/reportModel.d.ts +198 -0
- package/dist/planmagnet/reports/reportModel.d.ts.map +1 -0
- package/dist/planmagnet/reports/reportModel.js +328 -0
- package/dist/planmagnet/reports/reportModel.js.map +1 -0
- package/dist/planmagnet/reports/sharedReportRoute.d.ts +14 -0
- package/dist/planmagnet/reports/sharedReportRoute.d.ts.map +1 -0
- package/dist/planmagnet/reports/sharedReportRoute.js +9 -0
- package/dist/planmagnet/reports/sharedReportRoute.js.map +1 -0
- package/dist/planmagnet/utils/graphqlErrors.d.ts +6 -0
- package/dist/planmagnet/utils/graphqlErrors.d.ts.map +1 -1
- package/dist/planmagnet/utils/graphqlErrors.js +5 -2
- package/dist/planmagnet/utils/graphqlErrors.js.map +1 -1
- package/dist/planmagnet/utils/lineDiff.d.ts +21 -0
- package/dist/planmagnet/utils/lineDiff.d.ts.map +1 -0
- package/dist/planmagnet/utils/lineDiff.js +36 -0
- package/dist/planmagnet/utils/lineDiff.js.map +1 -0
- package/package.json +6 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReportsReportsPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ReportsReportsPagePage.tsx"],"sourcesContent":["import { useState } from 'react';\nimport { gql } from '@apollo/client';\nimport { useQuery } from '@apollo/client/react';\nimport {\n Badge,\n Card,\n CardContent,\n CardHeader,\n CardTitle,\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { BarChart3, ShieldCheck, TrendingUp, Users } from 'lucide-react';\nimport {\n Bar,\n BarChart,\n CartesianGrid,\n Legend,\n ReferenceLine,\n ResponsiveContainer,\n Tooltip,\n XAxis,\n YAxis,\n} from 'recharts';\nimport { usePlanMagnet } from '../providers/PlanMagnetProvider';\nimport { CycleTimeCard } from './analytics/DeliveryHealthCards';\n\n/**\n * Reports (BOFF-8048). Until this ticket, Reports had no saved-report model and no report runner, so the page said\n * so and pointed at Analytics instead (BOFF-7967). Every panel here is query-driven — it reads numbers the server\n * already computes (velocity, cycle time, throughput, release readiness) — with ZERO client-side row fabrication.\n * That property is the entire point: this page previously invented rows (\"Velocity Report\", \"Burndown\", …) with\n * made-up schedules and run counts, which is exactly what must never come back (see git history / BOFF-7967).\n *\n * `planmagnetThroughput` ships with the BOFF-8048 backend PR — until it deploys and the schema is re-pulled,\n * `bun run validate:schema` fails on the Throughput panel's query below (expected; not a regression in the other\n * three panels, which reuse queries that already exist and are already validated: planmagnetVelocity,\n * planmagnetCycleTime — via <CycleTimeCard>, planmagnetTeamVelocity and planmagnetReleaseReadiness).\n */\n\nconst GET_REPORTS_PROJECTS = gql`\n query GetReportsProjects($workspaceId: ID!) {\n planmagnetProjects(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n }\n }\n }\n`;\n\nconst GET_REPORTS_VELOCITY = gql`\n query GetReportsVelocity($workspaceId: ID!, $projectId: ID!, $trailingSprintCount: Int) {\n planmagnetVelocity(\n workspaceId: $workspaceId\n projectId: $projectId\n trailingSprintCount: $trailingSprintCount\n ) {\n projectId\n averageVelocity\n forecastNextSprintPoints\n sprints {\n sprintId\n sprintName\n sequenceNumber\n completedPoints\n completedCount\n plannedPoints\n }\n }\n }\n`;\n\n// New with BOFF-8048 — see the file-header note on schema-drift.\nconst GET_REPORTS_THROUGHPUT = gql`\n query GetReportsThroughput(\n $workspaceId: ID!\n $projectId: ID!\n $bucket: PlanmagnetThroughputBucket\n ) {\n planmagnetThroughput(workspaceId: $workspaceId, projectId: $projectId, bucket: $bucket) {\n projectId\n bucket\n startDate\n endDate\n points {\n periodStart\n completedCount\n completedPoints\n }\n }\n }\n`;\n\nconst GET_REPORTS_TEAMS = gql`\n query GetReportsTeams($workspaceId: ID!) {\n planmagnetTeams(workspaceId: $workspaceId, pagination: { first: 100 }) {\n items {\n id\n name\n }\n }\n }\n`;\n\nconst GET_REPORTS_TEAM_VELOCITY = gql`\n query GetReportsTeamVelocity($workspaceId: ID!, $teamId: ID!, $trailingSprintCount: Int) {\n planmagnetTeamVelocity(\n workspaceId: $workspaceId\n teamId: $teamId\n trailingSprintCount: $trailingSprintCount\n ) {\n teamId\n averageVelocity\n forecastNextSprintPoints\n sprints {\n sprintId\n sprintName\n sequenceNumber\n completedCount\n completedPoints\n plannedPoints\n byProject {\n projectId\n projectName\n count\n points\n }\n }\n }\n }\n`;\n\nconst GET_REPORTS_RELEASES = gql`\n query GetReportsReleases($workspaceId: ID!, $projectId: String) {\n planmagnetReleases(\n workspaceId: $workspaceId\n filter: { projectId: $projectId }\n pagination: { first: 50 }\n ) {\n items {\n id\n name\n status\n plannedDate\n }\n totalCount\n }\n }\n`;\n\nconst GET_RELEASE_READINESS = gql`\n query GetReportsReleaseReadiness($releaseId: ID!) {\n planmagnetReleaseReadiness(releaseId: $releaseId) {\n releaseId\n doneItems\n totalItems\n blockers {\n workItem {\n id\n key\n title\n }\n }\n }\n }\n`;\n\n// Non-terminal: still worth watching for readiness. RELEASED/ROLLED_BACK/CANCELLED are done stories, not upcoming.\nconst OPEN_RELEASE_STATUSES = new Set(['DRAFT', 'PLANNING', 'IN_PROGRESS', 'STAGING', 'READY']);\n\ninterface ProjectNode {\n id: string;\n name: string;\n}\n\ninterface VelocitySprintPoint {\n sprintId: string;\n sprintName: string;\n sequenceNumber: number;\n completedPoints: number;\n completedCount: number;\n plannedPoints: number | null;\n}\n\ninterface ReleaseNode {\n id: string;\n name: string;\n status: string;\n plannedDate: string | null;\n}\n\nfunction formatPeriod(iso: string): string {\n const d = new Date(iso);\n return `${d.getUTCMonth() + 1}/${d.getUTCDate()}`;\n}\n\n/** One release's readiness — its own query, independent of the others (§4.2.3: a handful of cards, no batching). */\nfunction ReleaseReadinessCard({ release }: { release: ReleaseNode }) {\n const { t } = useI18n();\n const { data, loading, error } = useQuery<{\n planmagnetReleaseReadiness: {\n releaseId: string;\n doneItems: number;\n totalItems: number;\n blockers: { workItem: { id: string; key: string; title: string } }[];\n };\n }>(GET_RELEASE_READINESS, { variables: { releaseId: release.id } });\n\n const readiness = data?.planmagnetReleaseReadiness;\n const percent =\n readiness && readiness.totalItems > 0\n ? Math.round((readiness.doneItems / readiness.totalItems) * 100)\n : null;\n const ready = readiness\n ? readiness.doneItems >= readiness.totalItems && readiness.blockers.length === 0\n : null;\n\n return (\n <Card data-testid={`release-readiness-${release.id}`}>\n <CardHeader>\n <CardTitle className=\"flex items-center justify-between text-sm\">\n <span>{release.name}</span>\n <Badge variant=\"outline\">{enumTitleCase(release.status)}</Badge>\n </CardTitle>\n </CardHeader>\n <CardContent className=\"space-y-2\">\n {loading ? (\n <p className=\"text-sm text-muted-foreground\">\n {t('planmagnet.reports.loading', 'Loading…')}\n </p>\n ) : error ? (\n <p className=\"text-sm text-destructive\">\n {t('planmagnet.reports.readiness.error', 'Readiness could not be loaded')}\n </p>\n ) : !readiness ? null : (\n <>\n <p className=\"text-sm\">\n <span className=\"font-semibold\">{readiness.doneItems}</span> /{' '}\n <span className=\"text-muted-foreground\">{readiness.totalItems}</span>{' '}\n {t('planmagnet.reports.readiness.itemsDone', 'items done')}\n {percent !== null && <span className=\"text-muted-foreground\"> ({percent}%)</span>}\n </p>\n <Badge variant={ready ? 'success' : 'warning'}>\n {ready\n ? t('planmagnet.reports.readiness.ready', 'Ready')\n : t('planmagnet.reports.readiness.notReady', 'Not ready')}\n </Badge>\n {readiness.blockers.length > 0 && (\n <p className=\"text-xs text-muted-foreground\">\n {t('planmagnet.reports.readiness.blockers', '{{count}} blocker(s)', {\n count: readiness.blockers.length,\n })}\n </p>\n )}\n </>\n )}\n </CardContent>\n </Card>\n );\n}\n\nfunction enumTitleCase(value: string): string {\n const words = value.toLowerCase().replace(/_/g, ' ');\n return words.charAt(0).toUpperCase() + words.slice(1);\n}\n\nfunction ProjectReportsPanels({\n workspaceId,\n projectId,\n}: {\n workspaceId?: string | null;\n projectId: string;\n}) {\n const { t } = useI18n();\n\n const { data: velocityData, loading: velocityLoading } = useQuery<{\n planmagnetVelocity: {\n averageVelocity: number;\n forecastNextSprintPoints: number;\n sprints: VelocitySprintPoint[];\n };\n }>(GET_REPORTS_VELOCITY, {\n variables: { workspaceId, projectId, trailingSprintCount: 10 },\n skip: !workspaceId || !projectId,\n });\n\n const {\n data: throughputData,\n loading: throughputLoading,\n error: throughputError,\n } = useQuery<{\n planmagnetThroughput: {\n points: { periodStart: string; completedCount: number; completedPoints: number }[];\n };\n }>(GET_REPORTS_THROUGHPUT, {\n variables: { workspaceId, projectId, bucket: 'WEEK' },\n skip: !workspaceId || !projectId,\n });\n\n const { data: releasesData } = useQuery<{\n planmagnetReleases: { items: ReleaseNode[]; totalCount: number };\n }>(GET_REPORTS_RELEASES, {\n variables: { workspaceId, projectId },\n skip: !workspaceId || !projectId,\n });\n\n const velocity = velocityData?.planmagnetVelocity;\n const velocityChartData =\n velocity?.sprints.map((s) => ({\n name: s.sprintName,\n completed: s.completedPoints,\n planned: s.plannedPoints ?? undefined,\n })) ?? [];\n const avgVelocity = velocity ? Math.round(velocity.averageVelocity) : 0;\n\n const throughputChartData =\n throughputData?.planmagnetThroughput.points.map((p) => ({\n period: formatPeriod(p.periodStart),\n count: p.completedCount,\n points: p.completedPoints,\n })) ?? [];\n\n const upcomingReleases = (releasesData?.planmagnetReleases.items ?? []).filter((r) =>\n OPEN_RELEASE_STATUSES.has(r.status)\n );\n\n return (\n <div className=\"space-y-6\">\n <div className=\"grid grid-cols-1 lg:grid-cols-2 gap-6\">\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <TrendingUp className=\"h-4 w-4\" />\n {t('planmagnet.reports.velocity.title', 'Sprint Velocity')} (\n {velocityChartData.length} {t('planmagnet.reports.velocity.sprints', 'sprints')})\n </CardTitle>\n </CardHeader>\n <CardContent>\n {velocityLoading ? (\n <div className=\"flex justify-center py-12\">\n <div className=\"animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n ) : velocityChartData.length > 0 ? (\n // recharts' `fill`/`stroke` render as literal SVG paint attributes, not Tailwind classNames — they\n // cannot consume semantic bg-*/text-* tokens. Same accepted exception as\n // AnalyticsAnalyticsPagePage.tsx's CFD_STATUS_COLORS (lint warns, does not error, here and there).\n <ResponsiveContainer width=\"100%\" height={220}>\n <BarChart data={velocityChartData}>\n <CartesianGrid strokeDasharray=\"3 3\" opacity={0.2} />\n <XAxis dataKey=\"name\" tick={{ fontSize: 11 }} />\n <YAxis tick={{ fontSize: 11 }} allowDecimals={false} />\n <Tooltip />\n <Legend wrapperStyle={{ fontSize: 12 }} />\n <Bar\n dataKey=\"planned\"\n name={t('planmagnet.reports.velocity.planned', 'Planned')}\n fill=\"#cbd5e1\"\n />\n <Bar\n dataKey=\"completed\"\n name={t('planmagnet.reports.velocity.completed', 'Completed')}\n fill=\"#6366f1\"\n />\n <ReferenceLine y={avgVelocity} stroke=\"#22c55e\" strokeDasharray=\"4 4\" />\n </BarChart>\n </ResponsiveContainer>\n ) : (\n <p className=\"text-sm text-muted-foreground py-8 text-center\">\n {t(\n 'planmagnet.reports.velocity.empty',\n 'No completed sprints yet for this project'\n )}\n </p>\n )}\n </CardContent>\n </Card>\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <BarChart3 className=\"h-4 w-4\" />\n {t('planmagnet.reports.throughput.title', 'Throughput')}\n </CardTitle>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'planmagnet.reports.throughput.subtitle',\n 'Work items completed per week, trailing 12 weeks.'\n )}\n </p>\n </CardHeader>\n <CardContent>\n {throughputLoading ? (\n <div className=\"flex justify-center py-12\">\n <div className=\"animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n ) : throughputError ? (\n <p className=\"text-sm text-muted-foreground py-8 text-center\">\n {t(\n 'planmagnet.reports.throughput.unavailable',\n 'Throughput is not available yet for this workspace.'\n )}\n </p>\n ) : throughputChartData.length > 0 ? (\n <ResponsiveContainer width=\"100%\" height={220}>\n <BarChart data={throughputChartData}>\n <CartesianGrid strokeDasharray=\"3 3\" opacity={0.2} />\n <XAxis dataKey=\"period\" tick={{ fontSize: 11 }} />\n <YAxis tick={{ fontSize: 11 }} allowDecimals={false} />\n <Tooltip />\n <Legend wrapperStyle={{ fontSize: 12 }} />\n <Bar\n dataKey=\"count\"\n name={t('planmagnet.reports.throughput.items', 'Items done')}\n fill=\"#0ea5e9\"\n />\n <Bar\n dataKey=\"points\"\n name={t('planmagnet.reports.throughput.points', 'Points done')}\n fill=\"#a855f7\"\n />\n </BarChart>\n </ResponsiveContainer>\n ) : (\n <p className=\"text-sm text-muted-foreground py-8 text-center\">\n {t('planmagnet.reports.throughput.empty', 'No work completed in this project yet')}\n </p>\n )}\n </CardContent>\n </Card>\n </div>\n\n <CycleTimeCard workspaceId={workspaceId} projectId={projectId} />\n\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <ShieldCheck className=\"h-4 w-4\" />\n {t('planmagnet.reports.readiness.title', 'Release readiness')}\n </CardTitle>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'planmagnet.reports.readiness.subtitle',\n 'Open releases for this project, and what still blocks each.'\n )}\n </p>\n </CardHeader>\n <CardContent>\n {upcomingReleases.length === 0 ? (\n <p className=\"text-sm text-muted-foreground py-4 text-center\">\n {t('planmagnet.reports.readiness.empty', 'No open releases for this project')}\n </p>\n ) : (\n <div className=\"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3\">\n {upcomingReleases.map((release) => (\n <ReleaseReadinessCard key={release.id} release={release} />\n ))}\n </div>\n )}\n </CardContent>\n </Card>\n </div>\n );\n}\n\nfunction TeamReportsPanel({ workspaceId }: { workspaceId?: string | null }) {\n const { t } = useI18n();\n const [teamId, setTeamId] = useState('');\n\n const { data: teamsData } = useQuery<{\n planmagnetTeams: { items: { id: string; name: string }[] };\n }>(GET_REPORTS_TEAMS, { variables: { workspaceId }, skip: !workspaceId });\n const teams = teamsData?.planmagnetTeams.items ?? [];\n const effectiveTeamId = teamId || teams[0]?.id || '';\n\n const { data, loading } = useQuery<{\n planmagnetTeamVelocity: {\n averageVelocity: number;\n forecastNextSprintPoints: number;\n sprints: {\n sprintId: string;\n sprintName: string;\n completedPoints: number;\n plannedPoints: number | null;\n }[];\n };\n }>(GET_REPORTS_TEAM_VELOCITY, {\n variables: { workspaceId, teamId: effectiveTeamId, trailingSprintCount: 10 },\n skip: !workspaceId || !effectiveTeamId,\n });\n\n const velocity = data?.planmagnetTeamVelocity;\n const chartData =\n velocity?.sprints.map((s) => ({\n name: s.sprintName,\n completed: s.completedPoints,\n planned: s.plannedPoints ?? undefined,\n })) ?? [];\n\n if (teams.length === 0) {\n return (\n <p className=\"text-sm text-muted-foreground py-8 text-center\">\n {t(\n 'planmagnet.reports.team.empty',\n 'No teams in this workspace yet — create one under Teams.'\n )}\n </p>\n );\n }\n\n return (\n <div className=\"space-y-4\">\n <Select value={effectiveTeamId} onValueChange={setTeamId}>\n <SelectTrigger className=\"h-8 w-56\">\n <SelectValue placeholder={t('planmagnet.reports.team.pick', 'Select team')} />\n </SelectTrigger>\n <SelectContent>\n {teams.map((team) => (\n <SelectItem key={team.id} value={team.id}>\n {team.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n <Card>\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2\">\n <Users className=\"h-4 w-4\" />\n {t('planmagnet.reports.team.velocityTitle', 'Team velocity')} ({chartData.length}{' '}\n {t('planmagnet.reports.velocity.sprints', 'sprints')})\n </CardTitle>\n <p className=\"text-xs text-muted-foreground\">\n {t(\n 'planmagnet.reports.team.velocitySubtitle',\n 'Whole-team completed points across the trailing 10 completed team sprints (BOFF-8044 per-project split, no double counting).'\n )}\n </p>\n </CardHeader>\n <CardContent>\n {loading ? (\n <div className=\"flex justify-center py-12\">\n <div className=\"animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n ) : chartData.length > 0 ? (\n <ResponsiveContainer width=\"100%\" height={220}>\n <BarChart data={chartData}>\n <CartesianGrid strokeDasharray=\"3 3\" opacity={0.2} />\n <XAxis dataKey=\"name\" tick={{ fontSize: 11 }} />\n <YAxis tick={{ fontSize: 11 }} allowDecimals={false} />\n <Tooltip />\n <Legend wrapperStyle={{ fontSize: 12 }} />\n <Bar\n dataKey=\"planned\"\n name={t('planmagnet.reports.velocity.planned', 'Planned')}\n fill=\"#cbd5e1\"\n />\n <Bar\n dataKey=\"completed\"\n name={t('planmagnet.reports.velocity.completed', 'Completed')}\n fill=\"#6366f1\"\n />\n </BarChart>\n </ResponsiveContainer>\n ) : (\n <p className=\"text-sm text-muted-foreground py-8 text-center\">\n {t('planmagnet.reports.team.velocityEmpty', 'No completed team sprints yet')}\n </p>\n )}\n </CardContent>\n </Card>\n </div>\n );\n}\n\nexport function ReportsReportsPagePage() {\n const { workspaceId } = usePlanMagnet();\n const { t } = useI18n();\n const [selectedProjectId, setSelectedProjectId] = useState('');\n\n const { data, loading, error } = useQuery<{ planmagnetProjects: { items: ProjectNode[] } }>(\n GET_REPORTS_PROJECTS,\n { variables: { workspaceId }, skip: !workspaceId }\n );\n\n const projects = data?.planmagnetProjects.items ?? [];\n const effectiveProjectId = selectedProjectId || projects[0]?.id || '';\n const effectiveProjectName = projects.find((p) => p.id === effectiveProjectId)?.name ?? '';\n\n // Only before the first load: a refetch must not blank the page.\n if (loading && !data) {\n return (\n <div className=\"flex items-center justify-center p-12\">\n <div className=\"animate-spin h-8 w-8 border-2 border-primary border-t-transparent rounded-full\" />\n </div>\n );\n }\n\n if (error) {\n return (\n <div className=\"p-6 text-destructive\">\n {t('planmagnet.reports.errorLoading', 'Reports could not be loaded')}: {error.message}\n </div>\n );\n }\n\n return (\n <div className=\"space-y-6 p-6\">\n <div>\n <h1 className=\"text-2xl font-semibold flex items-center gap-2\">\n <BarChart3 className=\"h-6 w-6\" />\n {t('planmagnet.reports.title', 'Reports')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'planmagnet.reports.subtitle',\n 'Delivery numbers computed on the server — velocity, cycle time, throughput and release readiness.'\n )}\n </p>\n </div>\n\n {projects.length === 0 ? (\n <Card>\n <CardContent className=\"py-12 text-center text-sm text-muted-foreground\">\n {t('planmagnet.reports.noProjects', 'No projects in this workspace yet.')}\n </CardContent>\n </Card>\n ) : (\n <Tabs defaultValue=\"project\">\n <div className=\"flex flex-col sm:flex-row gap-3 items-start sm:items-center sm:justify-between\">\n <TabsList>\n <TabsTrigger value=\"project\" data-testid=\"reports-tab-project\">\n {t('planmagnet.reports.tabs.project', 'Project')}\n </TabsTrigger>\n <TabsTrigger value=\"team\" data-testid=\"reports-tab-team\">\n {t('planmagnet.reports.tabs.team', 'Team')}\n </TabsTrigger>\n </TabsList>\n <Select value={effectiveProjectId} onValueChange={setSelectedProjectId}>\n <SelectTrigger className=\"h-8 w-56\" data-testid=\"reports-project-select\">\n <SelectValue placeholder={t('planmagnet.reports.pickProject', 'Select project')} />\n </SelectTrigger>\n <SelectContent>\n {projects.map((p) => (\n <SelectItem key={p.id} value={p.id}>\n {p.name}\n </SelectItem>\n ))}\n </SelectContent>\n </Select>\n </div>\n\n <TabsContent value=\"project\" className=\"mt-4\">\n {effectiveProjectId ? (\n <ProjectReportsPanels workspaceId={workspaceId} projectId={effectiveProjectId} />\n ) : (\n <p className=\"text-sm text-muted-foreground py-8 text-center\">\n {t('planmagnet.reports.pickProjectHint', 'Select a project to see its report.')}\n </p>\n )}\n {effectiveProjectName && (\n <p className=\"sr-only\" data-testid=\"reports-current-project\">\n {effectiveProjectName}\n </p>\n )}\n </TabsContent>\n <TabsContent value=\"team\" className=\"mt-4\">\n <TeamReportsPanel workspaceId={workspaceId} />\n </TabsContent>\n </Tabs>\n )}\n </div>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ReportsReportsPagePage.js","names":[],"sources":["../../../src/planmagnet/pages/ReportsReportsPagePage.tsx"],"sourcesContent":["import { useDeferredValue, useState } from 'react';\nimport { useMutation, useQuery } from '@apollo/client/react';\nimport {\n Badge,\n Button,\n Card,\n CardContent,\n CardDescription,\n CardHeader,\n CardTitle,\n Input,\n Tabs,\n TabsContent,\n TabsList,\n TabsTrigger,\n} from '@burdenoff/fe-libs/ui';\nimport { useI18n } from '@burdenoff/fe-libs/shared/providers/shell/I18nProvider';\nimport { BarChart3, LayoutTemplate, Plus } from 'lucide-react';\nimport { usePlanMagnet, usePlanMagnetNavigate } from '../providers/PlanMagnetProvider';\nimport { detailPath, rowLinkProps, stopRowActivation } from '../utils/rowNavigation';\nimport { PersonName } from '../people/People';\nimport { ConfirmButton, ErrorLine } from '../controls/ConfirmButton';\nimport { mutationErrorMessage } from '../utils/graphqlErrors';\nimport { LEAVES_PAGE_CONTEXT, throwOnError } from '../utils/mutationResult';\nimport {\n CREATE_REPORT,\n DELETE_REPORT,\n DUPLICATE_REPORT,\n LIST_REPORTS,\n LIST_REPORT_TEMPLATES,\n} from '../reports/reportGraphql';\nimport type { ReportSummary, ReportTemplate } from '../reports/reportModel';\n\n/**\n * Reports (ANR-13, replacing BOFF-8048's stand-in — see git history: this page used to say Reports had no\n * saved-report model and point at Analytics instead, since Save ran no mutation. It now does: a saved report\n * is a named, ownable, shareable, schedulable set of widgets over the same real analytics/work-item data\n * Analytics already reads directly — this page is the list + template gallery in front of it, not a parallel\n * feature.\n */\n\nfunction ReportRow({\n report,\n isOwner,\n onDuplicate,\n onDelete,\n}: {\n report: ReportSummary;\n isOwner: boolean;\n onDuplicate: (id: string) => void;\n onDelete: (id: string) => void;\n}) {\n const navigate = usePlanMagnetNavigate();\n const open = () => navigate(detailPath('/reports/report-page', report.id));\n return (\n <div\n {...rowLinkProps(open, report.name)}\n className=\"flex items-center justify-between gap-3 rounded-md border border-border p-3\"\n data-testid=\"report-list-item\"\n >\n <div className=\"min-w-0\">\n <p className=\"truncate font-medium\">{report.name}</p>\n {report.description && (\n <p className=\"truncate text-xs text-muted-foreground\">{report.description}</p>\n )}\n <p className=\"mt-0.5 text-xs text-muted-foreground\">\n <Badge\n variant={report.visibility === 'WORKSPACE' ? 'secondary' : 'outline'}\n className=\"mr-1.5\"\n >\n {report.visibility === 'WORKSPACE' ? 'Workspace' : 'Private'}\n </Badge>\n Owned by <PersonName id={report.ownerId} /> · Updated{' '}\n {new Date(report.updatedAt).toLocaleDateString()}\n </p>\n </div>\n <div className=\"flex shrink-0 items-center gap-1.5\" onClick={stopRowActivation}>\n <Button size=\"sm\" variant=\"outline\" onClick={() => onDuplicate(report.id)}>\n Duplicate\n </Button>\n {isOwner && (\n <ConfirmButton\n label=\"Delete\"\n icon={null}\n title={`Delete \"${report.name}\"?`}\n description=\"Its runs, shares and schedules are deleted too. This cannot be undone.\"\n confirmLabel=\"Delete\"\n destructive\n variant=\"outline\"\n disabled={false}\n onConfirm={() => onDelete(report.id)}\n />\n )}\n </div>\n </div>\n );\n}\n\nfunction ReportListTab({ mine }: { mine: boolean }) {\n const { workspaceId, currentUser } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const [search, setSearch] = useState('');\n const deferredSearch = useDeferredValue(search.trim());\n const [error, setError] = useState<string | null>(null);\n\n const variables = {\n workspaceId: workspaceId ?? '',\n filter: { mine: mine || undefined, search: deferredSearch || undefined },\n pagination: { first: 50 },\n };\n const {\n data,\n loading,\n error: queryError,\n } = useQuery<{\n planmagnetReports: { items: ReportSummary[]; totalCount: number };\n }>(LIST_REPORTS, { variables, skip: !workspaceId });\n const [duplicateReport] = useMutation(DUPLICATE_REPORT, {\n refetchQueries: [{ query: LIST_REPORTS, variables }],\n });\n const [deleteReport] = useMutation(DELETE_REPORT, {\n refetchQueries: [{ query: LIST_REPORTS, variables }],\n });\n\n const items = mine\n ? (data?.planmagnetReports.items ?? [])\n : (data?.planmagnetReports.items ?? []).filter((r) => r.visibility === 'WORKSPACE');\n\n const duplicate = async (id: string) => {\n setError(null);\n try {\n const result = await throwOnError(duplicateReport({ variables: { id } }));\n const copy = (result.data as { planmagnetDuplicateReport?: { id: string } } | undefined)\n ?.planmagnetDuplicateReport;\n if (copy) navigate(detailPath('/reports/edit-report-page', copy.id));\n } catch (e) {\n setError(mutationErrorMessage(e, 'This report could not be duplicated.'));\n }\n };\n const remove = async (id: string) => {\n setError(null);\n try {\n await throwOnError(deleteReport({ variables: { id } }));\n } catch (e) {\n setError(mutationErrorMessage(e, 'This report could not be deleted.'));\n }\n };\n\n return (\n <div className=\"space-y-3\">\n <Input\n value={search}\n onChange={(e) => setSearch(e.target.value)}\n placeholder=\"Search reports\"\n aria-label=\"Search reports\"\n className=\"max-w-sm\"\n />\n {error && <ErrorLine message={error} />}\n {queryError ? (\n <p className=\"text-sm text-destructive\">\n Reports could not be loaded: {queryError.message}\n </p>\n ) : loading && !data ? (\n <p className=\"py-8 text-center text-sm text-muted-foreground\">Loading…</p>\n ) : items.length === 0 ? (\n <p className=\"py-8 text-center text-sm text-muted-foreground\">\n {mine ? 'You have no reports yet.' : 'No workspace-visible reports yet.'}\n </p>\n ) : (\n <div className=\"space-y-2\">\n {items.map((report) => (\n <ReportRow\n key={report.id}\n report={report}\n isOwner={!!currentUser?.id && currentUser.id === report.ownerId}\n onDuplicate={(id) => void duplicate(id)}\n onDelete={(id) => void remove(id)}\n />\n ))}\n </div>\n )}\n </div>\n );\n}\n\nfunction TemplateGallery() {\n const { workspaceId } = usePlanMagnet();\n const navigate = usePlanMagnetNavigate();\n const { data, loading, error } = useQuery<{ planmagnetReportTemplates: ReportTemplate[] }>(\n LIST_REPORT_TEMPLATES\n );\n const [createReport, { loading: creating }] = useMutation(CREATE_REPORT);\n const [busyKey, setBusyKey] = useState<string | null>(null);\n const [createError, setCreateError] = useState<string | null>(null);\n\n const startFromTemplate = async (template: ReportTemplate) => {\n if (!workspaceId) return;\n setCreateError(null);\n setBusyKey(template.key);\n try {\n const result = await throwOnError(\n createReport({\n variables: {\n workspaceId,\n input: {\n name: template.name,\n description: template.description,\n templateKey: template.key,\n visibility: 'PRIVATE',\n definition: template.definition,\n },\n },\n context: LEAVES_PAGE_CONTEXT,\n })\n );\n const id = (result.data as { planmagnetCreateReport?: { id: string } } | undefined)\n ?.planmagnetCreateReport?.id;\n // Template widgets ship with empty params (project/sprint/team/date range) — the builder is where those\n // get filled in before the report is ever run.\n if (id) navigate(detailPath('/reports/edit-report-page', id));\n } catch (e) {\n setCreateError(\n mutationErrorMessage(e, 'This report could not be created from the template.')\n );\n } finally {\n setBusyKey(null);\n }\n };\n\n if (loading && !data)\n return <p className=\"py-8 text-center text-sm text-muted-foreground\">Loading…</p>;\n if (error) return <p className=\"text-sm text-destructive\">Templates could not be loaded.</p>;\n const templates = data?.planmagnetReportTemplates ?? [];\n\n return (\n <div className=\"space-y-3\">\n {createError && <ErrorLine message={createError} />}\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3\">\n {templates.map((template) => (\n <Card key={template.key} data-testid=\"report-template\">\n <CardHeader>\n <CardTitle className=\"flex items-center gap-2 text-sm\">\n <LayoutTemplate className=\"h-4 w-4\" />\n {template.name}\n </CardTitle>\n <CardDescription>{template.description}</CardDescription>\n </CardHeader>\n <CardContent>\n <p className=\"mb-3 text-xs text-muted-foreground\">\n {template.definition.widgets.length} widget\n {template.definition.widgets.length === 1 ? '' : 's'}\n </p>\n <Button\n size=\"sm\"\n className=\"w-full\"\n disabled={creating}\n onClick={() => void startFromTemplate(template)}\n >\n {busyKey === template.key ? 'Creating…' : 'Start from template'}\n </Button>\n </CardContent>\n </Card>\n ))}\n </div>\n </div>\n );\n}\n\nexport function ReportsReportsPagePage() {\n const { t } = useI18n();\n const navigate = usePlanMagnetNavigate();\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex flex-wrap items-start justify-between gap-3\">\n <div>\n <h1 className=\"flex items-center gap-2 text-2xl font-semibold\">\n <BarChart3 className=\"h-6 w-6\" />\n {t('planmagnet.reports.title', 'Reports')}\n </h1>\n <p className=\"text-sm text-muted-foreground\">\n {t(\n 'planmagnet.reports.subtitle',\n 'Build, run, share and schedule reports over your PlanMagnet data.'\n )}\n </p>\n </div>\n <Button\n size=\"sm\"\n onClick={() => navigate('/reports/create-report-page')}\n data-testid=\"report-new\"\n >\n <Plus className=\"mr-1 h-4 w-4\" />\n {t('planmagnet.reports.newBlank', 'New blank report')}\n </Button>\n </div>\n\n <Tabs defaultValue=\"mine\">\n <TabsList>\n <TabsTrigger value=\"mine\" data-testid=\"report-list\">\n My reports\n </TabsTrigger>\n <TabsTrigger value=\"workspace\">Workspace</TabsTrigger>\n <TabsTrigger value=\"templates\">Templates</TabsTrigger>\n </TabsList>\n <TabsContent value=\"mine\" className=\"mt-4\">\n <ReportListTab mine={true} />\n </TabsContent>\n <TabsContent value=\"workspace\" className=\"mt-4\">\n <ReportListTab mine={false} />\n </TabsContent>\n <TabsContent value=\"templates\" className=\"mt-4\">\n <TemplateGallery />\n </TabsContent>\n </Tabs>\n </div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TasksTaskDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TasksTaskDetailPagePage.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"TasksTaskDetailPagePage.d.ts","sourceRoot":"","sources":["../../../src/planmagnet/pages/TasksTaskDetailPagePage.tsx"],"names":[],"mappings":"AA+WA,wBAAgB,uBAAuB,4CAoLtC"}
|