Browse Source

Add Boards Report to Admin Reports

John R. Supplee 3 years ago
parent
commit
d9c290deda

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

@@ -26,6 +26,11 @@ template(name="adminReports")
                 i.fa.fa-magic
                 i.fa.fa-magic
                 | {{_ 'rulesReportTitle'}}
                 | {{_ 'rulesReportTitle'}}
 
 
+            li
+              a.js-report-boards(data-id="report-boards")
+                i.fa.fa-magic
+                | {{_ 'boardsReportTitle'}}
+
             li
             li
               a.js-report-cards(data-id="report-cards")
               a.js-report-cards(data-id="report-cards")
                 i.fa.fa-magic
                 i.fa.fa-magic
@@ -42,6 +47,8 @@ template(name="adminReports")
             +orphanedFilesReport
             +orphanedFilesReport
           else if showRulesReport.get
           else if showRulesReport.get
             +rulesReport
             +rulesReport
+          else if showBoardsReport.get
+            +boardsReport
           else if showCardsReport.get
           else if showCardsReport.get
             +cardsReport
             +cardsReport
 
 
@@ -139,3 +146,20 @@ template(name="cardsReport")
           td {{userNames card.assignees }}
           td {{userNames card.assignees }}
   else
   else
     div {{_ 'no-results' }}
     div {{_ 'no-results' }}
+
+template(name="boardsReport")
+  h1 {{_ 'boardsReportTitle'}}
+  if resultsCount
+    table.table
+      tr
+        th Title
+        th Id
+        th Members
+
+      each board in results
+        tr
+          td {{abbreviate board.title }}
+          td {{abbreviate board._id }}
+          td {{userNames board.members }}
+  else
+    div {{_ 'no-results' }}

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

@@ -11,6 +11,7 @@ BlazeComponent.extendComponent({
   showOrphanedFilesReport: new ReactiveVar(false),
   showOrphanedFilesReport: new ReactiveVar(false),
   showRulesReport: new ReactiveVar(false),
   showRulesReport: new ReactiveVar(false),
   showCardsReport: new ReactiveVar(false),
   showCardsReport: new ReactiveVar(false),
+  showBoardsReport: new ReactiveVar(false),
   sessionId: null,
   sessionId: null,
 
 
   onCreated() {
   onCreated() {
@@ -27,6 +28,7 @@ BlazeComponent.extendComponent({
         'click a.js-report-orphaned-files': this.switchMenu,
         'click a.js-report-orphaned-files': this.switchMenu,
         'click a.js-report-rules': this.switchMenu,
         'click a.js-report-rules': this.switchMenu,
         'click a.js-report-cards': this.switchMenu,
         'click a.js-report-cards': this.switchMenu,
+        'click a.js-report-boards': this.switchMenu,
       },
       },
     ];
     ];
   },
   },
@@ -38,6 +40,9 @@ BlazeComponent.extendComponent({
       this.showFilesReport.set(false);
       this.showFilesReport.set(false);
       this.showBrokenCardsReport.set(false);
       this.showBrokenCardsReport.set(false);
       this.showOrphanedFilesReport.set(false);
       this.showOrphanedFilesReport.set(false);
+      this.showRulesReport.set(false)
+      this.showBoardsReport.set(false);
+      this.showCardsReport.set(false);
       if (this.subscription) {
       if (this.subscription) {
         this.subscription.stop();
         this.subscription.stop();
       }
       }
@@ -70,6 +75,11 @@ BlazeComponent.extendComponent({
           this.showRulesReport.set(true);
           this.showRulesReport.set(true);
           this.loading.set(false);
           this.loading.set(false);
         });
         });
+      } else if ('report-boards' === targetID) {
+        this.subscription = Meteor.subscribe('boardsReport', () => {
+          this.showBoardsReport.set(true);
+          this.loading.set(false);
+        });
       } else if ('report-cards' === targetID) {
       } else if ('report-cards' === targetID) {
         const qp = new QueryParams();
         const qp = new QueryParams();
         qp.addPredicate(OPERATOR_LIMIT, 300);
         qp.addPredicate(OPERATOR_LIMIT, 300);
@@ -149,6 +159,24 @@ class AdminReport extends BlazeComponent {
   }
   }
 }.register('rulesReport'));
 }.register('rulesReport'));
 
 
+(class extends AdminReport {
+  collection = Boards;
+
+  userNames(members) {
+    let text = '';
+    members.forEach(member => {
+      const user = Users.findOne(member.userId);
+      text += text ? ', ' : '';
+      if (user) {
+        text += user.username;
+      } else {
+        text += member.userId
+      }
+    });
+    return text;
+  }
+}.register('boardsReport'));
+
 (class extends AdminReport {
 (class extends AdminReport {
   collection = Cards;
   collection = Cards;
 
 

+ 1 - 0
i18n/en.i18n.json

@@ -1061,6 +1061,7 @@
   "orphanedFilesReportTitle": "Orphaned Files Report",
   "orphanedFilesReportTitle": "Orphaned Files Report",
   "reports": "Reports",
   "reports": "Reports",
   "rulesReportTitle": "Rules Report",
   "rulesReportTitle": "Rules Report",
+  "boardsReportTitle": "Boards Report",
   "cardsReportTitle": "Cards Report",
   "cardsReportTitle": "Cards Report",
   "copy-swimlane": "Copy Swimlane",
   "copy-swimlane": "Copy Swimlane",
   "copySwimlanePopup-title": "Copy Swimlane",
   "copySwimlanePopup-title": "Copy Swimlane",

+ 54 - 0
server/publications/boards.js

@@ -2,6 +2,8 @@
 // non-archived boards:
 // non-archived boards:
 // 1. that the user is a member of
 // 1. that the user is a member of
 // 2. the user has starred
 // 2. the user has starred
+import Users from "../../models/users";
+
 Meteor.publish('boards', function() {
 Meteor.publish('boards', function() {
   const userId = this.userId;
   const userId = this.userId;
   // Ensure that the user is connected. If it is not, we need to return an empty
   // Ensure that the user is connected. If it is not, we need to return an empty
@@ -58,6 +60,58 @@ Meteor.publish('boards', function() {
   );
   );
 });
 });
 
 
+Meteor.publish('boardsReport', function() {
+  const userId = this.userId;
+  // Ensure that the user is connected. If it is not, we need to return an empty
+  // array to tell the client to remove the previously published docs.
+  if (!Match.test(userId, String) || !userId) return [];
+
+  boards = Boards.find(
+    {
+      archived: false,
+      $or: [
+        {
+          // _id: { $in: starredBoards },  // Commented out, to get a list of all public boards
+          permission: 'public',
+        },
+        { members: { $elemMatch: { userId, isActive: true } } },
+      ],
+    },
+    {
+      fields: {
+        _id: 1,
+        boardId: 1,
+        archived: 1,
+        slug: 1,
+        title: 1,
+        description: 1,
+        color: 1,
+        members: 1,
+        orgs: 1,
+        teams: 1,
+        permission: 1,
+        type: 1,
+        sort: 1,
+      },
+      sort: { sort: 1 /* boards default sorting */ },
+    },
+  );
+
+  const users = [];
+  boards.forEach(board => {
+    if (board.members) {
+      board.members.forEach(member => {
+        users.push(member.userId);
+      });
+    }
+  })
+
+  return [
+    boards,
+    Users.find({ _id: { $in: users } }, { fields: Users.safeFields }),
+  ]
+});
+
 Meteor.publish('archivedBoards', function() {
 Meteor.publish('archivedBoards', function() {
   const userId = this.userId;
   const userId = this.userId;
   if (!Match.test(userId, String)) return [];
   if (!Match.test(userId, String)) return [];