diff --git a/app.js b/app.js index c04e0cb4a..c2601ad5a 100644 --- a/app.js +++ b/app.js @@ -94,6 +94,11 @@ if (app.get('env') !== 'production') { endpointURL: '/api/v1/graph/ql' })); + // GraphQL documention. + app.get('/admin/docs', (req, res) => { + res.render('admin/docs'); + }); + } //============================================================================== diff --git a/client/coral-docs/src/index.js b/client/coral-docs/src/index.js new file mode 100644 index 000000000..5d8c49d9d --- /dev/null +++ b/client/coral-docs/src/index.js @@ -0,0 +1,8 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import {GraphQLDocs} from 'graphql-docs'; + +import fetcher from './services/fetcher'; + +// Render the application into the DOM +ReactDOM.render(, document.querySelector('#root')); diff --git a/client/coral-docs/src/services/fetcher.js b/client/coral-docs/src/services/fetcher.js new file mode 100644 index 000000000..e4d6f091d --- /dev/null +++ b/client/coral-docs/src/services/fetcher.js @@ -0,0 +1,10 @@ +export default function fetcher(query) { + return fetch(`${window.location.host}/api/v1/graph/ql`, { + method: 'POST', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + body: JSON.stringify({query}), + }).then((res) => res.json()); +} diff --git a/client/coral-embed-stream/src/Comment.js b/client/coral-embed-stream/src/Comment.js index c0c0d57d1..01e183a9b 100644 --- a/client/coral-embed-stream/src/Comment.js +++ b/client/coral-embed-stream/src/Comment.js @@ -18,7 +18,8 @@ import LikeButton from 'coral-plugin-likes/LikeButton'; import styles from './Comment.css'; -const getAction = (type, comment) => comment.actions.filter((a) => a.type === type)[0]; +const getActionSummary = (type, comment) => comment.action_summaries + .filter((a) => a.__typename === type)[0]; class Comment extends React.Component { @@ -35,7 +36,8 @@ class Comment extends React.Component { setActiveReplyBox: PropTypes.func.isRequired, refetch: PropTypes.func.isRequired, showSignInDialog: PropTypes.func.isRequired, - postAction: PropTypes.func.isRequired, + postFlag: PropTypes.func.isRequired, + postLike: PropTypes.func.isRequired, deleteAction: PropTypes.func.isRequired, parentId: PropTypes.string, addNotification: PropTypes.func.isRequired, @@ -51,7 +53,7 @@ class Comment extends React.Component { }), comment: PropTypes.shape({ depth: PropTypes.number, - actions: PropTypes.array.isRequired, + action_summaries: PropTypes.array.isRequired, body: PropTypes.string.isRequired, id: PropTypes.string.isRequired, replies: PropTypes.arrayOf( @@ -78,14 +80,15 @@ class Comment extends React.Component { refetch, addNotification, showSignInDialog, - postAction, + postLike, + postFlag, setActiveReplyBox, activeReplyBox, deleteAction } = this.props; - const like = getAction('LIKE', comment); - const flag = getAction('FLAG', comment); + const like = getActionSummary('LikeActionSummary', comment); + const flag = getActionSummary('FlagActionSummary', comment); return (
@@ -117,7 +120,7 @@ class Comment extends React.Component { flag={flag} id={comment.id} author_id={comment.user.id} - postAction={postAction} + postFlag={postFlag} deleteAction={deleteAction} showSignInDialog={showSignInDialog} currentUser={currentUser} /> @@ -150,7 +153,8 @@ class Comment extends React.Component { depth={depth + 1} asset={asset} currentUser={currentUser} - postAction={postAction} + postLike={postLike} + postFlag={postFlag} deleteAction={deleteAction} showSignInDialog={showSignInDialog} reactKey={reply.id} @@ -158,7 +162,6 @@ class Comment extends React.Component { comment={reply} />; }) } -
); } diff --git a/client/coral-embed-stream/src/Embed.js b/client/coral-embed-stream/src/Embed.js index a853efead..6cc783746 100644 --- a/client/coral-embed-stream/src/Embed.js +++ b/client/coral-embed-stream/src/Embed.js @@ -10,7 +10,7 @@ const {addNotification, clearNotification} = notificationActions; const {fetchAssetSuccess} = assetActions; import {queryStream} from 'coral-framework/graphql/queries'; -import {postComment, postAction, deleteAction} from 'coral-framework/graphql/mutations'; +import {postComment, postFlag, postLike, deleteAction} from 'coral-framework/graphql/mutations'; import {editName} from 'coral-framework/actions/user'; import {Notification, notificationActions, authActions, assetActions, pym} from 'coral-framework'; @@ -91,7 +91,7 @@ class Embed extends Component { minHeight: document.body.scrollHeight + 200 } : {}; - if (loading) { + if (loading || !asset) { return ; } @@ -146,7 +146,8 @@ class Embed extends Component { postItem={this.props.postItem} asset={asset} currentUser={user} - postAction={this.props.postAction} + postLike={this.props.postLike} + postFlag={this.props.postFlag} deleteAction={this.props.deleteAction} showSignInDialog={this.props.showSignInDialog} comments={asset.comments} /> @@ -209,7 +210,8 @@ const mapDispatchToProps = dispatch => ({ export default compose( connect(mapStateToProps, mapDispatchToProps), postComment, - postAction, + postFlag, + postLike, deleteAction, queryStream )(Embed); diff --git a/client/coral-embed-stream/src/Stream.js b/client/coral-embed-stream/src/Stream.js index 65743e6c7..53b54d4ba 100644 --- a/client/coral-embed-stream/src/Stream.js +++ b/client/coral-embed-stream/src/Stream.js @@ -37,7 +37,8 @@ class Stream extends React.Component { asset, postItem, addNotification, - postAction, + postFlag, + postLike, deleteAction, showSignInDialog, refetch @@ -56,7 +57,8 @@ class Stream extends React.Component { postItem={postItem} asset={asset} currentUser={currentUser} - postAction={postAction} + postLike={postLike} + postFlag={postFlag} deleteAction={deleteAction} showSignInDialog={showSignInDialog} key={comment.id} diff --git a/client/coral-framework/graphql/fragments/actionSummaryView.graphql b/client/coral-framework/graphql/fragments/actionSummaryView.graphql new file mode 100644 index 000000000..4ac232bf6 --- /dev/null +++ b/client/coral-framework/graphql/fragments/actionSummaryView.graphql @@ -0,0 +1,8 @@ +fragment actionSummaryView on ActionSummary { + __typename + count + current_user { + id + created_at + } +} diff --git a/client/coral-framework/graphql/fragments/commentView.graphql b/client/coral-framework/graphql/fragments/commentView.graphql index 29f9b3bfe..575434a31 100644 --- a/client/coral-framework/graphql/fragments/commentView.graphql +++ b/client/coral-framework/graphql/fragments/commentView.graphql @@ -1,3 +1,5 @@ +#import "../fragments/actionSummaryView.graphql" + fragment commentView on Comment { id body @@ -7,12 +9,7 @@ fragment commentView on Comment { id name: displayName } - actions { - type: action_type - count - current: current_user { - id - created_at - } + action_summaries { + ...actionSummaryView } } diff --git a/client/coral-framework/graphql/mutations/deleteAction.graphql b/client/coral-framework/graphql/mutations/deleteAction.graphql index bfce8cf6a..f8adf371c 100644 --- a/client/coral-framework/graphql/mutations/deleteAction.graphql +++ b/client/coral-framework/graphql/mutations/deleteAction.graphql @@ -1,3 +1,7 @@ mutation deleteAction ($id: ID!) { - deleteAction(id:$id) + deleteAction(id:$id) { + errors { + translation_key + } + } } diff --git a/client/coral-framework/graphql/mutations/index.js b/client/coral-framework/graphql/mutations/index.js index b97e5ff22..40ca0a7a3 100644 --- a/client/coral-framework/graphql/mutations/index.js +++ b/client/coral-framework/graphql/mutations/index.js @@ -1,6 +1,7 @@ import {graphql} from 'react-apollo'; import POST_COMMENT from './postComment.graphql'; -import POST_ACTION from './postAction.graphql'; +import POST_FLAG from './postFlag.graphql'; +import POST_LIKE from './postLike.graphql'; import DELETE_ACTION from './deleteAction.graphql'; import commentView from '../fragments/commentView.graphql'; @@ -21,12 +22,23 @@ export const postComment = graphql(POST_COMMENT, { }}), }); -export const postAction = graphql(POST_ACTION, { +export const postLike = graphql(POST_LIKE, { props: ({mutate}) => ({ - postAction: (action) => { + postLike: (like) => { return mutate({ variables: { - action + like + } + }); + }}), +}); + +export const postFlag = graphql(POST_FLAG, { + props: ({mutate}) => ({ + postFlag: (flag) => { + return mutate({ + variables: { + flag } }); }}), diff --git a/client/coral-framework/graphql/mutations/postAction.graphql b/client/coral-framework/graphql/mutations/postAction.graphql deleted file mode 100644 index fff737fa8..000000000 --- a/client/coral-framework/graphql/mutations/postAction.graphql +++ /dev/null @@ -1,5 +0,0 @@ -mutation CreateAction ($action: CreateActionInput!) { - createAction(action:$action) { - id - } -} diff --git a/client/coral-framework/graphql/mutations/postComment.graphql b/client/coral-framework/graphql/mutations/postComment.graphql index 499871766..6ce46eaa8 100644 --- a/client/coral-framework/graphql/mutations/postComment.graphql +++ b/client/coral-framework/graphql/mutations/postComment.graphql @@ -2,6 +2,11 @@ mutation CreateComment ($asset_id: ID!, $parent_id: ID, $body: String!) { createComment(asset_id:$asset_id, parent_id:$parent_id, body:$body) { - ...commentView + comment { + ...commentView + } + errors { + translation_key + } } } diff --git a/client/coral-framework/graphql/mutations/postFlag.graphql b/client/coral-framework/graphql/mutations/postFlag.graphql new file mode 100644 index 000000000..cabc2feef --- /dev/null +++ b/client/coral-framework/graphql/mutations/postFlag.graphql @@ -0,0 +1,10 @@ +mutation CreateFlag($flag: CreateFlagInput!) { + createFlag(flag:$flag) { + flag { + id + } + errors { + translation_key + } + } +} diff --git a/client/coral-framework/graphql/mutations/postLike.graphql b/client/coral-framework/graphql/mutations/postLike.graphql new file mode 100644 index 000000000..350904352 --- /dev/null +++ b/client/coral-framework/graphql/mutations/postLike.graphql @@ -0,0 +1,10 @@ +mutation CreateLike ($like: CreateLikeInput!) { + createLike(like:$like) { + like { + id + } + errors { + translation_key + } + } +} diff --git a/client/coral-framework/graphql/queries/index.js b/client/coral-framework/graphql/queries/index.js index 7ce065baa..ffd7dfdc9 100644 --- a/client/coral-framework/graphql/queries/index.js +++ b/client/coral-framework/graphql/queries/index.js @@ -13,7 +13,7 @@ function getQueryVariable(variable) { } // If no query is included, return a default string for development - return 'http://dev.default.stream'; + return 'http://localhost/default/stream'; } export const queryStream = graphql(STREAM_QUERY, { diff --git a/client/coral-plugin-commentbox/CommentBox.js b/client/coral-plugin-commentbox/CommentBox.js index 41c8f75fb..344ade150 100644 --- a/client/coral-plugin-commentbox/CommentBox.js +++ b/client/coral-plugin-commentbox/CommentBox.js @@ -8,9 +8,6 @@ const name = 'coral-plugin-commentbox'; class CommentBox extends Component { static propTypes = { - - // updateItem: PropTypes.func, - // comments: PropTypes.array, commentPostedHandler: PropTypes.func, postItem: PropTypes.func.isRequired, cancelButtonClicked: PropTypes.func, @@ -29,10 +26,6 @@ class CommentBox extends Component { postComment = () => { const { - - // child_id, - // updateItem, - // appendItemArray, commentPostedHandler, postItem, assetId, @@ -48,28 +41,13 @@ class CommentBox extends Component { parent_id: parentId }; - // let related; - // let parent_type; - // if (parent_id) { - // comment.parent_id = parent_id; - // related = 'children'; - // parent_type = 'comments'; - // } else { - // related = 'comments'; - // parent_type = 'assets'; - // } - // if (child_id || parent_id) { - // updateItem(child_id || parent_id, 'showReply', false, 'comments'); - // } - if (this.props.charCount && this.state.body.length > this.props.charCount) { return; } postItem(comment, 'comments') .then(({data}) => { - const postedComment = data.createComment; + const postedComment = data.createComment.comment; - // const commentId = postedComment.id; if (postedComment.status === 'REJECTED') { addNotification('error', lang.t('comment-post-banned-word')); } else if (postedComment.status === 'PREMOD') { diff --git a/client/coral-plugin-flags/FlagButton.js b/client/coral-plugin-flags/FlagButton.js index ec62f5396..e94dfc5fc 100644 --- a/client/coral-plugin-flags/FlagButton.js +++ b/client/coral-plugin-flags/FlagButton.js @@ -12,7 +12,7 @@ class FlagButton extends Component { showMenu: false, itemType: '', reason: '', - note: '', + message: '', step: 0, posted: false, localPost: null, @@ -23,7 +23,7 @@ class FlagButton extends Component { onReportClick = () => { const {currentUser, flag, deleteAction} = this.props; const {localPost, localDelete} = this.state; - const flagged = (flag && flag.current && !localDelete) || localPost; + const flagged = (flag && flag.current_user && !localDelete) || localPost; if (!currentUser) { const offset = document.getElementById(`c_${this.props.id}`).getBoundingClientRect().top - 75; this.props.showSignInDialog(offset); @@ -31,15 +31,15 @@ class FlagButton extends Component { } if (flagged) { this.setState((prev) => prev.localPost ? {...prev, localPost: null, step: 0} : {...prev, localDelete: true}); - deleteAction(localPost || flag.current.id); + deleteAction(localPost || flag.current_user.id); } else { this.setState({showMenu: !this.state.showMenu}); } } onPopupContinue = () => { - const {postAction, id, author_id} = this.props; - const {itemType, reason, step, posted} = this.state; + const {postFlag, id, author_id} = this.props; + const {itemType, reason, step, posted, message} = this.state; // Proceed to the next step or close the menu if we've reached the end if (step + 1 >= this.props.getPopupMenu.length) { @@ -67,13 +67,14 @@ class FlagButton extends Component { if (itemType === 'COMMENTS') { this.setState({localPost: 'temp'}); } - postAction({ + postFlag({ item_id, item_type: itemType, - action_type: 'FLAG' + reason, + message }).then(({data}) => { if (itemType === 'COMMENTS') { - this.setState({localPost: data.createAction.id}); + this.setState({localPost: data.createFlag.flag.id}); } }); } @@ -99,7 +100,7 @@ class FlagButton extends Component { } onNoteTextChange = (e) => { - this.setState({note: e.target.value}); + this.setState({message: e.target.value}); } handleClickOutside () { @@ -109,7 +110,7 @@ class FlagButton extends Component { render () { const {flag, getPopupMenu} = this.props; const {localPost, localDelete} = this.state; - const flagged = (flag && flag.current && !localDelete) || localPost; + const flagged = (flag && flag.current_user && !localDelete) || localPost; const popupMenu = getPopupMenu[this.state.step](this.state.itemType); return
@@ -150,15 +151,15 @@ class FlagButton extends Component { } { this.state.reason &&
-