Fix notifications fleet alert migration for MySQL and add UI fields
- Change alertscope from JSONB to TEXT for MySQL compatibility - Add Alert Fleet checkbox, scope, and timeout fields to notification form - Fields appear conditionally when Alert Fleet is checked
This commit is contained in:
@@ -231,6 +231,34 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div v-if="form.alertfleet" class="fleet-alert-options">
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="alertscope">Alert Scope (JSON)</label>
|
||||||
|
<textarea
|
||||||
|
id="alertscope"
|
||||||
|
v-model="alertScopeText"
|
||||||
|
class="form-control"
|
||||||
|
rows="3"
|
||||||
|
:disabled="isDetail"
|
||||||
|
placeholder='{"assettype": "computer", "location": "Building A"}'
|
||||||
|
></textarea>
|
||||||
|
<small class="form-hint">Optional: Filter alerts by asset type, location, or business unit (JSON format)</small>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group">
|
||||||
|
<label for="alerttimeout">Auto-dismiss Timeout (minutes)</label>
|
||||||
|
<input
|
||||||
|
id="alerttimeout"
|
||||||
|
v-model.number="form.alerttimeout"
|
||||||
|
type="number"
|
||||||
|
class="form-control"
|
||||||
|
min="0"
|
||||||
|
:disabled="isDetail"
|
||||||
|
/>
|
||||||
|
<small class="form-hint">Minutes until auto-dismiss (0 = manual acknowledgment only)</small>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-if="error" class="error-message">{{ error }}</div>
|
<div v-if="error" class="error-message">{{ error }}</div>
|
||||||
|
|
||||||
<div class="form-actions">
|
<div class="form-actions">
|
||||||
@@ -304,6 +332,32 @@ const form = ref({
|
|||||||
// site's wall clock, not the viewer's browser zone. Loaded in onMounted.
|
// site's wall clock, not the viewer's browser zone. Loaded in onMounted.
|
||||||
const siteTimezone = ref(DEFAULT_TZ)
|
const siteTimezone = ref(DEFAULT_TZ)
|
||||||
|
|
||||||
|
// Alert scope as text for editing (converts to/from JSON)
|
||||||
|
const alertScopeText = ref('')
|
||||||
|
|
||||||
|
watch(() => form.value.alertscope, (newVal) => {
|
||||||
|
if (newVal && typeof newVal === 'object') {
|
||||||
|
alertScopeText.value = JSON.stringify(newVal, null, 2)
|
||||||
|
} else if (newVal && typeof newVal === 'string') {
|
||||||
|
alertScopeText.value = newVal
|
||||||
|
} else {
|
||||||
|
alertScopeText.value = ''
|
||||||
|
}
|
||||||
|
}, { immediate: true })
|
||||||
|
|
||||||
|
watch(alertScopeText, (newVal) => {
|
||||||
|
if (!newVal.trim()) {
|
||||||
|
form.value.alertscope = null
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
form.value.alertscope = JSON.parse(newVal)
|
||||||
|
} catch (e) {
|
||||||
|
// Keep the text as-is until it's valid JSON
|
||||||
|
form.value.alertscope = newVal
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
function selectedTypeName() {
|
function selectedTypeName() {
|
||||||
const selectedType = types.value.find(t => t.notificationtypeid === parseInt(form.value.notificationtypeid))
|
const selectedType = types.value.find(t => t.notificationtypeid === parseInt(form.value.notificationtypeid))
|
||||||
return selectedType?.typename?.toLowerCase() || ''
|
return selectedType?.typename?.toLowerCase() || ''
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ to support fleet-wide alert broadcasting. Creates notificationacknowledgements
|
|||||||
table to track which assets have acknowledged fleet alerts.
|
table to track which assets have acknowledged fleet alerts.
|
||||||
|
|
||||||
Fleet alerts can be scoped to specific asset types, locations, or business units
|
Fleet alerts can be scoped to specific asset types, locations, or business units
|
||||||
via the alertscope JSONB field. alerttimeout=0 means no auto-dismiss (manual only).
|
via the alertscope TEXT field (JSON string). alerttimeout=0 means no auto-dismiss (manual only).
|
||||||
|
|
||||||
Idempotent: column and table creation are skipped when they already exist.
|
Idempotent: column and table creation are skipped when they already exist.
|
||||||
|
|
||||||
@@ -14,7 +14,6 @@ Revises: notifications0005boardorder
|
|||||||
"""
|
"""
|
||||||
from alembic import op
|
from alembic import op
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from sqlalchemy.dialects.postgresql import JSONB
|
|
||||||
|
|
||||||
|
|
||||||
revision = 'notifications0006fleetalerts'
|
revision = 'notifications0006fleetalerts'
|
||||||
@@ -43,7 +42,7 @@ def upgrade():
|
|||||||
|
|
||||||
if 'alertscope' not in cols:
|
if 'alertscope' not in cols:
|
||||||
op.add_column('notifications',
|
op.add_column('notifications',
|
||||||
sa.Column('alertscope', JSONB, nullable=True))
|
sa.Column('alertscope', sa.Text, nullable=True))
|
||||||
|
|
||||||
if 'alerttimeout' not in cols:
|
if 'alerttimeout' not in cols:
|
||||||
op.add_column('notifications',
|
op.add_column('notifications',
|
||||||
|
|||||||
Reference in New Issue
Block a user