Rows ran in display-style order and then alphabetically, so what led the screen was an accident of styling and the alphabet - a new type called Awareness landed above Recertification for no better reason than the letter A. Each type now carries a board position, lowest first, set on the Notification Types page. The migration seeds Recognition at 10 and Recertification at 20 and leaves everything else at 100, so an existing board keeps the order sites already expect. Steps of ten leave room to slot a row in without renumbering the rest. A row shared by several types sits wherever its earliest-ordered type puts it, so a category moves as a unit.
62 lines
2.0 KiB
Python
62 lines
2.0 KiB
Python
"""Add notificationtypes.boardorder (row order on the shopfloor board).
|
|
|
|
Rows were ordered by display style and then type name, so what led the screen
|
|
was an accident of styling and the alphabet. A site decides its own running
|
|
order now: low first, and rows sharing a category sort by the lowest order
|
|
among their types.
|
|
|
|
Existing rows default to 100. Recognition and Recertification are seeded ahead
|
|
of that (10 and 20) so the out-of-the-box board keeps the order sites already
|
|
expect, without pinning anything a site has since renamed.
|
|
|
|
Idempotent; downgrade drops the column.
|
|
|
|
Revision ID: notifications0005boardorder
|
|
Revises: notifications0004category
|
|
"""
|
|
from alembic import op
|
|
import sqlalchemy as sa
|
|
|
|
|
|
revision = 'notifications0005boardorder'
|
|
down_revision = 'notifications0004category'
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
_TABLE = 'notificationtypes'
|
|
_COLUMN = 'boardorder'
|
|
|
|
# Only the two types every site starts with; anything else keeps the default.
|
|
_SEEDED_ORDER = (('Recognition', 10), ('Recertification', 20))
|
|
|
|
|
|
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 in _column_names(insp, _TABLE):
|
|
return
|
|
op.add_column(_TABLE, sa.Column(_COLUMN, sa.Integer(), nullable=False,
|
|
server_default='100'))
|
|
# Seed the shipped types' order. Guarded on the default so a site that has
|
|
# already set an order (re-running after a manual add) is left alone.
|
|
for typename, order in _SEEDED_ORDER:
|
|
bind.execute(
|
|
sa.text('UPDATE notificationtypes SET boardorder = :order '
|
|
'WHERE typename = :typename AND boardorder = 100'),
|
|
{'order': order, 'typename': typename})
|
|
|
|
|
|
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)
|