389 lines
9.8 KiB
Vue
389 lines
9.8 KiB
Vue
<template>
|
|
<div
|
|
class="capture-card uk-card uk-card-default uk-padding-remove uk-width-medium"
|
|
:class="{ 'uk-card-secondary': $store.state.darkMode }"
|
|
>
|
|
<div class="uk-card-media-top">
|
|
<a class="lightbox-link" :href="imgURL" :data-caption="name">
|
|
<img
|
|
class="uk-width-1-1"
|
|
:data-src="thumbURL"
|
|
:alt="id"
|
|
width="300"
|
|
height="225"
|
|
uk-img
|
|
/>
|
|
</a>
|
|
</div>
|
|
|
|
<div class="uk-card-body uk-padding-small">
|
|
<div
|
|
class="uk-width-1-1 uk-margin-small uk-margin-remove-left uk-margin-remove-right"
|
|
uk-grid
|
|
>
|
|
<div class="uk-margin-remove-top uk-padding-remove uk-width-expand">
|
|
{{ name }}
|
|
</div>
|
|
<div class="uk-margin-remove-top uk-padding-remove uk-width-auto">
|
|
<a href="#" class="uk-icon" @click="delCaptureConfirm()">
|
|
<i class="material-icons">delete</i>
|
|
</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div
|
|
class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-expand"
|
|
>
|
|
<time>{{ time }}</time>
|
|
</div>
|
|
<div
|
|
class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-auto"
|
|
>
|
|
<a :href="metadataModalTarget" uk-toggle>More...</a>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="uk-card-footer uk-padding-small">
|
|
<button
|
|
v-if="openInImjoyMenuItems.length != 0"
|
|
class="uk-icon"
|
|
type="button"
|
|
>
|
|
<img
|
|
style="width:25px;"
|
|
src="https://imjoy.io/static/img/imjoy-icon.svg"
|
|
/>
|
|
</button>
|
|
<div uk-dropdown="pos: top-center">
|
|
<ul class="uk-nav uk-dropdown-nav">
|
|
<li v-for="item in openInImjoyMenuItems" :key="item.name">
|
|
<a href="#" @click="item.callback(name, imgURL)"
|
|
><i class="material-icons">launch</i>{{ item.title }}</a
|
|
>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div v-for="tag in tags" :key="tag" class="uk-display-inline">
|
|
<span
|
|
v-if="tag === 'temporary'"
|
|
class="uk-label uk-label-danger uk-margin-small-right"
|
|
uk-tooltip="title: Capture will be removed automatically; delay: 500"
|
|
>Temporary</span
|
|
>
|
|
<span
|
|
v-else
|
|
class="uk-label uk-margin-small-right deletable-label"
|
|
@click="delTagConfirm(tag)"
|
|
>
|
|
{{ tag }}
|
|
</span>
|
|
</div>
|
|
|
|
<a :href="tagModalTarget" uk-toggle>
|
|
<span class="uk-label uk-label-success uk-margin-small-right">Add</span>
|
|
</a>
|
|
</div>
|
|
|
|
<!-- Metadata modal -->
|
|
<div :id="metadataModalID" uk-modal>
|
|
<div
|
|
class="uk-modal-dialog uk-modal-body"
|
|
:class="{
|
|
'uk-light uk-background-secondary': $store.state.darkMode
|
|
}"
|
|
>
|
|
<button class="uk-modal-close-default" type="button" uk-close></button>
|
|
<h2 class="uk-modal-title">{{ name }}</h2>
|
|
<p><b>Path: </b>{{ path }}</p>
|
|
<p><b>Time: </b>{{ time }}</p>
|
|
<p><b>ID: </b>{{ id }}</p>
|
|
<p><b>Format: </b>{{ format }}</p>
|
|
|
|
<hr />
|
|
|
|
<div v-for="(value, key) in annotations" :key="key">
|
|
<p>
|
|
<b>{{ key }}: </b>{{ value }}
|
|
</p>
|
|
</div>
|
|
|
|
<hr />
|
|
|
|
<div class="uk-flex-bottom" uk-grid>
|
|
<div class="uk-width-2-3">
|
|
<keyvalList v-model="newAnnotations" />
|
|
</div>
|
|
<div class="uk-width-1-3">
|
|
<button
|
|
class="uk-button uk-button-primary uk-form-small uk-width-1-1"
|
|
@click="handleAnnotationsSubmit()"
|
|
>
|
|
Add annotation
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- New tag modal -->
|
|
<div :id="tagModalID" uk-modal>
|
|
<form
|
|
class="uk-modal-dialog uk-modal-body uk-margin-auto-vertical"
|
|
:class="{
|
|
'uk-light uk-background-secondary': $store.state.darkMode
|
|
}"
|
|
@submit.prevent="handleTagSubmit"
|
|
>
|
|
<div class="uk-inline">
|
|
<span class="uk-form-icon"><i class="material-icons">label</i></span>
|
|
<input
|
|
v-model="newTag"
|
|
autofocus
|
|
class="uk-input uk-form-width-medium uk-form-small"
|
|
type="text"
|
|
name="tagname"
|
|
placeholder="tag"
|
|
/>
|
|
|
|
<button
|
|
class="uk-button uk-button-default uk-margin-left uk-form-small uk-modal-close"
|
|
type="button"
|
|
>
|
|
Cancel
|
|
</button>
|
|
<button
|
|
type="submit"
|
|
class="uk-button uk-button-primary uk-margin-left uk-form-small"
|
|
>
|
|
Save
|
|
</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import UIkit from "uikit";
|
|
import axios from "axios";
|
|
import { mapState } from "vuex";
|
|
|
|
import keyvalList from "../../fieldComponents/keyvalList";
|
|
|
|
// Export main app
|
|
export default {
|
|
name: "CaptureCard",
|
|
|
|
components: {
|
|
keyvalList
|
|
},
|
|
|
|
props: {
|
|
id: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
name: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
time: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
path: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
format: {
|
|
type: String,
|
|
required: true
|
|
},
|
|
links: {
|
|
type: Object,
|
|
required: true
|
|
},
|
|
tags: {
|
|
type: Array,
|
|
required: false,
|
|
default: function() {
|
|
return [];
|
|
}
|
|
},
|
|
annotations: {
|
|
type: Object,
|
|
required: false,
|
|
default: function() {
|
|
return {};
|
|
}
|
|
}
|
|
},
|
|
|
|
data: function() {
|
|
return {
|
|
newTag: "",
|
|
newAnnotations: {}
|
|
};
|
|
},
|
|
|
|
computed: {
|
|
tagModalID: function() {
|
|
return this.makeModalName("tag-modal-");
|
|
},
|
|
tagModalTarget: function() {
|
|
return "#" + this.tagModalID;
|
|
},
|
|
metadataModalID: function() {
|
|
return this.makeModalName("metadata-modal-");
|
|
},
|
|
metadataModalTarget: function() {
|
|
return "#" + this.metadataModalID;
|
|
},
|
|
thumbURL: function() {
|
|
return `${this.links.download.href}?thumbnail=true`;
|
|
},
|
|
imgURL: function() {
|
|
return this.links.download.href;
|
|
},
|
|
tagsURL: function() {
|
|
return this.links.tags.href;
|
|
},
|
|
annotationsURL: function() {
|
|
return this.links.annotations.href;
|
|
},
|
|
captureURL: function() {
|
|
return this.links.self.href;
|
|
},
|
|
...mapState("imjoy", { openInImjoyMenuItems: "openImageMenu" })
|
|
},
|
|
|
|
created: function() {},
|
|
|
|
methods: {
|
|
getMetadata: function() {
|
|
// Send metadata request
|
|
axios
|
|
.get(this.captureURL)
|
|
.then(response => {
|
|
this.$emit("update:tags", response.data.metadata.image.tags);
|
|
this.$emit(
|
|
"update:annotations",
|
|
response.data.metadata.image.annotations
|
|
);
|
|
})
|
|
.catch(error => {
|
|
this.modalError(error); // Let mixin handle error
|
|
});
|
|
},
|
|
handleTagSubmit: function(event) {
|
|
if (this.newTag !== "") {
|
|
this.newTagRequest(this.newTag);
|
|
this.newTag = "";
|
|
}
|
|
UIkit.modal(event.target.parentNode).hide();
|
|
},
|
|
|
|
handleAnnotationsSubmit: function() {
|
|
this.putAnnotationsRequest(this.newAnnotations);
|
|
this.newAnnotations = {};
|
|
},
|
|
|
|
delCaptureConfirm: function() {
|
|
var context = this;
|
|
this.modalConfirm("Permanantly delete capture?").then(function() {
|
|
context.delCaptureRequest();
|
|
});
|
|
},
|
|
|
|
delCaptureRequest: function() {
|
|
// Send tag DELETE request
|
|
axios
|
|
.delete(this.captureURL)
|
|
.then(() => {
|
|
// Emit signal to update capture list
|
|
this.$root.$emit("globalUpdateCaptures");
|
|
})
|
|
.catch(error => {
|
|
this.modalError(error); // Let mixin handle error
|
|
});
|
|
},
|
|
|
|
newTagRequest: function(tagString) {
|
|
// Send tag PUT request
|
|
axios
|
|
.put(this.tagsURL, [tagString])
|
|
.then(() => {
|
|
// Update tag array
|
|
this.getTagRequest();
|
|
})
|
|
.catch(error => {
|
|
this.modalError(error); // Let mixin handle error
|
|
});
|
|
},
|
|
|
|
putAnnotationsRequest: function(annotationsObject) {
|
|
// Send metadata PUT request
|
|
axios
|
|
.put(this.annotationsURL, annotationsObject)
|
|
.then(() => {
|
|
// Update metadata object
|
|
this.getAnnotationsRequest();
|
|
})
|
|
.catch(error => {
|
|
this.modalError(error); // Let mixin handle error
|
|
});
|
|
},
|
|
|
|
delTagConfirm: function(tagString) {
|
|
var context = this;
|
|
this.modalConfirm(`Remove tag '${tagString}'?`).then(function() {
|
|
context.delTagRequest(tagString);
|
|
});
|
|
},
|
|
|
|
delTagRequest: function(tagString) {
|
|
// Send tag DELETE request
|
|
axios
|
|
.delete(this.tagsURL, { data: [tagString] })
|
|
.then(() => {
|
|
// Update tag array
|
|
this.getTagRequest();
|
|
})
|
|
.catch(error => {
|
|
this.modalError(error); // Let mixin handle error
|
|
});
|
|
},
|
|
|
|
getTagRequest: function() {
|
|
// Send tag request
|
|
axios
|
|
.get(this.tagsURL)
|
|
.then(response => {
|
|
// Pass the update tag array to the parent
|
|
this.$emit("update:tags", response.data);
|
|
})
|
|
.catch(error => {
|
|
this.modalError(error); // Let mixin handle error
|
|
});
|
|
},
|
|
|
|
getAnnotationsRequest: function() {
|
|
// Send tag request
|
|
axios
|
|
.get(this.annotationsURL)
|
|
.then(response => {
|
|
// Pass the update annotation array to the parent
|
|
this.$emit("update:annotations", response.data);
|
|
})
|
|
.catch(error => {
|
|
this.modalError(error); // Let mixin handle error
|
|
});
|
|
},
|
|
|
|
makeModalName: function(prefix) {
|
|
return prefix + this.id;
|
|
}
|
|
}
|
|
};
|
|
</script>
|