alerts: per-support-team webhook; printedparts routes low-stock to a chosen team

Support teams gain a webhookurl (migration 7d29 + API + settings-page field), so
a team is a notification target. send_webhook(url=) lets a caller override the
site default with a team's webhook. Printedparts gains a 'alert support team'
setting (printedparts_alert_supportteamid) + selector on its settings page;
low-stock alerts post to that team's webhook, falling back to the site
alert_webhook_url. Email leg unchanged. Same pattern extends to other alerting
plugins (printers low-toner next).
This commit is contained in:
cproudlock
2026-07-22 13:32:00 -04:00
parent 824863a95a
commit fb188fd302
9 changed files with 142 additions and 21 deletions

View File

@@ -76,6 +76,20 @@
</p>
</div>
<div class="form-group">
<label>Alert support team (Teams webhook)</label>
<select v-model="values.printedparts_alert_supportteamid" class="form-control">
<option value="">Site default webhook</option>
<option v-for="team in supportTeams" :key="team.supportteamid" :value="String(team.supportteamid)">
{{ team.teamname }}{{ team.webhookurl ? '' : ' (no webhook set)' }}
</option>
</select>
<p class="field-hint">
Low-stock alerts post to this team's webhook (set on Settings &gt;
Support Teams). Empty uses the site-wide alert webhook.
</p>
</div>
<button class="btn btn-primary" :disabled="saving" @click="save">
{{ saving ? 'Saving...' : 'Save' }}
</button>
@@ -85,7 +99,7 @@
<script setup>
import { ref, onMounted } from 'vue'
import { settingsApi, usersApi } from '@/api'
import { settingsApi, usersApi, supportteamsApi } from '@/api'
const KEYS = [
'printedparts_code_prefix',
@@ -93,7 +107,8 @@ const KEYS = [
'printedparts_unknown_badge',
'printedparts_alert_email',
'printedparts_alert_userids',
'printedparts_alert_roleids'
'printedparts_alert_roleids',
'printedparts_alert_supportteamid'
]
const values = ref({
@@ -102,8 +117,10 @@ const values = ref({
printedparts_unknown_badge: 'deny',
printedparts_alert_email: '',
printedparts_alert_userids: '',
printedparts_alert_roleids: ''
printedparts_alert_roleids: '',
printedparts_alert_supportteamid: ''
})
const supportTeams = ref([])
const users = ref([])
const selectedUserids = ref([])
const roles = ref([])
@@ -130,6 +147,8 @@ onMounted(async () => {
.split(',').map(id => id.trim()).filter(Boolean)
const rolesResponse = await usersApi.roles.list()
roles.value = rolesResponse.data.data || []
const teamsResponse = await supportteamsApi.list()
supportTeams.value = teamsResponse.data.data || []
} catch (loadError) {
error.value = 'Could not load settings'
console.error(loadError)