Added author_id to comment count query

This commit is contained in:
Wyatt Johnson
2017-05-16 14:20:20 -06:00
parent 4ca5c4bc09
commit f4b9191476
6 changed files with 148 additions and 20 deletions
+5 -3
View File
@@ -69,9 +69,11 @@ app.use('/api/v1/graph/ql', apollo.graphqlExpress(createGraphOptions));
if (app.get('env') !== 'production') {
// Interactive graphiql interface.
app.use('/api/v1/graph/iql', apollo.graphiqlExpress({
endpointURL: '/api/v1/graph/ql'
}));
app.use('/api/v1/graph/iql', (req, res) => {
res.render('graphiql', {
endpointURL: '/api/v1/graph/ql'
});
});
// GraphQL documention.
app.get('/admin/docs', (req, res) => {
+6 -2
View File
@@ -120,7 +120,7 @@ const getParentCountByAssetIDPersonalized = async (context, {assetId, excludeIgn
const ignoredUsers = freshUser.ignoresUsers;
query.author_id = {$nin: ignoredUsers};
}
return CommentModel.where(query).count();
};
@@ -191,7 +191,7 @@ const getCountByParentIDPersonalized = async (context, {id, excludeIgnored}) =>
* @return {Promise} resolves to the counts of the comments from the
* query
*/
const getCommentCountByQuery = (context, {ids, statuses, asset_id, parent_id}) => {
const getCommentCountByQuery = (context, {ids, statuses, asset_id, parent_id, author_id}) => {
let query = CommentModel.find();
if (ids) {
@@ -210,6 +210,10 @@ const getCommentCountByQuery = (context, {ids, statuses, asset_id, parent_id}) =
query = query.where({parent_id});
}
if (author_id) {
query = query.where({author_id});
}
return CommentModel
.find(query)
.count();
+3 -3
View File
@@ -34,7 +34,7 @@ const RootQuery = {
comment(_, {id}, {loaders: {Comments}}) {
return Comments.get.load(id);
},
async commentCount(_, {query: {action_type, statuses, asset_id, parent_id}}, {user, loaders: {Actions, Comments}}) {
async commentCount(_, {query: {action_type, statuses, asset_id, parent_id, author_id}}, {user, loaders: {Actions, Comments}}) {
if (user == null || !user.hasRoles('ADMIN')) {
return null;
}
@@ -43,10 +43,10 @@ const RootQuery = {
let ids = await Actions.getByTypes({action_type, item_type: 'COMMENTS'});
// Perform the query using the available resolver.
return Comments.getCountByQuery({ids, statuses, asset_id, parent_id});
return Comments.getCountByQuery({ids, statuses, asset_id, parent_id, author_id});
}
return Comments.getCountByQuery({statuses, asset_id, parent_id});
return Comments.getCountByQuery({statuses, asset_id, parent_id, author_id});
},
assetMetrics(_, {from, to, sort, limit = 10}, {user, loaders: {Metrics: {Assets}}}) {
+10 -11
View File
@@ -1,6 +1,7 @@
const {SubscriptionManager} = require('graphql-subscriptions');
const {SubscriptionServer} = require('subscriptions-transport-ws');
const _ = require('lodash');
const debug = require('debug')('talk:graph:subscriptions');
const pubsub = require('./pubsub');
const schema = require('./schema');
@@ -9,24 +10,22 @@ const plugins = require('../services/plugins');
const {deserializeUser} = require('../services/subscriptions');
// Core setup functions
let setupFunctions = {
commentAdded: (options, args) => ({
commentAdded: {
filter: (comment) => comment.asset_id === args.asset_id
},
}),
};
/**
* Plugin support requires that we merge in existing setupFunctions with our new
* plugin based ones. This allows plugins to extend existing setupFunctions as well
* as provide new ones.
*/
setupFunctions = plugins.get('server', 'setupFunctions').reduce((acc, {setupFunctions}) => {
const setupFunctions = plugins.get('server', 'setupFunctions').reduce((acc, {plugin, setupFunctions}) => {
debug(`added plugin '${plugin.name}'`);
return _.merge(acc, setupFunctions);
}, setupFunctions);
}, {
commentAdded: (options, args) => ({
commentAdded: {
filter: (comment) => comment.asset_id === args.asset_id
},
}),
});
/**
* This creates a new subscription manager.
+5 -1
View File
@@ -194,6 +194,10 @@ input CommentCountQuery {
# type.
action_type: ACTION_TYPE
# author_id allows the querying of comment counts based on the author of the
# comments.
author_id: ID
# Filter by a specific tag name.
tag: [String]
}
@@ -779,7 +783,7 @@ type EditCommentResponse implements Response {
comment: Comment
# An array of errors relating to the mutation that occured.
errors: [UserError]
errors: [UserError]
}
# All mutations for the application are defined on this object.
+119
View File
@@ -0,0 +1,119 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>GraphiQL</title>
<meta name="robots" content="noindex" />
<style>
html, body {
height: 100%;
margin: 0;
overflow: hidden;
width: 100%;
}
</style>
<link href="//cdn.jsdelivr.net/graphiql/0.9.1/graphiql.css" rel="stylesheet" />
<script src="//cdn.jsdelivr.net/fetch/0.9.0/fetch.min.js"></script>
<script src="//cdn.jsdelivr.net/react/15.0.0/react.min.js"></script>
<script src="//cdn.jsdelivr.net/react/15.0.0/react-dom.min.js"></script>
<script src="//cdn.jsdelivr.net/graphiql/0.9.1/graphiql.min.js"></script>
</head>
<body>
<script>
// Collect the URL parameters
var parameters = {};
window.location.search.substr(1).split('&').forEach(function (entry) {
var eq = entry.indexOf('=');
if (eq >= 0) {
parameters[decodeURIComponent(entry.slice(0, eq))] =
decodeURIComponent(entry.slice(eq + 1));
}
});
// Produce a Location query string from a parameter object.
function locationQuery(params, location) {
return (location ? location: '') + '?' + Object.keys(params).map(function (key) {
return encodeURIComponent(key) + '=' +
encodeURIComponent(params[key]);
}).join('&');
}
// Derive a fetch URL from the current URL, sans the GraphQL parameters.
var graphqlParamNames = {
query: true,
variables: true,
operationName: true
};
var otherParams = {};
for (var k in parameters) {
if (parameters.hasOwnProperty(k) && graphqlParamNames[k] !== true) {
otherParams[k] = parameters[k];
}
}
// We don't use safe-serialize for location, because it's not client input.
var fetchURL = locationQuery(otherParams, '<%= endpointURL %>');
// Defines a GraphQL fetcher using the fetch API.
function graphQLFetcher(graphQLParams) {
var headers = {
'Accept': 'application/json',
'Content-Type': 'application/json'
};
try {
let token = localStorage.getItem('token');
if (token) {
headers['Authorization'] = 'Bearer ' + token;
}
} catch (e) {
console.error(e);
}
return fetch(fetchURL, {
method: 'post',
headers: headers,
body: JSON.stringify(graphQLParams),
credentials: 'include',
}).then(function (response) {
return response.text();
}).then(function (responseBody) {
try {
return JSON.parse(responseBody);
} catch (error) {
return responseBody;
}
});
}
// When the query and variables string is edited, update the URL bar so
// that it can be easily shared.
function onEditQuery(newQuery) {
parameters.query = newQuery;
updateURL();
}
function onEditVariables(newVariables) {
parameters.variables = newVariables;
updateURL();
}
function onEditOperationName(newOperationName) {
parameters.operationName = newOperationName;
updateURL();
}
function updateURL() {
history.replaceState(null, null, locationQuery(parameters));
}
// Render <GraphiQL /> into the body.
ReactDOM.render(
React.createElement(GraphiQL, {
fetcher: graphQLFetcher,
onEditQuery: onEditQuery,
onEditVariables: onEditVariables,
onEditOperationName: onEditOperationName,
query: null,
response: null,
variables: null,
operationName: null,
}),
document.body
);
</script>
</body>
</html>