Commit Graph

1135 Commits

Author SHA1 Message Date
Dries Peeters a78eccfd71 docs: update docs index and PROJECT_STRUCTURE with new root docs
docs/README.md:
- Quick Links: add INSTALLATION, ARCHITECTURE, DEVELOPMENT, API (root)
- Getting Started: add Installation Guide (root)
- Developer: add root Contributing, Development Guide, Architecture
- API: add API quick reference (root)
- Installation & Deployment: list Installation Guide first

docs/development/PROJECT_STRUCTURE.md:
- Documentation Files: list root CONTRIBUTING, ARCHITECTURE, INSTALLATION,
  DEVELOPMENT, API with correct relative links (../../ for root from docs/development)
2026-03-11 08:19:48 +01:00
Dries Peeters 69eff31de4 docs: standardize CHANGELOG (Keep a Changelog, remove TBD placeholders)
- Remove placeholder version entries [4.8.0], [4.7.1], [4.7.0] with TBD dates
- Rename 'Release Notes Format' to 'Release notes format', reference
  Keep a Changelog and Semantic Versioning
- Align section list with actual headings (Added, Changed, Fixed, etc.)
2026-03-11 08:19:38 +01:00
Dries Peeters 24f8e7aef8 docs: update README with version, installation, and doc links
- Version: point to setup.py as single source of truth, link to CHANGELOG
- Tech stack: add Architecture overview link next to Project Structure
- Quick Start: add link to INSTALLATION.md for full steps
- Documentation: add Installation Guide, root Contributing, Development
  Guide, Architecture, API quick reference
- Contributing: link to CONTRIBUTING.md and DEVELOPMENT.md
2026-03-11 08:19:29 +01:00
Dries Peeters 97ca663e15 docs: add PR template and improve bug report template
- Add .github/PULL_REQUEST_TEMPLATE.md: description, type of change,
  checklist (tests, docs, CHANGELOG), links to CONTRIBUTING and CHANGELOG
- Enhance bug_report.md: add Environment section (TimeTracker version,
  deployment type, OS, browser) for easier triage
2026-03-11 08:19:21 +01:00
Dries Peeters 6b8e0404ad docs: add root API.md quick reference
- REST API overview, token auth, base URL /api/v1
- How to get and use API tokens (Admin → Api-tokens, Bearer header)
- Main resources table (projects, time entries, tasks, clients, etc.)
- Curl examples for GET projects and POST time entry
- Links to REST_API.md, API_TOKEN_SCOPES.md, API_VERSIONING.md
2026-03-11 08:19:09 +01:00
Dries Peeters 7faa3186da docs: add INSTALLATION.md and DEVELOPMENT.md
INSTALLATION.md:
- Prerequisites, Docker quick install (env.example, SECRET_KEY)
- First login and minimal config, SQLite quick-test option
- Production and troubleshooting links

DEVELOPMENT.md:
- Run locally (venv + flask run or Docker SQLite compose)
- Env setup, dependencies, folder tree
- Coding conventions, tests (pytest), contributing, releases
- Links to CONTRIBUTING, ARCHITECTURE, PROJECT_STRUCTURE
2026-03-11 08:19:01 +01:00
Dries Peeters 00666381fa docs: add ARCHITECTURE.md with system overview and diagrams
- High-level system overview (Flask, API, Docker, PostgreSQL)
- Main modules table (routes, services, models, desktop, mobile)
- Data flow and backend/frontend separation
- Design decisions (service layer, blueprint registry, API auth)
- Mermaid diagrams for request flow and app structure
- Links to PROJECT_STRUCTURE and Architecture Migration Guide
2026-03-11 08:18:52 +01:00
Dries Peeters a09b83477d docs: add root CONTRIBUTING.md and fix env.example reference
- Add root CONTRIBUTING.md with quick overview and links to full guide,
  Code of Conduct, and CHANGELOG
- Fix docs/development/CONTRIBUTING.md: use env.example (not .env.example)
  for cp command to match repository
2026-03-11 08:18:42 +01:00
Dries Peeters 2ee8da33a0 feat: TimeTracker polish and production readiness (plan implementation)
Quick wins (Phase A):
- A1: Quick timer actions — last timer context, Repeat last button, Quick start one-click form; pre-fill modal and tags from last entry
- A2: Unified empty states using empty_state macro on custom_view, time_entry_templates, saved_filters, issues; add loading_placeholder macro
- A3: Dashboard hierarchy — Activity and Support/Donate moved to secondary row below fold with reduced visual weight
- A4: Error/feedback consistency (flash-to-toast already in place)

Medium impact (Phase B):
- B5: Split API v1 — api_v1_common.py (shared helpers), api_v1_time_entries.py sub-blueprint for time-entries and timer/*; register api_v1_time_entries_bp
- B6: Start Timer UX — templates as prominent chips at top of modal; default last context and quick start from A1
- B7: Week in review — ReportingService.get_week_in_review(), route /reports/week-in-review, template and link from reports index
- B8: Tags discoverability — GET /api/tags, recent_tags in dashboard, tags input with datalist in Start Timer modal; last context includes tags
- B9: Frontend consolidation — document onboarding.js vs onboarding-enhanced.js in base.html
- B10: API validation — Marshmallow TimeEntryCreateSchema/TimeEntryUpdateSchema and handle_validation_error in api_v1_time_entries create/update

UX: Remove duplicate Timer actions — single Repeat last and Start Timer in header; body shows only Resume when recent entries exist (no duplicate Repeat last or Start new).
2026-03-11 08:00:47 +01:00
Dries Peeters 9f3048f6fb Update setup.py 2026-03-09 20:50:02 +01:00
Dries Peeters c1a1592d2f fix(pdf): show decorative images in export when they overflow the page
- In _on_page(), only skip IMAGE elements when their rect does not
  intersect the page (was skipping when top-left was outside, which
  hid overflowing images).
- Coerce element x, y, width, height to float to avoid type issues.
- In _draw_image_on_canvas(), clip all image drawing to the page
  rectangle (beginPath + rect + clipPath) so the visible portion
  is shown and overflow is clipped like in the preview.
- Try template image file path before get_image_base64 for more
  reliable loading across deployments.
- Add INFO log when drawing template images for debugging.

Fixes #537 (export not showing decorative image when over border).
2026-03-09 20:49:06 +01:00
Dries Peeters 55f2ef29fd feat(overtime): allow overtime calculation by weekly hours (Issue #551) 2026-03-09 20:33:48 +01:00
Dries Peeters 846592cbe9 feat(docker): configurable nginx host ports via HTTP_PORT and HTTPS_PORT
Allow overriding nginx port mappings with environment variables so users behind a reverse proxy (Nginx Proxy Manager, Traefik, etc.) or with 80/443 already in use can deploy without editing docker-compose.yml.

- docker-compose.yml: use \:80 and \:443
- env.example: document HTTP_PORT and HTTPS_PORT with example
- DOCKER_COMPOSE_SETUP.md: add Docker/nginx ports to env reference

Closes #553
2026-03-09 20:33:40 +01:00
Dries Peeters 4248a7e6d7 fix(admin): resolve database error when deleting user (#552)
Before deleting a user, explicitly remove their donation_interactions rows so the delete succeeds even when the table is missing (e.g. after support banner was removed via license). Also handle missing donation_interactions table in safe_commit like time_entry_approvals.
2026-03-09 20:32:47 +01:00
Dries Peeters 3641b277f5 Update tests 2026-03-08 06:50:42 +01:00
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