localize hardcoded strings in provider settings UI (#8931)

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Douwe Osinga <douwe@squareup.com>
This commit is contained in:
Clay Delk
2026-05-13 12:00:56 -04:00
committed by GitHub
parent 766304bf78
commit ccda954c05
6 changed files with 51 additions and 15 deletions
@@ -124,8 +124,8 @@ export function ConnectedFieldsPanel({
className="text-muted-foreground"
>
{resolveFieldValue(field, fieldValueMap).isSet
? "Edit"
: "Add"}
? t("common:actions.edit")
: t("common:actions.add")}
</Button>
)}
</div>
@@ -287,9 +287,9 @@ export function SetupFieldsPanel({
<AsyncButton
type="button"
state={saving ? "pending" : showSavedState ? "success" : "idle"}
idleLabel="Save"
pendingLabel="Saving..."
successLabel="Saved"
idleLabel={t("common:actions.save")}
pendingLabel={t("common:actions.saving")}
successLabel={t("common:actions.saved")}
pendingVisual="text"
pendingDelayMs={250}
size="sm"
@@ -71,7 +71,7 @@ export function ModelProviderRow({
inventorySyncing = false,
inventoryWarning = null,
}: ModelProviderRowProps) {
const { t } = useTranslation("settings");
const { t } = useTranslation(["settings", "common"]);
const [expanded, setExpanded] = useState(false);
const [configValues, setConfigValues] = useState<ProviderFieldValue[]>([]);
const [draftValues, setDraftValues] = useState<Record<string, string>>({});
@@ -114,7 +114,7 @@ export function ModelProviderRow({
setError(
nextError instanceof Error
? nextError.message
: "Failed to load provider settings",
: t("providers.errors.loadFailed"),
);
} finally {
if (showSkeleton) {
@@ -122,7 +122,7 @@ export function ModelProviderRow({
}
}
},
[fields, hasFields, onGetConfig, provider.id],
[fields, hasFields, onGetConfig, provider.id, t],
);
useEffect(() => {
@@ -185,7 +185,7 @@ export function ModelProviderRow({
setSetupError(
nextError instanceof Error
? nextError.message
: "Failed to complete sign-in",
: t("providers.errors.signInFailed"),
);
} finally {
unlisten();
@@ -230,7 +230,7 @@ export function ModelProviderRow({
async function handleSaveField(field: ProviderField) {
const nextValue = draftValues[field.key]?.trim() ?? "";
if (!nextValue) {
setError(`Enter a value for ${field.label}`);
setError(t("providers.errors.fieldRequired", { label: field.label }));
return;
}
setError("");
@@ -244,7 +244,9 @@ export function ModelProviderRow({
setShowSavedState(true);
} catch (nextError) {
setError(
nextError instanceof Error ? nextError.message : "Failed to save",
nextError instanceof Error
? nextError.message
: t("providers.errors.saveFailed"),
);
}
}
@@ -262,7 +264,11 @@ export function ModelProviderRow({
.map((field) => field.label);
if (missingLabels.length > 0) {
setError(`Fill in ${missingLabels.join(", ")}`);
setError(
t("providers.errors.fieldsMissing", {
fields: missingLabels.join(", "),
}),
);
return;
}
@@ -299,7 +305,9 @@ export function ModelProviderRow({
setShowSavedState(false);
} catch (nextError) {
setError(
nextError instanceof Error ? nextError.message : "Failed to save",
nextError instanceof Error
? nextError.message
: t("providers.errors.saveFailed"),
);
}
}
@@ -314,7 +322,9 @@ export function ModelProviderRow({
setShowSavedState(false);
} catch (nextError) {
setError(
nextError instanceof Error ? nextError.message : "Failed to remove",
nextError instanceof Error
? nextError.message
: t("providers.errors.removeFailed"),
);
}
}
@@ -373,7 +383,9 @@ export function ModelProviderRow({
{authenticating ? (
<Spinner className="size-3.5 text-current" />
) : null}
{setupError ? "Retry" : "Connect"}
{setupError
? t("common:actions.retry")
: t("common:actions.connect")}
</Button>
</div>
) : (
@@ -20,10 +20,14 @@
"remove": "Remove",
"rename": "Rename",
"restore": "Restore",
"add": "Add",
"connect": "Connect",
"retry": "Retry",
"run": "Run",
"running": "Running",
"save": "Save",
"saved": "Saved",
"saving": "Saving...",
"saveChanges": "Save changes",
"search": "Search",
"select": "Select",
@@ -343,6 +343,14 @@
"loading": "Loading provider catalog..."
},
"disconnect": "Disconnect",
"errors": {
"fieldRequired": "Enter a value for {{label}}",
"fieldsMissing": "Fill in {{fields}}",
"loadFailed": "Failed to load provider settings",
"removeFailed": "Failed to remove",
"saveFailed": "Failed to save",
"signInFailed": "Failed to complete sign-in"
},
"models": {
"description": "AI models power your agents. Goose requires one to work, but some agents bring their own.",
"notSet": "Not set",
@@ -20,10 +20,14 @@
"remove": "Quitar",
"rename": "Renombrar",
"restore": "Restaurar",
"add": "Agregar",
"connect": "Conectar",
"retry": "Reintentar",
"run": "Ejecutar",
"running": "Ejecutando",
"save": "Guardar",
"saved": "Guardado",
"saving": "Guardando...",
"saveChanges": "Guardar cambios",
"search": "Buscar",
"select": "Seleccionar",
@@ -343,6 +343,14 @@
"loading": "Cargando catálogo de proveedores..."
},
"disconnect": "Desconectar",
"errors": {
"fieldRequired": "Ingresa un valor para {{label}}",
"fieldsMissing": "Completa los campos: {{fields}}",
"loadFailed": "No se pudo cargar la configuración del proveedor",
"removeFailed": "Error al eliminar",
"saveFailed": "Error al guardar",
"signInFailed": "No se pudo completar el inicio de sesión"
},
"models": {
"description": "Necesitas al menos un proveedor de modelos para usar el agente Goose. Algunos agentes pueden traer sus propias conexiones de modelo.",
"notSet": "No configurado",