Add Excel export feature for regular and super boards#63
Merged
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
Adds a client-side Excel export feature for board transactions, supporting both regular boards (single worksheet) and super boards (one worksheet per sub-board) using SheetJS.
Changes:
- Introduced
exportBoardToExcelutility to generate.xlsxworkbooks with Hebrew headers, sanitization, and a footer. - Added export UI and flow in
BoardPage(header button for regular boards; actions menu item for super boards). - Added a one-shot Firestore read helper to fetch transactions per board for super-board export.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| src/utils/exportBoardToExcel.js | Builds and downloads .xlsx workbooks; sanitizes sheet/file names; maps transactions to rows. |
| src/pages/BoardPage.jsx | Adds export state/UI and export handler for regular + super boards. |
| src/firebase/transactions.js | Adds getTransactionsForBoard(boardId) one-shot read for export. |
| src/components/ui/BoardHierarchyActionsMenu.jsx | Extends actions menu to optionally include an export action with loading state. |
| index.html | Loads SheetJS via CDN so the export utility can use window.XLSX. |
Comments suppressed due to low confidence (1)
src/pages/BoardPage.jsx:65
exportErroris stored in component state and rendered at the top of the page, but it isn’t cleared when navigating to a different board. This can leave a stale export error visible on the next board until the user exports again. Consider resettingexportError(and optionallyexportingExcel) in the existinguseEffectthat runs onboardIdchanges.
const [exportingExcel, setExportingExcel] = useState(false);
const [exportError, setExportError] = useState(null);
const [userNickname, setUserNickname] = useState('');
/**
* Active payment-method filter.
* null → no filter active
* string → a perGroup key, e.g. "card:1234" or "type:cash"
*/
const [activePaymentFilterKey, setActivePaymentFilterKey] = useState(null);
// Clear the payment-method filter whenever the user navigates to a different board
useEffect(() => {
setActivePaymentFilterKey(null);
}, [boardId]);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…t-feature-to-expensemanagement-app
…js-to-exceljs Switch board Excel export to ExcelJS with polished worksheet styling
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub.
|
…o-expensemanagement-app' into codex/add-excel-export-feature-to-expensemanagement-app
Owner
Author
|
When exporting to |
Summary
Testing
|
…t-feature-for-regular-and-sup Fix exported transaction dates to be real Excel date cells in DD-MM-YYYY
… year in BoardsPage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Motivation
.xlsxfiles so data can be archived or viewed in Excel/Sheets.Description
src/utils/exportBoardToExcel.jsthat builds workbooks with Hebrew headers, nullable normalization (exported as empty cells), date formatting (dd/mm/yyyyfor validYYYY-MM-DD), numeric preservation for amounts, formula-injection protection for text fields, worksheet name and filename sanitization, and a spacer + footer row containing the attribution and URL (Generated by OF8's Expense Management web app - https://of8-expense-management.web.app/).handleExportExcel()insrc/pages/BoardPage.jsxto export the current board (single sheet) or fetch child boards and export one sheet per sub-board for super boards, and exposing loading/error state for the export action.src/components/ui/BoardHierarchyActionsMenu.jsxto optionally show aייצוא לאקסלentry for super boards inside the existing "פעולות לוח" modal, and by adding a board-levelייצוא לאקסלheader action button for regular boards near existing controls.getTransactionsForBoard(boardId)insrc/firebase/transactions.jsso super-board export can fetch each child board's transactions without changing existing realtime subscriptions or access rules.index.htmland load-checkedwindow.XLSXinside the export utility so no backend changes or new endpoints were required.תאריך עסקה (אופציונלי),שם העסק,סכום (₪),סוג עסקה,שם,4 ספרות אחרונות של הכרטיס,תשלום נוכחי,מתוך כמה תשלומים,פירוט/הערות (אופציונלי)..xlsx, text cells starting with=,+,-, or@are prefixed to prevent formula injection, and empty boards still export headers + spacer + footer.Testing
npx eslint src/pages/BoardPage.jsx src/components/ui/BoardHierarchyActionsMenu.jsx src/utils/exportBoardToExcel.js src/firebase/transactions.jswhich passed (one pre-existinguseMemowarning inBoardPage.jsxremains and is unrelated to the new feature).npm run buildand the production build completed successfully.npm install xlsxbut the environment returned403 Forbidden, so the implementation falls back to loading SheetJS from the CDN viaindex.html(this was intentional after failing to install the package).getTransactionsForBoard); null/undefined fields become empty cells; footer row is appended; negative amounts and numeric values are preserved as numbers.Codex Task