import { useState } from "react"; import { useMutation, useQueryClient } from "@tanstack/react-query"; import * as stylex from "@stylexjs/stylex"; import { clientUpdateMutation } from "@/lib/queries"; import type { Client, Group } from "@/lib/types"; import InlineError from "@/lib/InlineError"; import ConfigLockIndicator from "@/features/configuration/ConfigLockIndicator"; import { useReadOnlyConfig } from "@/features/configuration/authority"; import Dialog from "@/ui/Dialog"; import Select from "@/ui/Select"; import { styles as shared } from "@/ui/styles"; import { colors } from "@/ui/tokens.stylex"; interface Props { client: Client; groups: Group[]; onClose: () => void; } const styles = stylex.create({ heading: { fontSize: "1.125rem", lineHeight: "1.75rem", fontWeight: 600, }, form: { display: "flex", flexDirection: "column", gap: "1rem", marginTop: "1rem", }, fieldLabel: { display: "block", fontSize: "0.875rem", lineHeight: "1.25rem", fontWeight: 500, }, dialogInput: { marginTop: "0.25rem", width: "100%", }, actions: { display: "flex", flexWrap: "wrap", alignItems: "center", justifyContent: "flex-end", gap: "0.5rem", }, lockNote: { marginRight: "auto", fontSize: "0.75rem", lineHeight: "1rem", color: colors.textMuted, }, }); export default function ClientEditDialog({ client, groups, onClose }: Props) { const queryClient = useQueryClient(); const mutation = useMutation(clientUpdateMutation(queryClient)); // Adopting the learned name as a typed one is the natural gesture. const [name, setName] = useState(client.name === "" ? client.learned_name : client.name); const [groupId, setGroupId] = useState(client.group_id); // The dialog opens only where the save can land, but authority is polled and // can turn under an open dialog. So the save path consults it on every render // rather than trusting the state that was true when the dialog opened; the // draft stays on screen, locked, instead of vanishing mid-edit. const readOnly = useReadOnlyConfig(); return (

Edit {client.ip}

{ event.preventDefault(); // Enter in the name field submits without the Save button, so // the lock lives here too, not only in what is rendered. if (readOnly) return; mutation.mutate( { id: client.id, edit: { name: name.trim(), group_id: groupId } }, { onSuccess: onClose }, ); }} >