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
44
backend/app/schemas/collaboration.py
Normal file
44
backend/app/schemas/collaboration.py
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
from datetime import datetime
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class CommentCreate(BaseModel):
|
||||
body: str = Field(min_length=1, max_length=5000)
|
||||
parent_id: str | None = None
|
||||
|
||||
|
||||
class CommentResponse(BaseModel):
|
||||
id: str
|
||||
document_id: str
|
||||
body: str
|
||||
parent_id: str | None = None
|
||||
author_id: int
|
||||
author_name: str
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
resolved: bool = False
|
||||
|
||||
|
||||
class CommentResolveRequest(BaseModel):
|
||||
resolved: bool
|
||||
|
||||
|
||||
class NotificationResponse(BaseModel):
|
||||
id: str
|
||||
kind: str
|
||||
message: str
|
||||
document_id: str | None = None
|
||||
comment_id: str | None = None
|
||||
actor_name: str
|
||||
read: bool
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class ActivityResponse(BaseModel):
|
||||
id: str
|
||||
document_id: str
|
||||
kind: str
|
||||
message: str
|
||||
actor_name: str
|
||||
created_at: datetime
|
||||
|
|
@ -21,12 +21,15 @@ class DocumentCreate(BaseModel):
|
|||
content: dict[str, Any] = Field(default_factory=dict)
|
||||
template_id: str | None = None
|
||||
stead_id: str | None = None
|
||||
parent_page_id: str | None = None
|
||||
|
||||
|
||||
class DocumentUpdate(BaseModel):
|
||||
title: str | None = None
|
||||
content: dict[str, Any] | None = None
|
||||
starred: bool | None = None
|
||||
stead_id: str | None = None
|
||||
parent_page_id: str | None = None
|
||||
|
||||
|
||||
class ShareRequest(BaseModel):
|
||||
|
|
@ -40,6 +43,7 @@ class DocumentResponse(BaseModel):
|
|||
title: str
|
||||
template_id: str | None = None
|
||||
stead_id: str | None = None
|
||||
parent_page_id: str | None = None
|
||||
content: dict[str, Any]
|
||||
created_by: str
|
||||
created_at: datetime
|
||||
|
|
@ -49,3 +53,13 @@ class DocumentResponse(BaseModel):
|
|||
owner_id: int | None = None
|
||||
visibility: Visibility = "private"
|
||||
members: list[DocumentMember] = Field(default_factory=list)
|
||||
|
||||
|
||||
class DocumentVersionResponse(BaseModel):
|
||||
id: str
|
||||
document_id: str
|
||||
title: str
|
||||
content: dict[str, Any]
|
||||
created_by: str
|
||||
created_at: datetime
|
||||
reason: str
|
||||
|
|
|
|||
24
backend/app/schemas/template.py
Normal file
24
backend/app/schemas/template.py
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
|
||||
class TemplateCreate(BaseModel):
|
||||
name: str = Field(min_length=1, max_length=120)
|
||||
description: str = Field(default="", max_length=500)
|
||||
category: str = Field(default="General", min_length=1, max_length=60)
|
||||
emoji: str = Field(default="📄", max_length=8)
|
||||
content: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class TemplateResponse(TemplateCreate):
|
||||
id: str
|
||||
owner_id: int
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
members: list[dict[str, Any]] = Field(default_factory=list)
|
||||
|
||||
|
||||
class TemplateShareRequest(BaseModel):
|
||||
email_or_username: str
|
||||
|
|
@ -23,6 +23,11 @@ class UserUpdate(BaseModel):
|
|||
occupation: str | None = Field(default=None, max_length=150)
|
||||
|
||||
|
||||
class ChangePasswordRequest(BaseModel):
|
||||
current_password: str = Field(min_length=1, max_length=128)
|
||||
new_password: str = Field(min_length=8, max_length=128)
|
||||
|
||||
|
||||
class UserResponse(UserBase):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue