Releases: janayuv/export-invoice
v1.0.1 — Duplicate, Bulk Actions, Print & Accessibility
What's new in v1.0.1
Duplicate Invoice / Purchase Order
- New Duplicate button on invoice and PO detail pages
- Copies all fields and line items into a fresh draft with a new sequence number
- Keyboard shortcut:
Ctrl+D - Permission-gated: requires
create_invoice
Bulk Invoice Actions
- Checkbox column in the invoice list (select-all + per-row)
- Floating action bar when rows are selected: Finalize selected and Delete selected
- Both actions use a confirm dialog and run sequentially with progress toast
- Selection clears automatically when filters change
Print Support
- Print button on invoice detail pages triggers
window.print() @media printCSS hides sidebar and action bars; invoice preview renders at A4
Accessibility
scope=colon all table header cellsaria-sorton sort buttons (ascending / descending / none)tabIndex={0}+onKeyDownEnter/Space on clickable table rowsaria-labelon status badges, search input, and date filter inputs- Screen-reader-only
<caption>on the invoice table
Bug fixes (from v1.0.0 verification)
- All four items flagged in the post-release verification are now resolved
Export Invoice v1.0.0
Export Invoice v1.0.0 — Production release
First production-grade release: security hardening, data integrity, resilience, and UI completion.
Security
- Session restore syncs Rust
AuthSessionafter reload - Admin IPC requires admin role; PIN commands require session
- SQL read gating until authenticated (v1.0 product rule)
- Dual-layer field validation (Zod + Rust)
Reliability
- Startup-safe application logging (
logs/app.log) - Admin log viewer, error boundary, centralized error messages
- Read retry/backoff on list hooks
UX
- Shared PageHeader, EmptyState, ConfirmDialog, loaders
- Legacy screens aligned to design system; sorting, date filters, draft auto-save
Download the installer below (.msi for enterprise/silent install, .nsis setup for standard install).
Updater manifest latest.json included when signing secret is configured.
v0.7.0 — Admin Center
What's New in v0.7.0
Admin Center — 9-page operations suite
A new Admin Center section (admin role only) is now available in the sidebar with 9 fully functional pages:
| Page | Description |
|---|---|
| Database Management | 4-tab interface — overview, backup/restore, table browser, audit log |
| Activity Log | Paginated audit trail of every create/update/delete/finalize across the app |
| User Activity | Per-user view combining auth events and app actions side-by-side |
| System Health | 6 live metric cards (DB size, integrity, backup, users, documents) — auto-refreshes every 30s |
| Security Center | Telemetry strip + 14-day trend chart (recharts) + auth event log + locked accounts |
| Roles & Permissions | Read-only permission matrix derived from live PERMISSIONS constant + user assignments |
| Automation Center | Navigation hub linking all admin pages + background task history |
| Operations Center | System metrics + full incident log/resolve workflow |
| System Agent | Enable/disable background agent, interval selector, 4 manual task buttons (integrity check, backup, purge logs, vacuum) |
Activity Logging
Every create, update, delete, finalize, and status-change on invoices, purchase orders, and entries is now automatically recorded in the activity_log table. No action required — logs populate as you work.
New DB Migrations (28–31)
Applied automatically on first launch:
activity_log— full audit trail tablesystem_agent_settings— agent configuration (pre-seeded)automation_tasks— background task historyincidents— operational incident tracking
Upgrade Notes
- Requires a full app restart after update to apply migrations 28–31
- All new pages are admin-only (gated by
access_settingspermission) - No changes to existing invoice/PO/entry workflows
v0.6.0 — Full UI Redesign
What's new in v0.6.0
Full Visual Redesign
A complete dark-mode-first UI overhaul across all 8 screens. No backend logic, hooks, schemas, or types were changed — pure visual layer update.
Design system
- Color scale: zinc-900/zinc-50 surfaces with indigo-400 (#818cf8) as the primary accent
- Page entry: animate-fade-up on every route
- Typography: 10px uppercased labels, 20px bold page titles, 12px body text
- Cards: unified SettingsCard / SectionCard pattern with 26px indigo icon boxes
Screen-by-screen changes
| Screen | Change |
|---|---|
| Layout | Collapsible 56px/200px sidebar, active-route indigo pill, zinc-900 dark nav |
| Dashboard | Stat cards with colored icon boxes, recent invoices mini-table |
| InvoiceList | Compact table rows, amber/indigo status pills, search + filter bar |
| InvoiceNew | Two-panel: sticky header + 168px TOC rail + scrollable form with scroll-spy |
| InvoiceDetail | #c0c0c0 desk preview wrap, monospace invoice number h1, sm action buttons |
| InvoicePreview | Inline styles matching A4 PDF palette (hex colors, 1.5px borders) |
| PurchaseOrderList | Compact table, emerald/amber/zinc status badges |
| Settings | 6 SettingsCards, Save button in page header, dashed logo placeholder |
| LoginScreen | Letter-avatar user card grid replaces dropdown; auto-submit after 6 PIN digits |
Export Invoice v0.5.2
What's new in v0.5.2
Bug fix — Invoice qty field resets after selecting a Purchase Order
- Fixed a regression where typing in the Qty (or Unit Price) field on the invoice form would reset the input after every digit, but only after a Purchase Order had been selected
- Root cause:
updateTotalcalledsetValue('total_amount', …)on each keystroke, which notifieduseFieldArray's items subscriber and causedGoodsRowto re-render, re-attaching the RHF ref and overwriting the partial input value - Fix: removed reactive
total_amountmaintenance from the onChange handler; row totals and footer totals now compute live fromqty × unit_priceviauseWatch;total_amountis recomputed at submit time before saving
Download the installer below (.msi for enterprise/silent install, .exe for standard setup).
Export Invoice v0.5.1
What's new in v0.5.1
Bug fix — Database File picker (Settings)
- Fixed a "forbidden path" runtime error that prevented the Browse button from writing or clearing
selected_db.txtin the app config directory - Root cause: the Tauri capability granted the
write_text_file/remove/existscommands but no path scope for%APPDATA%\com.exportinvoice.app; addedfs:scope-appconfig-recursiveto resolve it - Export / PDF / Excel save flows are unaffected (they use dialog-returned paths which are scoped automatically by Tauri)
Download the installer below (.msi for enterprise/silent install, .exe for standard setup).
Export Invoice v0.5.0
What's new in v0.5.0
In-App Database Picker
- A new Database File card in Settings lets you point the app at any SQLite file instead of the bundled default
- Click Browse… to pick a
.db,.sqlite, or.sqlite3file via a native file dialog - The active database path is displayed; Use Default resets back to
export_invoice.dbwith one click - The chosen path is persisted across restarts (localStorage + a Rust-readable
selected_db.txtmirror in the app config dir) - The Rust startup layer reads
selected_db.txtand registers the full migration set for the selected file, so a brand-new empty database is automatically migrated on first load - Selecting or resetting falls back safely to the default if the target file is missing or the FS write fails — the two persistence layers are always kept in sync
Download the installer below (.msi for enterprise/silent install, .exe for standard setup).
v0.4.2 — Qty input fix (production)
Bug fix
Qty field no longer resets on every digit in the installed app (production build).
v0.4.1 fixed the issue in dev mode but not in the production binary. The real root cause was @base-ui/react/input (the InputPrimitive used by every Input component) resetting its display value whenever its parent re-renders — even without a controlled value= prop. This does not surface in Vite dev mode but is reproducible in the compiled Tauri binary.
What changed in v0.4.2
GoodsRow previously held three useWatch subscriptions (qty, price, currentTotal) that caused it to re-render on every keystroke, re-rendering its inputs and triggering the Base UI reset.
- Removed all three subscriptions and the
useEffectthat computed the total - Total is now computed inside
register'sonChangeoption (fires after RHF's store update, sogetValuesalready holds the new value) - Row amount display extracted into a standalone
RowTotalchild component — onlyRowTotalre-renders whentotal_amountchanges;GoodsRowand its inputs are never touched during typing
Unchanged
- Footer totals, Zod validation, submit payload, PDF/Excel exports
- All other invoice fields and backend logic
v0.4.1 — Qty input fix
Bug fix
Qty field no longer resets on every digit typed in the invoice form.
Root causes fixed
watch()calls inInvoiceNew.tsxsubscribed the entire form component to re-render on every child field change, including each keystroke in the Qty input. Replaced withuseWatch()so only the four watched fields (currency,transport_mode,incoterm,show_sa_number) trigger a parent re-render.- The Qty
<Input>was a controlled input (value={String(qty)}) tied to the parsed float fromuseWatch. Intermediate values like"1."were immediately overwritten by the form store value. Replaced withregister(..., { valueAsNumber: true }), matching the existingunit_pricepattern — the browser now owns the display state.
Unchanged
- Total-amount computation (
useWatch+useEffectinGoodsRow) - Footer totals, Zod validation, submit payload shape
- All other invoice fields, backend logic, and PDF/Excel exports
Export Invoice v0.4.0
What's new in v0.4.0
In-App Update Button
- A Check for Updates button (↻) now appears in the sidebar header next to the app version
- Clicking checks GitHub Releases for a newer version; a notification appears with Install and Later options
- Download progress is shown as a percentage while the update downloads in the background
- The app closes and relaunches automatically once the installer is ready
- Clear feedback at every step: checking, available, downloading (N%), complete, and error states all produce distinct tooltips and toasts
Version Display
- The sidebar version is now dynamic — always reads from the packaged app version at runtime, replacing the old hardcoded label
Download the installer below (.msi for enterprise/silent install, .exe for standard setup).