Added edge for metrics, fixed client linting errors

This commit is contained in:
Wyatt Johnson
2017-02-14 17:02:50 -07:00
parent 50e3e733c3
commit e640bc2cc0
7 changed files with 159 additions and 22 deletions
@@ -1,7 +1,6 @@
import React, {PropTypes} from 'react';
import styles from './FlagWidget.css';
const FlagWidget = props => {
const FlagWidget = () => {
return (
<table>
<thead>
+2
View File
@@ -3,6 +3,7 @@ const _ = require('lodash');
const Actions = require('./actions');
const Assets = require('./assets');
const Comments = require('./comments');
const Metrics = require('./metrics');
const Settings = require('./settings');
const Users = require('./users');
@@ -18,6 +19,7 @@ module.exports = (context) => {
Actions,
Assets,
Comments,
Metrics,
Settings,
Users
].map((loaders) => {
+137
View File
@@ -0,0 +1,137 @@
const _ = require('lodash');
const CommentModel = require('../../models/comment');
const AssetModel = require('../../models/asset');
const ActionModel = require('../../models/action');
const getMetrics = (context, {from, to}) => {
let commentMetrics = {};
let assetMetrics = [];
return ActionModel.aggregate([
// Find all actions that were created in the time range.
{$match: {
action_type: 'FLAG',
item_type: 'COMMENTS',
created_at: {
$gt: from,
$lt: to
}
}},
// Count all those items.
{$group: {
_id: '$item_id',
count: {
$sum: 1
}
}},
// Project the count to a better field.
{$project: {
item_id: '$_id',
count: '$count'
}}
]).then((actionSummaries) => {
// Collect all the action summaries into a dictionary.
actionSummaries.forEach((actionSummary) => {
commentMetrics[actionSummary.item_id] = actionSummary.count;
});
// Collect just the comment id's.
let commentIDs = actionSummaries.map((as) => as.item_id);
// Find those comments.
return CommentModel.aggregate([
// Get only those comments.
{$match: {
id: {
$in: commentIDs
}
}},
// Group by their asset id and push in the comment id.
{$group: {
_id: {
asset_id: '$asset_id'
},
ids: {
$addToSet: '$id'
}
}},
// Project that data only as better fields.
{$project: {
asset_id: '$_id.asset_id',
ids: '$ids'
}}
]);
})
.then((commentResults) => {
// Compute all the action summaries for the assets based on the time slice
// that you requested.
commentResults.forEach((result) => {
let actionCount = 0;
result.ids.forEach((id) => {
actionCount += commentMetrics[id];
});
assetMetrics.push({
id: result.asset_id,
actionCount,
actionableItemCount: result.ids.length
});
});
// Sort the assets by flag count.
assetMetrics.sort((a, b) => {
return b.flags - a.flags;
});
// Only keep the top 10.
assetMetrics = assetMetrics.slice(0, 10);
// Determine the assets that we need to return.
return AssetModel.find({
id: {
$in: assetMetrics.map((asset) => asset.id)
}
});
})
.then((assets) => {
// Join up the assets that are returned by their id.
let groupedAssets = _.groupBy(assets, 'id');
// Return from the sorted asset metrics and return their assetes.
return assetMetrics.map(({id, actionCount, actionableItemCount}) => {
if (id in groupedAssets) {
let asset = groupedAssets[id][0];
let flagAssetActionSummary = {
action_type: 'FLAG',
actionCount,
actionableItemCount
};
// Add the action summaries to the asset.
asset.action_summaries = [flagAssetActionSummary];
return asset;
}
return null;
}).filter((asset) => asset != null);
});
};
module.exports = (context) => ({
Metrics: {
get: ({from, to}) => getMetrics(context, {from, to})
}
});
+10
View File
@@ -0,0 +1,10 @@
const AssetActionSummary = {
__resolveType({action_type}) {
switch (action_type) {
case 'FLAG':
return 'FlagAssetActionSummary';
}
}
};
module.exports = AssetActionSummary;
+2
View File
@@ -1,5 +1,6 @@
const ActionSummary = require('./action_summary');
const Action = require('./action');
const AssetActionSummary = require('./asset_action_summary');
const Asset = require('./asset');
const Comment = require('./comment');
const Date = require('./date');
@@ -17,6 +18,7 @@ const ValidationUserError = require('./validation_user_error');
module.exports = {
ActionSummary,
Action,
AssetActionSummary,
Asset,
Comment,
Date,
+2 -2
View File
@@ -39,12 +39,12 @@ const RootQuery = {
return Comments.getByQuery(query);
},
metric(_, args, {user, loaders: {Assets}}) {
metrics(_, {from, to}, {user, loaders: {Metrics}}) {
if (user == null || !user.hasRoles('ADMIN')) {
return null;
}
return Assets.getForMetrics();
return Metrics.get({from, to});
},
// This returns the current user, ensure that if we aren't logged in, we
+5 -18
View File
@@ -198,16 +198,6 @@ interface AssetActionSummary {
actionableItemCount: Int
}
# A summary of counts related to all the Likes on an Asset.
type LikeAssetActionSummary implements AssetActionSummary {
# Number of actions associated with actionable types on this this Asset.
actionCount: Int
# Number of unique actionable types that are referenced by the actions.
actionableItemCount: Int
}
# A summary of counts related to all the Flags on an Asset.
type FlagAssetActionSummary implements AssetActionSummary {
@@ -343,15 +333,12 @@ type Asset {
# The date that the asset was closed at.
closedAt: Date
# The date that the asset was created.
created_at: Date
# Summary of all Actions against all entities associated with the Asset.
# (likes, flags, etc.)
action_summaries: [AssetActionSummary]
# Unique users that have commented on this Asset.
authorCount: Int
# The date that the asset was created.
created_at: Date
}
################################################################################
@@ -386,7 +373,7 @@ type ValidationUserError implements UserError {
}
################################################################################
## Queries
## Queries;
################################################################################
# Establishes the ordering of the content by their created_at time stamp.
@@ -424,8 +411,8 @@ type RootQuery {
# The currently logged in user based on the request.
me: User
# metrics
metric: [Asset]
# Metrics related to user actions are saturated into the assets returned.
metrics(from: Date!, to: Date!): [Asset]
}
################################################################################