Add a viewer for scans with delete and download buttons
This commit is contained in:
parent
7959b34c44
commit
858e99a47f
2 changed files with 232 additions and 6 deletions
221
webapp/src/components/tabContentComponents/scanListContent.vue
Normal file
221
webapp/src/components/tabContentComponents/scanListContent.vue
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
<template>
|
||||
<div class="galleryDisplay uk-padding uk-padding-remove-top">
|
||||
<!-- Gallery nav bar -->
|
||||
<nav
|
||||
class="gallery-navbar uk-navbar-container uk-navbar-transparent"
|
||||
uk-navbar="mode: click"
|
||||
>
|
||||
<!-- Right side buttons -->
|
||||
<div class="uk-navbar-right">
|
||||
<div class="uk-grid">
|
||||
<div>
|
||||
<button
|
||||
class="uk-button uk-button-default uk-width-1-1"
|
||||
type="button"
|
||||
@click="deleteAllScans()"
|
||||
>
|
||||
Delete All Scans
|
||||
</button>
|
||||
</div>
|
||||
<div>
|
||||
<button
|
||||
class="uk-button uk-button-default uk-width-1-1"
|
||||
type="button"
|
||||
@click="updateScans()"
|
||||
>
|
||||
Refresh Scans
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Gallery -->
|
||||
<div
|
||||
v-if="$store.getters.ready"
|
||||
class="uk-padding-remove-top"
|
||||
uk-lightbox="toggle: .lightbox-link"
|
||||
>
|
||||
<!-- Gallery capture cards -->
|
||||
<div class="gallery-grid uk-grid-match" uk-grid>
|
||||
<div v-for="item in scans" :key="item.id">
|
||||
<div class="uk-card">
|
||||
<div class="uk-card-body">
|
||||
<h3 class="uk-card-title">{{ item.name }}</h3>
|
||||
<a
|
||||
:href="`${scansUri}/${item.name}/images.zip`"
|
||||
:download="`${item.name}_images.zip`"
|
||||
class="uk-button uk-button-default"
|
||||
>
|
||||
Download images
|
||||
</a>
|
||||
<button class="uk-button" @click="deleteScan(item.name)">
|
||||
Delete
|
||||
</button>
|
||||
<ul>
|
||||
<li>{{ item.number_of_images }} images</li>
|
||||
<li>created {{ formatDate(item.created) }}</li>
|
||||
<li>modified {{ formatDate(item.modified) }}</li>
|
||||
</ul>
|
||||
|
||||
<div
|
||||
class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-expand"
|
||||
>
|
||||
<time>{{ item.created }}</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import axios from "axios";
|
||||
|
||||
// Export main app
|
||||
export default {
|
||||
name: "ScanListContent",
|
||||
|
||||
data: function() {
|
||||
return {
|
||||
scans: []
|
||||
};
|
||||
},
|
||||
|
||||
computed: {
|
||||
scansUri() {
|
||||
return this.$store.getters["wot/thingPropertyUrl"](
|
||||
"smart_scan",
|
||||
"scans",
|
||||
"readproperty",
|
||||
true
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
async mounted() {
|
||||
// Update on mount (does nothing if not connected)
|
||||
await this.updateScans();
|
||||
// A global signal listener to perform a gallery refresh
|
||||
this.$root.$on("globalUpdateScans", () => {
|
||||
this.updateScans();
|
||||
});
|
||||
},
|
||||
|
||||
created: function() {
|
||||
// Watch for host 'ready', then update status
|
||||
this.unwatchStoreFunction = this.$store.watch(
|
||||
(state, getters) => {
|
||||
return getters.ready;
|
||||
},
|
||||
ready => {
|
||||
if (ready) {
|
||||
// If the connection is now ready, update capture list
|
||||
this.updateScans();
|
||||
} else {
|
||||
// If the connection is now disconnected, empty capture list
|
||||
this.captures = {};
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
beforeDestroy() {
|
||||
// Remove global signal listener to perform a gallery refresh
|
||||
this.$root.$off("globalUpdateScans");
|
||||
// Then we call that function here to unwatch
|
||||
if (this.unwatchStoreFunction) {
|
||||
this.unwatchStoreFunction();
|
||||
this.unwatchStoreFunction = null;
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
async updateScans() {
|
||||
let scans = await this.readThingProperty("smart_scan", "scans");
|
||||
scans.forEach(scan => {
|
||||
scan.modified = Date.parse(scan.modified);
|
||||
scan.created = Date.parse(scan.created);
|
||||
});
|
||||
scans.sort((a, b) => {
|
||||
return b.modified - a.modified;
|
||||
});
|
||||
this.scans = scans;
|
||||
},
|
||||
formatDate(timestamp) {
|
||||
let d = new Date(timestamp);
|
||||
let yyyy = d.getFullYear();
|
||||
let mm = d.getMonth() + 1;
|
||||
let dd = d.getDate();
|
||||
let HH = d
|
||||
.getHours()
|
||||
.toString()
|
||||
.padStart(2, "0");
|
||||
let MM = d
|
||||
.getMinutes()
|
||||
.toString()
|
||||
.padStart(2, "0");
|
||||
return `${HH}:${MM} ${dd}/${mm}/${yyyy}`;
|
||||
},
|
||||
async deleteScan(name) {
|
||||
try {
|
||||
await this.modalConfirm(`Are you sure you want to delete ${name}?`);
|
||||
await axios.delete(`${this.scansUri}/${name}`);
|
||||
await this.updateScans();
|
||||
this.modalNotify(`Deleted ${name}`);
|
||||
} catch (e) {
|
||||
// if the confirmation was cancelled, it's rejected with null error
|
||||
if (e) this.modalError(e);
|
||||
}
|
||||
},
|
||||
async deleteAllScans() {
|
||||
try {
|
||||
await this.modalConfirm(
|
||||
"Are you sure you want to delete all scans from the microscope? " +
|
||||
"This is <b>irreversible</b>!"
|
||||
);
|
||||
await axios.delete(`${this.scansUri}`);
|
||||
await this.updateScans();
|
||||
this.modalNotify("Deleted all scans.");
|
||||
} catch (e) {
|
||||
// if the confirmation was cancelled, it's rejected with null error
|
||||
if (e) this.modalError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="less" scoped>
|
||||
.gallery-navbar {
|
||||
border-width: 0 0 1px 0;
|
||||
border-style: solid;
|
||||
border-color: rgba(180, 180, 180, 0.25);
|
||||
}
|
||||
|
||||
.gallery-navbar,
|
||||
.gallery-folder-heading {
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
/*
|
||||
.gallery-grid {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(auto-fill, 320px);
|
||||
justify-content: center;
|
||||
overflow-y: auto;
|
||||
}
|
||||
|
||||
.gallery-grid > div {
|
||||
display: inline-block;
|
||||
margin-bottom: 20px;
|
||||
}
|
||||
|
||||
/deep/ .capture-card {
|
||||
width: 300px;
|
||||
height: 100%; // Used to have all cards in a row match their heights
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}*/
|
||||
</style>
|
||||
Loading…
Add table
Add a link
Reference in a new issue