Commit Graph

1120 Commits

Author SHA1 Message Date
Dries Peeters ac829c5dbf Update setup.py 2026-03-08 06:22:27 +01:00
Dries Peeters 2c63f3ac78 fix(dashboard): remove cache to fix ORM detachment on second visit (Issue #549)
- Dashboard cached template data containing ORM objects (active_timer,
  recent_entries, top_projects, templates) that became detached when
  served in a different request, causing 'Instance not bound to a Session'
  and 'Database Error' on second visit
- Add migration 133 to merge heads 132 (timesheet governance) and 129
  (task tags) so flask db upgrade runs without conflicts
- Update CHANGELOG
2026-03-08 06:21:20 +01:00
Dries Peeters cac75d9e5e Update setup.py 2026-03-06 22:16:09 +01:00
Dries Peeters 2e1c18a345 feat(invoicing): add Factur-X CII export validation and transport guidance
Switch embedded invoice PDFs to Factur-X CII payloads and tighten the PDF/A-3 and AS4 handling so exports better match the standards they advertise. Document the experimental native Peppol transport path and cover the new validation and embedding behavior with focused tests.
2026-03-06 22:15:29 +01:00
Dries Peeters 463704f054 feat(ui): refresh shared layout patterns and responsive screens
Unify buttons, cards, headers, toasts, and form treatments across the app so screens feel consistent and are easier to scan on desktop and mobile. Update the broader template set to use the shared UI primitives and responsive spacing patterns introduced in this refresh.
2026-03-06 22:15:06 +01:00
Dries Peeters 9b7f6a54b0 docs: update project structure, quality gates, competitive analysis, and index
- PROJECT_STRUCTURE: add workforce/timesheet governance, desktop/mobile, workforce templates
- Add FRONTEND_QUALITY_GATES.md (a11y, performance, modernization milestones)
- Add competitive-analysis (gap rubric, phase 1/2 PRDs)
- Link new docs from development/README and main docs README
2026-03-06 15:46:18 +01:00
Dries Peeters 71900212bc test: add bulk task operations tests 2026-03-06 15:46:07 +01:00
Dries Peeters a52289a20b chore: update CI workflow, pre-commit, Makefile, and docker-compose
- Adjust ci-comprehensive workflow and pre-commit hooks
- Makefile targets and docker-compose configuration updates
2026-03-06 15:46:01 +01:00
Dries Peeters 07186d7b6b feat(web): base-init, PWA, keyboard shortcuts, onboarding, and template updates
- Add base-init.js for shared keyboard/sidebar init; single PWA registration in pwa-enhancements
- Update keyboard-shortcuts, onboarding, enhanced-search, service-worker
- Template updates: base, list pages, dashboard, mileage/gps, timer; fix duplicate IDs and a11y
2026-03-06 15:45:50 +01:00
Dries Peeters 2a283c3074 refactor(app): wire API, tasks, mileage, custom reports to blueprint registry
- Update api, api_docs, api_v1, custom_reports, mileage, tasks routes
- Update custom_report_service and time_tracking_service
- Export services in app/services/__init__.py
2026-03-06 15:45:31 +01:00
Dries Peeters 435e53957c feat(mobile): add finance/workforce screen and providers
- Add FinanceWorkforceScreen and finance_workforce_providers
- Update home_screen with IndexedStack tab state; api_client updates
- Align mobile with web/desktop for workforce and finance
2026-03-06 15:45:14 +01:00
Dries Peeters 80fde2f0c9 feat(desktop): add state module, notifications UI, and esbuild bundle
- Add state.js and ui/notifications.js; update app.js and api client
- Bundle with esbuild; update package.json dependencies
- Improve connection status and accessible notifications (aria-live/role)
2026-03-06 15:44:45 +01:00
Dries Peeters 531f16b597 feat(workforce): add timesheet governance, time-off, and workforce dashboard
- Add TimesheetPeriod, TimesheetPolicy, TimeOff models and migration 132
- Add workforce blueprint, routes, and workforce_governance_service
- Add workforce dashboard template; register blueprint via blueprint_registry
- Extend User model for time-off and policy associations
2026-03-06 15:44:35 +01:00
Dries Peeters fb169778cb Fix collapsed sidebar not expanding without refresh (#547)
Sync sidebar-collapsed class on document.documentElement when toggling.
The early script adds the class to documentElement on load; applyCollapsed
only updated appShell, so expanding left the class on html and labels
stayed hidden. Now both are updated so expand/collapse works correctly.
2026-03-05 18:55:06 +01:00
Dries Peeters a9c3a1b487 Fix collapsed sidebar flyout position when page is scrolled (#546)
The flyout submenu used document coordinates (getBoundingClientRect +
scrollX/scrollY) while having position:fixed, causing it to shift with
scroll and disappear off-screen. Use viewport-relative coordinates only
so the flyout stays aligned with the trigger.
2026-03-05 18:52:09 +01:00
Dries Peeters d0c5b0480d Update setup.py 2026-03-02 20:55:51 +01:00
Dries Peeters 777d6ad3bf fix(invoicing): harden PEPPOL transport and PDF/A-3 export compliance
Implement native PEPPOL transport plumbing (identifier validation, SMP/SML discovery, and AS4 send path) and make ZUGFeRD/PDF export fail fast when embedding or PDF/A-3 normalization fails. Add settings, migrations, validators, tests, and docs so compliance issues are visible and verifiable.
2026-03-02 20:55:02 +01:00
Dries Peeters 05ed93a240 feat(tasks): show estimated hours in lists and view; fix confirm button (Fixes #543, #544)
Task lists: add Estimated column to All Tasks table and project tasks table; show estimated hours in task view Details. Also fix Pause/Complete button text disappearing after canceling confirm dialog.
2026-03-02 20:33:21 +01:00
Dries Peeters 9883b61cbf Update setup.py 2026-03-01 07:39:41 +01:00
Dries Peeters 36d64e0cb1 ui: remove decorative image upload from invoice and quote edit forms
Decorative images are only managed via Admin PDF layout templates. Remove the per-document upload section and related JS from invoice and quote edit pages so users do not add images there; template-based decorative images in pdf_layout/quote_pdf_layout remain unchanged.
2026-03-01 07:36:31 +01:00
Dries Peeters 552675ff55 fix(invoicing): ZUGFeRD/EN 16931 PDF and UBL fixes (Discussion #433)
- UBL: add unitCode C62 to InvoicedQuantity (required by EN 16931 / Peppol BR-CL-23)
- ZugFerd: attach XML as Associated File with relationship Alternative
- ZugFerd: inject ZUGFeRD XMP RDF for validators
- Docs: document AF/XMP, PDF/A-3 limitation, and validation (b2brouter, portinvoice)
- Tests: assert UBL contains InvoicedQuantity with unitCode in ZugFerd and Peppol tests
2026-03-01 07:36:18 +01:00
Dries Peeters 300ffaef37 fix: persist decorative image size in PDF template (fixes #537)
When saving the PDF template design, decorative image dimensions were exported from the inner Image's width/height only, which do not include scale. Resizing via the transformer applies scale to the Group, so the saved template always had the original image size.

Use the group's getClientRect() for position and size when building template_json and legacy HTML preview, with fallback to image dimensions × scaleX/scaleY. Applied to both Invoice and Quote PDF layout editors.
2026-03-01 07:16:48 +01:00
Dries Peeters 61be74680b Update setup.py 2026-02-28 17:30:50 +01:00
Dries Peeters 3c5a937234 Add task tags and categorization (fixes #539)
Implement the advertised 'Task tags and categorization' feature that was
listed in docs but missing from the task edit form.

- Add tags column to tasks table (String 500, comma-separated)
- Add tags field to task create and edit forms with validation
- Display tags as badges on task view page and list pages
- Add tags filter to main tasks list and My Tasks with AJAX support
- Include tags in task export (CSV) and data export
- Add tags to Task API (create, update, list with filter)
- Add tag_list property to Task model for convenient parsing

Also: fix(oidc) use domain instead of IP for HTTPS metadata fetch
to fix TLS SNI (Fixes #540)
2026-02-28 17:28:54 +01:00
Dries Peeters 52a30edf43 Improve subtle awareness of key to hide donate prompts
- Add tooltips on sidebar and header support links (key option on hover)
- Add muted 'Get a one-time key' line under donate page hero
- Add muted key hint in about page support section
- Rephrase dashboard widget to 'You can hide this with a one-time key'
- Add new translatable strings to en messages.po
2026-02-28 17:28:04 +01:00
Dries Peeters 61256cdc60 Bump version to 4.20.6 and update documentation 2026-02-20 09:59:35 +01:00
Dries Peeters 35e3694cc1 Fix admin menu and PDF layout; update docs
Admin menu:
- PDF Templates is now a top-level submenu under Admin (same level as System Settings) so it opens without opening System Settings first.
- Remove PDF routes from admin_settings_open so only PDF Templates expands on invoice/quote PDF pages.
- Set pdfDropdown parent to adminDropdown in nested dropdown click handler.

PDF layout (invoice & quote):
- Preserve table groups (Items, Expenses) on save by skipping Groups in cleanup and ensuring table names are set and restored from design_json.
- Add test for saving and reloading layout with tables.

Docs:
- Update PDF layout access path to Admin → PDF Templates → Invoice PDF (and Quote PDF) in PDF_LAYOUT_CUSTOMIZATION.md, PDF_EDITOR_ENHANCED_FEATURES.md, PDF_EDITOR_QUICK_START.md, INVOICE_EXTRA_GOODS_PDF_EXPORT.md.
2026-02-20 09:56:44 +01:00
Dries Peeters dbd4a69f4b fix(inventory): make PO form stock_items/warehouses JSON-serializable
Pass dicts instead of StockItem/Warehouse ORM objects to the purchase
order form template so Jinja's tojson filter can serialize them for
the embedded script. Fixes TypeError when creating or editing a PO.

- new_purchase_order and edit_purchase_order now convert query results
  to minimal dicts (id, sku, name, unit for items; id, code, name for
  warehouses) before render_template.
- Add docs/implementation-notes/INVENTORY_PO_FORM_JSON.md describing
  the requirement and pattern for other forms embedding data in JS.
2026-02-20 09:30:56 +01:00
Dries Peeters 0a4b29c50d feat: add development-only data seeding with inventory and finance
- Add run_seed() in app/utils/seed_dev_data.py: users, clients, projects,
  tasks, time entries, expenses, comments, warehouses, stock items,
  warehouse stock, stock movements, currencies, tax rules, invoices,
  invoice items, and payments. Only runs when FLASK_ENV=development.
- Register 'flask seed' CLI command with options (users, clients,
  projects-per-client, tasks-per-project, days-back).
- Add scripts/seed-dev-data.py and docker/seed-dev-data.sh for local
  and Docker runs. Include seed scripts in image via Dockerfile chmod.
- Document in docs/development/SEED_DEV_DATA.md; update
  DATABASE_RECOVERY.md, DOCKER_COMPOSE_SETUP.md, and development README.
2026-02-20 09:28:30 +01:00
Dries Peeters acdf852f6a fix(tasks): show description textarea when Toast UI Editor fails to load (fixes #535)
When creating or editing a task, the description field relied entirely on the
Toast UI Editor from CDN. If that script failed to load (reverse proxy, CSP,
Firefox, or offline), users saw only an empty area and no way to enter a
description.

- Add fallback in create.html and edit.html: when window.toastui.Editor is
  unavailable, show the existing textarea (remove 'hidden') and hide the
  empty #description_editor div; set textarea min-height for usability.
- CHANGELOG: document fix under [Unreleased] -> Fixed.
- docs/TASK_MANAGEMENT_README: note fallback in Markdown Support section.
2026-02-20 09:01:54 +01:00
Dries Peeters 11c6c5559b Bump version to 4.20.5 and update documentation 2026-02-17 20:32:54 +01:00
Dries Peeters b6d208090b feat(dashboard): add pause, resume, and time adjustment to timer widget
- Add Pause and Stop buttons when a timer is running; Pause saves the
  segment so users can resume later without losing context.
- When no timer is active, show prominent 'Resume (project name)' to
  restart with the same project/task/notes as the last entry.
- Add quick time adjustment (-15 / -5 / +5 / +15 min) for the active
  timer via POST /timer/adjust (delta_minutes); limits ±4 hours.
- Update CHANGELOG, in-app Help, GETTING_STARTED, and FEATURES_COMPLETE
  to document the new dashboard timer behavior.
2026-02-17 20:26:14 +01:00
Dries Peeters 3f56a06ef0 feat(release): auto-trigger Render demo deploy after container push
Add trigger-demo-deploy job to cd-release workflow that POSTs to
Render deploy hook when TimeTrackerDemoRender org secret is set.
Runs after build-and-push; skips gracefully if secret is not
configured. Include demo deploy status in release summary.

Document in RENDER.md, CI_CD_DOCUMENTATION.md, and
GITHUB_ACTIONS_SETUP.md.
2026-02-17 20:23:46 +01:00
Dries Peeters 5593c9742f Redesign Log Time Manually page for clearer, more professional UI
- Group form into sections: Project & task, Date & time, Details (with headings and icons)
- Upgrade main card to rounded-xl and shadow-lg; add section borders and spacing
- Unify form labels and helper text to app design tokens
- Style primary Log Time and secondary Clear buttons to match dashboard
- Apply rounded-xl to duplicate-entry info banner
- Document change in CHANGELOG under [Unreleased]
2026-02-17 20:23:31 +01:00
Dries Peeters 07794987af fix(dashboard): remove duplicate const notesEl declaration
Reuse the existing notesEl variable when syncing Toast UI Editor notes
into the hidden textarea on form submit, fixing SyntaxError:
redeclaration of const notesEl in the start timer submit handler.
2026-02-17 20:16:11 +01:00
Dries Peeters 94ed0ae7d7 VErsion bump 2026-02-16 22:00:14 +01:00
Dries Peeters cd3b1b68ce Update Render 2026-02-16 21:49:48 +01:00
Dries Peeters 32f8a90ded Version bump 2026-02-16 21:28:44 +01:00
Dries Peeters 897c87dec8 fix: add merge migration for Alembic multiple heads (118 and 128)
Resolves 'Multiple head revisions' error during pre-deploy (flask db upgrade)
on Render. Two branches existed: 118_add_role_hidden_module_ids and
128_add_invoices_zugferd_pdf. New revision 129_merge_118_128_heads merges
them so 'alembic upgrade head' runs successfully.
2026-02-16 21:27:58 +01:00
Dries Peeters dbaec5c583 Update render.yaml 2026-02-16 21:11:34 +01:00
Dries Peeters 17dc6476b9 Update render.yaml 2026-02-16 20:58:19 +01:00
Dries Peeters c64149a783 Update render.yaml 2026-02-16 20:42:31 +01:00
Dries Peeters 5035ea8c66 Update render 2026-02-16 20:40:10 +01:00
Dries Peeters a3d362ec48 Version bump 2026-02-16 20:34:48 +01:00
Dries Peeters a6b60b16dd feat: Render deployment and demo mode for single-user demo
- Add render.yaml Blueprint: PostgreSQL + Python web service, auto-deploy on push
- Add demo mode (DEMO_MODE, DEMO_USERNAME, DEMO_PASSWORD): single fixed user only
- Login page shows demo credentials when demo mode is active
- Disable self-registration, admin user creation, and OIDC user creation in demo mode
- DB init creates demo user with password when DEMO_MODE is true
- Add docs/deploy/RENDER.md with deployment and demo mode instructions
2026-02-16 20:34:32 +01:00
Dries Peeters def875431c chore: bump version to 4.20.0 and update documentation 2026-02-16 09:34:15 +01:00
Dries Peeters 4f05c3d540 feat(header): group Chat, Timer, Help as aligned round buttons
- Group Chat, Timer, and Help in header as round icon buttons
- Vertically aligned, evenly spaced (gap-2), consistent w-10 h-10
- Header timer: one-click start/stop from any page via floating-timer-bar.js
- Fix timer manual entry URL (use /timer/manual, not /timer/manual_entry)
- Add Help button linking to help page
- Update FEATURES_COMPLETE (Header Quick Access, One-Click Timers)
- Update help page Time Tracking section with header timer tip
- Update CHANGELOG
2026-02-16 09:31:07 +01:00
Dries Peeters 7ae7de12d2 feat(setup): guided 6-step setup wizard for first-time configuration
Replace the single-page setup (telemetry + optional Google Calendar) with
a guided wizard that collects all base settings before completion.

Wizard steps:
1. Welcome - intro and Next
2. Region & time - timezone, date/time format, currency (Settings)
3. Company - name, address, email, optional phone/website (Settings)
4. System - allow self-registration, rounding minutes, single active
   timer, idle timeout (Settings)
5. Integrations (optional) - Google Calendar OAuth; can skip
6. Privacy & finish - telemetry opt-in; Complete Setup submits form

Backend (app/routes/setup.py):
- GET: pass settings and timezones to template for prefilling
- POST: validate timezone, date_format, currency, rounding_minutes,
  idle_timeout_minutes; persist all fields to Settings and
  mark_setup_complete(telemetry_enabled)
- Default timezone/currency to UTC/EUR when missing (keeps tests passing)

Frontend:
- initial_setup.html: 6 wizard steps, progress bar (Step X of 6),
  Back/Next and submit on last step
- setup-wizard.js: step navigation, progress update, optional
  client-side validation for step 2 (timezone, currency required)

Docs updated: TELEMETRY_QUICK_START.md, GETTING_STARTED.md,
TELEMETRY_IMPLEMENTATION_SUMMARY.md.
2026-02-16 08:02:33 +01:00
Dries Peeters d39c5a2f37 fix(pdf-layout): decorative image persistence and PDF preview (Issue #432)
Decorative images now survive save/load and no longer cause a black PDF preview:

- Sync imageUrl onto groups before generateCode() so template_json has
  correct source (invoice and quote layout editors).
- Inject name/imageUrl into design_json with position-based matching so
  reordering does not swap or drop URLs.
- Restore name and imageUrl from saved JSON onto canvas on load
  (synchronous) so Konva custom attrs are not required.
- Omit decorative image elements with empty source from template_json;
  placeholders stay visible in the editor but are not sent to ReportLab.
- ReportLab: explicitly skip decorative images with empty source; validate
  base64 data URI payload and decode in try/except to avoid bad PDF output.

Documentation: PDF_LAYOUT_CUSTOMIZATION.md and PDF_EDITOR_ENHANCED_FEATURES.md
updated with decorative image description, state persistence details, and
troubleshooting. CHANGELOG.md updated under [Unreleased] Fixed.
2026-02-16 07:37:59 +01:00
Dries Peeters b0809e2f90 feat(invoicing): add ZugFerd/Factur-X support and document Peppol & ZugFerd
- Add optional embedding of EN 16931 UBL XML in invoice PDFs (ZugFerd/Factur-X)
  when 'Embed EN 16931 XML in invoice PDFs' is enabled in Admin > Peppol e-Invoicing.
  Exported PDFs then contain ZUGFeRD-invoice.xml for hybrid human- and machine-readable
  invoices; same UBL as Peppol, usable via Peppol or email.
- New setting invoices_zugferd_pdf (migration 128), pikepdf dependency, and
  app.utils.zugferd helper (best-effort supplier/customer from Settings and client).
- Wire embed in export_invoice_pdf (and fallback path); admin checkbox and persistence.
- Docs: PEPPOL_EINVOICING.md retitled to 'Peppol and ZugFerd', new section for
  ZugFerd embedding; README and CHANGELOG updated; migration 128 noted.
- Tests: test_zugferd.py (embed adds attachment with expected XML; invalid PDF
  returns original bytes and error).
2026-02-16 07:36:49 +01:00