mirror of
https://github.com/router-for-me/Cli-Proxy-API-Management-Center.git
synced 2026-06-16 21:03:58 +08:00
fix(editing): harden unsaved navigation and draft cleanup
This commit is contained in:
@@ -23,19 +23,21 @@ export function useUnsavedChangesGuard(options: UseUnsavedChangesGuardOptions) {
|
||||
const { enabled = true, shouldBlock, dialog } = options;
|
||||
const { showConfirmation } = useNotificationStore();
|
||||
const lastBlockedRef = useRef<string>('');
|
||||
const allowNextNavigationRef = useRef(false);
|
||||
const allowNextNavigationUntilRef = useRef(0);
|
||||
const location = useLocation();
|
||||
|
||||
const allowNextNavigation = useCallback(() => {
|
||||
allowNextNavigationRef.current = true;
|
||||
// Allow a short window for programmatic navigations after successful save.
|
||||
// This avoids stale "allow" flags lingering when no navigation happens.
|
||||
allowNextNavigationUntilRef.current = Date.now() + 2_000;
|
||||
}, []);
|
||||
|
||||
const shouldBlockFunction = useCallback<BlockerFunction>(
|
||||
(args) => {
|
||||
if (allowNextNavigationRef.current) {
|
||||
if (!enabled) return false;
|
||||
if (allowNextNavigationUntilRef.current > Date.now()) {
|
||||
return false;
|
||||
}
|
||||
if (!enabled) return false;
|
||||
return typeof shouldBlock === 'function' ? shouldBlock(args) : shouldBlock;
|
||||
},
|
||||
[enabled, shouldBlock]
|
||||
@@ -44,8 +46,8 @@ export function useUnsavedChangesGuard(options: UseUnsavedChangesGuardOptions) {
|
||||
const blocker = useBlocker(shouldBlockFunction);
|
||||
|
||||
useEffect(() => {
|
||||
if (!allowNextNavigationRef.current) return;
|
||||
allowNextNavigationRef.current = false;
|
||||
if (allowNextNavigationUntilRef.current === 0) return;
|
||||
allowNextNavigationUntilRef.current = 0;
|
||||
}, [location.key]);
|
||||
|
||||
const blockedKey = useMemo(() => {
|
||||
|
||||
@@ -185,6 +185,7 @@ export function AiProvidersCodexEditPage() {
|
||||
if (initialData) {
|
||||
const nextForm: ProviderFormState = {
|
||||
...initialData,
|
||||
websockets: Boolean(initialData.websockets),
|
||||
headers: headersToEntries(initialData.headers),
|
||||
modelEntries: modelsToEntries(initialData.models),
|
||||
excludedText: excludedModelsToText(initialData.excludedModels),
|
||||
@@ -362,7 +363,7 @@ export function AiProvidersCodexEditPage() {
|
||||
priority: form.priority !== undefined ? Math.trunc(form.priority) : undefined,
|
||||
prefix: form.prefix?.trim() || undefined,
|
||||
baseUrl,
|
||||
websockets: form.websockets ?? false,
|
||||
websockets: Boolean(form.websockets),
|
||||
proxyUrl: form.proxyUrl?.trim() || undefined,
|
||||
headers: buildHeaderObject(form.headers),
|
||||
models: entriesToModels(form.modelEntries),
|
||||
|
||||
@@ -196,10 +196,12 @@ export const useClaudeEditDraftStore = create<ClaudeEditDraftState>((set, get) =
|
||||
clearDraft: (key) => {
|
||||
if (!key) return;
|
||||
set((state) => {
|
||||
if (!state.drafts[key]) return state;
|
||||
const next = { ...state.drafts };
|
||||
delete next[key];
|
||||
return { drafts: next };
|
||||
if (!state.drafts[key] && !state.refCounts[key]) return state;
|
||||
const nextDrafts = { ...state.drafts };
|
||||
delete nextDrafts[key];
|
||||
const nextCounts = { ...state.refCounts };
|
||||
delete nextCounts[key];
|
||||
return { drafts: nextDrafts, refCounts: nextCounts };
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
@@ -227,10 +227,12 @@ export const useOpenAIEditDraftStore = create<OpenAIEditDraftState>((set, get) =
|
||||
clearDraft: (key) => {
|
||||
if (!key) return;
|
||||
set((state) => {
|
||||
if (!state.drafts[key]) return state;
|
||||
const next = { ...state.drafts };
|
||||
delete next[key];
|
||||
return { drafts: next };
|
||||
if (!state.drafts[key] && !state.refCounts[key]) return state;
|
||||
const nextDrafts = { ...state.drafts };
|
||||
delete nextDrafts[key];
|
||||
const nextCounts = { ...state.refCounts };
|
||||
delete nextCounts[key];
|
||||
return { drafts: nextDrafts, refCounts: nextCounts };
|
||||
});
|
||||
},
|
||||
}));
|
||||
|
||||
Reference in New Issue
Block a user