Let an end time mean the card leaves the board
The shopfloor feed kept every ended notification up for a hardcoded 30 minutes, flagged resolved. A card with an 8:00 end time was still on the board at 8:29, which reads as an expiry that did not work - and in the carousel, grid and banner sections it read that way with no visual sign at all, since only the standard cards render the resolved state. The tail is now notificationtypes.gracewindowminutes, set per type on the Notification Types page and defaulting to 0, so an end time means what it says. A type whose cards are worth acknowledging after they clear - an incident, say - opts into a tail, and only that type's cards get one. The feed widens its query to the largest configured tail and then holds each row to its own type's window. That keeps one portable query rather than a per-type interval expression in SQL, and with every type at 0 it collapses to "still showing". Also fixes resolved serializing as null rather than false for a card with no end time, which the and-chain produced.
This commit is contained in:
@@ -87,6 +87,18 @@
|
||||
</select>
|
||||
</label>
|
||||
|
||||
<label class="field">
|
||||
<span>Keep showing after end (minutes)</span>
|
||||
<input v-model.number="form.gracewindowminutes" type="number"
|
||||
min="0" max="1440" step="5" />
|
||||
<small class="muted">
|
||||
0 means a card leaves the shopfloor board the moment its end time
|
||||
passes. A higher number keeps it up that long afterwards, marked
|
||||
RESOLVED - useful for an incident worth acknowledging once it
|
||||
clears.
|
||||
</small>
|
||||
</label>
|
||||
|
||||
<label class="field checkbox">
|
||||
<input v-model="form.splitperemployee" type="checkbox" />
|
||||
<span>Split one card per employee</span>
|
||||
@@ -170,9 +182,12 @@ function swatchColor(c) {
|
||||
}
|
||||
|
||||
function expiryLabel(t) {
|
||||
if (t.expirymode === 'duration' && t.expirydays) return `${t.expirydays} day(s)`
|
||||
if (t.expirymode === 'dailytime') return `daily @ ${String(t.expiryhour ?? 8).padStart(2, '0')}:00 ET`
|
||||
return 'none'
|
||||
const grace = t.gracewindowminutes ?? 0
|
||||
// The tail only means something next to the rule that ends the card.
|
||||
const tail = grace > 0 ? ` (+${grace}m resolved)` : ''
|
||||
if (t.expirymode === 'duration' && t.expirydays) return `${t.expirydays} day(s)${tail}`
|
||||
if (t.expirymode === 'dailytime') return `daily @ ${String(t.expiryhour ?? 8).padStart(2, '0')}:00 ET${tail}`
|
||||
return grace > 0 ? `none${tail}` : 'none'
|
||||
}
|
||||
|
||||
async function load() {
|
||||
@@ -199,6 +214,7 @@ function openNew() {
|
||||
expirymode: 'none',
|
||||
expirydays: null,
|
||||
expiryhour: null,
|
||||
gracewindowminutes: 0,
|
||||
isactive: true
|
||||
}
|
||||
editing.value = true
|
||||
@@ -217,6 +233,7 @@ function openEdit(t) {
|
||||
expirymode: t.expirymode || 'none',
|
||||
expirydays: t.expirydays ?? null,
|
||||
expiryhour: t.expiryhour ?? null,
|
||||
gracewindowminutes: t.gracewindowminutes ?? 0,
|
||||
isactive: t.isactive !== false
|
||||
}
|
||||
editing.value = true
|
||||
|
||||
Reference in New Issue
Block a user