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:
egg
2025-12-08 08:20:37 +08:00
parent 92834dbe0e
commit 599802b818
72 changed files with 6810 additions and 702 deletions

View File

@@ -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 ###

View File

@@ -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 ###