Browse Source

Add LabelSelect components

pull/1263/head
Hironsan 3 years ago
parent
commit
323bba9736
3 changed files with 247 additions and 0 deletions
  1. 46
      frontend/components/tasks/textClassification/LabelSelect.vue
  2. 108
      frontend/components/tasks/textClassification/multiLabel/LabelSelect.vue
  3. 93
      frontend/components/tasks/textClassification/singleLabel/LabelSelect.vue

46
frontend/components/tasks/textClassification/LabelSelect.vue

@ -0,0 +1,46 @@
<template>
<label-select-single
v-if="singleLabel"
:annotations="annotations"
:labels="labels"
@add="$emit('add', $event)"
@remove="$emit('remove', $event)"
/>
<label-select-multi
v-else
:annotations="annotations"
:labels="labels"
@add="$emit('add', $event)"
@remove="$emit('remove', $event)"
/>
</template>
<script>
import LabelSelectSingle from './singleLabel/LabelSelect.vue'
import LabelSelectMulti from './multiLabel/LabelSelect.vue'
export default {
components: {
LabelSelectSingle,
LabelSelectMulti
},
props: {
labels: {
type: Array,
default: () => [],
required: true
},
annotations: {
type: Array,
default: () => ([]),
required: true
},
singleLabel: {
type: Boolean,
default: false,
required: true
}
}
}
</script>

108
frontend/components/tasks/textClassification/multiLabel/LabelSelect.vue

@ -0,0 +1,108 @@
<template>
<v-combobox
v-model="annotatedLabels"
chips
:items="labels"
item-text="text"
hide-details
hide-selected
multiple
class="pt-0"
:search-input.sync="search"
@change="search=''"
>
<template v-slot:selection="{ attrs, item, select, selected }">
<v-chip
v-bind="attrs"
:input-value="selected"
:color="item.backgroundColor"
:text-color="$contrastColor(item.backgroundColor)"
close
@click="select"
@click:close="remove(item)"
>
<v-avatar
left
color="white"
class="black--text font-weight-bold"
>
{{ item.suffixKey }}
</v-avatar>
{{ item.text }}
</v-chip>
</template>
<template v-slot:item="{ item }">
<v-chip
:color="item.backgroundColor"
:text-color="$contrastColor(item.backgroundColor)"
>
<v-avatar
left
color="white"
class="black--text font-weight-bold"
>
{{ item.suffixKey }}
</v-avatar>
{{ item.text }}
</v-chip>
</template>
</v-combobox>
</template>
<script>
export default {
props: {
labels: {
type: Array,
default: () => [],
required: true
},
annotations: {
type: Array,
default: () => ([]),
required: true
}
},
data() {
return {
search: ''
}
},
computed: {
annotatedLabels: {
get() {
const labelIds = this.annotations.map(item => item.label)
return this.labels.filter(item => labelIds.includes(item.id))
},
set(newValue) {
if (newValue.length > this.annotations.length) {
const label = newValue[newValue.length - 1]
if (typeof label === 'object') {
this.add(label)
} else {
newValue.pop()
}
} else {
const label = this.annotatedLabels.find(x => !newValue.some(y => y.id === x.id))
if (typeof label === 'object') {
this.remove(label)
}
}
}
}
},
methods: {
add(label) {
this.$emit('add', label.id)
},
remove(label) {
const annotation = this.annotations.find(item => item.label === label.id)
this.$emit('remove', annotation.id)
}
}
}
</script>

93
frontend/components/tasks/textClassification/singleLabel/LabelSelect.vue

@ -0,0 +1,93 @@
<template>
<v-select
:value="annotatedLabel"
chips
:items="labels"
item-text="text"
hide-details
hide-selected
return-object
class="pt-0"
@change="addOrRemove"
>
<template v-slot:selection="{ attrs, item, select, selected }">
<v-chip
v-if="item.backgroundColor"
v-bind="attrs"
:input-value="selected"
:color="item.backgroundColor"
:text-color="$contrastColor(item.backgroundColor)"
close
@click="select"
@click:close="remove(item)"
>
<v-avatar
left
color="white"
class="black--text font-weight-bold"
>
{{ item.suffixKey }}
</v-avatar>
{{ item.text }}
</v-chip>
</template>
<template v-slot:item="{ item }">
<v-chip
:color="item.backgroundColor"
:text-color="$contrastColor(item.backgroundColor)"
>
<v-avatar
left
color="white"
class="black--text font-weight-bold"
>
{{ item.suffixKey }}
</v-avatar>
{{ item.text }}
</v-chip>
</template>
</v-select>
</template>
<script>
export default {
props: {
labels: {
type: Array,
default: () => [],
required: true
},
annotations: {
type: Array,
default: () => ([]),
required: true
}
},
computed: {
annotatedLabel() {
const labelIds = this.annotations.map(item => item.label)
return this.labels.find(item => labelIds.includes(item.id))
}
},
methods: {
addOrRemove(val) {
if (val) {
this.add(val)
} else {
this.remove(this.annotatedLabel)
}
},
add(label) {
this.$emit('add', label.id)
},
remove(label) {
const annotation = this.annotations.find(item => item.label === label.id)
this.$emit('remove', annotation.id)
}
}
}
</script>
Loading…
Cancel
Save