fix(settings): use useEffect for jira field init, fix token save UX
Some checks failed
Aegis CI / lint-and-test (push) Has been cancelled
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:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user