Per-type board rows with shared categories, a network device IP field, and two dark-mode dialogs

This commit is contained in:
2026-08-07 10:43:32 -04:00
parent bcf7a009f8
commit 7c5b1bc74e
12 changed files with 1154 additions and 829 deletions

View File

@@ -0,0 +1,47 @@
"""Add notificationtypes.boardcategory (shared heading on the shopfloor board).
The board grouped cards by display style alone, so every type set to grid landed
inside the Recertification row and every carousel type inside Recognition's,
under a heading that named someone else's type. Each type now gets a row of its
own; this column is the opt-in for the other direction - several types that
belong together (Change, Awareness, Incident) share one row under a category
name instead of taking three.
Idempotent; downgrade drops the column.
Revision ID: notifications0004category
Revises: notifications0003grace
"""
from alembic import op
import sqlalchemy as sa
revision = 'notifications0004category'
down_revision = 'notifications0003grace'
branch_labels = None
depends_on = None
_TABLE = 'notificationtypes'
_COLUMN = 'boardcategory'
def _column_names(insp, table):
return {c['name'] for c in insp.get_columns(table)}
def upgrade():
bind = op.get_bind()
insp = sa.inspect(bind)
if _TABLE not in insp.get_table_names():
return
if _COLUMN not in _column_names(insp, _TABLE):
op.add_column(_TABLE, sa.Column(_COLUMN, sa.String(50), nullable=True))
def downgrade():
bind = op.get_bind()
insp = sa.inspect(bind)
if _TABLE not in insp.get_table_names():
return
if _COLUMN in _column_names(insp, _TABLE):
op.drop_column(_TABLE, _COLUMN)