123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119 |
- <template>
- <div class="project-labels-window">
- <div class="label" v-for="label in labels" :key="label.id">
- <editable-headline :value="label.name"
- @change="editLabel(label.id, $event)"
- @remove="removeLabel(label.id)">{{ label.name }}
- </editable-headline>
- <media-selector v-if="labeledImages[label.id].length > 0"
- :project-id="currentProject.id"
- :media="labeledImages[label.id]"
- current="-1"
- :socket="socket"></media-selector>
- <div v-else
- class="no-elements">
- No labeled images found...
- </div>
- </div>
- <div class="label">
- <input-group>
- <text-input placeholder="New Label"
- v-model="createLabelValue"
- @enter="createLabel"/>
- <button-input type="primary" @click="createLabel">
- create
- </button-input>
- </input-group>
- </div>
- </div>
- </template>
- <script>
- import TextInput from "@/components/base/text-input";
- import MediaSelector from "@/components/media/media-selector";
- import EditableHeadline from "@/components/base/editable-headline";
- import ButtonInput from "@/components/base/button-input";
- import InputGroup from "@/components/base/input-group";
- export default {
- name: "project-labels-window",
- components: {InputGroup, ButtonInput, EditableHeadline, MediaSelector, TextInput},
- props: ['currentProject', 'socket'],
- data: function () {
- return {
- createLabelValue: ''
- }
- },
- computed: {
- labels: function () {
- let labels = Object.keys(this.currentProject.labels)
- .map(e => this.currentProject.labels[e]);
- labels.sort((a, b) => a.name < b.name ? -1 : +1);
- return labels;
- },
- labeledImages: function () {
- const result = {};
- for (let label of this.labels)
- result[label.id] = [];
- for (let image of Object.values(this.currentProject.data)) {
- for (let prediction of Object.values(image['predictionResults'])) {
- if ('label' in prediction
- && prediction.label in result
- && !result[prediction.label].includes(image)) {
- result[prediction.label].push(image);
- }
- }
- }
- return result;
- }
- },
- methods: {
- createLabel: function () {
- if (!this.createLabelValue)
- return;
- this.socket.post('/projects/' + this.currentProject.id + '/labels', {name: this.createLabelValue});
- this.createLabelValue = '';
- },
- editLabel: function (id, value) {
- this.socket.post('/projects/' + this.currentProject.id + '/labels/' + id, {name: value});
- },
- removeLabel: function (id) {
- this.socket.post('/projects/' + this.currentProject.id + '/labels/' + id, {delete: true});
- }
- }
- }
- </script>
- <style scoped>
- .project-labels-window {
- padding: 1rem;
- overflow: auto;
- }
- .label {
- margin-bottom: 1rem;
- }
- /deep/ .element {
- border: none;
- }
- /deep/ .element:not(:first-child) {
- margin-left: 0.1rem;
- }
- /deep/ .element:not(:last-child) {
- margin-right: 0.1rem;
- }
- .no-elements {
- margin-top: 0.5rem;
- }
- </style>
|