feat: implement workspace management and member invitations
- Added tenant API for managing workspaces, including listing, creating, and inviting members. - Introduced new models for organizations, workspaces, and workspace memberships in the backend. - Created frontend components for workspace administration, allowing users to manage workspaces and invite members. - Updated document listing to support workspace-specific filtering. - Implemented account settings page for user profile management and password changes. - Added end-to-end tests for workspace administration and dashboard functionalities.
This commit is contained in:
parent
809235e962
commit
bf5cd44dc1
20 changed files with 928 additions and 27 deletions
|
|
@ -2,8 +2,9 @@ from fastapi import APIRouter, Depends, HTTPException, Query, Response, status
|
|||
from motor.motor_asyncio import AsyncIOMotorDatabase
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.database import get_db
|
||||
from app.dependencies import get_current_user, get_mongo_db_dep
|
||||
from app.database import get_db
|
||||
from app.services.tenant_service import get_workspace
|
||||
from app.models.user import User
|
||||
from app.schemas.document import DocumentCreate, DocumentResponse, DocumentUpdate, DocumentVersionResponse, ShareRequest
|
||||
from app.schemas.collaboration import (
|
||||
|
|
@ -199,10 +200,19 @@ async def list_docs(
|
|||
stead_id: str | None = Query(None, description="Filter by parent stead"),
|
||||
parent_page_id: str | None = Query(None, description="Filter by parent page"),
|
||||
starred: bool | None = Query(None, description="Filter starred projects"),
|
||||
workspace_id: int | None = Query(None, description="Filter by workspace"),
|
||||
sort: str = Query("updated_at", description="Sort field: updated_at or last_visited_at"),
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncIOMotorDatabase = Depends(get_mongo_db_dep),
|
||||
auth_db: Session = Depends(get_db),
|
||||
) -> list[DocumentResponse]:
|
||||
if workspace_id is not None:
|
||||
if get_workspace(auth_db, workspace_id, current_user.id) is None:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Workspace access denied")
|
||||
await db["documents"].update_many(
|
||||
{"owner_id": current_user.id, "workspace_id": {"$exists": False}},
|
||||
{"$set": {"workspace_id": workspace_id}},
|
||||
)
|
||||
sort_field = "last_visited_at" if sort == "last_visited_at" else "updated_at"
|
||||
docs = await list_documents(
|
||||
db,
|
||||
|
|
@ -212,6 +222,7 @@ async def list_docs(
|
|||
parent_page_id=parent_page_id,
|
||||
starred=starred,
|
||||
sort=sort_field,
|
||||
workspace_id=workspace_id,
|
||||
)
|
||||
return [DocumentResponse(**doc) for doc in docs]
|
||||
|
||||
|
|
@ -243,7 +254,10 @@ async def create_doc(
|
|||
data: DocumentCreate,
|
||||
current_user: User = Depends(get_current_user),
|
||||
db: AsyncIOMotorDatabase = Depends(get_mongo_db_dep),
|
||||
auth_db: Session = Depends(get_db),
|
||||
) -> DocumentResponse:
|
||||
if data.workspace_id is not None and get_workspace(auth_db, data.workspace_id, current_user.id) is None:
|
||||
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Workspace access denied")
|
||||
created_by = current_user.full_name or current_user.username
|
||||
try:
|
||||
doc = await create_document(db, current_user.id, created_by, data)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue