Commit 4428e890 authored by Joel Collins's avatar Joel Collins
Browse files

Basic scan grouping

parent 2756185e
Loading
Loading
Loading
Loading
+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>
+130 −36
Original line number Diff line number Diff line
@@ -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>

@@ -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'
    }  
  },

@@ -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: {
@@ -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);
          };
@@ -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);
        };

@@ -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)
    }

  }
+1 −1
Original line number Diff line number Diff line
@@ -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()