feat: deferred dispatch, release-check provider, settings polish
- Defer quiet-hours dispatches into new deferred_dispatch table; drain job + periodic catch-up scan re-fire at window end with coalescing on (link, event_type, collection_id). - Add ON DELETE SET NULL migration on event_log_id and partial unique index on (link_id, collection_id, event_type) WHERE status='pending'. - Add release-check provider abstraction (Gitea/GitHub) with SSRF-safe URL validation, settings UI cassette, and scheduled polling. - Replace importlib-only version lookup with version.py helper that prefers the higher of installed metadata vs source pyproject so stale editable dev installs stop misreporting. - Aurora frontend polish: MetaStrip component, ReleaseCassette, EventDetailModal expansion, and i18n additions.
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
import EmptyState from '$lib/components/EmptyState.svelte';
|
||||
import ConfirmModal from '$lib/components/ConfirmModal.svelte';
|
||||
import IconButton from '$lib/components/IconButton.svelte';
|
||||
import MetaStrip, { type MetaTile } from '$lib/components/MetaStrip.svelte';
|
||||
import { chatActionItems } from '$lib/grid-items';
|
||||
import { snackSuccess, snackError } from '$lib/stores/snackbar.svelte';
|
||||
import { highlightFromUrl } from '$lib/highlight';
|
||||
@@ -94,6 +95,53 @@
|
||||
label: tt.charAt(0).toUpperCase() + tt.slice(1),
|
||||
})));
|
||||
|
||||
function targetTiles(target: NotificationTarget): MetaTile[] {
|
||||
const tiles: MetaTile[] = [];
|
||||
// Type tile — useful when the "all types" filter is active and rows
|
||||
// from multiple types appear side-by-side. The receivers count is
|
||||
// already shown inside the `target-summary` button, so we don't repeat
|
||||
// it as a tile.
|
||||
tiles.push({
|
||||
icon: TYPE_ICONS[target.type] || 'mdiTarget',
|
||||
label: target.type,
|
||||
tone: 'lavender',
|
||||
mono: true,
|
||||
});
|
||||
const botName = getBotName(target);
|
||||
if (botName) {
|
||||
tiles.push({
|
||||
icon: 'mdiRobot',
|
||||
label: botName,
|
||||
tone: 'sky',
|
||||
});
|
||||
}
|
||||
// Telegram targets expose a chat label in config — surface it so the
|
||||
// row reads "Telegram · @bot · Family chat" without expanding.
|
||||
const cfg = (target.config || {}) as Record<string, any>;
|
||||
if (target.type === 'telegram' && cfg.chat_id) {
|
||||
tiles.push({
|
||||
icon: 'mdiChat',
|
||||
label: String(cfg.chat_id),
|
||||
tone: 'orchid',
|
||||
mono: true,
|
||||
});
|
||||
}
|
||||
// Webhook target — show host
|
||||
if (target.type === 'webhook' && cfg.url) {
|
||||
let host = String(cfg.url);
|
||||
try { host = new URL(host).host; } catch { /* keep raw */ }
|
||||
tiles.push({
|
||||
icon: 'mdiLinkVariant',
|
||||
label: host,
|
||||
hint: String(cfg.url),
|
||||
href: String(cfg.url),
|
||||
tone: 'orchid',
|
||||
mono: true,
|
||||
});
|
||||
}
|
||||
return tiles;
|
||||
}
|
||||
|
||||
// ── Derived state ──
|
||||
|
||||
let allTargets = $derived(targetsCache.items);
|
||||
@@ -660,7 +708,7 @@
|
||||
{@const childLabel = target.type === 'broadcast' ? t('targets.childTargets') : t('targets.receivers')}
|
||||
<Card hover entityId={target.id}>
|
||||
<!-- Target header (clickable to toggle receiver visibility) -->
|
||||
<div class="flex items-center justify-between gap-2">
|
||||
<div class="flex items-center gap-2">
|
||||
<button
|
||||
type="button"
|
||||
class="target-summary"
|
||||
@@ -682,6 +730,7 @@
|
||||
<span class="target-summary__count target-summary__count--empty">{t('targets.noReceivers')}</span>
|
||||
{/if}
|
||||
</button>
|
||||
<MetaStrip tiles={targetTiles(target)} />
|
||||
<div class="flex items-center gap-1 shrink-0">
|
||||
<IconButton icon="mdiPencil" title={t('common.edit')} onclick={() => edit(target)} />
|
||||
<IconButton icon="mdiSend" title={t('targets.test')} onclick={() => test(target.id)} />
|
||||
@@ -765,7 +814,7 @@
|
||||
}
|
||||
|
||||
.target-summary {
|
||||
flex: 1;
|
||||
flex: 1 1 auto;
|
||||
min-width: 0;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -780,6 +829,12 @@
|
||||
border-radius: 8px;
|
||||
transition: background 0.15s ease;
|
||||
}
|
||||
@media (min-width: 1024px) {
|
||||
.target-summary {
|
||||
flex: 0 1 auto;
|
||||
max-width: 32rem;
|
||||
}
|
||||
}
|
||||
.target-summary:hover {
|
||||
background: var(--color-glass-strong);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user