feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
|
|
|
"""
|
|
|
|
|
Frontend Views Router for Time Tracking Module
|
|
|
|
|
===============================================
|
|
|
|
|
|
|
|
|
|
HTML page handlers for time tracking UI.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
import logging
|
|
|
|
|
import os
|
|
|
|
|
from pathlib import Path
|
|
|
|
|
from fastapi import APIRouter, Request
|
|
|
|
|
from fastapi.responses import HTMLResponse, FileResponse
|
|
|
|
|
|
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
|
|
|
|
# Path to templates - use absolute path from environment
|
|
|
|
|
BASE_DIR = Path(os.getenv("APP_ROOT", "/app"))
|
|
|
|
|
TEMPLATE_DIR = BASE_DIR / "app" / "timetracking" / "frontend"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/timetracking", response_class=HTMLResponse, name="timetracking_dashboard")
|
|
|
|
|
async def timetracking_dashboard(request: Request):
|
|
|
|
|
"""Time Tracking Dashboard - oversigt og sync"""
|
|
|
|
|
template_path = TEMPLATE_DIR / "dashboard.html"
|
|
|
|
|
logger.info(f"Serving dashboard from: {template_path}")
|
|
|
|
|
|
|
|
|
|
# Force no-cache headers to prevent browser caching
|
|
|
|
|
response = FileResponse(template_path)
|
|
|
|
|
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate, max-age=0"
|
|
|
|
|
response.headers["Pragma"] = "no-cache"
|
|
|
|
|
response.headers["Expires"] = "0"
|
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@router.get("/timetracking/wizard", response_class=HTMLResponse, name="timetracking_wizard")
|
|
|
|
|
async def timetracking_wizard(request: Request):
|
|
|
|
|
"""Time Tracking Wizard - step-by-step approval"""
|
|
|
|
|
template_path = TEMPLATE_DIR / "wizard.html"
|
|
|
|
|
logger.info(f"Serving wizard from: {template_path}")
|
|
|
|
|
|
|
|
|
|
# Force no-cache headers
|
|
|
|
|
response = FileResponse(template_path)
|
|
|
|
|
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate, max-age=0"
|
|
|
|
|
response.headers["Pragma"] = "no-cache"
|
|
|
|
|
response.headers["Expires"] = "0"
|
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
|
|
2025-12-10 18:29:13 +01:00
|
|
|
@router.get("/timetracking/customers", response_class=HTMLResponse, name="timetracking_customers")
|
|
|
|
|
async def timetracking_customers(request: Request):
|
|
|
|
|
"""Time Tracking Customers - manage hourly rates"""
|
|
|
|
|
template_path = TEMPLATE_DIR / "customers.html"
|
|
|
|
|
logger.info(f"Serving customers page from: {template_path}")
|
|
|
|
|
|
|
|
|
|
# Force no-cache headers
|
|
|
|
|
response = FileResponse(template_path)
|
|
|
|
|
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate, max-age=0"
|
|
|
|
|
response.headers["Pragma"] = "no-cache"
|
|
|
|
|
response.headers["Expires"] = "0"
|
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
|
|
feat(timetracking): Implement time tracking module with frontend views, HTML templates, and database migrations
- Added FastAPI router for time tracking views including dashboard, wizard, and orders.
- Created HTML templates for the time tracking wizard with responsive design and Bootstrap integration.
- Developed SQL migration script for the time tracking module, including tables for customers, cases, time entries, orders, and audit logs.
- Introduced a script to list all registered routes, focusing on time tracking routes.
- Added test script to verify route registration and specifically check for time tracking routes.
2025-12-09 22:46:30 +01:00
|
|
|
@router.get("/timetracking/orders", response_class=HTMLResponse, name="timetracking_orders")
|
|
|
|
|
async def timetracking_orders(request: Request):
|
|
|
|
|
"""Order oversigt"""
|
|
|
|
|
template_path = TEMPLATE_DIR / "orders.html"
|
|
|
|
|
logger.info(f"Serving orders from: {template_path}")
|
|
|
|
|
|
|
|
|
|
# Force no-cache headers
|
|
|
|
|
response = FileResponse(template_path)
|
|
|
|
|
response.headers["Cache-Control"] = "no-cache, no-store, must-revalidate, max-age=0"
|
|
|
|
|
response.headers["Pragma"] = "no-cache"
|
|
|
|
|
response.headers["Expires"] = "0"
|
|
|
|
|
return response
|