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 }}