feat: implement comments and activity panel in workspace
- Added CommentsPanel component for managing comments on documents. - Integrated comment creation, deletion, and resolution functionalities. - Implemented activity tracking for document interactions. - Enhanced SketchPage with editing and saving capabilities. - Introduced template management API endpoints for creating, sharing, and deleting templates. - Added runtime validation report for frontend and backend. - Created GettingStartedPanel for user onboarding with template options. - Implemented Playwright E2E tests for accessibility and export functionality.
This commit is contained in:
parent
6e354ba041
commit
809235e962
41 changed files with 2840 additions and 285 deletions
63
backend/app/routers/templates.py
Normal file
63
backend/app/routers/templates.py
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
from fastapi import APIRouter, Depends, HTTPException, status
|
||||
from motor.motor_asyncio import AsyncIOMotorDatabase
|
||||
|
||||
from app.dependencies import get_current_user, get_mongo_db_dep
|
||||
from app.models.user import User
|
||||
from app.schemas.template import TemplateCreate, TemplateResponse, TemplateShareRequest
|
||||
from app.services.template_service import create_template, delete_template, list_templates, share_template
|
||||
from app.database import get_db
|
||||
from app.services.user_service import get_user_by_email_or_username
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
router = APIRouter(prefix="/templates", tags=["templates"])
|
||||
|
||||
|
||||
@router.get("", response_model=list[TemplateResponse])
|
||||
async def get_templates(
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncIOMotorDatabase = Depends(get_mongo_db_dep),
|
||||
) -> list[TemplateResponse]:
|
||||
templates = await list_templates(db, current_user.id)
|
||||
return [TemplateResponse(**template) for template in templates]
|
||||
|
||||
|
||||
@router.post("", response_model=TemplateResponse, status_code=status.HTTP_201_CREATED)
|
||||
async def post_template(
|
||||
data: TemplateCreate,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncIOMotorDatabase = Depends(get_mongo_db_dep),
|
||||
) -> TemplateResponse:
|
||||
template = await create_template(db, current_user.id, data.model_dump())
|
||||
return TemplateResponse(**template)
|
||||
|
||||
|
||||
@router.delete("/{template_id}", status_code=status.HTTP_204_NO_CONTENT)
|
||||
async def remove_template(
|
||||
template_id: str,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncIOMotorDatabase = Depends(get_mongo_db_dep),
|
||||
) -> None:
|
||||
if not await delete_template(db, template_id, current_user.id):
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Template not found")
|
||||
|
||||
|
||||
@router.post("/{template_id}/share", response_model=TemplateResponse)
|
||||
async def add_template_member(
|
||||
template_id: str,
|
||||
data: TemplateShareRequest,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncIOMotorDatabase = Depends(get_mongo_db_dep),
|
||||
sql: Session = Depends(get_db),
|
||||
) -> TemplateResponse:
|
||||
user = get_user_by_email_or_username(sql, data.email_or_username.strip().lower())
|
||||
if user is None or user.id == current_user.id:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="User not found")
|
||||
template = await share_template(
|
||||
db,
|
||||
template_id,
|
||||
current_user.id,
|
||||
{"user_id": user.id, "name": user.full_name or user.username, "email": user.email},
|
||||
)
|
||||
if template is None:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Only the owner can share this template")
|
||||
return TemplateResponse(**template)
|
||||
Loading…
Add table
Add a link
Reference in a new issue