feat(web): filter domains by template and status

The domains list had no way to narrow itself down, so an operator with
dozens of zones had to scan the whole table to find the drifted ones.

Add two client-side filters above the table (the full list already
arrives in one request, so server-side filtering would only add contract
surface). The status filter compares against the same derived value the
row's badge renders — a domain with no template shows "без шаблона" and
must not match "drift" just because it kept a stale last_check_status
from before its template was detached, so that derivation lives in one
function used by both.

Sorting is now decided in the store: ListDomains orders by zone_name
instead of created_at, so every consumer of the list gets the same order
and the filters never reorder anything.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018Yr8frsaxBgab1Aa7yfPuU
This commit is contained in:
2026-08-19 19:24:58 +07:00
co-authored by Claude Opus 5
parent 98be357da8
commit caebc06076
5 changed files with 222 additions and 3 deletions
+39
View File
@@ -2,6 +2,7 @@ package store
import (
"context"
"reflect"
"testing"
"github.com/google/uuid"
@@ -506,3 +507,41 @@ func TestImportDomainsOnlyTouchesItsOwnAccount(t *testing.T) {
t.Fatalf("expected both accounts' domains to survive, got %+v", left)
}
}
// TestListDomains_SortedByZoneName pins the list order: domains come back
// alphabetically by zone name, never in creation order. The domains page
// relies on this — its filters reorder nothing, so the store is the single
// place the order is decided.
func TestListDomains_SortedByZoneName(t *testing.T) {
s, ctx := newStore(t)
acc, err := s.Queries().CreateAccount(ctx, db.CreateAccountParams{
ID: uuid.New(), ProjectID: defaultProject, Provider: "selectel", SecretEnc: "enc-blob",
})
if err != nil {
t.Fatal(err)
}
// Inserted in deliberately non-alphabetical order (one import call: a
// per-zone call would prune the previously imported domains), so a query
// still sorting by created_at would return zulu first.
if _, _, err := s.ImportDomains(ctx, defaultProject, acc.ID, []provider.Zone{
{ID: "z1", Name: "zulu.example.com"},
{ID: "z2", Name: "mike.example.com"},
{ID: "z3", Name: "alpha.example.com"},
}); err != nil {
t.Fatal(err)
}
list, err := s.ListDomains(ctx, defaultProject)
if err != nil {
t.Fatal(err)
}
got := make([]string, 0, len(list))
for _, d := range list {
got = append(got, d.ZoneName)
}
want := []string{"alpha.example.com", "mike.example.com", "zulu.example.com"}
if !reflect.DeepEqual(got, want) {
t.Fatalf("expected domains sorted by zone name %v, got %v", want, got)
}
}