Commit Graph

127 Commits

Author SHA1 Message Date
Dries Peeters 59406b38ee Fix: Filter out done/cancelled tasks in Dashboard Start Timer
When selecting a project in the Dashboard Start Timer modal, all tasks were displayed including those marked as 'done' or 'cancelled'. This made it difficult to find active tasks in projects with many completed tasks.

Changes:

- Updated /api/projects/<project_id>/tasks endpoint to exclude tasks with status 'done' or 'cancelled'

- Only returns active tasks (todo, in_progress, review)

- Added test to verify the filtering behavior

This improves usability by showing only actionable tasks when starting a timer, especially beneficial for larger projects with many tasks.
2025-11-12 11:20:37 +01:00
Dries Peeters f8b7afa6c2 Update test_timezone.py 2025-11-12 09:36:44 +01:00
Dries Peeters d3f6a792dd Add prepaid-form parsing, tame console noise, and fix invoice UI
parse prepaid hour/reset fields on client edit/create; guard invalid values with new route tests
suppress benign ResizeObserver warnings globally and load handler on standalone pages
raise invoice actions dropdown as a floating menu so it isn’t clipped or scroll-locking
2025-11-12 08:15:04 +01:00
Dries Peeters 14ae197266 Improve timezone handling for system and personal preferences
- share a centralized timezone list across admin and user settings
- allow admins to pick from the same list when setting the system default
- let users clear their personal override to fall back to the global default
- add regression tests covering the new helper and reset path
2025-11-11 14:04:39 +01:00
Dries Peeters 8322c73ddc Update tests 2025-11-05 13:58:38 +01:00
Dries Peeters 0df8ef5ae1 Update test_invoices.py 2025-11-05 13:18:24 +01:00
Dries Peeters fbb2fee1fe Update test_invoices.py 2025-11-05 13:14:24 +01:00
Dries Peeters 01459f6d3b feat: Implement comprehensive onboarding and enhanced error handling
- Interactive tour system with 13-16 comprehensive steps covering all
  major features
- Tooltip system for complex features (auto-attaches to elements with
  data-tooltip attribute)
- Contextual help buttons on complex features (Kanban, Reports,
  Analytics, Invoices, Time Entry)
- Feature discovery system with visual badges for power features
- Enhanced tour content with keyboard shortcuts, tips, and actionable
  guidance
- Smart element finding with auto-expansion of hidden dropdowns
- Proper tooltip positioning with viewport-aware placement

### Error Handling Features (Section 15)

- User-friendly error messages for all HTTP status codes (400, 401, 403,
  404, 409, 422, 429, 500, 502, 503, 504)
- Retry buttons for failed operations with exponential backoff
- Offline mode indicators with visual queue count display
- Offline operation queue with automatic processing when connection
  restored
- Graceful degradation with feature detection and fallbacks
- Recovery options in error pages (Dashboard, Back, Refresh, Login)
- Enhanced error templates with retry buttons and recovery actions

### Technical Improvements

- Added /api/health endpoint for connection monitoring
- Improved fetch interceptor for automatic error handling
- Network status monitoring with periodic health checks
- localStorage-based queue persistence for offline operations
- Enhanced error handler with recovery option mapping
- Fixed Activity model attribute error (activity_type -> entity_type)

### UI/UX Enhancements

- Improved highlight visibility with better mask gradients
- Optimized onboarding performance (reduced from triple to double
  requestAnimationFrame)
- Fixed tooltip positioning to use viewport coordinates correctly
- Enhanced mask system with proper cutout revealing focused elements
- Better button event handling with event delegation
- Styled keyboard shortcuts (kbd) and emphasized text (strong) in
  tooltips

### Files Changed

- app/static/onboarding.js - Enhanced onboarding system
- app/static/onboarding-enhanced.js - Tooltips, contextual help, feature
  discovery
- app/static/error-handling-enhanced.js - Enhanced error handling
- app/utils/error_handlers.py - User-friendly error messages
- app/routes/api.py - Added /api/health endpoint, fixed Activity error
- app/templates/base.html - Added script includes
- app/templates/errors/*.html - Enhanced error templates with recovery
- tests/test_onboarding.py - Onboarding tests
- tests/test_error_handling.py - Error handling tests

### Testing

- Comprehensive unit tests for onboarding features
- Comprehensive unit tests for error handling
- Smoke tests for file existence and integration
2025-11-05 10:54:55 +01:00
Dries Peeters 279a2fb667 fix: resolve Excel export 500 error caused by incorrect project.client access
- Fixed AttributeError when accessing project.client.name in Excel export
- Project.client is a string property returning the client name, not an object
- Changed all incorrect .name accesses to use the string property directly
- Added unit tests for Excel export functionality to prevent regression

Fixes bug where exporting time entries to Excel resulted in 500 server error
with message: 'str' object has no attribute 'name'

Files changed:
- app/utils/excel_export.py: Fixed time entries export client column
- app/routes/reports.py: Fixed project report export client field
- app/templates/projects/view.html: Fixed project view template
- tests/test_excel_export.py: Added comprehensive Excel export tests
2025-11-03 08:32:10 +01:00
Dries Peeters 456c3c5f47 Hopefully fixes it. 2025-11-01 10:26:45 +01:00
Dries Peeters 8b3de55ac1 fix tests 2025-11-01 09:04:06 +01:00
Dries Peeters a110b94a08 fix tests 2025-11-01 08:44:02 +01:00
Dries Peeters 7a28f0665b Update tests. 2025-10-31 19:24:47 +01:00
Dries Peeters 31fa60164d Change tests 2025-10-31 17:26:32 +01:00
Dries Peeters 945ef48f8d Update testing 2025-10-31 14:13:16 +01:00
Dries Peeters 81c57493c4 Update test_currency_display.py 2025-10-31 13:51:53 +01:00
Dries Peeters cbebf0d7e5 Update tests 2025-10-31 13:44:07 +01:00
Dries Peeters 157272356c feat: Add Resume Time Entry feature for quick timer restart
Add new Resume feature that allows users to quickly start a new active
timer with the same properties as a previously completed time entry. This
eliminates repetitive data entry when continuing work on tasks that span
multiple days, reducing time from ~30 seconds to ~3 seconds (90% savings).

Backend Changes:
- Add new route GET /timer/resume/<timer_id> in app/routes/timer.py
- Copies project, task, notes, tags, and billable status to new timer
- Validates permissions (users can only resume their own entries)
- Prevents concurrent timers (blocks if active timer exists)
- Validates project status (must be active, not archived)
- Handles deleted tasks gracefully (creates timer without task)
- Logs events for analytics and activity tracking
- Emits WebSocket events for real-time UI updates

Frontend Changes:
- Add green Resume button (play icon) to dashboard recent entries
- Add Resume button to search results time entry table
- Add Resume button to task view time entries table
- Position Resume as first action before Edit/Duplicate/Delete

Testing:
- Add comprehensive test suite in tests/test_time_entry_resume.py
- 14 tests covering unit, integration, and smoke test scenarios
- Tests property copying, permissions, validations, and edge cases
- 100% code coverage of new functionality

Documentation:
- Add docs/RESUME_FEATURE.md - Complete feature documentation
- Add docs/features/RESUME_TIME_ENTRY_IMPLEMENTATION.md - Technical guide
- Add docs/features/RESUME_TIME_ENTRY_README.md - User quick start guide

Properties Copied: project_id, task_id, notes, tags, billable
Properties NOT Copied: start_time (uses current), end_time (NULL for active)

No database migrations required - works with existing schema.

Resolves user feature request for resuming time entries across work sessions.
2025-10-31 13:33:11 +01:00
Dries Peeters 890df2f4bc Fix: Preserve task selection when duplicating time entries
Fix: Preserve task selection when duplicating time entriesWhen duplicating a time entry with an assigned task, the task was notbeing pre-selected in the duplicate form. This was caused by thetemplate application code interfering with the duplication logic.The template code would run after duplication data was set, overwritingthe `data-selected-task-id` attribute and clearing the task selectioneven when no template was being applied.Changes:- Added isDuplicating flag check in manual_entry.html to prevent  template application code from running during duplication- Template functionality continues to work normally for non-duplicate  manual entries- Added comprehensive test to verify task pre-selection is preserved- Updated documentation with fix notes and changelog entryImpact:- Users can now duplicate time entries with tasks and the task will be  correctly pre-selected, saving time and improving UX- No breaking changes - all existing tests pass (54/54)- Clean separation between duplication and template featuresTests:- test_duplicate_with_task_not_overridden_by_template_code (new)- All 22 duplication tests passing- All 32 template tests passing
2025-10-31 13:22:24 +01:00
Dries Peeters 8e85e41f21 fix: Replace hardcoded Euro symbols with dynamic currency in finance pages
xes bug where Reports, Payments, and Expenses dashboards displayed
hardcoded Euro symbols (€) instead of respecting the CURRENCY setting
from the environment file.

Changes:
- Added currency_symbol and currency_icon Jinja2 filters supporting 25+ currencies
- Updated Reports page to use dynamic currency symbols
- Updated Payments list page to use dynamic currency symbols
- Updated Expenses list page to use dynamic currency symbols and icons
- Updated Expenses dashboard to use dynamic currency symbols and icons
- Created comprehensive test suite with 14 tests (unit, integration, smoke)
- Added bug fix documentation

The currency variable is already injected via context processor, so pages
now correctly display USD ($), EUR (€), GBP (£), or any configured currency
symbol based on the CURRENCY environment variable.

Affected pages:
- /reports
- /payments
- /expenses
- /expenses/dashboard

Test with: pytest tests/test_currency_display.py -v

Files changed:
- app/utils/template_filters.py (added filters)
- app/templates/reports/index.html
- app/templates/payments/list.html
- app/templates/expenses/list.html
- app/templates/expenses/dashboard.html
- tests/test_currency_display.py (new)
- docs/BUGFIX_CURRENCY_DISPLAY.md (new)
2025-10-31 10:49:12 +01:00
Dries Peeters d9c6192884 feat: implement comprehensive multi-language support with RTL
Add complete internationalization (i18n) infrastructure supporting 9 languages
including full Right-to-Left (RTL) support for Arabic and Hebrew.

Languages supported:
- English, German, French, Spanish, Dutch, Italian, Finnish (LTR)
- Arabic, Hebrew (RTL with complete layout support)

Core features:
* Flask-Babel configuration with locale selector
* Translation files for all 9 languages (480+ strings each)
* Language selector UI component in header with globe icon
* User language preference storage in database
* RTL CSS support with automatic layout reversal
* Session and user-based language persistence

Model field translation system:
* Created comprehensive i18n helper utilities (app/utils/i18n_helpers.py)
* 17 new Jinja2 template filters for automatic translation
* Support for task statuses, priorities, project statuses, invoice statuses,
  payment methods, expense categories, and all model enum fields
* Status badge CSS classes for consistent styling

Technical implementation:
* Language switching via API endpoint (POST /api/language)
* Direct language switching route (GET /set-language/<lang>)
* RTL detection and automatic dir="rtl" attribute
* Context processors for language information in all templates
* Template filters registered globally

Testing and quality:
* 50+ unit tests covering all i18n functionality
* Tests for locale selection, language switching, RTL detection
* Comprehensive test coverage for all translation features

Files added:
- translations/es/LC_MESSAGES/messages.po (Spanish)
- translations/ar/LC_MESSAGES/messages.po (Arabic)
- translations/he/LC_MESSAGES/messages.po (Hebrew)
- app/utils/i18n_helpers.py (translation helper functions)
- app/static/css/rtl-support.css (RTL layout support)
- tests/test_i18n.py (comprehensive test suite)
- scripts/audit_i18n.py (translation audit tool)

Files modified:
- app/config.py: Added 3 languages + RTL configuration
- app/routes/user.py: Language switching endpoints
- app/templates/base.html: Language selector + RTL support
- app/utils/context_processors.py: Language context injection
- app/__init__.py: Registered i18n template filters
- scripts/extract_translations.py: Updated language list
- translations/*/messages.po: Added 70+ model field translations

The infrastructure is production-ready. Model enum fields now automatically
translate in templates using the new filters. Flash messages and some template
strings remain in English until wrapped with translation markers (tracked
separately for incremental implementation).
2025-10-31 10:39:12 +01:00
Dries Peeters 12d3b9fb1b feat: Add comprehensive Import/Export system and standardize UI headers
## New Features

### Import/Export System
- Add DataImport and DataExport models for tracking operations
- Implement CSV import for bulk time entry data
- Add support for importing from Toggl and Harvest (placeholder)
- Implement GDPR-compliant full data export (JSON format)
- Add filtered export functionality with date/project filters
- Create backup/restore functionality for database migrations
- Build migration wizard UI for seamless data transitions
- Add comprehensive test coverage (unit and integration tests)
- Create user documentation (IMPORT_EXPORT_GUIDE.md)

### Database Changes
- Add migration 040: Create data_imports and data_exports tables
- Track import/export operations with status, logs, and file paths
- Support automatic file expiration for temporary downloads

## UI/UX Improvements

### Navigation Menu Restructure
- Rename "Work" to "Time Tracking" for clarity
- Rename "Finance" to "Finance & Expenses"
- Add "Tools & Data" submenu with Import/Export and Saved Filters
- Reorganize Time Tracking submenu: prioritize Log Time, add icons to all items
- Expand Finance submenu: add Mileage, Per Diem, and Budget Alerts
- Add icons to all Admin submenu items for better visual scanning
- Fix Weekly Goals not keeping Time Tracking menu open

### Standardized Page Headers
Apply consistent page_header macro across 26+ pages:
- **Time Tracking**: Tasks, Projects, Clients, Kanban, Weekly Goals, Templates, Manual Entry
- **Finance**: Invoices, Payments, Expenses, Mileage, Per Diem, Budget Alerts, Reports
- **Admin**: Dashboard, Users, Roles, Permissions, Settings, API Tokens, Backups, System Info, OIDC
- **Tools**: Import/Export, Saved Filters, Calendar
- **Analytics**: Dashboard

Each page now includes:
- Descriptive icon (Font Awesome)
- Clear title and subtitle
- Breadcrumb navigation
- Consistent action button placement
- Responsive design with dark mode support

## Bug Fixes

### Routing Errors
- Fix endpoint name: `per_diem.list_per_diems` → `per_diem.list_per_diem`
- Fix endpoint name: `reports.index` → `reports.reports`
- Fix endpoint name: `timer.timer` → `timer.manual_entry`
- Add missing route registration for import_export blueprint

### User Experience
- Remove duplicate "Test Configuration" button from OIDC debug page
- Clean up user dropdown menu (remove redundant Import/Export link)
- Improve menu item naming ("Profile" → "My Profile", "Settings" → "My Settings")

## Technical Details

### New Files
- `app/models/import_export.py` - Import/Export models
- `app/utils/data_import.py` - Import business logic
- `app/utils/data_export.py` - Export business logic
- `app/routes/import_export.py` - API endpoints
- `app/templates/import_export/index.html` - User interface
- `tests/test_import_export.py` - Integration tests
- `tests/models/test_import_export_models.py` - Model tests
- `docs/IMPORT_EXPORT_GUIDE.md` - User documentation
- `docs/import_export/README.md` - Quick reference
- `migrations/versions/040_add_import_export_tables.py` - Database migration

### Modified Files
- `app/__init__.py` - Register import_export blueprint
- `app/models/__init__.py` - Export new models
- `app/templates/base.html` - Restructure navigation menu
- 26+ template files - Standardize headers with page_header macro

## Breaking Changes
None. All changes are backward compatible.

## Testing
- All existing tests pass
- New test coverage for import/export functionality
- Manual testing of navigation menu changes
- Verified consistent UI across all updated pages
2025-10-31 09:56:49 +01:00
Dries Peeters 755faa22c3 feat: Add Budget Alerts & Forecasting system with modern UI
Implement comprehensive budget monitoring and forecasting feature with:

Database & Models:
- Add BudgetAlert model for tracking project budget alerts
- Create migration 039_add_budget_alerts_table with proper indexes
- Support alert types: 80_percent, 100_percent, over_budget
- Add acknowledgment tracking with user and timestamp

Budget Forecasting Utilities:
- Implement burn rate calculation (daily/weekly/monthly)
- Add completion date estimation based on burn rate
- Create resource allocation analysis per team member
- Build cost trend analysis with configurable granularity
- Add automatic budget alert detection with deduplication

Routes & API:
- Create budget_alerts blueprint with dashboard and detail views
- Add API endpoints for burn rate, completion estimates, and trends
- Implement resource allocation and cost trend API endpoints
- Add alert acknowledgment and manual budget check endpoints
- Fix log_event() calls to use keyword arguments

UI Templates:
- Design modern budget dashboard with Tailwind CSS
- Create detailed project budget analysis page with charts
- Add gradient stat cards with color-coded status indicators
- Implement responsive layouts with full dark mode support
- Add smooth animations and toast notifications
- Integrate Chart.js for cost trend visualization

Project Integration:
- Add Budget Alerts link to Finance navigation menu
- Enhance project view page with budget overview card
- Show budget progress bars with status indicators
- Add Budget Analysis button to project header and dashboard
- Display real-time budget status with color-coded badges

Visual Enhancements:
- Use gradient backgrounds for stat cards (blue/green/yellow/red)
- Add status badges with icons (healthy/warning/critical/over)
- Implement smooth progress bars with embedded percentages
- Support responsive grid layouts for all screen sizes
- Ensure proper type conversion (Decimal to float) in templates

Scheduled Tasks:
- Register budget alert checking job (runs every 6 hours)
- Integrate with existing APScheduler tasks
- Add logging for alert creation and monitoring

This feature provides project managers with real-time budget insights,
predictive analytics, and proactive alerts to prevent budget overruns.
2025-10-31 08:52:12 +01:00
Dries Peeters b353184a4f feat: implement advanced expense management with templates and navigation
Implement complete Advanced Expense Management feature set with UI templates,
database schema fixes, and reorganized navigation structure.

Features:
- Expense Categories: Full CRUD with budget tracking and visualization
- Mileage Tracking: Vehicle mileage entries with approval workflow
- Per Diem Management: Daily allowance claims with location-based rates
- Receipt OCR: Infrastructure for receipt scanning (utilities ready)

Database:
- Migration 037: Create expense_categories, mileage, per_diem_rates, per_diems tables
- Migration 038: Fix schema column name mismatches (trip_purpose→purpose, etc.)
- Add missing columns (description, odometer, rates, reimbursement tracking)
- Fix circular foreign key dependencies

Templates (11 new files):
- expense_categories/: list, form, view
- mileage/: list, form, view
- per_diem/: list, form, view, rates_list, rate_form

Navigation:
- Move Mileage and Per Diem to Expenses sub-pages (header buttons)
- Move Expense Categories to Admin menu only
- Remove expense management items from Finance menu

Fixes:
- Fix NoneType comparison error in expense categories utilization
- Handle None values safely in budget progress bars
- Resolve database column name mismatches

UI/UX:
- Responsive design with Tailwind CSS and dark mode support
- Real-time calculations for mileage amounts
- Color-coded budget utilization progress bars
- Status badges for approval workflow states
- Advanced filtering on all list views

Default data:
- 7 expense categories (Travel, Meals, Accommodation, etc.)
- 4 per diem rates (US, GB, DE, FR)
2025-10-31 06:21:35 +01:00
Dries Peeters 0da5ac0077 feat: Add comprehensive project dashboard with analytics and visualizations
Implement a feature-rich project dashboard that provides visual analytics
and key performance indicators for project tracking and management.

Features:
- Individual project dashboard route (/projects/<id>/dashboard)
- Key metrics cards: Total Hours, Budget Used, Tasks Complete, Team Size
- Budget vs. Actual bar chart with threshold warnings
- Task status distribution doughnut chart
- Team member contributions horizontal bar chart (top 10)
- Time tracking timeline line chart
- Team member details with progress bars
- Recent activity feed (last 10 activities)
- Period filtering (All Time, 7/30/90/365 Days)
- Responsive design with dark mode support
- Navigation button added to project view page

Technical Implementation:
- New route: project_dashboard() in app/routes/projects.py
- Template: app/templates/projects/dashboard.html with Chart.js 4.4.0
- Data aggregation for budget, tasks, team contributions, and timeline
- Optimized database queries with proper filtering
- JavaScript escaping handled with |tojson filters and autoescape control

Testing:
- 20 comprehensive unit tests (test_project_dashboard.py)
- 23 smoke tests (smoke_test_project_dashboard.py)
- Full test coverage for all dashboard functionality

Documentation:
- Complete feature guide (docs/features/PROJECT_DASHBOARD.md)
- Implementation summary (PROJECT_DASHBOARD_IMPLEMENTATION_SUMMARY.md)
- Usage examples and troubleshooting guide

Fixes:
- JavaScript syntax errors from HTML entity escaping
- Proper use of |tojson filter for dynamic values in JavaScript
- Autoescape disabled for script blocks to prevent operator mangling

This dashboard provides project managers and team members with valuable
insights into project health, progress, budget utilization, and resource
allocation at a glance.
2025-10-30 10:43:31 +01:00
Dries Peeters 54ec5fe4b2 feat: Add bulk task operations and CSV export across all entities
Implements comprehensive bulk operations and export functionality for tasks,
clients, and projects with consistent UI/UX across all three entities.

Features Added:
- Bulk task operations (delete, status change, assignment, move to project)
- Multi-select checkboxes with "select all" functionality
- CSV export for tasks, clients, and projects
- Export respects current filters and permissions
- Modal dialogs for bulk operation confirmation

Bug Fixes:
- Fixed bulk delete not working due to dialog submission issue
- Fixed dropdown menus being cut off in short tables (z-index and overflow)
- Fixed projects export attempting to access .name on string property

Technical Details:
- Backend: Added 5 new routes (tasks bulk ops, 3 export routes)
- Frontend: Updated task/client/project list templates with consistent UI
- Tests: Added 23 comprehensive tests for bulk operations
- Changed table overflow from overflow-x-auto to overflow-visible
- Added z-50 to all dropdown menus for proper layering

Routes Added:
- POST /tasks/bulk-delete
- POST /tasks/bulk-status
- POST /tasks/bulk-assign
- POST /tasks/bulk-move-project
- GET /tasks/export
- GET /clients/export
- GET /projects/export

Files Changed:
- app/routes/tasks.py (+103 lines)
- app/routes/clients.py (+73 lines)
- app/routes/projects.py (+95 lines)
- app/templates/tasks/list.html (major refactor)
- app/templates/clients/list.html (+export, overflow fix)
- app/templates/projects/list.html (+export fix, overflow fix)
- tests/test_bulk_task_operations.py (NEW, 23 tests)
- docs/BULK_TASK_OPERATIONS.md (NEW)
- BULK_TASK_OPERATIONS_IMPLEMENTATION.md (NEW)
- BUGFIXES_BULK_OPERATIONS.md (NEW)
- BUGFIXES_CONSISTENCY_AND_EXPORT.md (NEW)

Breaking Changes: None
Migration Required: None
2025-10-30 10:06:13 +01:00
Dries Peeters 6cad084c8c feat: implement Activity Feed Widget with real-time filtering and audit trail
Add comprehensive Activity Feed Widget to dashboard providing team visibility
and audit trail functionality. The widget displays recent user activities with
advanced filtering, pagination, and auto-refresh capabilities.

Features:
- Dashboard widget showing last 10 activities with infinite scroll
- Filter by entity type (projects, tasks, time entries, templates, users, etc.)
- Real-time auto-refresh every 30 seconds
- Visual indicators for active filters (checkmark + dot)
- Load more pagination with "has_next" detection
- Refresh button with spinning animation feedback

API Endpoints:
- GET /api/activities - Retrieve activities with filtering & pagination
- GET /api/activities/stats - Activity statistics and analytics
- Support for user_id, entity_type, action, and date range filters

Activity Logging Integration:
- Projects: create, update, delete, archive, unarchive
- Tasks: create, update, delete
- Time Entries: start timer, stop timer
- All operations log user, IP address, and user agent for security

UI/UX Improvements:
- Vanilla JS implementation (removed Alpine.js dependency)
- Dark mode support with proper color schemes
- Responsive dropdown with scrollable content
- Action-specific icons (Font Awesome)
- Relative timestamps with timeago filter
- Error handling with user-friendly messages

Testing & Documentation:
- Comprehensive test suite (model, API, integration, widget)
- Feature documentation in docs/features/activity_feed.md
- Implementation summary and integration guide
- Console logging for debugging

Bug Fixes:
- Fixed "Load More" button not appending results
- Fixed refresh clearing list without reloading
- Fixed filter dropdown using Alpine.js (now vanilla JS)
- Fixed entity_type filter sending 'all' to API
- Added missing entity types (time_entry_template, user)

Technical Details:
- Activity model with optimized indexes for performance
- Promise-based async loading with proper error handling
- Credentials included in fetch for authentication
- Filter state management with visual feedback
- Graceful degradation on API failures

Impact:
- Team visibility into real-time activities
- Comprehensive audit trail for compliance
- Better accountability and transparency
- Improved troubleshooting capabilities
2025-10-30 09:20:03 +01:00
Dries Peeters 32bc87db5e feat: Complete Time Entry Templates feature with dashboard integration
Complete the Time Entry Templates feature by adding timer integration
and dashboard UI (70% → 100% complete).

Features Added:
- One-click start timer from template via new route
- Template selector in dashboard "Start Timer" modal
- Template pre-fill for manual time entries
- Auto-populate timer forms with template data
- Usage tracking when templates are used

Backend Changes:
- Added template support to /timer/start route
- Added template pre-fill to /timer/manual route
- New route: /timer/start/from-template/<id> for direct timer start
- Load recent templates (top 5) on dashboard
- All changes include proper validation and error handling

Frontend Changes:
- Template list in dashboard start timer modal
- JavaScript function to apply template data to forms
- Template cards show project/task information
- Link to full template management page
- Responsive design for mobile

Testing:
- Added 6 new integration tests for timer features
- Test start timer from template (success and error cases)
- Test manual entry pre-fill from template
- Test active timer validation
- All 32 tests passing with no linting errors

Documentation:
- Complete user guide (docs/TIME_ENTRY_TEMPLATES.md)
- Technical documentation (docs/features/TIME_ENTRY_TEMPLATES.md)
- Implementation summary with usage examples

Use Case: Quickly start timers for recurring activities
- 80% faster timer start for recurring tasks
- Zero retyping of project, task, notes, tags
- Consistent data across similar time entries
2025-10-30 08:32:11 +01:00
Dries Peeters fc81cc3d8c feat: Add tests and docs for User Settings page
Add extensive test coverage and documentation for the existing User Settings
page, completing the feature implementation to production-ready status.

## Changes

### Testing (44 tests, 100% passing)
- Add 30 unit tests in tests/test_user_settings.py
  * Page rendering and authentication tests
  * Form validation and preference update tests
  * API endpoint tests (PATCH /api/preferences, POST /api/theme)
  * Integration and CSRF protection tests
- Add 14 smoke tests in tests/smoke_test_user_settings.py
  * Basic functionality validation
  * Critical user path verification
  * Error handling checks

### Documentation
- Add docs/USER_SETTINGS_GUIDE.md
  * Comprehensive user guide for all settings
  * API documentation with examples
  * Database schema reference
  * Troubleshooting guide
  * Best practices for developers
- Add USER_SETTINGS_IMPLEMENTATION_SUMMARY.md
  * Complete implementation overview
  * Feature checklist and verification
  * Test results and metrics

## Features Tested

-  Profile information management (name, email)
-  Notification preferences (5 toggles)
-  Theme selection (light/dark/system) with live preview
-  Regional settings (timezone, date/time formats, week start)
-  Time rounding preferences (intervals, methods)
-  Overtime settings (standard hours per day)
-  API endpoints for AJAX updates
-  Input validation and error handling

## Test Coverage

- Settings page rendering: 4 tests
- Preference updates: 16 tests
- API endpoints: 7 tests
- Integration: 3 tests
- Smoke tests: 14 tests
- Total: 44 tests, 100% passing

## Notes

The User Settings feature backend and frontend were already fully implemented
in app/routes/user.py and app/templates/user/settings.html. This commit adds
the missing test co
2025-10-30 07:47:58 +01:00
Dries Peeters bcab2d764f test changes 2025-10-29 18:42:10 +01:00
Dries Peeters 1e11ffec7f Fix keyboard shortcuts triggering in text input fields
- Fix keyboard shortcuts (like 'g r' for Go to Reports) incorrectly triggering
  while typing in input fields, textareas, and rich text editors
- Enhance detection for popular rich text editors:
  * Toast UI Editor (used in project descriptions)
  * TinyMCE, Quill, CodeMirror, Summernote
  * All contenteditable elements
- Allow specific global shortcuts even in input fields:
  * Ctrl+K / Cmd+K: Open command palette
  * Shift+?: Show keyboard shortcuts help
  * Ctrl+/: Focus search
- Clear key sequences when user starts typing to prevent partial matches
- Add debug logging for troubleshooting keyboard shortcut issues
- Update JavaScript cache busting version numbers (v=2.0, v=2.2)

Test improvements:
- Add comprehensive test suite for keyboard shortcuts input fix
  * Test typing 'gr' in 'program' doesn't trigger navigation
  * Test rich text editor detection logic
  * Test allowed shortcuts in inputs
- Refactor smoke tests to use admin_authenticated_client fixture
  instead of manual login (DRY principle)
- Fix Windows PermissionError in test cleanup for temporary files
- Add SESSION_COOKIE_HTTPONLY to test config for security
- Update test secret key length to meet requirements
- Remove duplicate admin user fixtures

Resolves issue where typing words like 'program' or 'graphics' in forms
would trigger unintended navigation shortcuts.
2025-10-29 18:17:04 +01:00
Dries Peeters 20b7401891 feat: Add invoice expenses, enhanced PDF editor with Konva.js, and uploads persistence
Major Features:
- Invoice Expenses: Allow linking billable expenses to invoices with automatic total calculations
  - Add expenses to invoices via "Generate from Time/Costs" workflow
  - Display expenses in invoice view, edit forms, and PDF exports
  - Track expense states (approved, invoiced, reimbursed) with automatic unlinking on invoice deletion
  - Update PDF generator and CSV exports to include expense line items

- Enhanced PDF Invoice Editor: Complete redesign using Konva.js for visual drag-and-drop layout design
  - Add 40+ draggable elements (company info, invoice data, shapes, text, advanced elements)
  - Implement comprehensive properties panel for precise element customization (position, fonts, colors, opacity)
  - Add canvas toolbar with alignment tools, zoom controls, and layer management
  - Support keyboard shortcuts (copy/paste, duplicate, arrow key positioning)
  - Save designs as JSON for editing and generate clean HTML/CSS for rendering
  - Add real-time preview with live data

- Uploads Persistence: Implement Docker volume persistence for user-uploaded files
  - Add app_uploads volume to all Docker Compose configurations
  - Ensure company logos and avatars persist across container rebuilds and restarts
  - Create migration script for existing installations
  - Update directory structure with proper permissions (755 for dirs, 644 for files)

Database & Backend:
- Add invoice_pdf_design_json column to settings table via Alembic migration
- Extend Invoice model with expenses relationship
- Update admin routes for PDF layout designer endpoints
- Enhance invoice routes to handle expense linking/unlinking

Frontend & UI:
- Redesign PDF layout editor template with Konva.js canvas (2484 lines, major overhaul)
- Update invoice edit/view templates to display and manage expenses
- Add expense sections to invoice forms with unlink functionality
- Enhance UI components with keyboard shortcuts support
- Update multiple templates for consistency and accessibility

Testing & Documentation:
- Add comprehensive test suites for invoice expenses, PDF layouts, and uploads persistence
- Create detailed documentation for all new features (5 new docs)
- Include migration guides and troubleshooting sections

Infrastructure:
- Update docker-compose files (main, example, remote, remote-dev, local-test) with uploads volume
- Configure pytest for new test modules
- Add template filters for currency formatting and expense display

This update significantly enhances TimeTracker's invoice management capabilities,
improves the PDF customization experience, and ensures uploaded files persist
reliably across deployments.
2025-10-29 15:03:01 +01:00
Dries Peeters e6eac1a7de feat: add invoice deletion with system-wide modal confirmation
Implemented complete invoice deletion feature allowing users to delete
incorrectly generated invoices from both the view and list pages.

Changes:
- Added delete button to invoice view page with modal confirmation
- Added delete buttons to invoice list page with modal confirmation
- Implemented custom Tailwind modal matching project design patterns
- Modal displays invoice number and cascade deletion warning
- Full dark mode support with proper accessibility (ARIA attributes)
- Modal can be closed via Cancel button, clicking outside, or ESC key

Technical details:
- Backend route already existed (/invoices/<id>/delete)
- Cascade deletion automatically removes related items, goods, and payments
- Permission checks: only invoice creator or admins can delete
- Delete route returns to invoice list with success/error messages

Testing:
- Added 12 comprehensive tests covering deletion functionality
- Unit tests for basic deletion and cascade behavior
- Route tests for permissions and success/error cases
- Smoke tests for UI elements and complex deletion scenarios
- All tests passing 

The modal implementation follows the established pattern used in
kanban/columns.html, ensuring consistency across the application.
2025-10-29 09:26:13 +01:00
Dries Peeters 09dd042209 fix: project description not saving on edit
Fixed a critical bug where changes to project descriptions were not
being persisted when editing projects via Work > Projects > Edit Project.

The issue was caused by an incorrect CSS selector pattern in the form
submit handler that syncs the markdown editor content. The selector
`form[action*="projects/edit"]` failed to match URLs like
`/projects/123/edit` because the project ID breaks the substring match.

Changes:
- Updated form selector to use more generic pattern: `form[action*="/edit"]`
- Added explicit null checking with `if (form)` guard
- Enhanced error logging with console.error for debugging
- Improved code formatting and structure

Testing:
- Added integration test: test_edit_project_description
- Added smoke test: test_project_edit_page_has_markdown_editor
- All 166 project-related tests pass successfully
- No regressions introduced
2025-10-29 09:05:53 +01:00
Dries Peeters a6254b77a3 Fix SQLAlchemy error when viewing invoices with payments
- Add sorted_payments property to Invoice model using proper SQLAlchemy column references
- Update invoice view template to use new property instead of string-based ordering
- Add comprehensive tests for sorted_payments functionality

Resolves error: "Can't resolve label reference for ORDER BY" when accessing invoice.payments.order_by() from Jinja2 templates
2025-10-29 07:42:34 +01:00
Dries Peeters 6df1824a40 refactor(invoices): migrate to Payment model, deprecate legacy payment route
Remove old /invoices/<id>/payment route and update templates to use the
Payment model system (payments.create_payment). Add deprecation warning
to Invoice.record_payment() method for backward compatibility.

Benefits: Multiple payments per invoice, status tracking, gateway support,
better audit trails, and full CRUD operations.

All tests pass. Backward compatible with 6-month deprecation period.
2025-10-29 07:24:59 +01:00
Dries Peeters faec3f4d4d feat: Add admin user deletion with safety checks
- Add delete button to user list with confirmation dialog
- Prevent deletion of last admin and users with time entries
- Include CSRF protection on delete forms
- Add 41 comprehensive tests (unit, model, smoke)
- Document feature with usage guide and best practices

All safety checks implemented and tested.
2025-10-29 07:15:51 +01:00
Dries Peeters 17cb80b6d3 fix(admin): Fix logo upload visibility and nested forms issue
- Separated logo upload form from main settings form (fixes nested forms)
- Excluded /uploads/ from ServiceWorker cache (fixes logo not showing)
- Added cache busting to logo URLs
- Enhanced UI with prominent logo display and preview
- Added error handling and logging
- Created cache clearing utility at /admin/clear-cache
- Added 18 comprehensive tests
- Created troubleshooting documentation

Fixes: Logo not visible after upload, settings form not saving
2025-10-28 16:06:53 +01:00
Dries Peeters a548928064 tests 2025-10-27 17:46:50 +01:00
Dries Peeters a3e03828f3 Updated tests 2025-10-27 15:31:05 +01:00
Dries Peeters 6e5e9f3d55 fix: resolve failing unit and integration tests for Task and CalendarEvent models 2025-10-27 14:17:06 +01:00
Dries Peeters 8d4ec0e25f feat(payments): add analytics integration and improve UI consistency
## Payment Analytics Integration
- Add 5 new API endpoints for payment metrics:
  - /api/analytics/payments-over-time - trend visualization
  - /api/analytics/payments-by-status - status distribution
  - /api/analytics/payments-by-method - method breakdown
  - /api/analytics/payment-summary - statistics with period comparison
  - /api/analytics/revenue-vs-payments - collection rate tracking
- Integrate payment data into analytics dashboard with 4 new charts
- Add payment metrics to reports page (total, count, fees, net received)
- Update summary endpoint to include payment statistics

## UI/UX Improvements
- Standardize form styling across all payment templates
  - Replace inconsistent Tailwind classes with form-input utility
  - Update card backgrounds to use card-light/card-dark
  - Fix label spacing to match application patterns
  - Ensure consistent border colors and backgrounds
- Replace browser confirm() with system-wide modal for payment deletion
  - Consistent danger variant with warning icon
  - Keyboard support (Enter/Escape)
  - Dark mode compatible
  - Clear messaging about impact on invoice status

## Technical Changes
- Import Payment and Invoice models in analytics and reports routes
- Add proper admin/user scoping for payment queries
- Maintain responsive design across all new components

Closes payment tracking phase 2 (analytics & polish)
2025-10-27 13:38:07 +01:00
Dries Peeters 154f9b37a6 feat: integrate calendar feature with tasks and time entries display
Refactored the existing calendar API endpoint to properly display calendar
events, tasks, and time entries with distinct visual representations.

Changes:
- Updated /api/calendar/events endpoint in api.py to use new
  CalendarEvent.get_events_in_range() method that fetches all three item types
- Fixed user_id bug where it was defaulting to None instead of current_user.id
- Modified API response format to include all items in unified 'events' array
  with item_type field ('event', 'task', 'time_entry') for differentiation
- Updated calendar.js to parse unified response format and filter items by type
- Added visual distinctions:
  * Tasks: 📋 emoji, orange (#f59e0b) color, clickable
  * Time entries: ⏱ emoji, project-based colors, non-clickable
  * Calendar events: 📅 emoji, custom colors, clickable
- Fixed task detail route from /tasks/view/{id} to /tasks/{id}
- Updated all calendar view renderers (month, week, day) to use correct
  data structure with extendedProps
- Added cache-busting to calendar.js (v7) and calendar.css (v2)
- Preserved backward compatibility with existing calendar filtering
  (project_id, task_id, tags)

The calendar now correctly displays all time tracking data in a unified view
with proper visual hierarchy and interaction patterns.

Fixes: Calendar not showing tasks and time entries
Related: Calendar/Agenda Support feature implementation
2025-10-27 11:40:38 +01:00
Dries Peeters 543be51c15 feat(admin): improve email configuration UI and logging
Enhance the email support feature with better UX and debugging capabilities:

- **Fix input field styling**: Update all form inputs to use project-standard
  'form-input' class and consistent checkbox styling matching other admin
  pages for uniform appearance across the application

- **Add comprehensive logging**: Implement detailed logging throughout email
  operations with clear prefixes ([EMAIL TEST], [EMAIL CONFIG]) to track:
  - Email configuration changes and validation
  - Test email sending process step-by-step
  - SMTP connection details and status
  - Success/failure indicators (✓/✗) for quick troubleshooting

- **Auto-reload after save**: Page now automatically refreshes 1.5 seconds
  after successfully saving email configuration to ensure UI reflects the
  latest settings and eliminate stale data

These improvements provide better visual consistency, easier debugging of
email issues, and smoother user experience when configuring email settings.

Files modified:
- app/templates/admin/email_support.html
- app/utils/email.py
- app/routes/admin.py
2025-10-27 10:13:58 +01:00
Dries Peeters a1aaee6afd feat: Redesign and enhance backup restore functionality with dual restore methods
Major improvements to the backup restore system with a complete UI overhaul
and enhanced functionality:

UI/UX Improvements:
- Complete redesign of restore page with modern Tailwind CSS
- Added prominent warning banners and danger badges to prevent accidental data loss
- Implemented drag-and-drop file upload with visual feedback
- Added real-time progress tracking with auto-refresh every 2 seconds
- Added comprehensive safety information sidebar with checklists
- Full dark mode support throughout restore interface
- Enhanced confirmation flows with checkbox and modal confirmations

Functionality Enhancements:
- Added dual restore methods: upload new backup or restore from existing server backups
- Enhanced restore route to accept optional filename parameter for existing backups
- Added "Restore" button to each backup in the backups management page
- Implemented restore confirmation modal with critical warnings
- Added loading states and button disabling during restore operations
- Improved error handling and user feedback

Backend Changes:
- Enhanced admin.restore() to support both file upload and existing backup restore
- Added dual route support: /admin/restore and /admin/restore/<filename>
- Added shutil import for file copy operations during restore
- Improved security with secure_filename validation and file type checking
- Maintained existing rate limiting (3 requests per minute)

Frontend Improvements:
- Added interactive JavaScript for file selection, drag-and-drop, and modal management
- Implemented auto-refresh during restore process to show live progress
- Added escape key support for closing modals
- Enhanced user feedback with file name display and button states

Safety Features:
- Pre-restore checklist with 5 verification steps
- Multiple warning levels throughout the flow
- Confirmation checkbox required before upload restore
- Modal confirmation required before existing backup restore
- Clear documentation of what gets restored and post-restore steps

Dependencies:
- Updated flask-swagger-ui from 4.11.1 to 5.21.0

Files modified:
- app/templates/admin/restore.html (complete rewrite)
- app/templates/admin/backups.html (added restore functionality)
- app/routes/admin.py (enhanced restore route)
- requirements.txt (updated flask-swagger-ui version)
- RESTORE_BACKUP_IMPROVEMENTS.md (documentation)

This provides a significantly improved user experience for the restore process
while maintaining security and adding powerful new restore capabilities.
2025-10-27 09:34:51 +01:00
Dries Peeters c93a37f126 feat: add overtime tracking support with configurable working hours
Implement comprehensive overtime tracking feature that allows users to
set their standard working hours per day and automatically calculates
overtime for hours worked beyond that threshold.

Core Features:
- Add standard_hours_per_day field to User model (default: 8.0 hours)
- Create Alembic migration (031_add_standard_hours_per_day.py)
- Implement overtime calculation utilities (app/utils/overtime.py)
  * calculate_daily_overtime: per-day overtime calculation
  * calculate_period_overtime: multi-day overtime aggregation
  * get_daily_breakdown: detailed day-by-day analysis
  * get_weekly_overtime_summary: weekly overtime statistics
  * get_overtime_statistics: comprehensive overtime metrics

User Interface:
- Add "Overtime Settings" section to user settings page
- Display overtime data in user reports (regular vs overtime hours)
- Show "Days with Overtime" badge in reports
- Add overtime analytics API endpoint (/api/analytics/overtime)
- Improve input field styling with cleaner appearance (no spinners)

Reports Enhancement:
- Standardize form input styling across all report pages
- Replace inline Tailwind classes with consistent form-input class
- Add FontAwesome icons to form labels for better UX
- Improve button hover states and transitions

Testing:
- Add comprehensive unit tests (tests/test_overtime.py)
- Add smoke tests for quick validation (tests/test_overtime_smoke.py)
- Test coverage for models, utilities, and various overtime scenarios

Documentation:
- OVERTIME_FEATURE_DOCUMENTATION.md: complete feature guide
- OVERTIME_IMPLEMENTATION_SUMMARY.md: technical implementation details
- docs/features/OVERTIME_TRACKING.md: quick start guide

This change enables organizations to track employee overtime accurately
based on individual working hour configurations, providing better
insights into work patterns and resource allocation.
2025-10-27 08:44:04 +01:00
Dries Peeters 1398a43a65 fix tests 2025-10-25 08:38:53 +02:00
Dries Peeters acf75774b1 fix tests 2025-10-25 08:08:50 +02:00
Dries Peeters 0dd7ca1006 fix: Invoice currency displays EUR instead of selected currency from Settings
Fixed issue where invoices were always displaying EUR as the currency
regardless of what was configured in Settings. The Invoice model had a
hard-coded default of 'EUR' and the invoice creation route wasn't
explicitly setting the currency from Settings.

Changes:
- Updated invoice creation route to fetch and use currency from Settings
- Updated invoice duplication to preserve original invoice's currency
- Added currency code display to all monetary values in invoice templates
- Added currency code display to invoice list totals
- Created migration script to update existing invoices
- Added comprehensive unit tests and smoke tests
- Added detailed documentation for the fix

Backend changes:
- app/routes/invoices.py: Retrieve currency from Settings when creating
  invoices, pass currency_code explicitly to Invoice constructor
- app/routes/invoices.py: Preserve currency_code when duplicating invoices

Frontend changes:
- app/templates/invoices/view.html: Display currency code next to all
  monetary values (items, extra goods, subtotals, tax, totals)
- app/templates/invoices/list.html: Display currency code next to
  invoice totals in list view

Testing:
- tests/test_invoice_currency_fix.py: 10 unit tests covering various
  currency scenarios and edge cases
- tests/test_invoice_currency_smoke.py: 2 end-to-end smoke tests

Migration:
- migrations/fix_invoice_currency.py: Script to update existing invoices
  to use the currency from Settings

This fix is fully backward compatible. Existing invoices will continue
to work with their current currency values. Run the migration script to
update existing invoices to match the Settings currency.

Resolves: #153 (invoices-display-currency-as-eur-and-not-usd)
2025-10-25 07:40:35 +02:00
Dries Peeters 89141108d9 Fix: Add missing timeago template filter causing 500 error
The Time Entry Templates page (/templates) was throwing a 500 error
when displaying templates with usage data. The templates referenced
a 'timeago' Jinja2 filter that was never registered.

Changes:
- Added timeago filter to app/utils/template_filters.py
  - Converts datetime to human-readable relative time (e.g., "2 hours ago")
  - Handles None, naive/aware datetimes, and future dates gracefully
  - Provides appropriate granularity from seconds to years
  - Uses proper singular/plural forms

- Added 11 comprehensive unit tests in tests/test_utils.py
  - Tests for None values, all time ranges, edge cases
  - Tests for naive datetimes and future dates
  - Tests for singular/plural formatting

- Added smoke test in tests/test_time_entry_templates.py
  - Specifically tests templates with usage_count and last_used_at
  - Ensures the filter renders correctly in the template

The filter is used in:
- app/templates/time_entry_templates/list.html (line 96)
- app/templates/time_entry_templates/edit.html (line 140)

Fixes #151
2025-10-25 06:53:13 +02:00