Loading src/components/paneDisplayComponents/galleryComponents/scanCard.vue 0 → 100644 +90 −0 Original line number Diff line number Diff line <template> <div class="captureCard uk-card uk-card-primary uk-card-hover uk-padding-remove uk-width-medium uk-margin-right"> <div class="uk-card-media-top"> <img class="uk-width-1-1" v-bind:src="thumbnail" v-bind:alt="metadata.scan_id" uk-img> </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"><b>Scan:</b> {{ metadata.custom.basename }}</div> </div> <div class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-expand"><time>{{ betterTimestring }}</time></div> <div class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-auto"> <a v-bind:href="metadataModalTarget" uk-toggle>More...</a> </div> </div> <div class="uk-card-footer uk-padding-small"> <span v-for="tag in metadata.tags" :key="tag" class="uk-label uk-margin-small-right deletable-label"> {{ tag }} </span> </div> <div v-bind: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">{{ metadata.basename }}</h2> <p><b>Time: </b>{{ betterTimestring }}</p> <p><b>Scan ID: </b>{{ metadata.custom.scan_id }}</p> <div v-for="(value, key) in metadata.custom" :key="key" > <p><b>{{ key }}: </b>{{ value }}</p> </div> </div> </div> </div> </template> <script> import UIkit from 'uikit'; import axios from 'axios' // Export main app export default { name: 'captureCard', props: { metadata: { type: Object, required: true }, thumbnail: { type: String, required: true } }, methods: { makeModalName: function(prefix) { return prefix + this.metadata.id } }, 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 }, betterTimestring: function () { var dtSplit = this.metadata.custom.time.split("_"); var date = dtSplit[0] var time = dtSplit[1].replace(/-/g, ":") return date + " " + time } } } </script> src/components/paneDisplayComponents/galleryDisplay.vue +130 −36 Original line number Diff line number Diff line Loading @@ -27,12 +27,18 @@ <div v-if="$store.getters.ready" class="uk-padding-remove-top" uk-lightbox="toggle: .lightbox-link"> <div class="uk-grid-medium uk-padding uk-padding-remove-right uk-grid-match" uk-grid> <div v-for="item in sortedItems" :key="item.metadata.id"> <captureCard v-for="capture in sortedDateCaptures" :key="capture.metadata.id" :metadata="capture.metadata" :temporary="capture.temporary" v-if="!('isScan' in item)" :metadata="item.metadata" :temporary="item.temporary" /> <scanCard v-else :metadata="item.metadata" :thumbnail="item.thumbnail" /> </div> </div> Loading @@ -44,20 +50,23 @@ <script> import axios from 'axios' import captureCard from './galleryComponents/captureCard.vue' import scanCard from './galleryComponents/scanCard.vue' // Export main app export default { name: 'galleryDisplay', components: { captureCard captureCard, scanCard }, data: function () { return { captureList: [], checkedTags: [], sortDescending: true sortDescending: true, scanTag: 'scan' } }, Loading @@ -80,7 +89,47 @@ export default { .catch(error => { this.$store.dispatch('handleHTTPError', error); // Let store handle error }) }, filterCaptureList: function(list, filterTags) { var result = []; for (var capture of list) { // Assume exclusion var includeCapture = false; // Filter by selected tags var tags = capture.metadata.tags; let checker = (arr, target) => target.every(v => arr.includes(v)); // True if all tags match includeCapture = checker(tags, filterTags); // Add to capture list if matched if (includeCapture == true) { result.push(capture); }; }; return result }, sortCaptureList: function(list) { function compare(a, b) { if (a.metadata.time < b.metadata.time) return -1; if (a.metadata.time > b.metadata.time) return 1; return 0; } if (this.sortDescending == true) { return list.sort(compare).reverse(); } else { return list.sort(compare); } } }, computed: { Loading @@ -91,10 +140,8 @@ export default { allTags: function () { // Return an array of unique tags across all captures var tags = []; for (var i in this.captureList) { var capture = this.captureList[i] for (var j in capture.metadata.tags) { var tag = capture.metadata.tags[j]; for (var capture of this.captureList) { for (var tag of capture.metadata.tags) { if (!tags.includes(tag)) { tags.push(tag); }; Loading @@ -103,22 +150,17 @@ export default { return tags.sort() }, filteredCaptures: function () { noScanCaptureList: function () { var captures = []; for (var i in this.captureList) { // Quickly access capture object var capture = this.captureList[i]; for (var capture of this.captureList) { // Assume exclusion var includeCapture = false; // Filter by selected tags var tags = capture.metadata.tags; let checker = (arr, target) => target.every(v => arr.includes(v)); // True if all tags match includeCapture = checker(tags, this.checkedTags); // Add to capture list if matched if (includeCapture == true) { if (!tags.includes(this.scanTag)) { captures.push(capture); }; Loading @@ -127,21 +169,73 @@ export default { return captures }, sortedDateCaptures: function () { function compare(a, b) { if (a.metadata.time < b.metadata.time) return -1; if (a.metadata.time > b.metadata.time) return 1; return 0; allScans: function () { // Return an array of unique tags across all captures var scans = {}; for (var capture of this.captureList) { var custom = capture.metadata.custom; var tags = capture.metadata.tags; if ('scan_id' in custom) { var id = custom['scan_id'] // If this scan ID hasn't been seen before if (!(id in scans)) { scans[id] = {} scans[id].isScan = true scans[id].captureList = [] scans[id].metadata = { filename: custom.basename, time: custom.time, id: custom.scan_id } scans[id].metadata.tags = [] scans[id].metadata.custom = {} }; if (this.sortDescending == true) { return this.filteredCaptures.sort(compare).reverse(); // Add the capture object to the scan scans[id].captureList.push(capture) // Add missing scan metadata, prioritising first capture for (var key of Object.keys(custom)) { if (!(key in scans[id].metadata.custom)) { scans[id].metadata.custom[key] = custom[key] }; }; // Append missing tags for (var tag of tags) { if (!scans[id].metadata.tags.includes(tag)) { scans[id].metadata.tags.push(tag) }; }; // Create a preview thumbnail if (!('thumbnail' in scans[id])) { scans[id].thumbnail = this.$store.getters.uri + "/camera/capture/" + capture.metadata.id + "/download?thumbnail=true" } else { return this.filteredCaptures.sort(compare); } }; return scans }, scanList: function () { return Object.values(this.allScans) }, itemList: function () { return this.noScanCaptureList.concat(this.scanList) }, filteredItems: function () { return this.filterCaptureList(this.itemList, this.checkedTags) }, sortedItems: function () { return this.sortCaptureList(this.filteredItems) } } Loading src/components/paneSettingsComponents/microscopeSettings.vue +1 −1 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ export default { }, recalibrateConfirm: function() { context = this var context = this this.modalConfirm('Start recalibration? This may take a while, and the microscope will be locked during this time.') .then(function() { context.recalibrateRequest() Loading Loading
src/components/paneDisplayComponents/galleryComponents/scanCard.vue 0 → 100644 +90 −0 Original line number Diff line number Diff line <template> <div class="captureCard uk-card uk-card-primary uk-card-hover uk-padding-remove uk-width-medium uk-margin-right"> <div class="uk-card-media-top"> <img class="uk-width-1-1" v-bind:src="thumbnail" v-bind:alt="metadata.scan_id" uk-img> </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"><b>Scan:</b> {{ metadata.custom.basename }}</div> </div> <div class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-expand"><time>{{ betterTimestring }}</time></div> <div class="uk-text-meta uk-margin-remove-top uk-padding-remove uk-width-auto"> <a v-bind:href="metadataModalTarget" uk-toggle>More...</a> </div> </div> <div class="uk-card-footer uk-padding-small"> <span v-for="tag in metadata.tags" :key="tag" class="uk-label uk-margin-small-right deletable-label"> {{ tag }} </span> </div> <div v-bind: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">{{ metadata.basename }}</h2> <p><b>Time: </b>{{ betterTimestring }}</p> <p><b>Scan ID: </b>{{ metadata.custom.scan_id }}</p> <div v-for="(value, key) in metadata.custom" :key="key" > <p><b>{{ key }}: </b>{{ value }}</p> </div> </div> </div> </div> </template> <script> import UIkit from 'uikit'; import axios from 'axios' // Export main app export default { name: 'captureCard', props: { metadata: { type: Object, required: true }, thumbnail: { type: String, required: true } }, methods: { makeModalName: function(prefix) { return prefix + this.metadata.id } }, 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 }, betterTimestring: function () { var dtSplit = this.metadata.custom.time.split("_"); var date = dtSplit[0] var time = dtSplit[1].replace(/-/g, ":") return date + " " + time } } } </script>
src/components/paneDisplayComponents/galleryDisplay.vue +130 −36 Original line number Diff line number Diff line Loading @@ -27,12 +27,18 @@ <div v-if="$store.getters.ready" class="uk-padding-remove-top" uk-lightbox="toggle: .lightbox-link"> <div class="uk-grid-medium uk-padding uk-padding-remove-right uk-grid-match" uk-grid> <div v-for="item in sortedItems" :key="item.metadata.id"> <captureCard v-for="capture in sortedDateCaptures" :key="capture.metadata.id" :metadata="capture.metadata" :temporary="capture.temporary" v-if="!('isScan' in item)" :metadata="item.metadata" :temporary="item.temporary" /> <scanCard v-else :metadata="item.metadata" :thumbnail="item.thumbnail" /> </div> </div> Loading @@ -44,20 +50,23 @@ <script> import axios from 'axios' import captureCard from './galleryComponents/captureCard.vue' import scanCard from './galleryComponents/scanCard.vue' // Export main app export default { name: 'galleryDisplay', components: { captureCard captureCard, scanCard }, data: function () { return { captureList: [], checkedTags: [], sortDescending: true sortDescending: true, scanTag: 'scan' } }, Loading @@ -80,7 +89,47 @@ export default { .catch(error => { this.$store.dispatch('handleHTTPError', error); // Let store handle error }) }, filterCaptureList: function(list, filterTags) { var result = []; for (var capture of list) { // Assume exclusion var includeCapture = false; // Filter by selected tags var tags = capture.metadata.tags; let checker = (arr, target) => target.every(v => arr.includes(v)); // True if all tags match includeCapture = checker(tags, filterTags); // Add to capture list if matched if (includeCapture == true) { result.push(capture); }; }; return result }, sortCaptureList: function(list) { function compare(a, b) { if (a.metadata.time < b.metadata.time) return -1; if (a.metadata.time > b.metadata.time) return 1; return 0; } if (this.sortDescending == true) { return list.sort(compare).reverse(); } else { return list.sort(compare); } } }, computed: { Loading @@ -91,10 +140,8 @@ export default { allTags: function () { // Return an array of unique tags across all captures var tags = []; for (var i in this.captureList) { var capture = this.captureList[i] for (var j in capture.metadata.tags) { var tag = capture.metadata.tags[j]; for (var capture of this.captureList) { for (var tag of capture.metadata.tags) { if (!tags.includes(tag)) { tags.push(tag); }; Loading @@ -103,22 +150,17 @@ export default { return tags.sort() }, filteredCaptures: function () { noScanCaptureList: function () { var captures = []; for (var i in this.captureList) { // Quickly access capture object var capture = this.captureList[i]; for (var capture of this.captureList) { // Assume exclusion var includeCapture = false; // Filter by selected tags var tags = capture.metadata.tags; let checker = (arr, target) => target.every(v => arr.includes(v)); // True if all tags match includeCapture = checker(tags, this.checkedTags); // Add to capture list if matched if (includeCapture == true) { if (!tags.includes(this.scanTag)) { captures.push(capture); }; Loading @@ -127,21 +169,73 @@ export default { return captures }, sortedDateCaptures: function () { function compare(a, b) { if (a.metadata.time < b.metadata.time) return -1; if (a.metadata.time > b.metadata.time) return 1; return 0; allScans: function () { // Return an array of unique tags across all captures var scans = {}; for (var capture of this.captureList) { var custom = capture.metadata.custom; var tags = capture.metadata.tags; if ('scan_id' in custom) { var id = custom['scan_id'] // If this scan ID hasn't been seen before if (!(id in scans)) { scans[id] = {} scans[id].isScan = true scans[id].captureList = [] scans[id].metadata = { filename: custom.basename, time: custom.time, id: custom.scan_id } scans[id].metadata.tags = [] scans[id].metadata.custom = {} }; if (this.sortDescending == true) { return this.filteredCaptures.sort(compare).reverse(); // Add the capture object to the scan scans[id].captureList.push(capture) // Add missing scan metadata, prioritising first capture for (var key of Object.keys(custom)) { if (!(key in scans[id].metadata.custom)) { scans[id].metadata.custom[key] = custom[key] }; }; // Append missing tags for (var tag of tags) { if (!scans[id].metadata.tags.includes(tag)) { scans[id].metadata.tags.push(tag) }; }; // Create a preview thumbnail if (!('thumbnail' in scans[id])) { scans[id].thumbnail = this.$store.getters.uri + "/camera/capture/" + capture.metadata.id + "/download?thumbnail=true" } else { return this.filteredCaptures.sort(compare); } }; return scans }, scanList: function () { return Object.values(this.allScans) }, itemList: function () { return this.noScanCaptureList.concat(this.scanList) }, filteredItems: function () { return this.filterCaptureList(this.itemList, this.checkedTags) }, sortedItems: function () { return this.sortCaptureList(this.filteredItems) } } Loading
src/components/paneSettingsComponents/microscopeSettings.vue +1 −1 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ export default { }, recalibrateConfirm: function() { context = this var context = this this.modalConfirm('Start recalibration? This may take a while, and the microscope will be locked during this time.') .then(function() { context.recalibrateRequest() Loading