fix: don't register pic.ngo subdomain until availability check completes
Auto-save was firing with picAvail === null (the moment the user typed a new cell name, before the 900ms availability debounce even started), which caused the backend to immediately register the subdomain on DDNS. Track the last saved/loaded cell name in loadedCellName. When domainMode is pic_ngo and the typed name differs from the loaded name, block auto-save until picAvail reaches a terminal state (available or unreachable). Also update loadedCellName on successful save so subsequent edits to the same name are not blocked. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -432,6 +432,7 @@ function Settings() {
|
||||
// identity
|
||||
const [identity, setIdentity] = useState({ cell_name: '', domain: '', ip_range: '' });
|
||||
const [identityDirty, setIdentityDirty] = useState(false);
|
||||
const [loadedCellName, setLoadedCellName] = useState('');
|
||||
|
||||
// DDNS
|
||||
const [domainMode, setDomainMode] = useState('lan');
|
||||
@@ -475,6 +476,7 @@ function Settings() {
|
||||
domain: cfg.domain || '',
|
||||
ip_range: cfg.ip_range || '',
|
||||
});
|
||||
setLoadedCellName(cfg.cell_name || '');
|
||||
setIdentityDirty(false);
|
||||
setDomainMode(cfg.domain_mode || 'lan');
|
||||
setDomainName(cfg.domain_name || '');
|
||||
@@ -545,6 +547,7 @@ function Settings() {
|
||||
try {
|
||||
const res = await cellAPI.updateConfig(identity);
|
||||
setIdentityDirty(false);
|
||||
setLoadedCellName(identity.cell_name);
|
||||
draftConfig?.setDirty('identity', false);
|
||||
if (res.data.warnings?.length) res.data.warnings.forEach((w) => toast(w, 'warning'));
|
||||
// Refresh to get updated domain_name after DDNS registration
|
||||
@@ -687,10 +690,15 @@ function Settings() {
|
||||
useEffect(() => {
|
||||
if (!identityDirty) return;
|
||||
if (ipRangeError || cellNameError || domainError) return;
|
||||
if (domainMode === 'pic_ngo' && (picAvail === 'taken' || picAvail === 'checking')) return;
|
||||
// In pic_ngo mode, if the cell name differs from what was last saved/loaded,
|
||||
// wait for the availability check to reach a terminal state before saving.
|
||||
// 'available' and 'unreachable' are terminal; null/'checking'/'taken' are not.
|
||||
if (domainMode === 'pic_ngo' && identity.cell_name !== loadedCellName) {
|
||||
if (picAvail !== 'available' && picAvail !== 'unreachable') return;
|
||||
}
|
||||
const timer = setTimeout(() => saveIdentityRef.current(), 800);
|
||||
return () => clearTimeout(timer);
|
||||
}, [identity, identityDirty, ipRangeError, cellNameError, domainError, domainMode, picAvail]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
}, [identity, identityDirty, ipRangeError, cellNameError, domainError, domainMode, picAvail, loadedCellName]); // eslint-disable-line react-hooks/exhaustive-deps
|
||||
|
||||
useEffect(() => {
|
||||
const timers = SERVICE_DEFS
|
||||
|
||||
Reference in New Issue
Block a user