fix(frontend): align Settings desktop labels on French (#78)
UX decision (carnet #78): the human UI of IdeA is French by default, uniform per surface — proper nouns and technical acronyms (URL, LAN, IP/CIDR, HTTPS, API, CLI…) stay as-is. Settings mixed English (AI Profiles, Deployment) with French (Appareils, frozen by UX for #77). Renames the Settings menu/nav, the Profils IA and Déploiement panels (titles, actions, states, help text) to French, per the carnet's exhaustive list. Updates the affected tests accordingly. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@ -39,30 +39,30 @@ interface ModeOption {
|
||||
const MODE_OPTIONS: ModeOption[] = [
|
||||
{
|
||||
mode: "localOnly",
|
||||
title: "This computer only",
|
||||
title: "Cet ordinateur uniquement",
|
||||
description:
|
||||
"For using IdeA on this desktop only. Remote devices cannot connect.",
|
||||
"Pour utiliser IdeA uniquement sur cet ordinateur. Les appareils distants ne peuvent pas se connecter.",
|
||||
},
|
||||
{
|
||||
mode: "remoteProxyLocal",
|
||||
title: "Remote access, proxy on this computer",
|
||||
title: "Accès distant, proxy sur cet ordinateur",
|
||||
description:
|
||||
"Use this when your HTTPS proxy runs on the same machine as IdeA Desktop.",
|
||||
"À utiliser quand le proxy HTTPS tourne sur la même machine qu'IdeA Desktop.",
|
||||
},
|
||||
{
|
||||
mode: "remoteProxyOtherMachine",
|
||||
title: "Remote access, proxy on another machine",
|
||||
title: "Accès distant, proxy sur une autre machine",
|
||||
description:
|
||||
"Use this when the HTTPS proxy runs on another machine. IdeA will only accept traffic from that proxy.",
|
||||
"À utiliser quand le proxy HTTPS tourne sur une autre machine. IdeA n'acceptera que le trafic provenant de ce proxy.",
|
||||
},
|
||||
];
|
||||
|
||||
const STATE_LABEL: Record<string, string> = {
|
||||
stopped: "Stopped",
|
||||
starting: "Starting…",
|
||||
running: "Running",
|
||||
stopping: "Stopping…",
|
||||
failed: "Failed",
|
||||
stopped: "Arrêté",
|
||||
starting: "Démarrage…",
|
||||
running: "En cours d'exécution",
|
||||
stopping: "Arrêt…",
|
||||
failed: "Échec",
|
||||
};
|
||||
|
||||
/** Copy-to-clipboard button; degrades to disabled where the API is absent. */
|
||||
@ -86,7 +86,7 @@ function CopyButton({ value, label }: { value: string; label: string }) {
|
||||
);
|
||||
}}
|
||||
>
|
||||
{copied ? "Copied" : "Copy"}
|
||||
{copied ? "Copié" : "Copier"}
|
||||
</Button>
|
||||
);
|
||||
}
|
||||
@ -108,8 +108,8 @@ export function DeploymentSettings() {
|
||||
|
||||
if (!vm.ready || !vm.settings) {
|
||||
return (
|
||||
<Panel aria-label="deployment settings" title="Deployment">
|
||||
<p className="text-sm text-muted">Loading…</p>
|
||||
<Panel aria-label="deployment settings" title="Déploiement">
|
||||
<p className="text-sm text-muted">Chargement…</p>
|
||||
</Panel>
|
||||
);
|
||||
}
|
||||
@ -124,7 +124,7 @@ export function DeploymentSettings() {
|
||||
<div aria-label="deployment settings" className="flex flex-col gap-4">
|
||||
{/* ── Status ────────────────────────────────────────────────────────── */}
|
||||
<Panel
|
||||
title="Server"
|
||||
title="Serveur"
|
||||
actions={
|
||||
running || status.state === "stopping" ? (
|
||||
<Button
|
||||
@ -132,7 +132,7 @@ export function DeploymentSettings() {
|
||||
onClick={() => void vm.stop()}
|
||||
disabled={vm.busy || transitioning}
|
||||
>
|
||||
Stop
|
||||
Arrêter
|
||||
</Button>
|
||||
) : (
|
||||
<Button
|
||||
@ -140,7 +140,7 @@ export function DeploymentSettings() {
|
||||
onClick={() => void vm.start()}
|
||||
disabled={vm.busy || transitioning}
|
||||
>
|
||||
Start
|
||||
Démarrer
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
@ -161,12 +161,12 @@ export function DeploymentSettings() {
|
||||
|
||||
{status.localUrl && (
|
||||
<p className="text-xs text-muted">
|
||||
Local URL: <code className="font-mono text-content">{status.localUrl}</code>
|
||||
URL locale : <code className="font-mono text-content">{status.localUrl}</code>
|
||||
</p>
|
||||
)}
|
||||
{status.publicUrl && (
|
||||
<p className="text-xs text-muted">
|
||||
Public URL: <code className="font-mono text-content">{status.publicUrl}</code>
|
||||
URL publique : <code className="font-mono text-content">{status.publicUrl}</code>
|
||||
</p>
|
||||
)}
|
||||
|
||||
@ -184,12 +184,12 @@ export function DeploymentSettings() {
|
||||
</div>
|
||||
</Panel>
|
||||
|
||||
{/* ── Exposure ──────────────────────────────────────────────────────── */}
|
||||
<Panel title="Exposure">
|
||||
{/* ── Exposure (ticket #78 — "Accès réseau" per UX) ────────────────── */}
|
||||
<Panel title="Accès réseau">
|
||||
<div className="flex flex-col gap-4">
|
||||
<div
|
||||
role="radiogroup"
|
||||
aria-label="exposure mode"
|
||||
aria-label="mode d'accès réseau"
|
||||
className="flex flex-col gap-2"
|
||||
>
|
||||
{MODE_OPTIONS.map((option) => {
|
||||
@ -234,7 +234,7 @@ export function DeploymentSettings() {
|
||||
</Field>
|
||||
|
||||
{remote && (
|
||||
<Field label="Public origin" hint="Example: https://idea.example.com">
|
||||
<Field label="Origine publique" hint="Exemple : https://idea.example.com">
|
||||
{({ id, describedBy }) => (
|
||||
<Input
|
||||
id={id}
|
||||
@ -251,8 +251,8 @@ export function DeploymentSettings() {
|
||||
<>
|
||||
{/* Addresses come from the backend probe — never invented here. */}
|
||||
<Field
|
||||
label="LAN address to bind"
|
||||
hint="The address on this machine that the proxy will connect to."
|
||||
label="Adresse LAN d'écoute"
|
||||
hint="L'adresse de cette machine à laquelle le proxy se connectera."
|
||||
>
|
||||
{({ id, describedBy }) =>
|
||||
vm.candidateLanAddresses.length > 0 ? (
|
||||
@ -263,7 +263,7 @@ export function DeploymentSettings() {
|
||||
value={settings.lanBindAddress ?? ""}
|
||||
onChange={(e) => vm.setLanBindAddress(e.target.value)}
|
||||
>
|
||||
<option value="">Select an address…</option>
|
||||
<option value="">Sélectionner une adresse…</option>
|
||||
{vm.candidateLanAddresses.map((address) => (
|
||||
<option key={address} value={address}>
|
||||
{address}
|
||||
@ -283,8 +283,8 @@ export function DeploymentSettings() {
|
||||
</Field>
|
||||
|
||||
<Field
|
||||
label="Authorized proxy IP/CIDR"
|
||||
hint="This is not where IdeA listens. It is the machine allowed to contact IdeA."
|
||||
label="IP/CIDR du proxy autorisé"
|
||||
hint="Ce n'est pas l'adresse d'écoute d'IdeA. C'est la machine autorisée à contacter IdeA."
|
||||
>
|
||||
{({ id, describedBy }) => (
|
||||
<Input
|
||||
@ -298,8 +298,8 @@ export function DeploymentSettings() {
|
||||
</Field>
|
||||
|
||||
<p className="rounded-md border border-warning/40 bg-warning/10 px-3 py-2 text-xs text-warning">
|
||||
If your proxy is not on this computer, choose this mode.
|
||||
Otherwise the proxy may time out without an IdeA error.
|
||||
Si votre proxy n'est pas sur cet ordinateur, choisissez ce mode.
|
||||
Sinon, le proxy peut expirer sans erreur IdeA.
|
||||
</p>
|
||||
</>
|
||||
)}
|
||||
@ -321,16 +321,16 @@ export function DeploymentSettings() {
|
||||
|
||||
{/* ── Proxy setup: the upstream to paste, backend-provided ──────────── */}
|
||||
{remote && (
|
||||
<Panel title="Proxy setup">
|
||||
<Panel title="Configuration du proxy">
|
||||
<div className="flex flex-col gap-2">
|
||||
<p className="text-xs text-muted">
|
||||
Point your HTTPS reverse proxy at this upstream.
|
||||
Faites pointer votre proxy inverse HTTPS vers cet upstream.
|
||||
</p>
|
||||
{vm.upstreamUrl ? (
|
||||
<ReadOnlyValue value={vm.upstreamUrl} copyLabel="copy upstream url" />
|
||||
<ReadOnlyValue value={vm.upstreamUrl} copyLabel="copier l'URL upstream" />
|
||||
) : (
|
||||
<p className="text-xs text-faint">
|
||||
Complete the settings above to get the upstream URL.
|
||||
Complétez les paramètres ci-dessus pour obtenir l'URL upstream.
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
@ -338,10 +338,11 @@ export function DeploymentSettings() {
|
||||
)}
|
||||
|
||||
{/* ── Pairing moved to its own surface (#77) — leave a signpost ─────── */}
|
||||
<Panel title="Pairing">
|
||||
<Panel title="Appairage">
|
||||
<p className="text-sm text-muted">
|
||||
Pairing is managed in <span className="text-content">Settings → Appareils</span>,
|
||||
where you can generate a code and revoke devices.
|
||||
L'appairage est géré dans{" "}
|
||||
<span className="text-content">Paramètres → Appareils</span>, où
|
||||
vous pouvez générer un code et révoquer des appareils.
|
||||
</p>
|
||||
</Panel>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user