46 lines
1.4 KiB
TypeScript
46 lines
1.4 KiB
TypeScript
import * as stylex from "@stylexjs/stylex";
|
|
import { colors } from "@/ui/tokens.stylex";
|
|
import { useAuthority } from "./authority";
|
|
|
|
const styles = stylex.create({
|
|
tag: {
|
|
marginLeft: "0.5rem",
|
|
borderWidth: 1,
|
|
borderStyle: "solid",
|
|
borderColor: colors.border,
|
|
borderRadius: "0.25rem",
|
|
paddingInline: "0.375rem",
|
|
paddingBlock: "0.125rem",
|
|
fontSize: "0.75rem",
|
|
lineHeight: "1rem",
|
|
color: colors.textMuted,
|
|
},
|
|
});
|
|
|
|
/**
|
|
* The compact lock, for a configuration control that survives outside a
|
|
* configuration page — the Clients page edits a group assignment the file may
|
|
* own. The configuration pages themselves do not use it: they change rendering
|
|
* rather than annotate a control they left up.
|
|
*
|
|
* The word is real text, not colour or an icon, so a screen reader announces
|
|
* the reason the control will not answer.
|
|
*/
|
|
export default function ConfigLockIndicator() {
|
|
const authority = useAuthority();
|
|
if (authority.state === "resolved" && authority.status.authority === "database") return null;
|
|
|
|
const reason =
|
|
authority.state === "pending"
|
|
? "Checking which configuration source this server obeys"
|
|
: authority.state === "failed"
|
|
? "Configuration status unavailable, so edits are held back"
|
|
: `Managed by ${authority.status.path ?? "the configuration file"}; edit the file and restart nxdns`;
|
|
|
|
return (
|
|
<span title={reason} aria-label={`Locked. ${reason}.`} {...stylex.props(styles.tag)}>
|
|
Locked
|
|
</span>
|
|
);
|
|
}
|