Start the UI transition from ScanList to Gallery
This commit is contained in:
parent
d358d89334
commit
5f6b54247d
5 changed files with 71 additions and 76 deletions
|
|
@ -85,7 +85,7 @@ import aboutContent from "./tabContentComponents/aboutContent.vue";
|
||||||
import controlContent from "./tabContentComponents/controlContent.vue";
|
import controlContent from "./tabContentComponents/controlContent.vue";
|
||||||
import loggingContent from "./tabContentComponents/loggingContent.vue";
|
import loggingContent from "./tabContentComponents/loggingContent.vue";
|
||||||
import powerContent from "./tabContentComponents/powerContent.vue";
|
import powerContent from "./tabContentComponents/powerContent.vue";
|
||||||
import scanListContent from "./tabContentComponents/scanListContent.vue";
|
import galleryContent from "./tabContentComponents/galleryContent.vue";
|
||||||
import settingsContent from "./tabContentComponents/settingsContent.vue";
|
import settingsContent from "./tabContentComponents/settingsContent.vue";
|
||||||
import slideScanContent from "./tabContentComponents/slideScanContent.vue";
|
import slideScanContent from "./tabContentComponents/slideScanContent.vue";
|
||||||
import viewContent from "./tabContentComponents/viewContent.vue";
|
import viewContent from "./tabContentComponents/viewContent.vue";
|
||||||
|
|
@ -158,10 +158,10 @@ export default {
|
||||||
requiredThings: ["smart_scan"],
|
requiredThings: ["smart_scan"],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "scan-list",
|
id: "gallery",
|
||||||
title: "Scan List",
|
title: "Gallery",
|
||||||
icon: "photo_library",
|
icon: "photo_library",
|
||||||
component: markRaw(scanListContent),
|
component: markRaw(galleryContent),
|
||||||
requiredThings: ["smart_scan"],
|
requiredThings: ["smart_scan"],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -12,16 +12,16 @@
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h3 class="uk-card-title scan-card-title">{{ scanData.name }}</h3>
|
<h3 class="uk-card-title gallery-card-title">{{ itemData.name }}</h3>
|
||||||
<div class="button-container">
|
<div class="button-container">
|
||||||
<div class="uk-button-group scan-card-buttons">
|
<div class="uk-button-group gallery-card-buttons">
|
||||||
<action-button
|
<action-button
|
||||||
class="uk-width-1-2"
|
class="uk-width-1-2"
|
||||||
thing="smart_scan"
|
thing="smart_scan"
|
||||||
action="download_zip"
|
action="download_zip"
|
||||||
submit-label="Download All"
|
submit-label="Download All"
|
||||||
:can-terminate="false"
|
:can-terminate="false"
|
||||||
:submit-data="{ scan_name: scanData.name }"
|
:submit-data="{ scan_name: itemData.name }"
|
||||||
:button-primary="true"
|
:button-primary="true"
|
||||||
@response="downloadZipFile"
|
@response="downloadZipFile"
|
||||||
@error="modalError"
|
@error="modalError"
|
||||||
|
|
@ -29,45 +29,45 @@
|
||||||
<EndpointButton
|
<EndpointButton
|
||||||
class="uk-width-1-2"
|
class="uk-width-1-2"
|
||||||
:button-primary="true"
|
:button-primary="true"
|
||||||
:is-disabled="!scanData.stitch_available"
|
:is-disabled="!itemData.stitch_available"
|
||||||
:url="downloadStitchFile"
|
:url="downloadStitchFile"
|
||||||
button-label="Download JPEG"
|
button-label="Download JPEG"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<button class="uk-button uk-button-default uk-width-1-1" @click="deleteScan">Delete</button>
|
<button class="uk-button uk-button-default uk-width-1-1" @click="deleteScan">Delete</button>
|
||||||
<action-button
|
<action-button
|
||||||
v-if="scanData.can_stitch | (scanData.stitch_available & !scanData.dzi)"
|
v-if="itemData.can_stitch | (itemData.stitch_available & !itemData.dzi)"
|
||||||
submit-label="Stitch Images"
|
submit-label="Stitch Images"
|
||||||
thing="smart_scan"
|
thing="smart_scan"
|
||||||
action="stitch_scan"
|
action="stitch_scan"
|
||||||
:can-terminate="true"
|
:can-terminate="true"
|
||||||
:submit-data="{ scan_name: scanData.name }"
|
:submit-data="{ scan_name: itemData.name }"
|
||||||
:button-primary="false"
|
:button-primary="false"
|
||||||
:modal-progress="true"
|
:modal-progress="true"
|
||||||
@error="modalError"
|
@error="modalError"
|
||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
v-if="scanData.dzi"
|
v-if="itemData.dzi"
|
||||||
class="uk-button uk-button-default uk-width-1-1"
|
class="uk-button uk-button-default uk-width-1-1"
|
||||||
@click="requestViewer"
|
@click="requestViewer"
|
||||||
>
|
>
|
||||||
Show Stitched Scan
|
Show Stitched Scan
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
<div class="scan-info">
|
<div class="item-info">
|
||||||
<ul>
|
<ul>
|
||||||
<li>{{ scanData.number_of_images }} images</li>
|
<li>{{ itemData.number_of_images }} images</li>
|
||||||
<li>Created: {{ formatDate(scanData.created) }}</li>
|
<li>Created: {{ formatDate(itemData.created) }}</li>
|
||||||
<li>Duration: {{ formatDuration(scanData.duration) }}</li>
|
<li>Duration: {{ formatDuration(itemData.duration) }}</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul>
|
<ul>
|
||||||
<li v-if="scanData.number_of_images < 3" class="warning-msg">
|
<li v-if="itemData.number_of_images < 3" class="warning-msg">
|
||||||
Not enough images to stitch
|
Not enough images to stitch
|
||||||
</li>
|
</li>
|
||||||
<li v-else-if="!scanData.dzi && scanData.stitch_available" class="alert-msg">
|
<li v-else-if="!itemData.dzi && itemData.stitch_available" class="alert-msg">
|
||||||
Interactive preview not available
|
Interactive preview not available
|
||||||
</li>
|
</li>
|
||||||
<li v-else-if="!scanData.stitch_available" class="alert-msg">
|
<li v-else-if="!itemData.stitch_available" class="alert-msg">
|
||||||
High quality stitch not available
|
High quality stitch not available
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -85,21 +85,17 @@ import { useSettingsStore } from "@/stores/settings.js";
|
||||||
|
|
||||||
// Export main app
|
// Export main app
|
||||||
export default {
|
export default {
|
||||||
name: "ScanCard",
|
name: "GalleryCard",
|
||||||
components: {
|
components: {
|
||||||
actionButton,
|
actionButton,
|
||||||
EndpointButton,
|
EndpointButton,
|
||||||
},
|
},
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
scanData: {
|
itemData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
scansUri: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
emits: ["viewer-requested", "update-requested"],
|
emits: ["viewer-requested", "update-requested"],
|
||||||
|
|
@ -107,10 +103,10 @@ export default {
|
||||||
computed: {
|
computed: {
|
||||||
...mapState(useSettingsStore, ["baseUri"]),
|
...mapState(useSettingsStore, ["baseUri"]),
|
||||||
downloadStitchFile() {
|
downloadStitchFile() {
|
||||||
return `${this.baseUri}/smart_scan/get_stitch/${this.scanData.name}`;
|
return `${this.baseUri}/smart_scan/get_stitch/${this.itemData.name}`;
|
||||||
},
|
},
|
||||||
thumbnailPath() {
|
thumbnailPath() {
|
||||||
return `${this.baseUri}/smart_scan/scans/stitched_thumbnail.jpg?scan_name=${this.scanData.name}&modified=${this.scanData.modified}`;
|
return `${this.baseUri}/smart_scan/scans/stitched_thumbnail.jpg?scan_name=${this.itemData.name}&modified=${this.itemData.modified}`;
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -142,14 +138,14 @@ export default {
|
||||||
},
|
},
|
||||||
requestViewer() {
|
requestViewer() {
|
||||||
// Notify parent that thumbnail was clicked
|
// Notify parent that thumbnail was clicked
|
||||||
this.$emit("viewer-requested", this.scanData);
|
this.$emit("viewer-requested", this.itemData);
|
||||||
},
|
},
|
||||||
async deleteScan() {
|
async deleteScan() {
|
||||||
try {
|
try {
|
||||||
await this.modalConfirm(`Are you sure you want to delete ${this.scanData.name}?`);
|
await this.modalConfirm(`Are you sure you want to delete ${this.itemData.name}?`);
|
||||||
await axios.delete(`${this.scansUri}/${this.scanData.name}`);
|
await axios.delete(`${this.baseUri}/smart_scan/scans/${this.itemData.name}`);
|
||||||
this.$emit("update-requested");
|
this.$emit("update-requested");
|
||||||
this.modalNotify(`Deleted ${this.scanData.name}`);
|
this.modalNotify(`Deleted ${this.itemData.name}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// if the confirmation was cancelled, it's rejected with null error
|
// if the confirmation was cancelled, it's rejected with null error
|
||||||
if (e) this.modalError(e);
|
if (e) this.modalError(e);
|
||||||
|
|
@ -189,11 +185,11 @@ ul {
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scan-card-buttons {
|
.gallery-card-buttons {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scan-card-title {
|
.gallery-card-title {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<!-- Right side buttons -->
|
<!-- Right side buttons -->
|
||||||
<div class="uk-navbar-right">
|
<div class="uk-navbar-right">
|
||||||
<div class="uk-grid">
|
<div class="uk-grid">
|
||||||
<div class="scan-list-button">
|
<div class="gallery-button">
|
||||||
<action-button
|
<action-button
|
||||||
class="uk-width-1-1"
|
class="uk-width-1-1"
|
||||||
thing="smart_scan"
|
thing="smart_scan"
|
||||||
|
|
@ -21,7 +21,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
class="uk-button uk-button-default uk-width-1-1 scan-list-button"
|
class="uk-button uk-button-default uk-width-1-1 gallery-button"
|
||||||
type="button"
|
type="button"
|
||||||
@click="deleteAllScans()"
|
@click="deleteAllScans()"
|
||||||
>
|
>
|
||||||
|
|
@ -30,11 +30,11 @@
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
class="uk-button uk-button-default uk-width-1-1 scan-list-button"
|
class="uk-button uk-button-default uk-width-1-1 gallery-button"
|
||||||
type="button"
|
type="button"
|
||||||
@click="updateScans()"
|
@click="refreshGallery()"
|
||||||
>
|
>
|
||||||
Refresh Scans
|
Refresh
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -47,16 +47,15 @@
|
||||||
<div v-if="ready" class="uk-padding-remove-top" uk-lightbox="toggle: .lightbox-link">
|
<div v-if="ready" class="uk-padding-remove-top" uk-lightbox="toggle: .lightbox-link">
|
||||||
<!-- Gallery capture cards -->
|
<!-- Gallery capture cards -->
|
||||||
<div class="gallery-grid uk-grid-match" uk-grid>
|
<div class="gallery-grid uk-grid-match" uk-grid>
|
||||||
<div v-if="scansEmpty">
|
<div v-if="noItems">
|
||||||
<h2>No scans available</h2>
|
<h2>Nothing to show</h2>
|
||||||
<p>There are no scans available to show.</p>
|
<p>There is no captured data to show..</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-for="scanData in paginatedScans" :key="scanData.id">
|
<div v-for="itemData in paginatedItems" :key="itemData.id">
|
||||||
<scan-card
|
<gallery-card
|
||||||
:scan-data="scanData"
|
:item-data="itemData"
|
||||||
:scans-uri="scansUri"
|
|
||||||
@viewer-requested="showScan"
|
@viewer-requested="showScan"
|
||||||
@update-requested="updateScans"
|
@update-requested="refreshGallery"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -73,8 +72,8 @@
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import PaginateLinks from "@/components/genericComponents/paginateLinks.vue";
|
import PaginateLinks from "@/components/genericComponents/paginateLinks.vue";
|
||||||
import actionButton from "../labThingsComponents/actionButton.vue";
|
import actionButton from "../labThingsComponents/actionButton.vue";
|
||||||
import scanCard from "./scanListComponents/scanCard.vue";
|
import galleryCard from "./galleryComponents/galleryCard.vue";
|
||||||
import ScanViewerModal from "./scanListComponents/scanViewer.vue";
|
import ScanViewerModal from "./galleryComponents/scanViewer.vue";
|
||||||
import { eventBus } from "../../eventBus.js";
|
import { eventBus } from "../../eventBus.js";
|
||||||
import { useIntersectionObserver } from "@vueuse/core";
|
import { useIntersectionObserver } from "@vueuse/core";
|
||||||
import { useSettingsStore } from "@/stores/settings.js";
|
import { useSettingsStore } from "@/stores/settings.js";
|
||||||
|
|
@ -83,10 +82,10 @@ import { watch } from "vue";
|
||||||
|
|
||||||
// Export main app
|
// Export main app
|
||||||
export default {
|
export default {
|
||||||
name: "ScanListContent",
|
name: "GalleryContent",
|
||||||
components: {
|
components: {
|
||||||
actionButton,
|
actionButton,
|
||||||
scanCard,
|
galleryCard,
|
||||||
ScanViewerModal,
|
ScanViewerModal,
|
||||||
PaginateLinks,
|
PaginateLinks,
|
||||||
},
|
},
|
||||||
|
|
@ -95,7 +94,7 @@ export default {
|
||||||
|
|
||||||
data: function () {
|
data: function () {
|
||||||
return {
|
return {
|
||||||
scans: [],
|
all_items: [],
|
||||||
selectedScan: null,
|
selectedScan: null,
|
||||||
osdViewer: null,
|
osdViewer: null,
|
||||||
currentPage: 1,
|
currentPage: 1,
|
||||||
|
|
@ -110,8 +109,8 @@ export default {
|
||||||
// The actual property does not exist. So allowUndefined=true
|
// The actual property does not exist. So allowUndefined=true
|
||||||
return this.thingPropertyUrl("smart_scan", "scans", true);
|
return this.thingPropertyUrl("smart_scan", "scans", true);
|
||||||
},
|
},
|
||||||
scansEmpty() {
|
noItmesy() {
|
||||||
return this.scans.length == 0;
|
return this.all_items.length == 0;
|
||||||
},
|
},
|
||||||
selectedScanDZI() {
|
selectedScanDZI() {
|
||||||
if (this.selectedScan && this.selectedScan.dzi != "") {
|
if (this.selectedScan && this.selectedScan.dzi != "") {
|
||||||
|
|
@ -121,11 +120,11 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
totalPages() {
|
totalPages() {
|
||||||
return Math.ceil(this.scans.length / this.itemsPerPage);
|
return Math.ceil(this.all_items.length / this.itemsPerPage);
|
||||||
},
|
},
|
||||||
paginatedScans() {
|
paginatedItems() {
|
||||||
const start = (this.currentPage - 1) * this.itemsPerPage;
|
const start = (this.currentPage - 1) * this.itemsPerPage;
|
||||||
return this.scans.slice(start, start + this.itemsPerPage);
|
return this.all_items.slice(start, start + this.itemsPerPage);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
@ -134,9 +133,9 @@ export default {
|
||||||
const { ready } = storeToRefs(store);
|
const { ready } = storeToRefs(store);
|
||||||
watch(ready, (isReady) => {
|
watch(ready, (isReady) => {
|
||||||
if (isReady) {
|
if (isReady) {
|
||||||
this.updateScans();
|
this.refreshGallery();
|
||||||
} else {
|
} else {
|
||||||
this.scans = [];
|
this.all_items = [];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
useIntersectionObserver(
|
useIntersectionObserver(
|
||||||
|
|
@ -149,51 +148,51 @@ export default {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
// Update on mount (does nothing if not connected)
|
// Update on mount (does nothing if not connected)
|
||||||
await this.updateScans();
|
await this.refreshGallery();
|
||||||
// A global signal listener to perform a gallery refresh
|
// A global signal listener to perform a gallery refresh
|
||||||
eventBus.on("globalUpdateScans", () => {
|
eventBus.on("globalRefreshGallery", () => {
|
||||||
this.updateScans();
|
this.refreshGallery();
|
||||||
});
|
});
|
||||||
eventBus.on("modalClosed", () => {
|
eventBus.on("modalClosed", () => {
|
||||||
// Handle the modal closed event here
|
// Handle the modal closed event here
|
||||||
this.updateScans();
|
this.refreshGallery();
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
// Remove global signal listener to perform a gallery refresh
|
// Remove global signal listener to perform a gallery refresh
|
||||||
eventBus.off("globalUpdateScans", this.updateScans);
|
eventBus.off("globalRefreshGallery", this.refreshGallery);
|
||||||
// Then we call that function here to unwatch
|
// Then we call that function here to unwatch
|
||||||
if (this.unwatchStoreFunction) {
|
if (this.unwatchStoreFunction) {
|
||||||
this.unwatchStoreFunction();
|
this.unwatchStoreFunction();
|
||||||
this.unwatchStoreFunction = null;
|
this.unwatchStoreFunction = null;
|
||||||
}
|
}
|
||||||
eventBus.off("modalClosed", this.updateScans); // Clean up event listener
|
eventBus.off("modalClosed", this.refreshGallery); // Clean up event listener
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
visibilityChanged(isVisible) {
|
visibilityChanged(isVisible) {
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
this.updateScans();
|
this.refreshGallery();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async updateScans() {
|
async refreshGallery() {
|
||||||
try {
|
try {
|
||||||
let scans = await this.readThingProperty("gallery", "list_data");
|
let all_items = await this.readThingProperty("gallery", "list_data");
|
||||||
if (!scans | (scans.length == 0)) {
|
if (!all_items | (all_items.length == 0)) {
|
||||||
this.scans = scans;
|
this.all_items = all_items;
|
||||||
}
|
}
|
||||||
scans.forEach((scan) => {
|
all_items.forEach((item) => {
|
||||||
scan.can_stitch = !scan.stitch_available && scan.number_of_images > 3;
|
item.can_stitch = !item.stitch_available && item.number_of_images > 3;
|
||||||
});
|
});
|
||||||
scans.sort((a, b) => {
|
all_items.sort((a, b) => {
|
||||||
return b.created - a.created;
|
return b.created - a.created;
|
||||||
});
|
});
|
||||||
this.scans = scans;
|
this.all_items = all_items;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error("Failed to refresh scans");
|
console.error("Failed to refresh gallery items.");
|
||||||
console.error(err);
|
console.error(err);
|
||||||
this.scans = [];
|
this.all_items = [];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async deleteAllScans() {
|
async deleteAllScans() {
|
||||||
|
|
@ -203,7 +202,7 @@ export default {
|
||||||
"This is <b>irreversible</b>!",
|
"This is <b>irreversible</b>!",
|
||||||
);
|
);
|
||||||
await axios.delete(`${this.scansUri}`);
|
await axios.delete(`${this.scansUri}`);
|
||||||
await this.updateScans();
|
await this.refreshGallery();
|
||||||
this.modalNotify("Deleted all scans.");
|
this.modalNotify("Deleted all scans.");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// if the confirmation was cancelled, it's rejected with null error
|
// if the confirmation was cancelled, it's rejected with null error
|
||||||
|
|
@ -240,7 +239,7 @@ export default {
|
||||||
margin-bottom: 30px;
|
margin-bottom: 30px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.scan-list-button {
|
.gallery-button {
|
||||||
margin-top: 5px;
|
margin-top: 5px;
|
||||||
margin-bottom: 2px;
|
margin-bottom: 2px;
|
||||||
}
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue