Ver código fonte

Add admin reports to admin panel
* Broken cards
* Attachments
* Orphaned Attachments

John R. Supplee 4 anos atrás
pai
commit
0e593c7d81

+ 4 - 3
client/components/main/globalSearch.jade

@@ -11,9 +11,10 @@ template(name="globalSearchModalTitle")
       | {{_ 'globalSearch-title'}}
 
 template(name="resultsPaged")
-  h1
-    = resultsHeading.get
-    a.fa.fa-link(title="{{_ 'link-to-search' }}" href="{{ getSearchHref }}")
+  if resultsHeading.get
+    h1
+      = resultsHeading.get
+      a.fa.fa-link(title="{{_ 'link-to-search' }}" href="{{ getSearchHref }}")
   each card in results.get
     +resultCard(card)
   table.global-search-footer

+ 2 - 3
client/components/main/globalSearch.js

@@ -204,9 +204,8 @@ class GlobalSearchComponent extends CardSearchPagedComponent {
   }
 
   events() {
-    return [
+    return super.events().concat([
       {
-        ...super.events()[0],
         'submit .js-search-query-form'(evt) {
           evt.preventDefault();
           this.searchAllBoards(evt.target.searchQuery.value);
@@ -259,7 +258,7 @@ class GlobalSearchComponent extends CardSearchPagedComponent {
           this.hasResults.set(false);
         },
       },
-    ];
+    ]);
   }
 }
 

+ 85 - 0
client/components/settings/adminReports.jade

@@ -0,0 +1,85 @@
+template(name="adminReports")
+  .setting-content
+    unless currentUser.isAdmin
+      | {{_ 'error-notAuthorized'}}
+    else
+      .content-body
+        .side-menu
+          ul
+            li
+              a.js-report-broken(data-id="report-broken")
+                i.fa.fa-chain-broken
+                | {{_ 'broken-cards'}}
+
+            li
+              a.js-report-files(data-id="report-orphaned-files")
+                i.fa.fa-paperclip
+                | {{_ 'orphanedFilesReportTitle'}}
+
+            li
+              a.js-report-files(data-id="report-files")
+                i.fa.fa-paperclip
+                | {{_ 'filesReportTitle'}}
+
+        .main-body
+          if loading.get
+            +spinner
+          else if showBrokenCardsReport.get
+            +brokenCardsReport
+          else if showFilesReport.get
+            +filesReport
+          else if showOrphanedFilesReport.get
+            +orphanedFilesReport
+
+
+template(name="brokenCardsReport")
+  .global-search-results-list-wrapper
+    h1 {{_ 'broken-cards'}}
+    if resultsCount
+      +resultsPaged(this)
+    else
+      div {{_ 'no-results' }}
+
+template(name="filesReport")
+  h1 {{_ 'filesReportTitle'}}
+  if resultsCount
+    table.table
+      tr
+        th Filename
+        th.right Size (kB)
+        th MIME Type
+        th.center Usage
+        th MD5 Sum
+        th ID
+
+      each att in attachmentFiles
+        tr
+          td {{ att.filename }}
+          td.right {{fileSize att.length }}
+          td {{ att.contentType }}
+          td.center {{usageCount att._id.toHexString }}
+          td {{ att.md5 }}
+          td {{ att._id.toHexString }}
+  else
+    div {{_ 'no-results' }}
+
+template(name="orphanedFilesReport")
+  h1 {{_ 'orphanedFilesReportTitle'}}
+  if resultsCount
+    table.table
+      tr
+        th Filename
+        th.right Size (kB)
+        th MIME Type
+        th MD5 Sum
+        th ID
+
+      each att in attachmentFiles
+        tr
+          td {{ att.filename }}
+          td.right {{fileSize att.length }}
+          td {{ att.contentType }}
+          td {{ att.md5 }}
+          td {{ att._id.toHexString }}
+  else
+    div {{_ 'no-results' }}

+ 108 - 0
client/components/settings/adminReports.js

@@ -0,0 +1,108 @@
+import { AttachmentStorage } from '/models/attachments';
+import { CardSearchPagedComponent } from '/client/lib/cardSearch';
+import SessionData from '/models/usersessiondata';
+
+BlazeComponent.extendComponent({
+  subscription: null,
+  showFilesReport: new ReactiveVar(false),
+  showBrokenCardsReport: new ReactiveVar(false),
+  showOrphanedFilesReport: new ReactiveVar(false),
+
+  onCreated() {
+    this.error = new ReactiveVar('');
+    this.loading = new ReactiveVar(false);
+  },
+
+  events() {
+    return [
+      {
+        'click a.js-report-broken': this.switchMenu,
+        'click a.js-report-files': this.switchMenu,
+        'click a.js-report-orphaned-files': this.switchMenu,
+      },
+    ];
+  },
+
+  switchMenu(event) {
+    const target = $(event.target);
+    if (!target.hasClass('active')) {
+      this.loading.set(true);
+      this.showFilesReport.set(false);
+      this.showBrokenCardsReport.set(false);
+      this.showOrphanedFilesReport.set(false);
+      if (this.subscription) {
+        this.subscription.stop();
+      }
+
+      $('.side-menu li.active').removeClass('active');
+      target.parent().addClass('active');
+      const targetID = target.data('id');
+
+      if ('report-broken' === targetID) {
+        this.showBrokenCardsReport.set(true);
+        this.subscription = Meteor.subscribe(
+          'brokenCards',
+          SessionData.getSessionId(),
+          () => {
+            this.loading.set(false);
+          },
+        );
+      } else if ('report-files' === targetID) {
+        this.showFilesReport.set(true);
+        this.subscription = Meteor.subscribe('attachmentsList', () => {
+          this.loading.set(false);
+        });
+      } else if ('report-orphaned-files' === targetID) {
+        this.showOrphanedFilesReport.set(true);
+        this.subscription = Meteor.subscribe('orphanedAttachments', () => {
+          this.loading.set(false);
+        });
+      }
+    }
+  },
+}).register('adminReports');
+
+Template.filesReport.helpers({
+  attachmentFiles() {
+    // eslint-disable-next-line no-console
+    // console.log('attachments:', AttachmentStorage.find());
+    // console.log('attachments.count:', AttachmentStorage.find().count());
+    return AttachmentStorage.find();
+  },
+
+  resultsCount() {
+    return AttachmentStorage.find().count();
+  },
+
+  fileSize(size) {
+    return Math.round(size / 1024);
+  },
+
+  usageCount(key) {
+    return Attachments.find({ 'copies.attachments.key': key }).count();
+  },
+});
+
+Template.orphanedFilesReport.helpers({
+  attachmentFiles() {
+    // eslint-disable-next-line no-console
+    // console.log('attachments:', AttachmentStorage.find());
+    // console.log('attachments.count:', AttachmentStorage.find().count());
+    return AttachmentStorage.find();
+  },
+
+  resultsCount() {
+    return AttachmentStorage.find().count();
+  },
+
+  fileSize(size) {
+    return Math.round(size / 1024);
+  },
+});
+
+class BrokenCardsComponent extends CardSearchPagedComponent {
+  onCreated() {
+    super.onCreated();
+  }
+}
+BrokenCardsComponent.register('brokenCardsReport');

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

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

+ 3 - 0
client/lib/cardSearch.js

@@ -32,8 +32,11 @@ export class CardSearchPagedComponent extends BlazeComponent {
         that.searching.set(false);
         that.hasResults.set(false);
         that.serverError.set(true);
+        // eslint-disable-next-line no-console
         console.log('Error.reason:', error.reason);
+        // eslint-disable-next-line no-console
         console.log('Error.message:', error.message);
+        // eslint-disable-next-line no-console
         console.log('Error.stack:', error.stack);
       },
     };

+ 22 - 0
config/router.js

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

+ 4 - 1
i18n/en.i18n.json

@@ -991,5 +991,8 @@
   "now-system-messages-of-all-users-are-hidden": "Now system messages of all users are hidden",
   "move-swimlane": "Move Swimlane",
   "moveSwimlanePopup-title": "Move Swimlane",
-  "creator": "Creator"
+  "creator": "Creator",
+  "filesReportTitle": "Attachments Report",
+  "orphanedFilesReportTitle": "Orphaned Files Report",
+  "reports": "Reports"
 }

+ 5 - 0
models/attachments.js

@@ -1,3 +1,8 @@
+export const AttachmentStorage = new Mongo.Collection(
+  'cfs_gridfs.attachments.files',
+);
+export const AvatarStorage = new Mongo.Collection('cfs_gridfs.avatars.files');
+
 const localFSStore = process.env.ATTACHMENTS_STORE_PATH;
 const storeName = 'attachments';
 const defaultStoreOptions = {