feat: Add Chat UX improvements with notifications and @mention support
- Add ActionBar component with expandable toolbar for mobile - Add @mention functionality with autocomplete dropdown - Add browser notification system (push, sound, vibration) - Add NotificationSettings modal for user preferences - Add mention badges on room list cards - Add ReportPreview with Markdown rendering and copy/download - Add message copy functionality with hover actions - Add backend mentions field to messages with Alembic migration - Add lots field to rooms, remove templates - Optimize WebSocket database session handling - Various UX polish (animations, accessibility) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -13,7 +13,6 @@ from app.modules.chat_room import schemas
|
||||
from app.modules.chat_room.models import MemberRole, RoomStatus
|
||||
from app.modules.chat_room.services.room_service import room_service
|
||||
from app.modules.chat_room.services.membership_service import membership_service
|
||||
from app.modules.chat_room.services.template_service import template_service
|
||||
from app.modules.chat_room.dependencies import (
|
||||
get_current_room,
|
||||
require_room_permission,
|
||||
@@ -36,25 +35,7 @@ async def create_room(
|
||||
"""Create a new incident room"""
|
||||
user_email = current_user["username"]
|
||||
|
||||
# Check if using template
|
||||
if room_data.template:
|
||||
template = template_service.get_template_by_name(db, room_data.template)
|
||||
if template:
|
||||
room = template_service.create_room_from_template(
|
||||
db,
|
||||
template.template_id,
|
||||
user_email,
|
||||
room_data.title,
|
||||
room_data.location,
|
||||
room_data.description
|
||||
)
|
||||
else:
|
||||
raise HTTPException(
|
||||
status_code=status.HTTP_400_BAD_REQUEST,
|
||||
detail=f"Template '{room_data.template}' not found"
|
||||
)
|
||||
else:
|
||||
room = room_service.create_room(db, user_email, room_data)
|
||||
room = room_service.create_room(db, user_email, room_data)
|
||||
|
||||
# Get user role for response
|
||||
role = membership_service.get_user_role_in_room(db, room.room_id, user_email)
|
||||
@@ -508,12 +489,56 @@ async def get_user_permissions(
|
||||
return permissions[role]
|
||||
|
||||
|
||||
# Template Endpoints
|
||||
@router.get("/templates", response_model=List[schemas.TemplateResponse])
|
||||
async def list_templates(
|
||||
db: Session = Depends(get_db),
|
||||
_: dict = Depends(get_current_user)
|
||||
# LOT Endpoints
|
||||
@router.post("/{room_id}/lots", response_model=List[str])
|
||||
async def add_lot(
|
||||
room_id: str,
|
||||
request: schemas.AddLotRequest,
|
||||
_: None = Depends(require_room_permission("update_metadata")),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""List available room templates"""
|
||||
templates = template_service.get_templates(db)
|
||||
return [schemas.TemplateResponse.from_orm(t) for t in templates]
|
||||
"""Add a LOT batch number to the room"""
|
||||
from app.modules.chat_room.models import IncidentRoom
|
||||
|
||||
room = db.query(IncidentRoom).filter(IncidentRoom.room_id == room_id).first()
|
||||
if not room:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Room not found")
|
||||
|
||||
# Get current lots or initialize empty list
|
||||
current_lots = room.lots or []
|
||||
|
||||
# Prevent duplicates
|
||||
if request.lot not in current_lots:
|
||||
current_lots.append(request.lot)
|
||||
room.lots = current_lots
|
||||
room.last_updated_at = datetime.utcnow()
|
||||
db.commit()
|
||||
db.refresh(room)
|
||||
|
||||
return room.lots
|
||||
|
||||
|
||||
@router.delete("/{room_id}/lots/{lot}", response_model=List[str])
|
||||
async def remove_lot(
|
||||
room_id: str,
|
||||
lot: str,
|
||||
_: None = Depends(require_room_permission("update_metadata")),
|
||||
db: Session = Depends(get_db)
|
||||
):
|
||||
"""Remove a LOT batch number from the room"""
|
||||
from app.modules.chat_room.models import IncidentRoom
|
||||
|
||||
room = db.query(IncidentRoom).filter(IncidentRoom.room_id == room_id).first()
|
||||
if not room:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Room not found")
|
||||
|
||||
current_lots = room.lots or []
|
||||
|
||||
if lot in current_lots:
|
||||
current_lots.remove(lot)
|
||||
room.lots = current_lots
|
||||
room.last_updated_at = datetime.utcnow()
|
||||
db.commit()
|
||||
db.refresh(room)
|
||||
|
||||
return room.lots
|
||||
Reference in New Issue
Block a user