milestone 32: task-shaped configuration, file mode as a rendering, config status api
Gates / frontend (push) Successful in 1m22s
Gates / test (push) Successful in 1m54s
Gates / test-aarch64 (push) Successful in 7m57s
Gates / package (push) Successful in 5m29s
Gates / container (push) Successful in 10s
CI / gates (push) Successful in 32m51s
Gates / frontend (push) Successful in 1m22s
Gates / test (push) Successful in 1m54s
Gates / test-aarch64 (push) Successful in 7m57s
Gates / package (push) Successful in 5m29s
Gates / container (push) Successful in 10s
CI / gates (push) Successful in 32m51s
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
/**
|
||||
* How a client says who it is, shared by the list and the detail page.
|
||||
*
|
||||
* The learned marker lives here and nowhere else. A client is named once on
|
||||
* each of these two pages, so the tag is information; the query tables render
|
||||
* the same muted name through `ClientName` without it, because repeating the
|
||||
* tag down every row of a log is noise.
|
||||
*/
|
||||
|
||||
import * as stylex from "@stylexjs/stylex";
|
||||
import type { Client } from "@/lib/types";
|
||||
import type { Authority } from "@/features/configuration/authority";
|
||||
import { styles as shared } from "@/ui/styles";
|
||||
import { colors } from "@/ui/tokens.stylex";
|
||||
|
||||
const styles = stylex.create({
|
||||
unnamed: {
|
||||
color: colors.textMuted,
|
||||
},
|
||||
});
|
||||
|
||||
export function ClientDisplayName({ client }: { client: Client }) {
|
||||
if (client.name !== "") return <>{client.name}</>;
|
||||
if (client.learned_name !== "") {
|
||||
return (
|
||||
<span {...stylex.props(shared.learnedName)}>
|
||||
{client.learned_name}
|
||||
<span {...stylex.props(shared.learnedTag)}>learned</span>
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return <span {...stylex.props(styles.unnamed)}>—</span>;
|
||||
}
|
||||
|
||||
export interface Provenance {
|
||||
label: string;
|
||||
detail: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Where this row's name and group came from.
|
||||
*
|
||||
* `hand_edited` records that an operator settled this client, but not which
|
||||
* operator surface did: under file authority the reconciler sets it from the
|
||||
* declaration, and in database mode the admin's own edit does. Authority is the
|
||||
* only way to tell them apart, so while it is pending or unreachable the page
|
||||
* says what it knows and names the doubt rather than picking one.
|
||||
*/
|
||||
export function provenanceOf(client: Client, authority: Authority): Provenance {
|
||||
if (!client.hand_edited) {
|
||||
return {
|
||||
label: "Learned",
|
||||
detail: "This client appeared from DNS traffic. Its name, if any, comes from reverse DNS.",
|
||||
};
|
||||
}
|
||||
if (authority.state === "resolved" && authority.status.authority === "managed_file") {
|
||||
return {
|
||||
label: "Declared",
|
||||
detail: `Declared in ${authority.status.path ?? "the configuration file"}. Reverse DNS does not overwrite it.`,
|
||||
};
|
||||
}
|
||||
if (authority.state === "resolved") {
|
||||
return {
|
||||
label: "Edited",
|
||||
detail: "The name and group were set here. Reverse DNS does not overwrite them.",
|
||||
};
|
||||
}
|
||||
return {
|
||||
label: "Set by hand",
|
||||
detail: "Either declared in the configuration file or edited here — nxdns cannot say which until it reports its configuration status.",
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user