Updated client to simplify capture data

This commit is contained in:
Joel Collins 2020-11-03 15:40:28 +00:00
parent 6c51da5394
commit 982154ce22
4 changed files with 143 additions and 119 deletions

View file

@ -360,7 +360,7 @@ export default {
enterApp: function() { enterApp: function() {
// Stuff to do once connected and all init modals are finished // Stuff to do once connected and all init modals are finished
console.log("Entering main application"); console.log("Entering main application");
this.currentTab = "view"; //this.currentTab = "view";
} }
} }
}; };

View file

@ -4,11 +4,11 @@
:class="{ 'uk-card-secondary': $store.state.globalSettings.darkMode }" :class="{ 'uk-card-secondary': $store.state.globalSettings.darkMode }"
> >
<div class="uk-card-media-top"> <div class="uk-card-media-top">
<a class="lightbox-link" :href="imgURL" :data-caption="fileName"> <a class="lightbox-link" :href="imgURL" :data-caption="name">
<img <img
class="uk-width-1-1" class="uk-width-1-1"
:data-src="thumbURL" :data-src="thumbURL"
:alt="captureState.metadata.image.id" :alt="id"
width="300" width="300"
height="225" height="225"
uk-img uk-img
@ -22,7 +22,7 @@
uk-grid uk-grid
> >
<div class="uk-margin-remove-top uk-padding-remove uk-width-expand"> <div class="uk-margin-remove-top uk-padding-remove uk-width-expand">
{{ fileName }} {{ name }}
</div> </div>
<div class="uk-margin-remove-top uk-padding-remove uk-width-auto"> <div class="uk-margin-remove-top uk-padding-remove uk-width-auto">
<a href="#" class="uk-icon" @click="delCaptureConfirm()"> <a href="#" class="uk-icon" @click="delCaptureConfirm()">
@ -34,7 +34,7 @@
<div <div
class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-expand" class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-expand"
> >
<time>{{ captureState.metadata.image.acquisitionDate }}</time> <time>{{ time }}</time>
</div> </div>
<div <div
class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-auto" class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-auto"
@ -75,11 +75,11 @@
}" }"
> >
<button class="uk-modal-close-default" type="button" uk-close></button> <button class="uk-modal-close-default" type="button" uk-close></button>
<h2 class="uk-modal-title">{{ fileName }}</h2> <h2 class="uk-modal-title">{{ name }}</h2>
<p><b>Path: </b>{{ captureState.path }}</p> <p><b>Path: </b>{{ path }}</p>
<p><b>Time: </b>{{ captureState.metadata.image.acquisitionDate }}</p> <p><b>Time: </b>{{ time }}</p>
<p><b>ID: </b>{{ captureState.metadata.image.id }}</p> <p><b>ID: </b>{{ id }}</p>
<p><b>Format: </b>{{ captureState.metadata.image.format }}</p> <p><b>Format: </b>{{ format }}</p>
<hr /> <hr />
@ -161,27 +161,54 @@ export default {
}, },
props: { props: {
captureState: { 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, type: Object,
required: true required: true
},
tags: {
type: Array,
required: false,
default: function() {
return [];
}
},
annotations: {
type: Object,
required: false,
default: function() {
return {};
}
} }
}, },
data: function() { data: function() {
return { return {
tags: [],
newTag: "", newTag: "",
annotations: {},
newAnnotations: {} newAnnotations: {}
}; };
}, },
computed: { computed: {
fileName: function() {
return this.captureState.name // If this.captureState.filename exists
? this.captureState.name // Use this.captureState.filename
: this.captureState.metadata.filename; // Otherwise use old this.captureState.metadata.filename
},
tagModalID: function() { tagModalID: function() {
return this.makeModalName("tag-modal-"); return this.makeModalName("tag-modal-");
}, },
@ -195,29 +222,41 @@ export default {
return "#" + this.metadataModalID; return "#" + this.metadataModalID;
}, },
thumbURL: function() { thumbURL: function() {
return `${this.captureState.links.download.href}?thumbnail=true`; return `${this.links.download.href}?thumbnail=true`;
}, },
imgURL: function() { imgURL: function() {
return this.captureState.links.download.href; return this.links.download.href;
}, },
tagsURL: function() { tagsURL: function() {
return this.captureState.links.tags.href; return this.links.tags.href;
}, },
annotationsURL: function() { annotationsURL: function() {
return this.captureState.links.annotations.href; return this.links.annotations.href;
}, },
captureURL: function() { captureURL: function() {
return this.captureState.links.self.href; return this.links.self.href;
} }
}, },
created: function() { created: function() {},
// Get initial metadata from prop
this.tags = this.captureState.metadata.image.tags;
this.annotations = this.captureState.metadata.annotations;
},
methods: { methods: {
getMetadata: function() {
// Send metadata request
console.log("Loading capture metadata...");
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) { handleTagSubmit: function(event) {
if (this.newTag !== "") { if (this.newTag !== "") {
this.newTagRequest(this.newTag); this.newTagRequest(this.newTag);
@ -303,7 +342,8 @@ export default {
axios axios
.get(this.tagsURL) .get(this.tagsURL)
.then(response => { .then(response => {
this.tags = response.data; // Pass the update tag array to the parent
this.$emit("update:tags", response.data);
}) })
.catch(error => { .catch(error => {
this.modalError(error); // Let mixin handle error this.modalError(error); // Let mixin handle error
@ -315,7 +355,8 @@ export default {
axios axios
.get(this.annotationsURL) .get(this.annotationsURL)
.then(response => { .then(response => {
this.annotations = response.data; // Pass the update annotation array to the parent
this.$emit("update:annotations", response.data);
}) })
.catch(error => { .catch(error => {
this.modalError(error); // Let mixin handle error this.modalError(error); // Let mixin handle error
@ -323,7 +364,7 @@ export default {
}, },
makeModalName: function(prefix) { makeModalName: function(prefix) {
return prefix + this.captureState.metadata.image.id; return prefix + this.id;
} }
} }
}; };

View file

@ -6,8 +6,8 @@
<a href="#"> <a href="#">
<img <img
class="uk-width-1-1" class="uk-width-1-1"
:data-src="scanState.thumbnail" :data-src="thumbnail"
:alt="scanState.metadata.image.id" :alt="id"
width="300" width="300"
height="225" height="225"
uk-img uk-img
@ -22,8 +22,8 @@
uk-grid uk-grid
> >
<div class="uk-margin-remove-top uk-padding-remove uk-width-expand"> <div class="uk-margin-remove-top uk-padding-remove uk-width-expand">
<b>{{ scanState.metadata.type || "Dataset" }}: </b> <b>{{ type }}: </b>
{{ scanState.metadata.image.name }} {{ name }}
</div> </div>
<div class="uk-margin-remove-top uk-padding-remove uk-width-auto"> <div class="uk-margin-remove-top uk-padding-remove uk-width-auto">
<a href="#" class="uk-icon" @click="delAllConfirm()"> <a href="#" class="uk-icon" @click="delAllConfirm()">
@ -35,44 +35,19 @@
<div <div
class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-expand" class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-expand"
> >
<time>{{ scanState.metadata.image.acquisitionDate }}</time> <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> </div>
<div class="uk-card-footer uk-padding-small"> <div class="uk-card-footer uk-padding-small">
<span <span
v-for="tag in scanState.metadata.image.tags" v-for="tag in tags"
:key="tag" :key="tag"
class="uk-label uk-margin-small-right deletable-label" class="uk-label uk-margin-small-right deletable-label"
> >
{{ tag }} {{ tag }}
</span> </span>
</div> </div>
<div :id="metadataModalID" uk-modal>
<div class="uk-modal-dialog uk-modal-body">
<button class="uk-modal-close-default" type="button" uk-close></button>
<h2 class="uk-modal-title">{{ scanState.metadata.image.name }}</h2>
<p><b>Time: </b>{{ scanState.metadata.image.acquisitionDate }}</p>
<p><b>ID: </b>{{ scanState.metadata.image.id }}</p>
<hr />
<div
v-for="(value, key) in scanState.metadata.image.annotations"
:key="key"
>
<p>
<b>{{ key }}: </b>{{ value }}
</p>
</div>
</div>
</div>
</div> </div>
</template> </template>
@ -84,25 +59,37 @@ export default {
name: "ScanCard", name: "ScanCard",
props: { props: {
scanState: { id: {
type: Object, type: String,
required: true required: true
},
name: {
type: String,
required: true
},
time: {
type: String,
required: true
},
type: {
type: String,
required: false,
default: "Dataset"
},
thumbnail: {
type: String,
required: true
},
tags: {
type: Array,
required: false,
default: function() {
return [];
}
} }
}, },
computed: { 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;
},
allURLs: function() { allURLs: function() {
var urls = []; var urls = [];
for (var capture of this.scanState.captures) { for (var capture of this.scanState.captures) {
@ -114,11 +101,7 @@ export default {
methods: { methods: {
onClick: function() { onClick: function() {
this.$emit("selectFolder", this.scanState.metadata.image.id); this.$emit("selectFolder", this.id);
},
makeModalName: function(prefix) {
return prefix + this.scanState.metadata.image.id;
}, },
delAllConfirm: function() { delAllConfirm: function() {

View file

@ -91,20 +91,37 @@
<div class="uk-margin-left"> <div class="uk-margin-left">
<h3 class="uk-margin-remove uk-margin-left"> <h3 class="uk-margin-remove uk-margin-left">
<b>SCAN</b> <b>SCAN</b>
{{ allScans[galleryFolder].metadata.image.name }} {{ allScans[galleryFolder].name }}
</h3> </h3>
</div> </div>
</div> </div>
<!-- Gallery capture cards --> <!-- Gallery capture cards -->
<div class="gallery-grid"> <div class="gallery-grid">
<div v-for="item in pagedItems" :key="item.metadata.id"> <div v-for="item in pagedItems" :key="item.id">
<scanCard <scanCard
v-if="'isScan' in item" v-if="'isScan' in item"
:scan-state="item" :id="item.id"
:name="item.name"
:time="item.time"
:tags="item.tags"
:type="item.type"
:thumbnail="item.thumbnail"
@selectFolder="selectFolder" @selectFolder="selectFolder"
/> />
<captureCard v-else :capture-state="item" /> <captureCard
v-else
:id="item.id"
:links="item.links"
:name="item.name"
:format="item.format"
:path="item.path"
:time="item.time"
:tags="item.tags"
:annotations="item.annotations"
@update:tags="item.tags = $event"
@update:annotations="item.annotations = $event"
/>
</div> </div>
</div> </div>
@ -164,7 +181,7 @@ export default {
// Return an array of unique tags across all captures // Return an array of unique tags across all captures
var tags = []; var tags = [];
for (var capture of this.captures) { for (var capture of this.captures) {
for (var tag of capture.metadata.image.tags) { for (var tag of capture.tags) {
if (!tags.includes(tag)) { if (!tags.includes(tag)) {
tags.push(tag); tags.push(tag);
} }
@ -178,7 +195,7 @@ export default {
var captures = []; var captures = [];
for (var capture of this.captures) { for (var capture of this.captures) {
// Add to capture list if matched // Add to capture list if matched
if (!capture.metadata.dataset) { if (!capture.dataset) {
captures.push(capture); captures.push(capture);
} }
} }
@ -191,9 +208,7 @@ export default {
var scans = {}; var scans = {};
for (var capture of this.captures) { for (var capture of this.captures) {
var annotations = capture.metadata.image.annotations; var dataset = capture.dataset;
var tags = capture.metadata.image.tags;
var dataset = capture.metadata.dataset;
if (dataset) { if (dataset) {
var id = dataset["id"]; var id = dataset["id"];
@ -201,34 +216,22 @@ export default {
// If this scan ID hasn't been seen before // If this scan ID hasn't been seen before
if (!(id in scans)) { if (!(id in scans)) {
scans[id] = {}; scans[id] = {};
scans[id].id = id;
scans[id].name = dataset.name;
scans[id].type = dataset.type;
// Use time of first found capture in dataset
scans[id].time = capture.time;
scans[id].isScan = true; scans[id].isScan = true;
scans[id].captures = []; scans[id].captures = [];
scans[id].metadata = { scans[id].tags = [];
image: {
name: dataset.name,
acquisitionDate: dataset.acquisitionDate,
id: dataset.id,
tags: [],
annotations: {}
},
type: dataset.type
};
} }
// Add the capture object to the scan // Add the capture object to the scan
scans[id].captures.push(capture); scans[id].captures.push(capture);
// Add missing scan metadata, prioritising first capture
for (var key of Object.keys(annotations)) {
if (!(key in scans[id].metadata.image.annotations)) {
scans[id].metadata.image.annotations[key] = annotations[key];
}
}
// Append missing tags // Append missing tags
for (var tag of tags) { for (var tag of capture.tags) {
if (!scans[id].metadata.image.tags.includes(tag)) { if (!scans[id].tags.includes(tag)) {
scans[id].metadata.image.tags.push(tag); scans[id].tags.push(tag);
} }
} }
@ -272,11 +275,11 @@ export default {
if ("captures" in item) { if ("captures" in item) {
for (var capture of item.captures) { for (var capture of item.captures) {
// Get the ID of each capture in the set // Get the ID of each capture in the set
captures[capture.metadata.image.id] = capture; captures[capture.id] = capture;
} }
} else { } else {
// If it's a single capture, get the ID of the capture // If it's a single capture, get the ID of the capture
captures[item.metadata.image.id] = item; captures[item.id] = item;
} }
} }
@ -360,7 +363,7 @@ export default {
var includeCapture = false; var includeCapture = false;
// Filter by selected tags // Filter by selected tags
var tags = capture.metadata.image.tags; var tags = capture.tags;
let checker = (arr, target) => target.every(v => arr.includes(v)); let checker = (arr, target) => target.every(v => arr.includes(v));
// True if all tags match // True if all tags match
includeCapture = checker(tags, filterTags); includeCapture = checker(tags, filterTags);
@ -377,10 +380,8 @@ export default {
sortCaptures: function(list) { sortCaptures: function(list) {
// Sort a list of captures by metadata time // Sort a list of captures by metadata time
function compare(a, b) { function compare(a, b) {
if (a.metadata.image.acquisitionDate < b.metadata.image.acquisitionDate) if (a.time < b.time) return -1;
return -1; if (a.time > b.time) return 1;
if (a.metadata.image.acquisitionDate > b.metadata.image.acquisitionDate)
return 1;
return 0; return 0;
} }
@ -397,7 +398,6 @@ export default {
}, },
selectFolder: function(folderID) { selectFolder: function(folderID) {
console.log(folderID);
this.galleryFolder = folderID; this.galleryFolder = folderID;
} }
} }