Four bugs fixed:
1. Banner delay (up to 5 s): DraftConfigContext now exposes isDirty as
reactive useState so App.jsx re-renders immediately when any section
marks itself dirty, instead of waiting for the next checkPending() poll.
2. Banner re-triggers after Apply (race): For non-'*' container restarts
(e.g., cell_name → DNS restart) the background thread took ~300 ms to
clear _pending_restart. A concurrent checkPending() poll could see
needs_restart=True and overwrite the frontend's optimistic clear.
Fix: set needs_restart=False and applying=True synchronously before
spawning the thread.
3. Apply showed banner during applyPending() when hasDirty()==false:
setApplyStatus('saving') was skipped for the auto-save-then-apply
path, leaving applyStatus=null while applyPending() ran and the
banner stayed visible. Always set 'saving' before applyPending().
4. Cert status always 'unknown' in pic_ngo mode: _check_cert_via_ssl
connected to cell-caddy:443 but sent SNI='cell-caddy'. Caddy finds no
matching cert and returns nothing. Fix: pass the effective public
domain (e.g. pic1.pic.ngo) as SNI so Caddy returns the right cert.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { createContext, useContext, useRef, useCallback } from 'react';
|
||||
import { createContext, useContext, useRef, useCallback, useState } from 'react';
|
||||
|
||||
const DraftConfigContext = createContext(null);
|
||||
|
||||
@@ -11,9 +11,12 @@ export function DraftConfigProvider({ children }) {
|
||||
}, []);
|
||||
|
||||
const hasDirtyRef = useRef({}); // key → boolean
|
||||
// isDirty is a reactive mirror of hasDirtyRef so consumers re-render immediately.
|
||||
const [isDirty, setIsDirty] = useState(false);
|
||||
|
||||
const setDirty = useCallback((key, isDirty) => {
|
||||
hasDirtyRef.current[key] = isDirty;
|
||||
const setDirty = useCallback((key, dirty) => {
|
||||
hasDirtyRef.current[key] = dirty;
|
||||
setIsDirty(Object.values(hasDirtyRef.current).some(Boolean));
|
||||
}, []);
|
||||
|
||||
const hasDirty = useCallback(() => {
|
||||
@@ -27,10 +30,11 @@ export function DraftConfigProvider({ children }) {
|
||||
|
||||
const clearAllDirty = useCallback(() => {
|
||||
hasDirtyRef.current = {};
|
||||
setIsDirty(false);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<DraftConfigContext.Provider value={{ registerFlusher, setDirty, hasDirty, flushAll, clearAllDirty }}>
|
||||
<DraftConfigContext.Provider value={{ registerFlusher, setDirty, hasDirty, isDirty, flushAll, clearAllDirty }}>
|
||||
{children}
|
||||
</DraftConfigContext.Provider>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user