123 lines
3.9 KiB
Python
123 lines
3.9 KiB
Python
"""Areas: grouping within domains."""
|
|
|
|
from fastapi import APIRouter, Request, Form, Depends
|
|
from fastapi.templating import Jinja2Templates
|
|
from fastapi.responses import RedirectResponse
|
|
from sqlalchemy.ext.asyncio import AsyncSession
|
|
from sqlalchemy import text
|
|
from typing import Optional
|
|
|
|
from core.database import get_db
|
|
from core.base_repository import BaseRepository
|
|
from core.sidebar import get_sidebar_data
|
|
|
|
router = APIRouter(prefix="/areas", tags=["areas"])
|
|
templates = Jinja2Templates(directory="templates")
|
|
|
|
|
|
@router.get("/")
|
|
async def list_areas(
|
|
request: Request,
|
|
domain_id: Optional[str] = None,
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
repo = BaseRepository("areas", db)
|
|
sidebar = await get_sidebar_data(db)
|
|
filters = {}
|
|
if domain_id:
|
|
filters["domain_id"] = domain_id
|
|
|
|
result = await db.execute(text("""
|
|
SELECT a.*, d.name as domain_name, d.color as domain_color
|
|
FROM areas a
|
|
JOIN domains d ON a.domain_id = d.id
|
|
WHERE a.is_deleted = false
|
|
ORDER BY d.sort_order, d.name, a.sort_order, a.name
|
|
"""))
|
|
items = [dict(r._mapping) for r in result]
|
|
if domain_id:
|
|
items = [i for i in items if str(i["domain_id"]) == domain_id]
|
|
|
|
# Get domains for filter/form
|
|
domains_repo = BaseRepository("domains", db)
|
|
domains = await domains_repo.list()
|
|
|
|
return templates.TemplateResponse("areas.html", {
|
|
"request": request, "sidebar": sidebar, "items": items,
|
|
"domains": domains, "current_domain_id": domain_id or "",
|
|
"page_title": "Areas", "active_nav": "areas",
|
|
})
|
|
|
|
|
|
@router.get("/create")
|
|
async def create_form(
|
|
request: Request,
|
|
domain_id: Optional[str] = None,
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
sidebar = await get_sidebar_data(db)
|
|
domains_repo = BaseRepository("domains", db)
|
|
domains = await domains_repo.list()
|
|
return templates.TemplateResponse("area_form.html", {
|
|
"request": request, "sidebar": sidebar, "domains": domains,
|
|
"page_title": "New Area", "active_nav": "areas",
|
|
"item": None, "prefill_domain_id": domain_id or "",
|
|
})
|
|
|
|
|
|
@router.post("/create")
|
|
async def create_area(
|
|
request: Request,
|
|
name: str = Form(...),
|
|
domain_id: str = Form(...),
|
|
description: Optional[str] = Form(None),
|
|
status: str = Form("active"),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
repo = BaseRepository("areas", db)
|
|
await repo.create({
|
|
"name": name, "domain_id": domain_id,
|
|
"description": description, "status": status,
|
|
})
|
|
return RedirectResponse(url="/areas", status_code=303)
|
|
|
|
|
|
@router.get("/{area_id}/edit")
|
|
async def edit_form(area_id: str, request: Request, db: AsyncSession = Depends(get_db)):
|
|
repo = BaseRepository("areas", db)
|
|
sidebar = await get_sidebar_data(db)
|
|
item = await repo.get(area_id)
|
|
if not item:
|
|
return RedirectResponse(url="/areas", status_code=303)
|
|
domains_repo = BaseRepository("domains", db)
|
|
domains = await domains_repo.list()
|
|
return templates.TemplateResponse("area_form.html", {
|
|
"request": request, "sidebar": sidebar, "domains": domains,
|
|
"page_title": f"Edit {item['name']}", "active_nav": "areas",
|
|
"item": item, "prefill_domain_id": "",
|
|
})
|
|
|
|
|
|
@router.post("/{area_id}/edit")
|
|
async def update_area(
|
|
area_id: str,
|
|
name: str = Form(...),
|
|
domain_id: str = Form(...),
|
|
description: Optional[str] = Form(None),
|
|
status: str = Form("active"),
|
|
db: AsyncSession = Depends(get_db),
|
|
):
|
|
repo = BaseRepository("areas", db)
|
|
await repo.update(area_id, {
|
|
"name": name, "domain_id": domain_id,
|
|
"description": description, "status": status,
|
|
})
|
|
return RedirectResponse(url="/areas", status_code=303)
|
|
|
|
|
|
@router.post("/{area_id}/delete")
|
|
async def delete_area(area_id: str, db: AsyncSession = Depends(get_db)):
|
|
repo = BaseRepository("areas", db)
|
|
await repo.soft_delete(area_id)
|
|
return RedirectResponse(url="/areas", status_code=303)
|