diff --git a/src/renderer/components/settings/sections/ConfigEditorDialog.tsx b/src/renderer/components/settings/sections/ConfigEditorDialog.tsx index 6284dc42..dabe26d1 100644 --- a/src/renderer/components/settings/sections/ConfigEditorDialog.tsx +++ b/src/renderer/components/settings/sections/ConfigEditorDialog.tsx @@ -175,57 +175,63 @@ export const ConfigEditorDialog = ({ setJsonError(null); const init = async (): Promise => { - const config = await api.config.get(); - if (destroyed) return; + try { + const config = await api.config.get(); + if (destroyed) return; - const jsonText = JSON.stringify(config, null, 2); - initialConfigRef.current = jsonText; - setLoading(false); + const jsonText = JSON.stringify(config, null, 2); + initialConfigRef.current = jsonText; + setLoading(false); - // Wait for DOM render - requestAnimationFrame(() => { - if (destroyed || !editorRef.current) return; + // Wait for DOM render + requestAnimationFrame(() => { + if (destroyed || !editorRef.current) return; - // Clean up existing view - if (viewRef.current) { - viewRef.current.destroy(); - viewRef.current = null; - } + // Clean up existing view + if (viewRef.current) { + viewRef.current.destroy(); + viewRef.current = null; + } - const state = EditorState.create({ - doc: jsonText, - extensions: [ - lineNumbers(), - highlightActiveLineGutter(), - highlightActiveLine(), - history(), - foldGutter(), - indentOnInput(), - bracketMatching(), - json(), - syntaxHighlighting(oneDarkHighlightStyle), - jsonLinter, - lintGutter(), - search(), - keymap.of([...defaultKeymap, ...historyKeymap, ...foldKeymap, ...searchKeymap]), - baseEditorTheme, - configEditorTheme, - // eslint-disable-next-line sonarjs/no-nested-functions -- CodeMirror listener callback within useEffect setup - EditorView.updateListener.of((update) => { - if (update.docChanged) { - const text = update.state.doc.toString(); - scheduleSave(text); - } - }), - ], + const state = EditorState.create({ + doc: jsonText, + extensions: [ + lineNumbers(), + highlightActiveLineGutter(), + highlightActiveLine(), + history(), + foldGutter(), + indentOnInput(), + bracketMatching(), + json(), + syntaxHighlighting(oneDarkHighlightStyle), + jsonLinter, + lintGutter(), + search(), + keymap.of([...defaultKeymap, ...historyKeymap, ...foldKeymap, ...searchKeymap]), + baseEditorTheme, + configEditorTheme, + // eslint-disable-next-line sonarjs/no-nested-functions -- CodeMirror listener callback within useEffect setup + EditorView.updateListener.of((update) => { + if (update.docChanged) { + const text = update.state.doc.toString(); + scheduleSave(text); + } + }), + ], + }); + + const view = new EditorView({ + state, + parent: editorRef.current, + }); + viewRef.current = view; }); - - const view = new EditorView({ - state, - parent: editorRef.current, - }); - viewRef.current = view; - }); + } catch (e) { + if (destroyed) return; + setLoading(false); + setJsonError(e instanceof Error ? e.message : 'Failed to load config'); + } }; void init(); diff --git a/src/renderer/components/team/dialogs/CreateTaskDialog.tsx b/src/renderer/components/team/dialogs/CreateTaskDialog.tsx index 3096f38d..91dcc6e1 100644 --- a/src/renderer/components/team/dialogs/CreateTaskDialog.tsx +++ b/src/renderer/components/team/dialogs/CreateTaskDialog.tsx @@ -102,6 +102,10 @@ export const CreateTaskDialog = ({ descChipDraft.setChips([defaultChip]); } else if (defaultDescription) { descriptionDraft.setValue(defaultDescription); + descChipDraft.clearChipDraft(); + } else { + descriptionDraft.clearDraft(); + descChipDraft.clearChipDraft(); } setOwner(defaultOwner); setBlockedBy([]); diff --git a/src/renderer/hooks/useAttachments.ts b/src/renderer/hooks/useAttachments.ts index 368ecc5c..2833ea20 100644 --- a/src/renderer/hooks/useAttachments.ts +++ b/src/renderer/hooks/useAttachments.ts @@ -106,7 +106,14 @@ export function useAttachments(options?: UseAttachmentsOptions): UseAttachmentsR // Load persisted attachments on mount useEffect(() => { - if (!persistenceKey) return; + if (!persistenceKey) { + // Transitioning to non-persistent context: flush pending save and clear stale state + flushPending(); + attachmentsRef.current = []; + // eslint-disable-next-line react-hooks/set-state-in-effect -- intentional sync reset on key transition + setAttachments([]); + return; + } let cancelled = false; // Flush any pending debounced save for the previous key before switching.