From fc486f40702156467bdb56d687cf271d50edca1b Mon Sep 17 00:00:00 2001 From: Richard Eckart de Castilho Date: Tue, 24 Oct 2023 21:05:17 +0200 Subject: [PATCH] #4256 - Avoid saving preferences immediately on load - Enable preference saving only after the editor has properly initialized - Changes to preferences should only trigger annotation reloads once the editor has fully initialized - Fix small layout issue on ProjectsOverviewPage - Fix dashlet order on ProjectsOverviewPage --- .../apache-annotator/ApacheAnnotatorEditor.ts | 84 ++++++++++--------- .../ApacheAnnotatorVisualizer.ts | 6 +- .../inception-ui-dashboard-activity/pom.xml | 4 + .../activity/ActivitiesDashletExtension.java | 2 + .../dashlet/DocumentHintDashletExtension.java | 2 + .../projectlist/ProjectsOverviewPage.html | 2 +- 6 files changed, 57 insertions(+), 43 deletions(-) diff --git a/inception/inception-html-apache-annotator-editor/src/main/ts/src/apache-annotator/ApacheAnnotatorEditor.ts b/inception/inception-html-apache-annotator-editor/src/main/ts/src/apache-annotator/ApacheAnnotatorEditor.ts index 4dd6f66d0b2..2422eaddd52 100644 --- a/inception/inception-html-apache-annotator-editor/src/main/ts/src/apache-annotator/ApacheAnnotatorEditor.ts +++ b/inception/inception-html-apache-annotator-editor/src/main/ts/src/apache-annotator/ApacheAnnotatorEditor.ts @@ -21,6 +21,7 @@ import { ApacheAnnotatorSelector } from './ApacheAnnotatorSelector' import ApacheAnnotatorToolbar from './ApacheAnnotatorToolbar.svelte' import { showEmptyHighlights, showLabels } from './ApacheAnnotatorState' import AnnotationDetailPopOver from '@inception-project/inception-js-api/src/widget/AnnotationDetailPopOver.svelte' +import { Writable } from 'svelte/store' export class ApacheAnnotatorEditor implements AnnotationEditor { private ajax: DiamAjax @@ -43,51 +44,54 @@ export class ApacheAnnotatorEditor implements AnnotationEditor { ajax.loadPreferences(userPreferencesKey).then((p) => { preferences = Object.assign(preferences, defaultPreferences, p) console.log('Loaded preferences', preferences) - showLabels.set( - preferences.showLabels !== undefined - ? preferences.showLabels - : defaultPreferences.showLabels - ) - - showEmptyHighlights.set( - preferences.showEmptyHighlights !== undefined - ? preferences.showEmptyHighlights - : defaultPreferences.showEmptyHighlights - ) - - showLabels.subscribe((mode) => { - preferences.showLabels = mode - ajax.savePreferences(userPreferencesKey, preferences) - }) + let preferencesDebounceTimeout: number | undefined = undefined + + function bindPreference(writable: Writable, propertyName: string) { + writable.set( + preferences[propertyName] !== undefined + ? preferences[propertyName] + : defaultPreferences[propertyName] + ) + + writable.subscribe((value) => { + preferences[propertyName] = value + if (preferencesDebounceTimeout) { + window.clearTimeout(preferencesDebounceTimeout) + preferencesDebounceTimeout = undefined + } + preferencesDebounceTimeout = window.setTimeout(() => { + console.log("Saved preferences") + ajax.savePreferences(userPreferencesKey, preferences) + }, 250) + }) + } - showEmptyHighlights.subscribe((mode) => { - preferences.showEmptyHighlights = mode - ajax.savePreferences(userPreferencesKey, preferences) + bindPreference(showLabels, "showLabels") + bindPreference(showEmptyHighlights, "showEmptyHighlights") + }).then(() => { + this.vis = new ApacheAnnotatorVisualizer(this.root, this.ajax) + this.selector = new ApacheAnnotatorSelector(this.root, this.ajax) + this.toolbar = this.createToolbar() + + this.popover = new AnnotationDetailPopOver({ + target: this.root.ownerDocument.body, + props: { + root: this.root, + ajax: this.ajax + } }) - }) - - this.vis = new ApacheAnnotatorVisualizer(this.root, this.ajax) - this.selector = new ApacheAnnotatorSelector(this.root, this.ajax) - this.toolbar = this.createToolbar() - this.popover = new AnnotationDetailPopOver({ - target: this.root.ownerDocument.body, - props: { - root: this.root, - ajax: this.ajax - } - }) + // Event handler for creating an annotion or selecting an annotation + this.root.addEventListener('mouseup', e => this.onMouseUp(e)) - // Event handler for creating an annotion or selecting an annotation - this.root.addEventListener('mouseup', e => this.onMouseUp(e)) + // Event handler for opening the context menu + this.root.addEventListener('contextmenu', e => this.onRightClick(e)) - // Event handler for opening the context menu - this.root.addEventListener('contextmenu', e => this.onRightClick(e)) - - // Prevent right-click from triggering a selection event - this.root.addEventListener('mousedown', e => this.cancelRightClick(e), { capture: true }) - this.root.addEventListener('mouseup', e => this.cancelRightClick(e), { capture: true }) - this.root.addEventListener('mouseclick', e => this.cancelRightClick(e), { capture: true }) + // Prevent right-click from triggering a selection event + this.root.addEventListener('mousedown', e => this.cancelRightClick(e), { capture: true }) + this.root.addEventListener('mouseup', e => this.cancelRightClick(e), { capture: true }) + this.root.addEventListener('mouseclick', e => this.cancelRightClick(e), { capture: true }) + }) } private createToolbar () { diff --git a/inception/inception-html-apache-annotator-editor/src/main/ts/src/apache-annotator/ApacheAnnotatorVisualizer.ts b/inception/inception-html-apache-annotator-editor/src/main/ts/src/apache-annotator/ApacheAnnotatorVisualizer.ts index d2da6fa32a9..78ad512554a 100644 --- a/inception/inception-html-apache-annotator-editor/src/main/ts/src/apache-annotator/ApacheAnnotatorVisualizer.ts +++ b/inception/inception-html-apache-annotator-editor/src/main/ts/src/apache-annotator/ApacheAnnotatorVisualizer.ts @@ -75,15 +75,17 @@ export class ApacheAnnotatorVisualizer { this.root.addEventListener('mouseover', e => this.addAnnotationHighlight(e as MouseEvent)) this.root.addEventListener('mouseout', e => this.removeAnnotationHighight(e as MouseEvent)) + let initialized = false showLabels.subscribe(enabled => { this.showInlineLabels = enabled - this.loadAnnotations() + if (initialized) this.loadAnnotations() }) showEmptyHighlights.subscribe(enabled => { this.showEmptyHighlights = enabled - this.loadAnnotations() + if (initialized) this.loadAnnotations() }) + initialized = true } private showResizer (event: Event): void { diff --git a/inception/inception-ui-dashboard-activity/pom.xml b/inception/inception-ui-dashboard-activity/pom.xml index fe8e94dc302..9bfeeac01e9 100644 --- a/inception/inception-ui-dashboard-activity/pom.xml +++ b/inception/inception-ui-dashboard-activity/pom.xml @@ -75,6 +75,10 @@ inception-security + + org.springframework + spring-core + org.springframework spring-context diff --git a/inception/inception-ui-dashboard-activity/src/main/java/de/tudarmstadt/ukp/inception/ui/core/dashboard/activity/ActivitiesDashletExtension.java b/inception/inception-ui-dashboard-activity/src/main/java/de/tudarmstadt/ukp/inception/ui/core/dashboard/activity/ActivitiesDashletExtension.java index 9512c31312e..66cf44ebacf 100644 --- a/inception/inception-ui-dashboard-activity/src/main/java/de/tudarmstadt/ukp/inception/ui/core/dashboard/activity/ActivitiesDashletExtension.java +++ b/inception/inception-ui-dashboard-activity/src/main/java/de/tudarmstadt/ukp/inception/ui/core/dashboard/activity/ActivitiesDashletExtension.java @@ -19,12 +19,14 @@ import org.apache.wicket.model.IModel; import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import de.tudarmstadt.ukp.clarin.webanno.model.Project; import de.tudarmstadt.ukp.inception.ui.core.dashboard.dashlet.ProjectDashboardDashletExtension; import de.tudarmstadt.ukp.inception.workload.model.WorkloadManagementService; +@Order(10000) @Component public class ActivitiesDashletExtension implements ProjectDashboardDashletExtension diff --git a/inception/inception-ui-dashboard/src/main/java/de/tudarmstadt/ukp/inception/ui/core/dashboard/dashlet/DocumentHintDashletExtension.java b/inception/inception-ui-dashboard/src/main/java/de/tudarmstadt/ukp/inception/ui/core/dashboard/dashlet/DocumentHintDashletExtension.java index feb7d159778..ea27e84cfc5 100644 --- a/inception/inception-ui-dashboard/src/main/java/de/tudarmstadt/ukp/inception/ui/core/dashboard/dashlet/DocumentHintDashletExtension.java +++ b/inception/inception-ui-dashboard/src/main/java/de/tudarmstadt/ukp/inception/ui/core/dashboard/dashlet/DocumentHintDashletExtension.java @@ -19,12 +19,14 @@ import org.apache.wicket.model.IModel; import org.apache.wicket.spring.injection.annot.SpringBean; +import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import de.tudarmstadt.ukp.clarin.webanno.model.Project; import de.tudarmstadt.ukp.clarin.webanno.project.ProjectAccess; import de.tudarmstadt.ukp.inception.workload.model.WorkloadManagementService; +@Order(100) @Component public class DocumentHintDashletExtension implements ProjectDashboardDashletExtension diff --git a/inception/inception-ui-dashboard/src/main/java/de/tudarmstadt/ukp/inception/ui/core/dashboard/projectlist/ProjectsOverviewPage.html b/inception/inception-ui-dashboard/src/main/java/de/tudarmstadt/ukp/inception/ui/core/dashboard/projectlist/ProjectsOverviewPage.html index 254b2f5f000..767e50c7c12 100644 --- a/inception/inception-ui-dashboard/src/main/java/de/tudarmstadt/ukp/inception/ui/core/dashboard/projectlist/ProjectsOverviewPage.html +++ b/inception/inception-ui-dashboard/src/main/java/de/tudarmstadt/ukp/inception/ui/core/dashboard/projectlist/ProjectsOverviewPage.html @@ -52,7 +52,7 @@
-
+