Quellcode durchsuchen

Attachment Management at Admin Console

Martin Filser vor 3 Jahren
Ursprung
Commit
b8d14abe0c

+ 81 - 0
client/components/settings/attachments.jade

@@ -0,0 +1,81 @@
+template(name="attachments")
+  .setting-content.attachments-content
+    unless currentUser.isAdmin
+      | {{_ 'error-notAuthorized'}}
+    else
+      .content-body
+        .side-menu
+          ul
+            li
+              a.js-move-attachments(data-id="move-attachments")
+                i.fa.fa-arrow-right
+                | {{_ 'attachment-move'}}
+
+        .main-body
+          if loading.get
+            +spinner
+          else if showMoveAttachments.get
+            +moveAttachments
+
+template(name="moveAttachments")
+  .js-move-attachment
+    button.js-move-all-attachments-to-fs {{_ 'move-all-attachments-to-fs'}}
+  .js-move-attachment
+    button.js-move-all-attachments-to-gridfs {{_ 'move-all-attachments-to-gridfs'}}
+
+  each board in getBoardsWithAttachments
+    +moveBoardAttachments board
+
+template(name="moveBoardAttachments")
+  .board-description
+    table
+      tr
+        th {{_ 'board'}} ID
+        th {{_ 'board-title'}}
+      tr
+        td {{ _id }}
+        td {{ title }}
+
+  .js-move-attachment
+    button.js-move-all-attachments-of-board-to-fs {{_ 'move-all-attachments-of-board-to-fs'}}
+  .js-move-attachment
+    button.js-move-all-attachments-of-board-to-gridfs {{_ 'move-all-attachments-of-board-to-gridfs'}}
+
+  .board-attachments
+    table
+      tr
+        th {{_ 'card'}}-Id
+        th {{_ 'attachment'}}-Id
+        th {{_ 'name'}}
+        th {{_ 'path'}}
+        th {{_ 'version-name'}}
+        th {{_ 'size'}} (B)
+        th GridFsFileId
+        th {{_ 'storage'}}
+        th {{_ 'action'}}
+
+      each attachment in attachments
+        +moveAttachment attachment
+
+template(name="moveAttachment")
+  each version in flatVersion
+    tr
+      td {{ meta.cardId }}
+      td {{ _id }}
+      td {{ name }}
+      td {{ version.path }}
+      td {{ version.versionName }}
+      td {{ version.size }}
+      td {{ version.meta.gridFsFileId }}
+      td {{ version.storageName }}
+      td
+        if $neq version.storageName "fs"
+          button.js-move-storage-fs
+            i.fa.fa-arrow-right
+            | {{_ 'attachment-move-storage-fs'}}
+
+        if $neq version.storageName "gridfs"
+          if version.storageName
+            button.js-move-storage-gridfs
+              i.fa.fa-arrow-right
+              | {{_ 'attachment-move-storage-gridfs'}}

+ 123 - 0
client/components/settings/attachments.js

@@ -0,0 +1,123 @@
+import Attachments, { fileStoreStrategyFactory } from '/models/attachments';
+
+BlazeComponent.extendComponent({
+  subscription: null,
+  showMoveAttachments: new ReactiveVar(false),
+  sessionId: null,
+
+  onCreated() {
+    this.error = new ReactiveVar('');
+    this.loading = new ReactiveVar(false);
+  },
+
+  events() {
+    return [
+      {
+        'click a.js-move-attachments': this.switchMenu,
+      },
+    ];
+  },
+
+  switchMenu(event) {
+    const target = $(event.target);
+    if (!target.hasClass('active')) {
+      this.loading.set(true);
+      this.showMoveAttachments.set(false);
+      if (this.subscription) {
+        this.subscription.stop();
+      }
+
+      $('.side-menu li.active').removeClass('active');
+      target.parent().addClass('active');
+      const targetID = target.data('id');
+
+      if ('move-attachments' === targetID) {
+        this.showMoveAttachments.set(true);
+        this.subscription = Meteor.subscribe('attachmentsList', () => {
+          this.loading.set(false);
+        });
+      }
+    }
+  },
+}).register('attachments');
+
+BlazeComponent.extendComponent({
+  getBoardsWithAttachments() {
+    this.attachments = Attachments.find().get();
+    this.attachmentsByBoardId = _.chain(this.attachments)
+      .groupBy(fileObj => fileObj.meta.boardId)
+      .value();
+
+    const ret = Object.keys(this.attachmentsByBoardId)
+      .map(boardId => {
+        const boardAttachments = this.attachmentsByBoardId[boardId];
+
+        _.each(boardAttachments, _attachment => {
+          _attachment.flatVersion = Object.keys(_attachment.versions)
+            .map(_versionName => {
+              const _version = Object.assign(_attachment.versions[_versionName], {"versionName": _versionName});
+              _version.storageName = fileStoreStrategyFactory.getFileStrategy(_attachment, _versionName).getStorageName();
+              return _version;
+            });
+        });
+        const board = Boards.findOne(boardId);
+        board.attachments = boardAttachments;
+        return board;
+      })
+    return ret;
+  },
+  getBoardData(boardid) {
+    const ret = Boards.findOne(boardId);
+    return ret;
+  },
+  events() {
+    return [
+      {
+        'click button.js-move-all-attachments-to-fs'(event) {
+          this.attachments.forEach(_attachment => {
+            Meteor.call('moveAttachmentToStorage', _attachment._id, "fs");
+          });
+        },
+        'click button.js-move-all-attachments-to-gridfs'(event) {
+          this.attachments.forEach(_attachment => {
+            Meteor.call('moveAttachmentToStorage', _attachment._id, "gridfs");
+          });
+        },
+      }
+    ]
+  }
+}).register('moveAttachments');
+
+BlazeComponent.extendComponent({
+  events() {
+    return [
+      {
+        'click button.js-move-all-attachments-of-board-to-fs'(event) {
+          this.data().attachments.forEach(_attachment => {
+            Meteor.call('moveAttachmentToStorage', _attachment._id, "fs");
+          });
+        },
+        'click button.js-move-all-attachments-of-board-to-gridfs'(event) {
+          this.data().attachments.forEach(_attachment => {
+            Meteor.call('moveAttachmentToStorage', _attachment._id, "gridfs");
+          });
+        },
+      }
+    ]
+  },
+}).register('moveBoardAttachments');
+
+BlazeComponent.extendComponent({
+  events() {
+    return [
+      {
+        'click button.js-move-storage-fs'(event) {
+          Meteor.call('moveAttachmentToStorage', this.data()._id, "fs");
+        },
+        'click button.js-move-storage-gridfs'(event) {
+          Meteor.call('moveAttachmentToStorage', this.data()._id, "gridfs");
+        },
+      }
+    ]
+  },
+}).register('moveAttachment');

+ 4 - 0
client/components/settings/settingHeader.jade

@@ -16,6 +16,10 @@ template(name="settingHeaderBar")
         i.fa(class="fa-list")
         span {{_ 'reports'}}
 
+      a.setting-header-btn.informations(href="{{pathFor 'attachments'}}")
+        i.fa(class="fa-paperclip")
+        span {{_ 'attachments'}}
+
       a.setting-header-btn.informations(href="{{pathFor 'information'}}")
         i.fa(class="fa-info-circle")
         span {{_ 'info'}}

+ 24 - 0
config/router.js

@@ -355,6 +355,30 @@ FlowRouter.route('/admin-reports', {
   },
 });
 
+FlowRouter.route('/attachments', {
+  name: 'attachments',
+  triggersEnter: [
+    AccountsTemplates.ensureSignedIn,
+    () => {
+      Session.set('currentBoard', null);
+      Session.set('currentList', null);
+      Session.set('currentCard', null);
+      Session.set('popupCardId', null);
+      Session.set('popupCardBoardId', null);
+
+      Filter.reset();
+      Session.set('sortBy', '');
+      EscapeActions.executeAll();
+    },
+  ],
+  action() {
+    BlazeLayout.render('defaultLayout', {
+      headerBar: 'settingHeaderBar',
+      content: 'attachments',
+    });
+  },
+});
+
 FlowRouter.notFound = {
   action() {
     BlazeLayout.render('defaultLayout', { content: 'notFound' });

+ 12 - 1
i18n/en.i18n.json

@@ -1166,5 +1166,16 @@
   "subtaskActionsPopup-title": "Subtask Actions",
   "attachmentActionsPopup-title": "Attachment Actions",
   "attachment-move-storage-fs": "Move attachment to filesystem",
-  "attachment-move-storage-gridfs": "Move attachment to GridFS"
+  "attachment-move-storage-gridfs": "Move attachment to GridFS",
+  "attachment-move": "Move Attachment",
+  "move-all-attachments-to-fs": "Move all attachments to filesystem",
+  "move-all-attachments-to-gridfs": "Move all attachments to GridFS",
+  "move-all-attachments-of-board-to-fs": "Move all attachments of board to filesystem",
+  "move-all-attachments-of-board-to-gridfs": "Move all attachments of board to GridFS",
+  "path": "Path",
+  "version-name": "Version-Name",
+  "size": "Size",
+  "storage": "Storage",
+  "action": "Action",
+  "board-title": "Board Title"
 }

+ 1 - 1
models/attachments.js

@@ -13,7 +13,7 @@ if (Meteor.isServer) {
   storagePath = path.join(process.env.WRITABLE_PATH, 'attachments');
 }
 
-const fileStoreStrategyFactory = new FileStoreStrategyFactory(AttachmentStoreStrategyFilesystem, storagePath, AttachmentStoreStrategyGridFs, attachmentBucket);
+export const fileStoreStrategyFactory = new FileStoreStrategyFactory(AttachmentStoreStrategyFilesystem, storagePath, AttachmentStoreStrategyGridFs, attachmentBucket);
 
 // XXX Enforce a schema for the Attachments FilesCollection
 // see: https://github.com/VeliovGroup/Meteor-Files/wiki/Schema

+ 4 - 2
server/publications/attachments.js

@@ -1,7 +1,7 @@
 import Attachments from '/models/attachments';
 import { ObjectID } from 'bson';
 
-Meteor.publish('attachmentsList', function() {
+Meteor.publish('attachmentsList', function(limit) {
   const ret = Attachments.find(
     {},
     {
@@ -11,11 +11,13 @@ Meteor.publish('attachmentsList', function() {
         size: 1,
         type: 1,
         meta: 1,
+        path: 1,
+        versions: 1,
       },
       sort: {
         name: 1,
       },
-      limit: 250,
+      limit: limit,
     },
   ).cursor;
   return ret;