@@ -8,6 +8,7 @@ import { Hotkey } from "../core/Hotkey";
88import { destroy as destroySharedStore } from "../mixins/SharedChoiceStore/mixin" ;
99import ToolsManager from "../tools/Manager" ;
1010import Utils from "../utils" ;
11+ import { debounce } from "../utils/debounce" ;
1112import { guidGenerator } from "../utils/unique" ;
1213import { clamp , delay , isDefined } from "../utils/utilities" ;
1314import { CREATE_RELATION_MODE } from "./Annotation/LinkingModes" ;
@@ -540,11 +541,47 @@ export default types
540541 }
541542 }
542543
543- function assignConfig ( config ) {
544+ // Internal function that actually applies the config
545+ const applyConfigInternal = flow ( function * ( config ) {
544546 const cs = self . annotationStore ;
545547
548+ // Show cursor as "wait" to indicate processing
549+ document . body . style . cursor = "wait" ;
550+
546551 self . config = config ;
547- cs . initRoot ( self . config ) ;
552+
553+ // Yield to let React update the UI (shows loading cursor)
554+ yield delay ( 0 ) ;
555+
556+ try {
557+ // Parse XML and rebuild tree (this is the slow part)
558+ cs . initRoot ( self . config ) ;
559+
560+ // Yield again to let React render
561+ yield delay ( 0 ) ;
562+ } catch ( error ) {
563+ console . error ( "Error applying config:" , error ) ;
564+ InfoModal . error ( `Config error: ${ error . message } ` ) ;
565+ } finally {
566+ // Always reset cursor
567+ document . body . style . cursor = "default" ;
568+ }
569+ } ) ;
570+
571+ // Debounced version - waits 500ms after last change before applying
572+ const debouncedApplyConfig = debounce ( ( config ) => {
573+ applyConfigInternal ( config ) ;
574+ } , 500 ) ;
575+
576+ // Public function - debounces rapid changes
577+ function assignConfig ( config , immediate = false ) {
578+ if ( immediate ) {
579+ // For initial load or explicit updates
580+ applyConfigInternal ( config ) ;
581+ } else {
582+ // For live editing - debounce to avoid blocking on every keystroke
583+ debouncedApplyConfig ( config ) ;
584+ }
548585 }
549586
550587 /* eslint-disable no-unused-vars */
@@ -805,6 +842,7 @@ export default types
805842 as . afterReset ?. ( ) ;
806843
807844 if ( ! as . initialized ) {
845+ // Use immediate init for reset (not user editing)
808846 as . initRoot ( self . config ) ;
809847 if ( isFF ( FF_LSDV_4620_3_ML ) && ! appControls ?. isRendered ( ) ) {
810848 appControls ?. render ( ) ;
0 commit comments