refactor: consolidate module interval display logic and improve edit form handling
CI / changes (push) Successful in 6s
CI / openapi (push) Has been skipped
CI / go (push) Has been skipped
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, , evobgp-web) (push) Successful in 1m1s
CI / docker-web (deploy/docker/evobgp-web/Dockerfile, evobgp-all, evobgp-web-all) (push) Successful in 1m2s
CI / docker-bird (push) Has been skipped
CI / bird2 (push) Has been skipped
CI / docker-go-prime (push) Has been skipped
CI / docker-go (deploy/docker/evobgp-agent/Dockerfile, , evobgp-agent) (push) Has been skipped
CI / docker-go (evobgp-all, 1, deploy/docker/gobinary/Dockerfile, , evobgp-all) (push) Has been skipped
CI / docker-go (evobgp-api, 1, deploy/docker/gobinary/Dockerfile, , evobgp-api) (push) Has been skipped
CI / docker-go (evobgp-deploy, 0, deploy/docker/gobinary/Dockerfile, , evobgp-deploy) (push) Has been skipped
CI / docker-go (evobgp-ingest, 0, deploy/docker/gobinary/Dockerfile, , evobgp-ingest) (push) Has been skipped
CI / docker-go (evobgp-node, 0, deploy/docker/gobinary/Dockerfile, , evobgp-node) (push) Has been skipped
CI / docker-go (evobgp-render, 0, deploy/docker/gobinary/Dockerfile, , evobgp-render) (push) Has been skipped
CI / docker-go (evobgp-scheduler, 0, deploy/docker/gobinary/Dockerfile, , evobgp-scheduler) (push) Has been skipped

Introduced a new utility function, moduleIntervalLabel, to streamline the display of module interval information across different components. Enhanced the edit form functionality by ensuring proper handling of nullable values for community and DoH profile selections, improving data integrity and user experience during module updates.
This commit is contained in:
Denozordec
2026-04-08 19:33:09 +07:00
parent 05ec176c7a
commit 1f85654653
2 changed files with 41 additions and 8 deletions
+10 -4
View File
@@ -120,6 +120,14 @@
}
}
function moduleIntervalLabel(moduleRow: ModuleRow): string {
const cron = typeof moduleRow.cron_expr === 'string' ? moduleRow.cron_expr.trim() : moduleRow.cron_expr;
if (cron) return cron;
return moduleRow.refresh_interval_sec !== null && moduleRow.refresh_interval_sec !== undefined
? `${moduleRow.refresh_interval_sec}с`
: '—';
}
function toggleModuleSelection(id: string) {
const next = new Set(selectedModuleIds);
if (next.has(id)) next.delete(id);
@@ -237,9 +245,7 @@
</TableCell>
<TableCell class="text-muted-foreground">{m.priority}</TableCell>
<TableCell class="text-muted-foreground font-mono text-xs">
{m.cron_expr ?? (m.refresh_interval_sec !== null && m.refresh_interval_sec !== undefined
? `${m.refresh_interval_sec}с`
: '—')}
{moduleIntervalLabel(m)}
</TableCell>
<TableCell>
{#if m.enabled}
@@ -286,7 +292,7 @@
{moduleTypes.find((t) => t.value === form.type)?.label ?? 'Выберите тип'}
</SelectTrigger>
<SelectContent>
{#each moduleTypes as t}
{#each moduleTypes as t (t.value)}
<SelectItem value={t.value}>{t.label}</SelectItem>
{/each}
</SelectContent>
+31 -4
View File
@@ -146,6 +146,8 @@
// Module edit
let editDialog = $state(false);
let editForm = $state<ModulePatch>({});
let editDefaultCommunitySelect = $state('__none__');
let editDohProfileSelect = $state('__none__');
let editSaving = $state(false);
let deleteModDialog = $state(false);
let deletingMod = $state(false);
@@ -265,13 +267,28 @@
default_community_id: mod.default_community_id,
doh_profile_id: mod.doh_profile_id
};
editDefaultCommunitySelect = nullableSelectValue(mod.default_community_id);
editDohProfileSelect = nullableSelectValue(mod.doh_profile_id);
editDialog = true;
}
async function saveMod() {
editSaving = true;
try {
await apiMutate<ModuleRow>(`/v1/modules/${moduleId}`, 'PATCH', editForm);
const cron = typeof editForm.cron_expr === 'string' ? editForm.cron_expr.trim() : editForm.cron_expr;
const intervalRaw = editForm.refresh_interval_sec;
const interval =
intervalRaw === null || intervalRaw === undefined
? null
: Number(intervalRaw);
const payload: ModulePatch = {
...editForm,
cron_expr: cron ? cron : null,
refresh_interval_sec: Number.isFinite(interval) ? interval : null,
default_community_id: fromNullableSelect(editDefaultCommunitySelect),
doh_profile_id: fromNullableSelect(editDohProfileSelect)
};
await apiMutate<ModuleRow>(`/v1/modules/${moduleId}`, 'PATCH', payload);
await loadMod();
toast.success('Модуль обновлён');
editDialog = false;
@@ -733,6 +750,14 @@
return value;
}
function moduleIntervalLabel(moduleRow: ModuleRow): string {
const cron = typeof moduleRow.cron_expr === 'string' ? moduleRow.cron_expr.trim() : moduleRow.cron_expr;
if (cron) return cron;
return moduleRow.refresh_interval_sec !== null && moduleRow.refresh_interval_sec !== undefined
? `${moduleRow.refresh_interval_sec}с`
: '—';
}
const activeTab = $derived.by(() => {
if (!mod) return 'entries';
switch (mod.type) {
@@ -810,7 +835,7 @@
<Card class="bg-chart-5/10 p-3">
<p class="text-muted-foreground flex items-center gap-1.5 text-xs"><Timer class="size-3.5" />Интервал</p>
<p class="font-semibold font-mono text-sm">
{mod.cron_expr ?? (mod.refresh_interval_sec !== null && mod.refresh_interval_sec !== undefined ? `${mod.refresh_interval_sec}с` : '—')}
{moduleIntervalLabel(mod)}
</p>
</Card>
<Card class="bg-chart-4/10 p-3">
@@ -1281,8 +1306,9 @@
<Label for="e-comm">Community по умолчанию</Label>
<Select
type="single"
value={nullableSelectValue(editForm.default_community_id)}
value={editDefaultCommunitySelect}
onValueChange={(v) => {
editDefaultCommunitySelect = nullableSelectValue(v);
editForm.default_community_id = fromNullableSelect(v);
}}
>
@@ -1301,8 +1327,9 @@
<Label for="e-doh">DoH профиль</Label>
<Select
type="single"
value={nullableSelectValue(editForm.doh_profile_id)}
value={editDohProfileSelect}
onValueChange={(v) => {
editDohProfileSelect = nullableSelectValue(v);
editForm.doh_profile_id = fromNullableSelect(v);
}}
>