Skip to content

Commit

Permalink
fix: resolve issues with highlighting and panel actions when switchin…
Browse files Browse the repository at this point in the history
…g annotation tabs (#486)

---------

Co-authored-by: malkja <[email protected]>
  • Loading branch information
paulpestov and malkja authored Oct 18, 2024
1 parent d48a87a commit fc99523
Show file tree
Hide file tree
Showing 6 changed files with 97 additions and 65 deletions.
6 changes: 4 additions & 2 deletions src/components/annotations/AnnotationsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ interface Props {
types: AnnotationType[]
}
const props = defineProps<Props>();
const emit = defineEmits(['init'])
const annotations = computed<Annotation[]>(() => annotationStore.annotations);
const filteredAnnotations = computed<Annotation[]>(() => annotationStore.filteredAnnotations);
Expand All @@ -53,14 +54,15 @@ watch(
annotationStore.resetAnnotations();
annotationStore.selectFilteredAnnotations(props.types);
annotationStore.highlightTargetsLevel0();
emit('init')
},
{ immediate: true },
);
const unsubscribe = TextEventBus.on('click', ({ target }) => {
const unsubscribe = TextEventBus.on('click', ({ target }) => {
// Next we look up which annotations need to be selected
// Next we look up which annotations need to be selected
let annotationIds = {};
Utils.getValuesFromAttribute(target, 'data-annotation-ids').forEach((value) => annotationIds[value] = true);
Expand Down
31 changes: 28 additions & 3 deletions src/components/annotations/variants/VariantsView.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ allocateWitnessColorInVariantItem()
const annotations = computed<Annotation[]>(() => annotationStore.annotations);
const activeContentUrl = computed<string>(() => contentsStore.activeContentUrl);
const filteredAnnotations = computed<Annotation[]>(() => annotationStore.filteredAnnotations);
const updateTextHighlighting = computed(() =>
// We need to make sure that annotations are loaded (this.annotations),
// the text HTML is present in DOM (this.activeContentUrl is set after DOM update)
Expand All @@ -29,21 +31,36 @@ watch(
annotationStore.resetAnnotations();
annotationStore.selectFilteredAnnotations([{ name: 'Variant' }]);
annotationStore.highlightTargetsLevel0();
annotationStore.isSingleSelectMode = false
},
{ immediate: true },
);
const unsubscribe = TextEventBus.on('click', ({ target }) => {
const targetIsSelected = parseInt(target.getAttribute('data-annotation-level'), 10) > 0;
const ids = getAnnotationIdsFromTarget(target)
const annotations = filteredAnnotations.value.filter((filtered) => ids.find(id => filtered.id === id))
if (!annotationStore.isSingleSelectMode) {
// We check if the found annotation ids are currently displayed in the active tab, if not we skip the handling
// the annotations referring to the target are not displayed - we do not proceed further
if (annotations.length === 0) return
} else {
// if we are in single select mode, we still have variant annotations, but there are not shown
// if we click at a part of text whose related annotations are not in the variant annotations, then we do not proceed further
const variantAnnotations = getVariantAnnotations(annotationStore.annotations, 'Variant')
if (!variantAnnotations.find((annotation) => annotation.id === ids[0])) {
return
}
}
const targetIsSelected = parseInt(target.getAttribute('data-annotation-level'), 10) > 0
if (annotationStore.isSingleSelectMode) {
if (targetIsSelected) {
annotationStore.removeFilteredAnnotations(ids)
annotationStore.deactivateAnnotationsByIds(ids)
}
else {
} else {
annotationStore.addFilteredAnnotations(ids)
annotationStore.activateAnnotationsByIds(ids)
}
Expand All @@ -59,6 +76,14 @@ const unsubscribe = TextEventBus.on('click', ({ target }) => {
onBeforeUnmount(() => unsubscribe())
function getVariantAnnotations(annotations, type) {
let variantAnnotations = []
annotations.forEach((annotation) => {
if(annotation.body['x-content-type'] === type) variantAnnotations.push(annotation)
})
return variantAnnotations
}
function allocateWitnessColorInVariantItem() {
const colors = {}
if (!annotationStore.witnesses) return
Expand Down
34 changes: 15 additions & 19 deletions src/components/panels/Panel.vue
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ import ContentView from '@/components/ContentView.vue';
import ImageView from '@/components/ImageView.vue';
import PanelZoomAction from '@/components/panels/actions/PanelZoomAction.vue';
import PanelCheckAction from '@/components/panels/actions/PanelCheckAction.vue';
import PanelToggleAction from '@/components/panels/actions/PanelToggleAction.vue';
import VariantsToggleModeAction from '@/components/panels/actions/VariantsToggleModeAction.vue';
import PanelImageAction from '@/components/panels/actions/PanelImageAction.vue';
import LoadingSpinner from '@/components/LoadingSpinner.vue';
import MessageBox from '@/components/MessageBox.vue';
Expand All @@ -161,7 +161,7 @@ export default {
PanelImageAction,
PanelCheckAction,
PanelZoomAction,
PanelToggleAction,
VariantsToggleModeAction,
TreeView,
TabView,
TabPanel,
Expand Down Expand Up @@ -276,19 +276,25 @@ export default {
if (!url) return;
const selected = false;
const events = {
const actionEvents = {
update: (value) => {
if (value === null) return;
if (value) annotationStore.selectAll();
else annotationStore.selectNone();
},
};
const viewEvents = {
init: () => {
tabs.value[i].actions[0].props.selected = false
}
}
unsubscribe.value = annotationStore.$onAction(({
name, args,
}) => {
if (tabs.value.length
&& tabs.value[0]?.actions?.length
&& tabs.value[i]?.actions?.length
&& (name === 'setActiveAnnotations')) {
const activeAnnotations = args[0];
const activeAmount = Object.keys(activeAnnotations).length;
Expand All @@ -309,40 +315,30 @@ export default {
selected,
label: t('select_all'),
},
events,
events: actionEvents,
}];
tabs.value = [...tabs.value, {
component,
label,
props: { ...connector.options },
actions,
events: viewEvents
}];
}
function createVariantsView(view) {
const annotationStore = useAnnotationsStore();
const { connector, label } = view;
const { component } = findComponent(connector.id);
const selectedSingleMode = false
const eventsSingleSelectMode = {
update: (value) => {
if (value) annotationStore.enableSingleSelectMode();
else annotationStore.disableSingleSelectMode();
},
};
const actions = [{
component: 'PanelToggleAction',
component: 'VariantsToggleModeAction',
props: {
selected: selectedSingleMode,
selected: false,
label: t('single_select_mode'),
},
events: eventsSingleSelectMode,
}];
tabs.value = [...tabs.value, {
component,
label,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,29 +39,36 @@
<script setup>
import { ref, watch } from 'vue';
import ToggleButton from 'primevue/togglebutton';
import {useAnnotationsStore} from "@/stores/annotations";
// Unlike other panel action components, this one is not generic and is being used only in combination with VariantsView.
// Updating the selected value from outside was not working, so we use the annotationStore directly here.
const props = defineProps({
selected: Boolean,
label: String,
});
const emit = defineEmits(['update']);
const selectedModel = ref(false);
const annotationStore = useAnnotationsStore();
watch(
() => props.selected,
(value) => {
selectedModel.value = value;
},
(value) => { selectedModel.value = value },
{ immediate: true },
);
watch(
() => annotationStore.isSingleSelectMode,
(value) => { selectedModel.value = value },
);
watch(
selectedModel,
(value, oldValue) => {
if (value !== oldValue) {
emit('update', value);
}
(value) => {
if (value) annotationStore.enableSingleSelectMode();
else annotationStore.disableSingleSelectMode();
},
);
</script>
9 changes: 4 additions & 5 deletions src/stores/annotations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ export const useAnnotationsStore = defineStore('annotations', () => {

// When filtering by witness it can happen that a target is used for some other active annotation item,
// In that case, we want to keep the level of highlighting it had and

filteredAnnotations.value
.filter(annotation => !activeIds.includes(annotation.id))
.forEach(annotation => {
Expand All @@ -145,11 +145,10 @@ export const useAnnotationsStore = defineStore('annotations', () => {
const selectorIsActive = activeIds.filter(id => selector === AnnotationUtils.generateTargetSelector(activeAnnotations.value[id])).length > 0;
const target = document.querySelector(selector)
if(!target) return;

if (!selectorIsActive && AnnotationUtils.getCurrentLevel(target) < 0) {
AnnotationUtils.highlightTargets(selector, {level: 0});
}

})
}

Expand Down Expand Up @@ -301,7 +300,7 @@ export const useAnnotationsStore = defineStore('annotations', () => {

const addHighlightClickListeners = () => {
const textEl = document.querySelector('#text-content>div>*');

if (!textEl) return;

textEl.addEventListener('click', ({target}) => {
Expand All @@ -317,7 +316,7 @@ export const useAnnotationsStore = defineStore('annotations', () => {
if (!target.dataset.annotation) {
target = getNearestParentAnnotation(target);
}

if (!target) {
return;
}
Expand Down
Loading

0 comments on commit fc99523

Please sign in to comment.