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:
@@ -23,7 +23,7 @@ from app.core.database import Base
|
||||
|
||||
# Import all models to register them with Base.metadata
|
||||
from app.modules.auth.models import UserSession, User
|
||||
from app.modules.chat_room.models import IncidentRoom, RoomMember, RoomTemplate
|
||||
from app.modules.chat_room.models import IncidentRoom, RoomMember
|
||||
from app.modules.realtime.models import Message, MessageReaction, MessageEditHistory
|
||||
from app.modules.file_storage.models import RoomFile
|
||||
from app.modules.report_generation.models import GeneratedReport
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
"""add_mentions_field_to_messages
|
||||
|
||||
Revision ID: 4c5eb6e941db
|
||||
Revises: 7e6983a72e7b
|
||||
Create Date: 2025-12-08 07:44:11.115314
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '4c5eb6e941db'
|
||||
down_revision: Union[str, None] = '7e6983a72e7b'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.add_column('tr_messages', sa.Column('mentions', sa.JSON(), nullable=True))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('tr_messages', 'mentions')
|
||||
# ### end Alembic commands ###
|
||||
@@ -0,0 +1,46 @@
|
||||
"""remove templates add lots field
|
||||
|
||||
Revision ID: 7e6983a72e7b
|
||||
Revises: ea3798f776f4
|
||||
Create Date: 2025-12-07 14:53:33.722821
|
||||
|
||||
"""
|
||||
from typing import Sequence, Union
|
||||
|
||||
from alembic import op
|
||||
import sqlalchemy as sa
|
||||
from sqlalchemy.dialects import mysql
|
||||
|
||||
# revision identifiers, used by Alembic.
|
||||
revision: str = '7e6983a72e7b'
|
||||
down_revision: Union[str, None] = 'ea3798f776f4'
|
||||
branch_labels: Union[str, Sequence[str], None] = None
|
||||
depends_on: Union[str, Sequence[str], None] = None
|
||||
|
||||
|
||||
def upgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_index('name', table_name='tr_room_templates')
|
||||
op.drop_table('tr_room_templates')
|
||||
op.add_column('tr_incident_rooms', sa.Column('lots', sa.JSON(), nullable=False, comment='LOT batch numbers (JSON array)'))
|
||||
# ### end Alembic commands ###
|
||||
|
||||
|
||||
def downgrade() -> None:
|
||||
# ### commands auto generated by Alembic - please adjust! ###
|
||||
op.drop_column('tr_incident_rooms', 'lots')
|
||||
op.create_table('tr_room_templates',
|
||||
sa.Column('template_id', mysql.INTEGER(), autoincrement=True, nullable=False),
|
||||
sa.Column('name', mysql.VARCHAR(length=100), nullable=False),
|
||||
sa.Column('description', mysql.TEXT(), nullable=True),
|
||||
sa.Column('incident_type', mysql.ENUM('EQUIPMENT_FAILURE', 'MATERIAL_SHORTAGE', 'QUALITY_ISSUE', 'OTHER'), nullable=False),
|
||||
sa.Column('default_severity', mysql.ENUM('LOW', 'MEDIUM', 'HIGH', 'CRITICAL'), nullable=False),
|
||||
sa.Column('default_members', mysql.TEXT(), nullable=True),
|
||||
sa.Column('metadata_fields', mysql.TEXT(), nullable=True),
|
||||
sa.PrimaryKeyConstraint('template_id'),
|
||||
mysql_collate='utf8mb4_0900_ai_ci',
|
||||
mysql_default_charset='utf8mb4',
|
||||
mysql_engine='InnoDB'
|
||||
)
|
||||
op.create_index('name', 'tr_room_templates', ['name'], unique=True)
|
||||
# ### end Alembic commands ###
|
||||
Reference in New Issue
Block a user