瀏覽代碼

Merge branch '62-remove-images' into 'master'

Resolve "remove images"

Closes #62

See merge request troebs/pycs!57
Eric Tröbs 4 年之前
父節點
當前提交
01ee81172a
共有 3 個文件被更改,包括 82 次插入3 次删除
  1. 4 1
      pycs/frontend/WebServer.py
  2. 3 0
      pycs/projects/Project.py
  3. 75 2
      webui/src/components/projects/project-data-add-window.vue

+ 4 - 1
pycs/frontend/WebServer.py

@@ -196,7 +196,10 @@ class WebServer:
             # add result
             result = request.get_json(force=True)
             if result:
-                target_object.add_result(result)
+                if 'delete' in result:
+                    project.remove_media_file(file_identifier)
+                else:
+                    target_object.add_result(result)
 
             # return default success response
             return response()

+ 3 - 0
pycs/projects/Project.py

@@ -33,6 +33,9 @@ class Project(ObservableDict):
         file = MediaFile(file, self)
         self['data'][file['id']] = file
 
+    def remove_media_file(self, file_id):
+        del self['data'][file_id]
+
     def add_label(self, name):
         label_uuid = str(uuid1())
         self['labels'][label_uuid] = {

+ 75 - 2
webui/src/components/projects/project-data-add-window.vue

@@ -13,6 +13,25 @@
         </template>
       </div>
     </template>
+
+    <template v-if="this.data.length > 0">
+      <h1>Data</h1>
+
+      <div class="wrapper">
+        <div class="data">
+          <div v-for="d in this.data"
+               v-bind:key="d.id"
+               class="element">
+            <img alt="media" class="media"
+                 :src="d.src"
+                 :srcset="d.srcset" :sizes="d.sizes">
+            <img alt="remove" class="remove"
+                 @click="removeMedia(d.src)"
+                 src="@/assets/icons/x-circle.svg">
+          </div>
+        </div>
+      </div>
+    </template>
   </div>
 </template>
 
@@ -24,22 +43,42 @@ export default {
   name: "project-data-add-window",
   components: {ProgressBar, FileInput},
   props: ['socket', 'currentProject'],
+  data: function () {
+    return {
+      sizes: [400, 700, 1000]
+    }
+  },
   computed: {
-    uploads: function() {
+    uploads: function () {
       const filtered = Object.keys(this.currentProject.jobs)
           .map(e => this.currentProject.jobs[e])
           .filter(e => e.type === 'upload');
 
       filtered.sort(this.sortUploads);
       return filtered;
+    },
+    data: function () {
+      return Object.keys(this.currentProject.data).map(key => {
+        const data = this.currentProject.data[key];
+        const src = this.socket.media(this.currentProject.id, data.id);
+
+        return Object.assign({
+          src: src,
+          srcset: this.sizes.map(e => src + '/' + e + ' ' + e + 'w').join(','),
+          sizes: '10rem'
+        }, data);
+      });
     }
   },
   methods: {
-    sortUploads: function(u, v) {
+    sortUploads: function (u, v) {
       if (u.created < v.created)
         return 1;
       else
         return -1;
+    },
+    removeMedia: function (src) {
+      this.socket.post(src, {delete: true})
     }
   }
 }
@@ -48,6 +87,8 @@ export default {
 <style scoped>
 .project-data-add-window {
   padding: 1rem;
+  display: flex;
+  flex-direction: column;
 }
 
 h1 {
@@ -62,4 +103,36 @@ h1 {
 .progress-bar {
   margin-left: 1rem;
 }
+
+.wrapper {
+  flex-basis: 0;
+  flex-grow: 1;
+  overflow-y: auto;
+}
+
+.data {
+  display: grid;
+  grid-template-columns: repeat(auto-fill, 10rem);
+}
+
+.element {
+  display: flex;
+  justify-content: center;
+  align-items: center;
+  position: relative;
+}
+
+.media {
+  max-height: 7rem;
+}
+
+.remove {
+  position: absolute;
+  top: 0.2rem;
+  right: 0.2rem;
+  background-color: rgba(255, 255, 255, 0.5);
+  padding: 0.4rem;
+  border-radius: 0.2rem;
+  filter: invert(1);
+}
 </style>