work on withList and queries generation

This commit is contained in:
xavcz 2016-11-19 20:01:17 +01:00
parent 4ac4c4cd06
commit 6c14712a74
16 changed files with 129 additions and 39 deletions

View file

@ -40,7 +40,7 @@ class Movie extends Component {
return (
<div key={movie.name} style={{paddingBottom: "15px",marginBottom: "15px", borderBottom: "1px solid #ccc"}}>
<h2>{movie.name} ({movie.year})</h2>
<p>{movie.review} by <strong>{movie.user && movie.user.username}</strong></p>
<p>{movie.review} by <strong>{movie.user && movie.user.__displayName}</strong></p>
{this.renderEdit()}
</div>
)

View file

@ -6,6 +6,7 @@ import { Accounts } from 'meteor/std:accounts-ui';
import { ModalTrigger } from "meteor/nova:core";
import Movie from './Movie.jsx';
import Movies from '../collection.js';
import { compose } from 'react-apollo';
import { withCurrentUser, withList } from 'meteor/nova:core';
import { moviesListProps, moviesSingleProps } from '../containers/fragments.js';
@ -60,4 +61,4 @@ const listOptions = {
fragmentName: 'moviesListProps',
};
export default withList(listOptions)(withCurrentUser(MoviesList));
export default compose(withList(listOptions), withCurrentUser)(MoviesList);

View file

@ -11,6 +11,9 @@ const moviesListProps = createFragment(gql`
year
review
privateComments
user {
__displayName
}
}
`)

View file

@ -2,11 +2,11 @@ import Telescope from 'meteor/nova:lib';
import mutations from './mutations.js';
const resolvers = {
// Movie: {
// user(post, args, context) {
// return context.Users.findOne({ _id: post.userId }, { fields: context.getViewableFields(context.currentUser, context.Users) });
// },
// },
Movie: {
user(movie, args, context) {
return context.Users.findOne({ _id: movie.userId }, { fields: context.getViewableFields(context.currentUser, context.Users) });
},
},
Query: {
moviesList(root, {offset, limit}, context, info) {
const protectedLimit = (limit < 1 || limit > 10) ? 10 : limit;

View file

@ -2,11 +2,11 @@ import Telescope from 'meteor/nova:lib';
import React, { PropTypes, Component } from 'react';
import { FormattedMessage } from 'react-intl';
import { Button, DropdownButton, MenuItem, Modal } from 'react-bootstrap';
import { /* ModalTrigger, */ ContextPasser } from "meteor/nova:core";
import { /* ModalTrigger, */ ContextPasser, withList } from "meteor/nova:core";
import { withRouter } from 'react-router'
import { LinkContainer } from 'react-router-bootstrap';
import Users from 'meteor/nova:users';
import { withCategoriesList } from 'meteor/nova:base-containers';
import Categories from 'meteor/nova:categories';
// note: cannot use ModalTrigger component because of https://github.com/react-bootstrap/react-bootstrap/issues/1808
@ -152,4 +152,13 @@ CategoriesList.propTypes = {
results: React.PropTypes.array,
};
Telescope.registerComponent('CategoriesList', CategoriesList, withRouter, withCategoriesList);
const categoriesListOptions = {
queryName: 'getCategoriesList',
collection: CategoriesList,
listResolverName: 'categoriesList',
totalResolverName: 'categoriesListTotal',
fragment: Categories.fragments.full,
fragmentName: 'fullCategoryInfo',
};
Telescope.registerComponent('CategoriesList', CategoriesList, withRouter, withList(categoriesListOptions));

View file

@ -18,14 +18,13 @@ const CategoriesNewForm = (props, context) => {
getCategoriesList: (prev, {mutationResult}) => {
const newCategory = mutationResult.data.categoriesNew;
const newCategoriesList = update(prev, {
categories: {
categoriesList: {
$push: [newCategory]
},
categoriesListTotal: {
$set: prev.categoriesListTotal + 1
},
});
// note: 'newCategoriesList' is extended with the category but somehow when the query updates it e
return newCategoriesList;
},
}}

View file

@ -46,7 +46,7 @@ const CommentsNewForm = (props, context) => {
// console.log('[commentsNew] previous comment list', prev);
const newComment = mutationResult.data.commentsNew;
const newCommentsList = update(prev, {
comments: {
commentsList: {
$push: [newComment]
},
commentsListTotal: {

View file

@ -1,10 +1,8 @@
import Telescope from 'meteor/nova:lib';
import React from 'react';
import {FormattedMessage } from 'react-intl';
import { ModalTrigger, withCurrentUser } from 'meteor/nova:core';
import { ModalTrigger, withCurrentUser, withList } from 'meteor/nova:core';
import Comments from 'meteor/nova:comments';
import { withCommentsList } from 'meteor/nova:base-containers';
const PostsCommentsThread = (props, context) => {
@ -50,4 +48,16 @@ PostsCommentsThread.propTypes = {
currentUser: React.PropTypes.object
};
Telescope.registerComponent('PostsCommentsThread', PostsCommentsThread, withCurrentUser, withCommentsList);
const commentsListOptions = {
queryName: 'getCommentsList',
collection: Comments,
listResolverName: 'commentsList',
totalResolverName: 'commentsListTotal',
fragment: Comments.fragments.full,
fragmentName: 'fullCommentInfo',
ownPropsVariables: [
{propName: 'postId', graphqlType: 'String', usedForTotal: true},
],
};
Telescope.registerComponent('PostsCommentsThread', PostsCommentsThread, withCurrentUser, withList(commentsListOptions));

View file

@ -1,6 +1,7 @@
import Telescope from 'meteor/nova:lib';
import React from 'react';
import { withPostsList } from 'meteor/nova:base-containers';
import { withList } from 'meteor/nova:core';
import Posts from 'meteor/nova:posts';
const PostsList = (props) => {
@ -54,4 +55,19 @@ PostsList.propTypes = {
showHeader: React.PropTypes.bool,
};
Telescope.registerComponent('PostsList', PostsList, withPostsList);
const postsListOptions = {
queryName: 'getPostsList',
collection: Posts,
listResolverName: 'postsList',
totalResolverName: 'postsListTotal',
fragment: Posts.fragments.full,
fragmentName: 'fullPostInfo',
ownPropsVariables: [
// test note: can't overwrite atm
// {propName: 'limit', graphqlType: 'Int', defaultValue: 2, usedForTotal: false},
// note:give the list hoc the ability to catch props coming from upper in the component tree
{propName: 'terms', graphqlType: 'Terms', usedForTotal: true},
],
};
Telescope.registerComponent('PostsList', PostsList, withList(postsListOptions));

View file

@ -24,7 +24,7 @@ const PostsNewForm = (props, context) => {
getPostsList: (prev, { mutationResult }) => {
const newPost = mutationResult.data.postsNew;
const newList = update(prev, {
posts: {
postsList: {
$unshift: [newPost],
},
postsListTotal: {

View file

@ -2,7 +2,7 @@ import Telescope from 'meteor/nova:lib';
import Categories from './collection.js';
Telescope.graphQL.addQuery(`
categories: [Category]
categoriesList(offset: Int, limit: Int): [Category]
categoriesListTotal: Int
category(_id: String): Category
`);

View file

@ -13,7 +13,7 @@ export default resolvers = {
}
},
Query: {
categories(root, args, context) {
categoriesList(root, args, context) {
const options = {
fields: context.getViewableFields(context.currentUser, context.Categories)
};

View file

@ -3,7 +3,7 @@ import Comments from './collection.js';
// declare comments queries
Telescope.graphQL.addQuery(`
comments(postId: String): [Comment]
commentsList(postId: String, offset: Int, limit: Int): [Comment]
commentsListTotal(postId: String): Int
comment(_id: String): Comment
`);

View file

@ -31,11 +31,13 @@ const resolvers = {
},
},
Query: {
comments(root, {postId}, context) {
commentsList(root, {postId, offset, limit}, context) {
const options = {
// limit: 5, // no limit for now
limit: (limit < 1 || limit > 10) ? 10 : limit,
skip: offset,
fields: context.getViewableFields(context.currentUser, context.Comments)
}
};
return context.Comments.find({postId: postId}, options).fetch();
},
commentsListTotal(root, {postId}, context) {

View file

@ -5,27 +5,77 @@ import gql from 'graphql-tag';
export default function withList (options) {
console.log("withList")
console.log(options)
// extract arguments from the options of the hoc
const { queryName, collection, listResolverName, totalResolverName, fragment, fragmentName, ownPropsVariables = [] } = options;
console.log("withList: ", queryName);
// console.log(options);
const { queryName, collection, listResolverName, totalResolverName, fragment, fragmentName } = options;
// default variables for the gql query list
const defaultQueryVariables = [
{propName: 'offset', graphqlType: 'Int', defaultValue: 0, usedForTotal: false},
{propName: 'limit', graphqlType: 'Int', defaultValue: 5, usedForTotal: false},
];
// concat the default query variables with the ones from the props of the wrapped component
const propsVariables = [...defaultQueryVariables, ...ownPropsVariables];
console.log('props variables (default+ownProps)', propsVariables);
// output something like: `$offset: Int, $limit: Int, $terms: Terms`
const queryVariablesTypeDef = propsVariables.reduce((string, {propName, graphqlType}, index) => {
// don't add ", " if the current typeDef is the first iteration
const commaSeparation = index === 0 ? "" : ", ";
return `${string}${commaSeparation}$${propName}: ${graphqlType}`;
}, "");
console.log('query variables type def', queryVariablesTypeDef);
// output something like: `offset: $offset, limit: $limit, terms: $terms`
const queryVariablesList = propsVariables.reduce((string, {propName}, index) => {
// don't add ", " if the current typeDef is the first iteration
const commaSeparation = index === 0 ? "" : ", ";
return `${string}${commaSeparation}${propName}: $${propName}`;
}, "");
console.log('query variables list', queryVariablesList);
// output something like: `terms: $terms`
const queryVariablesTotal = propsVariables.filter(({usedForTotal}) => !!usedForTotal).reduce((string, {propName}, index) => {
// don't add ", " if the current typeDef is the first iteration
const commaSeparation = index === 0 ? "" : ", ";
return `${string}${commaSeparation}${propName}: $${propName}`;
}, "");
console.log('query variables total', queryVariablesTotal);
const callQueryVariablesTotal = !!queryVariablesTotal ? `(${queryVariablesTotal})` : "";
return graphql(gql`
query ${queryName}($offset: Int, $limit: Int) {
${totalResolverName}
${listResolverName}(offset: $offset, limit: $limit) {
query ${queryName}(${queryVariablesTypeDef}) {
${totalResolverName}${callQueryVariablesTotal}
${listResolverName}(${queryVariablesList}) {
...${fragmentName}
}
}
`, {
options(ownProps) {
const queryVariables = propsVariables.reduce((variables, {propName, defaultValue}) => ({
...variables,
[propName]: ownProps[propName] || defaultValue
}), {});
console.log('actual query variables', queryVariables);
return {
variables: {
offset: 0,
limit: 5
},
variables: queryVariables,
fragments: fragment,
pollInterval: 20000,
// pollInterval: 20000,
};
},
props(props) {

View file

@ -14,7 +14,7 @@ export default resolvers = {
},
},
Query: {
posts(root, {terms, offset, limit}, context, info) {
postsList(root, {terms, offset, limit}, context, info) {
// console.log("// context")
// console.log(context)
let {selector, options} = context.Posts.parameters.get(terms);
@ -40,7 +40,7 @@ export default resolvers = {
Telescope.graphQL.addResolvers(resolvers);
Telescope.graphQL.addQuery(`
posts(terms: Terms, offset: Int, limit: Int): [Post]
postsList(terms: Terms, offset: Int, limit: Int): [Post]
postsListTotal(terms: Terms): Int
post(_id: String): Post
`);