fix(settings): use useEffect for jira field init, fix token save UX
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled

Replace render-body setState with useEffect so field initialisation
is idiomatic React and never races with user input. Also clarifies
placeholder text: empty token field = keep current, not clear it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
kitos
2026-05-26 17:04:22 +02:00
parent 217c4c88b2
commit fd4a625760

View File

@@ -1,4 +1,4 @@
import { useState } from "react";
import { useState, useEffect } from "react";
import { useQuery, useMutation, useQueryClient } from "@tanstack/react-query";
import {
Settings,
@@ -820,21 +820,24 @@ function ProfileSection() {
const [jiraApiToken, setJiraApiToken] = useState<string>("");
const [showToken, setShowToken] = useState(false);
const [dirty, setDirty] = useState(false);
const [initialised, setInitialised] = useState(false);
// Sync from server on first load
if (me && !initialised) {
// Initialise editable fields from server on first successful load
useEffect(() => {
if (me) {
setJiraAccountId(me.jira_account_id ?? "");
setJiraEmail(me.jira_email ?? "");
setInitialised(true);
// Never pre-fill the token — we only know whether it is set, not its value
}
// Only run when `me` transitions from undefined → data (i.e., first load)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [!!me]);
const saveMut = useMutation({
mutationFn: updateMyPreferences,
onSuccess: () => {
qc.invalidateQueries({ queryKey: ["me-prefs"] });
setDirty(false);
setJiraApiToken("");
setJiraApiToken(""); // clear token field after save — it's now persisted
setToast({ msg: "Profile settings saved", type: "success" });
},
onError: () => setToast({ msg: "Failed to save", type: "error" }),
@@ -845,9 +848,10 @@ function ProfileSection() {
jira_account_id: jiraAccountId || null,
jira_email: jiraEmail || null,
};
// Only send token if user typed something (empty string clears it)
if (jiraApiToken !== "") {
payload.jira_api_token = jiraApiToken;
// Only send token when the user has typed something new
// (empty field = "keep current token unchanged")
if (jiraApiToken.trim() !== "") {
payload.jira_api_token = jiraApiToken.trim();
}
saveMut.mutate(payload);
};
@@ -936,7 +940,7 @@ function ProfileSection() {
setJiraApiToken(e.target.value);
setDirty(true);
}}
placeholder={me?.jira_token_set ? "•••••••••••• (leave blank to keep current)" : "Paste your Atlassian API token"}
placeholder={me?.jira_token_set ? "Leave blank to keep current token" : "Paste your Atlassian API token here"}
className="w-full rounded-lg border border-gray-700 bg-gray-800 px-3 py-2 pr-10 text-sm text-gray-200 placeholder-gray-600 focus:border-cyan-500 focus:outline-none"
/>
<button