feat(trackers): user filters for Gitea, webhook polling cleanup, dashboard navigability

- Gitea: NotificationTracker now exposes sender allowlist / blocklist filters
  via MultiEntitySelect, populated from Gitea /users/search merged with past
  EventLog senders so the picker is useful before the first webhook arrives.
- Webhook providers (gitea, planka, webhook): stop scheduling interval polling
  jobs on tracker create/update/startup; hide the "every Xs" indicator in the
  tracker list since there is no polling.
- Dashboard: stat cards are now <a> links that route to providers, trackers,
  targets, command-trackers, or scroll to the events panel. Provider deck
  rows highlight the target provider on click.
- Command trackers / command configs: auto-reselect the right config when the
  provider type changes (matches notification-tracker behavior).
- Migration: drop legacy batch_duration column from notification_tracker —
  the field is gone from the model but its NOT NULL constraint blocked
  inserts on older DBs.
- Docs: refresh entity-relationships.md with current NotificationTracker
  fields (filters, adaptive_max_skip, default_*_config_id).
This commit is contained in:
2026-04-27 15:24:44 +03:00
parent c43dc598a1
commit 42af7a6551
14 changed files with 321 additions and 19 deletions
@@ -113,6 +113,26 @@
editing = null;
showForm = true;
}
// Re-pick the command config when the provider changes. The previously
// selected id may belong to a different provider type and would no longer
// appear in the filtered EntitySelect, leaving the selector empty.
let _prevProviderId = $state(0);
$effect(() => {
if (showForm && form.provider_id && form.provider_id !== _prevProviderId) {
_prevProviderId = form.provider_id;
if (editing === null) {
const ptype = providers.find(p => p.id === form.provider_id)?.type || '';
if (ptype) {
const currentCfg = commandConfigs.find(c => c.id === form.command_config_id);
if (!currentCfg || currentCfg.provider_type !== ptype) {
const first = commandConfigs.find(c => c.provider_type === ptype);
form.command_config_id = first?.id ?? 0;
}
}
}
}
});
function editTracker(trk: any) {
form = {
name: trk.name,