29 lines
1.4 KiB
TypeScript
29 lines
1.4 KiB
TypeScript
import { Server } from "@/lib/api";
|
|
|
|
/*
|
|
* The browser's copy of services.ResolveTargets.
|
|
*
|
|
* This is a deliberate duplication: the authority is UnionTargets/MatchesTags in
|
|
* server/internal/services/targets.go, and this exists only so a screen can
|
|
* answer "how many servers?" without a round trip, since the browser already
|
|
* holds the fleet. It must stay identical in MEANING to the Go version and
|
|
* change in the same commit as it.
|
|
*
|
|
* It lives here rather than in a component because it had already been written
|
|
* twice — once in the designer and once, wrongly, on the workflows list, where
|
|
* the count ignored tags entirely and a tag-only workflow reported zero targets.
|
|
*/
|
|
|
|
/** True when srv carries every pair in sel. Tag keys AND together. */
|
|
export function matchesTags(srv: Server, sel: Record<string, string>): boolean {
|
|
// An EMPTY selector matches NOTHING, not everything. The alternative turns a
|
|
// cleared field in the editor into a fleet-wide run.
|
|
if (Object.keys(sel).length === 0) return false;
|
|
return Object.entries(sel).every(([k, v]) => srv.tags?.[k] === v);
|
|
}
|
|
|
|
/** The distinct union of the named servers and the tag matches, in fleet order. */
|
|
export function resolveTargets(servers: Server[], ids: string[], sel: Record<string, string>): Server[] {
|
|
return servers.filter((s) => ids.includes(s.server_id) || matchesTags(s, sel));
|
|
}
|