|
@@ -2,30 +2,39 @@
|
|
<div class="paginated-media">
|
|
<div class="paginated-media">
|
|
<div class="media" ref="media">
|
|
<div class="media" ref="media">
|
|
<div v-for="image in images"
|
|
<div v-for="image in images"
|
|
- v-bind:key="image.identifier"
|
|
|
|
|
|
+ v-bind:key="image.path"
|
|
class="image"
|
|
class="image"
|
|
@click="$emit('click', image)">
|
|
@click="$emit('click', image)">
|
|
<img :alt="image.name" :src="image.src">
|
|
<img :alt="image.name" :src="image.src">
|
|
|
|
|
|
- <div v-if="current && current.identifier === image.identifier"
|
|
|
|
|
|
+ <div v-if="current && current.path === image.path"
|
|
class="active"/>
|
|
class="active"/>
|
|
|
|
|
|
- <div v-if="deletable"
|
|
|
|
- class="delete"
|
|
|
|
- @click="deleteElement(image)">
|
|
|
|
|
|
+ <div v-if="deletable" class="media-control delete" @click="deleteElement(image)">
|
|
<img alt="remove" src="@/assets/icons/x-circle.svg">
|
|
<img alt="remove" src="@/assets/icons/x-circle.svg">
|
|
</div>
|
|
</div>
|
|
|
|
+
|
|
|
|
+ <div title="Annotated file" v-if="image.has_annotations" class="annotated">
|
|
|
|
+ <img alt="annotated" src="@/assets/icons/tag.svg">
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div title="Copy results from previous file"
|
|
|
|
+ v-if="inline && elements.previous && elements.previous.has_annotations && current && current.identifier == image.identifier" class="media-control copy"
|
|
|
|
+ @click="copyFromPrev2Current">
|
|
|
|
+ <img alt="copy" src="@/assets/icons/paper-airplane.svg">
|
|
|
|
+ </div>
|
|
|
|
+
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
- <div v-if="!inline" class="pagination">
|
|
|
|
- <div class="button" :class="{clickable: page > 1}" @click="prevPage">
|
|
|
|
|
|
+ <div class="pagination">
|
|
|
|
+ <div v-if="!inline" class="button" :class="{clickable: page > 1}" @click="prevPage">
|
|
<
|
|
<
|
|
</div>
|
|
</div>
|
|
<div class="text">
|
|
<div class="text">
|
|
- {{ page }} / {{ pageCount }}
|
|
|
|
|
|
+ Page {{ page }} / {{ pageCount }}
|
|
</div>
|
|
</div>
|
|
- <div class="button" :class="{clickable: page < pageCount}" @click="nextPage">
|
|
|
|
|
|
+ <div v-if="!inline" class="button" :class="{clickable: page < pageCount}" @click="nextPage">
|
|
>
|
|
>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
@@ -35,7 +44,15 @@
|
|
<script>
|
|
<script>
|
|
export default {
|
|
export default {
|
|
name: "paginated-media",
|
|
name: "paginated-media",
|
|
- props: ['rows', 'width', 'inline', 'deletable', 'current', 'filter'],
|
|
|
|
|
|
+ props: [
|
|
|
|
+ 'rows',
|
|
|
|
+ 'width',
|
|
|
|
+ 'inline',
|
|
|
|
+ 'deletable',
|
|
|
|
+ 'current',
|
|
|
|
+ 'filter',
|
|
|
|
+ 'only_annotations'
|
|
|
|
+ ],
|
|
mounted: function () {
|
|
mounted: function () {
|
|
window.addEventListener('resize', this.resize);
|
|
window.addEventListener('resize', this.resize);
|
|
window.addEventListener('wheel', this.scroll);
|
|
window.addEventListener('wheel', this.scroll);
|
|
@@ -98,10 +115,10 @@ export default {
|
|
// edited file is in the current image list
|
|
// edited file is in the current image list
|
|
if (this.filter !== false) {
|
|
if (this.filter !== false) {
|
|
for (let image of this.images) {
|
|
for (let image of this.images) {
|
|
- if (image.identifier === file.identifier) {
|
|
|
|
|
|
+ if (image.path === file.path) {
|
|
this.get(() => {
|
|
this.get(() => {
|
|
// click the first image if the current shown was removed
|
|
// click the first image if the current shown was removed
|
|
- if (this.current.identifier === file.identifier) {
|
|
|
|
|
|
+ if (this.current.path === file.path) {
|
|
this.$emit('click', this.images[0]);
|
|
this.$emit('click', this.images[0]);
|
|
}
|
|
}
|
|
});
|
|
});
|
|
@@ -113,6 +130,14 @@ export default {
|
|
deleteElement: function (element) {
|
|
deleteElement: function (element) {
|
|
this.$root.socket.post(`/data/${element.identifier}/remove`, {remove: true});
|
|
this.$root.socket.post(`/data/${element.identifier}/remove`, {remove: true});
|
|
},
|
|
},
|
|
|
|
+ copyFromPrev2Current: function () {
|
|
|
|
+ if (!this.elements.previous || !this.current)
|
|
|
|
+ return
|
|
|
|
+
|
|
|
|
+ let copy_from = this.elements.previous.identifier;
|
|
|
|
+ let copy_to = this.current.identifier;
|
|
|
|
+ this.$root.socket.post(`/data/${copy_to}/copy_results`, {copy_from});
|
|
|
|
+ },
|
|
prevPage: function (callback) {
|
|
prevPage: function (callback) {
|
|
if (this.page > 1)
|
|
if (this.page > 1)
|
|
this.page -= 1;
|
|
this.page -= 1;
|
|
@@ -166,6 +191,14 @@ export default {
|
|
else
|
|
else
|
|
url = `/projects/${this.$root.project.identifier}/data/${this.filter}/${offset}/${limit}`;
|
|
url = `/projects/${this.$root.project.identifier}/data/${this.filter}/${offset}/${limit}`;
|
|
|
|
|
|
|
|
+ if (this.only_annotations === true)
|
|
|
|
+ url = `${url}?only_with_annotations=1`
|
|
|
|
+ else if (this.only_annotations === false)
|
|
|
|
+ url = `${url}?only_with_annotations=0`
|
|
|
|
+
|
|
|
|
+ // for null or undefined, do not change the URL
|
|
|
|
+
|
|
|
|
+
|
|
// call endpoint
|
|
// call endpoint
|
|
this.$root.socket.get(url)
|
|
this.$root.socket.get(url)
|
|
.then(response => response.json())
|
|
.then(response => response.json())
|
|
@@ -201,9 +234,9 @@ export default {
|
|
if (this.images.length === 0)
|
|
if (this.images.length === 0)
|
|
return;
|
|
return;
|
|
|
|
|
|
- if (this.current.identifier < this.images[0].identifier)
|
|
|
|
|
|
+ if (this.current.path < this.images[0].path)
|
|
this.prevPage(this.findCurrent);
|
|
this.prevPage(this.findCurrent);
|
|
- else if (this.current.identifier > this.images[this.images.length - 1].identifier)
|
|
|
|
|
|
+ else if (this.current.path > this.images[this.images.length - 1].path)
|
|
this.nextPage(this.findCurrent);
|
|
this.nextPage(this.findCurrent);
|
|
}
|
|
}
|
|
},
|
|
},
|
|
@@ -220,8 +253,15 @@ export default {
|
|
// find current in list
|
|
// find current in list
|
|
this.findCurrent();
|
|
this.findCurrent();
|
|
|
|
|
|
|
|
+ let url = `/data/${this.current.identifier}/previous_next`;
|
|
|
|
+
|
|
|
|
+ if (this.only_annotations === true)
|
|
|
|
+ url = `${url}?only_with_annotations=1`
|
|
|
|
+ else if (this.only_annotations === false)
|
|
|
|
+ url = `${url}?only_with_annotations=0`
|
|
|
|
+
|
|
// receive previous and next element
|
|
// receive previous and next element
|
|
- this.$root.socket.get(`/data/${this.current.identifier}/previous_next`)
|
|
|
|
|
|
+ this.$root.socket.get(url)
|
|
.then(response => response.json())
|
|
.then(response => response.json())
|
|
.then(data => {
|
|
.then(data => {
|
|
if (this.filter === undefined || this.filter === false) {
|
|
if (this.filter === undefined || this.filter === false) {
|
|
@@ -243,6 +283,14 @@ export default {
|
|
else
|
|
else
|
|
this.$emit('click', this.images[0]);
|
|
this.$emit('click', this.images[0]);
|
|
});
|
|
});
|
|
|
|
+ },
|
|
|
|
+ only_annotations: function() {
|
|
|
|
+ this.get(() => {
|
|
|
|
+ if (this.images.length === 0)
|
|
|
|
+ this.$emit('click', false);
|
|
|
|
+ else
|
|
|
|
+ this.$emit('click', this.images[0]);
|
|
|
|
+ });
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -288,15 +336,34 @@ export default {
|
|
box-shadow: 0 0 20px -5px var(--primary) inset;
|
|
box-shadow: 0 0 20px -5px var(--primary) inset;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+.media .media-control {
|
|
|
|
+ background-color: rgba(255, 255, 255, 0.4);
|
|
|
|
+ border-radius: 2rem;
|
|
|
|
+ filter: invert(1);
|
|
|
|
+ padding: 0.3rem 0.3rem 0.1rem;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+.media .media-control:hover {
|
|
|
|
+ background-color: rgba(255, 255, 255, 0.8);
|
|
|
|
+}
|
|
|
|
+
|
|
.media .delete {
|
|
.media .delete {
|
|
position: absolute;
|
|
position: absolute;
|
|
top: 0.15rem;
|
|
top: 0.15rem;
|
|
right: 0.15rem;
|
|
right: 0.15rem;
|
|
|
|
+}
|
|
|
|
|
|
- background-color: rgba(255, 255, 255, 0.4);
|
|
|
|
- border-radius: 2rem;
|
|
|
|
- padding: 0.3rem 0.3rem 0.1rem;
|
|
|
|
- filter: invert(1);
|
|
|
|
|
|
+.media .annotated {
|
|
|
|
+ position: absolute;
|
|
|
|
+ top: 0.15rem;
|
|
|
|
+ left: 0.15rem;
|
|
|
|
+
|
|
|
|
+ padding: 0.3rem 0.3rem 0.3rem;
|
|
|
|
+}
|
|
|
|
+.media .copy {
|
|
|
|
+ position: absolute;
|
|
|
|
+ bottom: 0.10rem;
|
|
|
|
+ left: 0.10rem;
|
|
}
|
|
}
|
|
|
|
|
|
.media .delete img {
|
|
.media .delete img {
|