From 46473142ba23bab970dab659ce5264d72e92890a Mon Sep 17 00:00:00 2001 From: Chi Vinh Le Date: Tue, 18 Jul 2017 21:23:39 +0700 Subject: [PATCH] Use generic version of addTag, removeTag in framework --- client/coral-framework/graphql/mutations.js | 111 ++++++++++++++++++++ plugin-api/beta/client/hocs/withTags.js | 108 ++----------------- 2 files changed, 120 insertions(+), 99 deletions(-) diff --git a/client/coral-framework/graphql/mutations.js b/client/coral-framework/graphql/mutations.js index 024778c1e..91d2ae0ab 100644 --- a/client/coral-framework/graphql/mutations.js +++ b/client/coral-framework/graphql/mutations.js @@ -1,6 +1,117 @@ import {gql} from 'react-apollo'; import withMutation from '../hocs/withMutation'; +function convertItemType(item_type) { + switch (item_type) { + case 'COMMENTS': + return 'Comment'; + case 'USERS': + return 'User'; + case 'ASSETS': + return 'Asset'; + default: + throw new Error(`Unknown item_type ${item_type}`); + } +} + +function getTagFragment(item_type) { + return gql` + fragment Coral_UpdateFragment on ${convertItemType(item_type)} { + tags { + tag { + name + } + } + } + `; +} + +export const withAddTag = withMutation( + gql` + mutation AddTag($id: ID!, $asset_id: ID!, $name: String!, $item_type: TAGGABLE_ITEM_TYPE!) { + addTag(tag: {name: $name, id: $id, item_type: $item_type, asset_id: $asset_id}) { + ...ModifyTagResponse + } + } + `, { + props: ({mutate}) => ({ + addTag: ({id, name, assetId, itemType}) => { + return mutate({ + variables: { + id, + name, + asset_id: assetId, + item_type: itemType, + }, + optimisticResponse: { + addTag: { + __typename: 'ModifyTagResponse', + errors: null, + } + }, + update: (proxy) => { + const fragmentId = `${convertItemType(itemType)}_${id}`; + const fragment = getTagFragment(itemType); + + // Read the data from our cache for this query. + const data = proxy.readFragment({fragment, id: fragmentId}); + + data.tags.push({ + tag: { + __typename: 'Tag', + name + }, + __typename: 'TagLink' + }); + + // Write our data back to the cache. + proxy.writeFragment({fragment, id: fragmentId, data}); + }, + }); + }}), + }); + +export const withRemoveTag = withMutation( + gql` + mutation RemoveTag($id: ID!, $asset_id: ID!, $name: String!, $item_type: TAGGABLE_ITEM_TYPE!) { + removeTag(tag: {name: $name, id: $id, item_type: $item_type, asset_id: $asset_id}) { + ...ModifyTagResponse + } + } + `, { + props: ({mutate}) => ({ + removeTag: ({id, name, assetId, itemType}) => { + return mutate({ + variables: { + id, + name, + asset_id: assetId, + item_type: itemType, + }, + optimisticResponse: { + removeTag: { + __typename: 'ModifyTagResponse', + errors: null, + } + }, + update: (proxy) => { + const fragmentId = `${convertItemType(itemType)}_${id}`; + const fragment = getTagFragment(itemType); + + // Read the data from our cache for this query. + const data = proxy.readFragment({fragment, id: fragmentId}); + + const idx = data.tags.findIndex((i) => i.tag.name === name); + + data.tags = [...data.tags.slice(0, idx), ...data.tags.slice(idx + 1)]; + + // Write our data back to the cache. + proxy.writeFragment({fragment, id: fragmentId, data}); + } + }); + }}), + }); + export const withSetCommentStatus = withMutation( gql` mutation SetCommentStatus($commentId: ID!, $status: COMMENT_STATUS!){ diff --git a/plugin-api/beta/client/hocs/withTags.js b/plugin-api/beta/client/hocs/withTags.js index bf559024a..75d434bef 100644 --- a/plugin-api/beta/client/hocs/withTags.js +++ b/plugin-api/beta/client/hocs/withTags.js @@ -4,7 +4,7 @@ import {bindActionCreators} from 'redux'; import {compose, gql} from 'react-apollo'; import {getDisplayName} from 'coral-framework/helpers/hoc'; import {capitalize} from 'coral-framework/helpers/strings'; -import withMutation from 'coral-framework/hocs/withMutation'; +import {withAddTag, withRemoveTag} from 'coral-framework/graphql/mutations'; import withFragments from 'coral-framework/hocs/withFragments'; import {addNotification} from 'coral-framework/actions/notification'; import {forEachError, isTagged} from 'coral-framework/utils'; @@ -15,100 +15,8 @@ export default (tag) => (WrappedComponent) => { return null; } - tag = tag.toLowerCase(); const Tag = capitalize(tag); - - const COMMENT_FRAGMENT = gql` - fragment Coral_UpdateFragment on Comment { - tags { - tag { - name - } - } - } - `; - - const withAddTag = withMutation( - gql` - mutation AddTag($id: ID!, $asset_id: ID!, $name: String!) { - addTag(tag: {name: $name, id: $id, item_type: COMMENTS, asset_id: $asset_id}) { - ...ModifyTagResponse - } - } - `, { - props: ({mutate}) => ({ - addTag: ({id, name, assetId}) => { - return mutate({ - variables: { - id, - name, - asset_id: assetId - }, - optimisticResponse: { - addTag: { - __typename: 'ModifyTagResponse', - errors: null, - } - }, - update: (proxy) => { - const fragmentId = `Comment_${id}`; - - // Read the data from our cache for this query. - const data = proxy.readFragment({fragment: COMMENT_FRAGMENT, id: fragmentId}); - - data.tags.push({ - tag: { - __typename: 'Tag', - name: Tag.toUpperCase() - }, - __typename: 'TagLink' - }); - - // Write our data back to the cache. - proxy.writeFragment({fragment: COMMENT_FRAGMENT, id: fragmentId, data}); - }, - }); - }}), - }); - - const withRemoveTag = withMutation( - gql` - mutation RemoveTag($id: ID!, $asset_id: ID!, $name: String!) { - removeTag(tag: {name: $name, id: $id, item_type: COMMENTS, asset_id: $asset_id}) { - ...ModifyTagResponse - } - } - `, { - props: ({mutate}) => ({ - removeTag: ({id, name, assetId}) => { - return mutate({ - variables: { - id, - name, - asset_id: assetId - }, - optimisticResponse: { - removeTag: { - __typename: 'ModifyTagResponse', - errors: null, - } - }, - update: (proxy) => { - const fragmentId = `Comment_${id}`; - - // Read the data from our cache for this query. - const data = proxy.readFragment({fragment: COMMENT_FRAGMENT, id: fragmentId}); - - const idx = data.tags.findIndex((i) => i.tag.name === Tag.toUpperCase()); - - data.tags = [...data.tags.slice(0, idx), ...data.tags.slice(idx + 1)]; - - // Write our data back to the cache. - proxy.writeFragment({fragment: COMMENT_FRAGMENT, id: fragmentId, data}); - } - }); - }}), - }); + const TAG = tag.toUpperCase(); class WithTags extends React.Component { loading = false; @@ -124,8 +32,9 @@ export default (tag) => (WrappedComponent) => { this.props.addTag({ id: comment.id, - name: Tag.toUpperCase(), - assetId: asset.id + name: TAG, + assetId: asset.id, + itemType: 'COMMENTS', }) .then(() => { this.loading = false; @@ -145,8 +54,9 @@ export default (tag) => (WrappedComponent) => { this.props.removeTag({ id: comment.id, - name: Tag.toUpperCase(), - assetId: asset.id + name: TAG, + assetId: asset.id, + itemType: 'COMMENTS', }) .then(() => { this.loading = false; @@ -160,7 +70,7 @@ export default (tag) => (WrappedComponent) => { render() { const {comment} = this.props; - const alreadyTagged = isTagged(comment.tags, Tag.toUpperCase()); + const alreadyTagged = isTagged(comment.tags, TAG); return