Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Finish 2. point of roadmap: variants list (variants selection) #457

Closed
wants to merge 15 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions examples/ahiqar-arabic-karshuni-with-variants-local.html
Original file line number Diff line number Diff line change
Expand Up @@ -114,19 +114,19 @@
"types": [
{
"name": "Person",
"icon": "biPersonFill"
"icon": "person"
},
{
"name": "Place",
"icon": "biGeoAltFill"
"icon": "marker"
},
{
"name": "Editorial Comment",
"icon": "biChatFill"
"icon": "chat"
},
{
"name": "Reference",
"icon": "biBoxArrowUpRight"
"icon": "externalLink"
}
]
}
Expand All @@ -141,7 +141,7 @@
"types": [
{
"name": "Motif",
"icon": "biPenFill"
"icon": "pen"
}
]
}
Expand All @@ -156,7 +156,7 @@
"types": [
{
"name": "Variant",
"icon": "biPenFill"
"icon": "pen"
}
]
}
Expand Down
36 changes: 31 additions & 5 deletions src/components/annotations/AnnotationVariantItem.vue
Original file line number Diff line number Diff line change
@@ -1,21 +1,47 @@
<template>
<div v-for="(variant, i) in annotation.body.value" :key="i" class="t-items-center t-flex">
<span v-if="variant.witness" v-html="variant.witness" class="t-mr-7"/>
<span v-else class="t-mr-7"> - </span>
<span v-html="variant.entry"/>
<div v-for="(variant, i) in annotation.body.value" :key="i" class="t-items-center t-flex t-mb-1"
:class="[
't-relative t-py-2 t-px-3 t-mb-1 t-rounded-md',
{ 'hover:t-bg-gray-200 dark:hover:t-bg-gray-600 t-cursor-pointer': !isText(annotation) && !isActive(annotation) },
{ 't-bg-gray-300 dark:t-bg-gray-600 active': isActive(annotation) }]"
@click="isText(annotation) ? ()=>{} : toggle(annotation)" :data-annotation-id="annotation.id">
<div class="t-relative t-rounded-3xl t-box-border t-w-75 t-h-8 t-border-2 t-p-[2px]" :style="{'border-color': getItemColorBasedOnIndex(i)}">
<span v-if="variant.witness" v-html="variant.witness" class="t-text-sm"/>
<span v-else class="t-text-sm"> - </span>
</div>
<span v-html="variant.entry" class="t-absolute t-ml-[150px]"/>
<button class="t-bg-blue-500 t-hover:bg-blue-700 t-text-white t-text-sm t-font-bold t-py-1 t-px-2 t-rounded-full t-absolute t-ml-[250px]"
@click="openVariantsModal()">
Open detail
</button>
</div>
</template>



<script setup lang="ts">
import colors from '@/utils/color'
import AnnotationIcon from './AnnotationIcon.vue';
import { getItemColorBasedOnIndex } from '@/utils/color';


function openVariantsModal(){
console.log('open the variants modal')
}


export interface Props {
annotation: Annotation
annotation: Annotation,
isText: (annotation: Annotation) => boolean,
isActive: (annotation: Annotation) => boolean,
toggle: (annotation: Annotation) => void,
}

const props = withDefaults(defineProps<Props>(), {
annotation: () => <Annotation>{},
isText: () => true,
isActive: () => true,
toggle: () => null,
})

</script>
Expand Down
42 changes: 28 additions & 14 deletions src/components/annotations/AnnotationsList.vue
Original file line number Diff line number Diff line change
@@ -1,28 +1,24 @@
<template>
<div class="annotations-list t-overflow-auto">
<TopBar v-if="isVariantsTabOpened()" :variant-annotations="getVariantAnnotations()" />
<div
v-for="annotation in configuredAnnotations"
:key="annotation.id"
:data-annotation-id="annotation.id"
class="item"
:class="[
't-py-2 t-px-3 t-mb-1 t-rounded-md',
{ 'hover:t-bg-gray-200 dark:hover:t-bg-gray-600 t-cursor-pointer': !isText(annotation) && !isActive(annotation) },
{ 't-bg-gray-300 dark:t-bg-gray-600 active': isActive(annotation) }
]"
@click="isText(annotation) ? ()=>{} : toggle(annotation)"
>

<div v-if="!isVariant(annotation)" class="t-flex t-items-center t-space-x-2">
<div v-if="!isVariant(annotation)" class="t-flex t-items-center t-space-x-2 item" :class="[
't-py-2 t-px-3 t-mb-1 t-rounded-md',
{ 'hover:t-bg-gray-200 dark:hover:t-bg-gray-600 t-cursor-pointer': !isText(annotation) && !isActive(annotation) },
{ 't-bg-gray-300 dark:t-bg-gray-600 active': isActive(annotation) }]"
@click="isText(annotation) ? ()=>{} : toggle(annotation)" :data-annotation-id="annotation.id">
<AnnotationIcon
v-if="!isText(annotation)"
:name="getIconName(annotation.body['x-content-type'])"
v-if="!isText(annotation)"
:name="getIconName(annotation.body['x-content-type'])"
/>
<span v-html="annotation.body.value"/>
</div>

<div v-else>
<AnnotationVariantItem :annotation="annotation" />
<div v-else class="variants-annotation">
<AnnotationVariantItem :annotation="annotation" :isText="isText" :isActive="isActive" :toggle="toggle"/>
</div>

<!-- eslint-disable -- https://eslint.vuejs.org/rules/no-v-html.html -->
Expand All @@ -32,10 +28,12 @@
</div>
</template>


<script setup lang="ts">
import { computed } from 'vue';
import AnnotationIcon from '@/components/annotations/AnnotationIcon.vue';
import AnnotationVariantItem from '@/components/annotations/AnnotationVariantItem.vue'
import TopBar from '@/components/annotations/TopBar.vue'

interface AnnotationTypesMapping {
[key: string]: string | 'annotation'
Expand Down Expand Up @@ -68,6 +66,7 @@ function isActive(annotation: Annotation): boolean {
function isText(annotation: Annotation): boolean {
return annotationTypesMapping.value[annotation.body['x-content-type']] === 'text';
}

function getIconName(typeName: string): string {
return props.types.find(({ name }) => name === typeName)?.icon || 'pencil';
}
Expand All @@ -76,10 +75,25 @@ function isVariant(annotation) {
return annotation.body['x-content-type'] === 'Variant';
}

function isVariantsTabOpened() {
return props.configuredAnnotations[0].body['x-content-type'] === 'Variant';
}

function getVariantAnnotations(): Annotation[]{
let variantAnnotations: Annotation[] = []
props.configuredAnnotations.forEach((annotation) => {
if (isVariant(annotation)) variantAnnotations.push(annotation)
})

return variantAnnotations
}

</script>



<style lang="scss" scoped>



</style>
63 changes: 63 additions & 0 deletions src/components/annotations/TopBar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<template>
<div class="t-items-center t-flex t-mb-[30px]">
<WitnessChipInTopBar v-for="(witness, i) in getWitnesses()" :key="i" :witness="witness" :variantAnnotations="variantAnnotations" :index="i"/>
<div class="t-ml-[70px]">
<button class="t-border-[2px] t-rounded-[5px] t-border-sky-400 t-w-[100px] t-bg-sky-200 t-hover:bg-sky-700 t-mr-[2px] t-text-[15px] t-font-bold t-text-sky-500"
@click="handleVariantsClick()"> Variants </button>
<button class="t-border-[1px] t-rounded-[5px] t-border-slate-300 t-w-[100px] t-text-[15px] t-text-zinc-500"
@click="handleWitnessesClick()"> Witnesses </button>
</div>
</div>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { getItemColorBasedOnIndex } from '@/utils/color'
import WitnessChipInTopBar from '@/components/annotations/WitnessChipInTopBar.vue'


export interface Props {
variantAnnotations: Annotation[]
}

const props = withDefaults(defineProps<Props>(), {
variantAnnotations: () => <Annotation[]>[],
})

const checked = ref(false);

function getWitnesses(): string[] {
let witnessesString: string [] = []
props.variantAnnotations.forEach((annotation) => {
annotation.body.value.forEach((variantItem) => {
if (!witnessesString.includes(variantItem.witness.slice(0,4))) {
// made the witness much shorter in order to show them all horizontally
witnessesString.push(variantItem.witness.slice(0,4))
}
})
})

return witnessesString;
}

function handleVariantsClick() {
console.log('clicked the variants button')
}

function handleWitnessesClick() {
console.log('clicked the witnesses button')
}



function handleSpecificWitnessclick(witness: string) {
// i want to differentiate whether it is about showing the variants or hiding them
console.log('witness', witness)
}

</script>


<style scoped>

</style>
105 changes: 105 additions & 0 deletions src/components/annotations/WitnessChipInTopBar.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
<template>
<button :id="'wit-chip-in-top-bar-'+index.toString()" class="t-relative t-rounded-3xl t-box-border t-bg-neutral-300 t-w-75 t-h-8 t-border-2 t-p-[2px] t-ml-[15px]"
:style="{'border-color': getItemColorBasedOnIndex(index)}" @click="handleClick()"> {{ props.witness }} </button>
</template>

<script setup lang="ts">
import { ref } from 'vue';
import { getItemColorBasedOnIndex } from '@/utils/color';

export interface Props {
witness: string,
variantAnnotations: Annotation[],
index: number
}

const props = withDefaults(defineProps<Props>(), {
witness: () => <string>'',
variantAnnotations: () => <Annotation[]>[],
index: () => <number>0,
})

let checked = ref(true);


function handleClick() {
const witChipButtonEl = document.getElementById("wit-chip-in-top-bar-"+props.index.toString())
checked.value = !checked.value
toggleButtonColor(checked.value, witChipButtonEl)
toggleVariantItems(checked.value)
toggleHighlightedText(checked.value)
}

function toggleButtonColor(checked: boolean, witChipButtonEl) {
if (checked === false) {
// change the background color value in the button to white
witChipButtonEl.classList.replace("t-bg-neutral-300", "t-bg-white")
}
else {
witChipButtonEl.classList.replace("t-bg-white", "t-bg-neutral-300");
}
}

function toggleVariantItems(checked: boolean) {
const variantsAnnotationsinTab = document.getElementsByClassName('variants-annotation')
Array.from(variantsAnnotationsinTab).forEach((variantsAnnotation) => {
Array.from(variantsAnnotation.children).forEach((variantItem) => {
let spanElement = variantItem.getElementsByTagName("span")[0]
if(spanElement.innerHTML.includes(props.witness)) {
if (checked) {
variantItem.classList.replace('t-hidden', 't-block')
}
else {
variantItem.classList.add('t-hidden')
}
}
})
})
}


function toggleHighlightedText(checked: boolean) {


// get the selectors on the text for which there is a variant in our witness
const selectorsAnnotated: string [] = getSelectorsAnnotated()

if (selectorsAnnotated.length > 0) {
selectorsAnnotated.forEach((selector) => {
const spanElement = document.querySelector(selector)
if (checked === true) {
spanElement.classList.replace('t-hidden', 't-inline')
}
else {
spanElement.classList.add('t-hidden')
}
})

}
}

function getSelectorsAnnotated(): string[] {
let selectorsAnnotated: string[] = []
props.variantAnnotations.forEach((variantAnnotation) => {
if (isWitnessOnThisAnnotation(variantAnnotation) === true) {
selectorsAnnotated.push(variantAnnotation.target[0].selector.value)
}
})

return selectorsAnnotated
}

function isWitnessOnThisAnnotation(variantAnnotation): boolean {
let isWitnessOnAnnotation = false
variantAnnotation.body.value.forEach((variantItem) => {
if (variantItem.witness.includes(props.witness)) isWitnessOnAnnotation = true
})
return isWitnessOnAnnotation
}


</script>

<style scoped>

</style>
9 changes: 7 additions & 2 deletions src/stores/annotations.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as AnnotationUtils from '@/utils/annotations';
import { request } from '@/utils/http';
import * as Utils from '@/utils';
import { scrollIntoViewIfNeeded } from '@/utils';
import { useConfigStore} from '@/stores/config';
import { useConfigStore } from '@/stores/config';


export const useAnnotationsStore = defineStore('annotations', () => {
Expand Down Expand Up @@ -62,6 +62,9 @@ export const useAnnotationsStore = defineStore('annotations', () => {
if (elements.length > 0) {
const target: HTMLElement = elements[0];
Utils.addIcon(target, newActiveAnnotation, iconName);
if (newActiveAnnotation.body['x-content-type'] === 'Variant') {
Utils.addWitness(target, newActiveAnnotation);
}
scrollIntoViewIfNeeded(target, target.closest('.panel-body'));
}
};
Expand Down Expand Up @@ -133,11 +136,13 @@ export const useAnnotationsStore = defineStore('annotations', () => {
if (selector) {
AnnotationUtils.highlightTargets(selector, { operation: 'DEC' });
AnnotationUtils.removeIcon(removeAnnotation);
if(removeAnnotation.body['x-content-type'] === 'Variant') {
AnnotationUtils.removeWitness(selector, removeAnnotation)
}
}
};



const resetAnnotations = () => {

if (annotations.value !== null) {
Expand Down
Loading