diff --git a/plugins/notifications/api/routes.py b/plugins/notifications/api/routes.py index cf9275b..3e30c6b 100644 --- a/plugins/notifications/api/routes.py +++ b/plugins/notifications/api/routes.py @@ -140,6 +140,10 @@ def _apply_expiry_fields(t, data): _DISPLAY_STYLES = ('standard', 'carousel', 'grid', 'banner') +# Ceiling on a type's board position. Wide enough to leave gaps between rows +# (10, 20, 30 ...) so inserting one later needs no renumbering. +_MAX_BOARD_ORDER = 999 + # Ceiling on the per-type post-expiry tail. A day is already far longer than # "recently ended"; anything more is an end time that should have been later. _MAX_GRACE_MINUTES = 1440 @@ -164,6 +168,16 @@ def _apply_display_fields(t, data): # Blank stores as NULL: "no category" is the absence of one, not the # empty-string category that every uncategorised type would share. t.boardcategory = category or None + if 'boardorder' in data: + raw = data.get('boardorder') + raw = 100 if raw in (None, '') else raw + try: + order = int(raw) + except (TypeError, ValueError): + return "boardorder must be a whole number" + if order < 0 or order > _MAX_BOARD_ORDER: + return "boardorder must be between 0 and %d" % _MAX_BOARD_ORDER + t.boardorder = order if 'gracewindowminutes' in data: raw = data.get('gracewindowminutes') raw = 0 if raw in (None, '') else raw @@ -185,11 +199,12 @@ def _config_version(): reach pages that are already open.""" types = NotificationType.query.order_by(NotificationType.notificationtypeid).all() parts = [ - "%s|%s|%s|%d|%d|%s|%s|%s|%d|%d|%s" % ( + "%s|%s|%s|%d|%d|%s|%s|%s|%d|%d|%s|%d" % ( t.notificationtypeid, t.typecolor, t.displaystyle, int(bool(t.splitperemployee)), int(bool(t.showemployeephoto)), t.expirymode, t.expirydays, t.expiryhour, int(bool(t.isactive)), int(t.gracewindowminutes or 0), t.boardcategory or '', + int(t.boardorder if t.boardorder is not None else 100), ) for t in types ] @@ -791,6 +806,7 @@ def get_shopfloor_notifications(): # blank gives the type a row of its own. 'displaystyle': (ntype.displaystyle or 'standard') if ntype else 'standard', 'boardcategory': (ntype.boardcategory or '') if ntype else '', + 'boardorder': int(ntype.boardorder if ntype and ntype.boardorder is not None else 100), } # Employee info (photo only when the type wants it) diff --git a/plugins/notifications/frontend/views/NotificationTypesList.vue b/plugins/notifications/frontend/views/NotificationTypesList.vue index 40e717d..6cde7e3 100644 --- a/plugins/notifications/frontend/views/NotificationTypesList.vue +++ b/plugins/notifications/frontend/views/NotificationTypesList.vue @@ -33,6 +33,7 @@ {{ t.typecolor }} + #{{ t.boardorder ?? 100 }} {{ t.displaystyle || 'standard' }} {{ t.boardcategory }} @@ -90,6 +91,17 @@ + +