diff --git a/client/coral-framework/hocs/index.js b/client/coral-framework/hocs/index.js index 97bf910d9..e16e09941 100644 --- a/client/coral-framework/hocs/index.js +++ b/client/coral-framework/hocs/index.js @@ -18,6 +18,7 @@ export { default as withVariables } from './withVariables'; export { default as WithRefetch } from './withRefetch'; export { default as withFetchMore } from './withFetchMore'; export { default as withSubscribeToMore } from './withSubscribeToMore'; +export { default as withGraphQLExtension } from './withGraphQLExtension'; export { default as withResendEmailConfirmation, } from './withResendEmailConfirmation'; diff --git a/client/coral-framework/hocs/withGraphQLExtension.js b/client/coral-framework/hocs/withGraphQLExtension.js new file mode 100644 index 000000000..c44a94e47 --- /dev/null +++ b/client/coral-framework/hocs/withGraphQLExtension.js @@ -0,0 +1,19 @@ +import React from 'react'; +import hoistStatics from 'recompose/hoistStatics'; + +/** + * WithGraphQLExtension adds graphql configuration to the + * GraphQL registry, only works on Components used + * directly in a Slot. + */ +export default extension => + hoistStatics(WrappedComponent => { + class WithGraphQLExtension extends React.Component { + render() { + return ; + } + } + + WrappedComponent.graphqlExtension = extension; + return WithGraphQLExtension; + }); diff --git a/client/coral-framework/services/plugins.js b/client/coral-framework/services/plugins.js index 3879249ac..b390f1a1b 100644 --- a/client/coral-framework/services/plugins.js +++ b/client/coral-framework/services/plugins.js @@ -7,6 +7,7 @@ import isEmpty from 'lodash/isEmpty'; import flatten from 'lodash/flatten'; import mapValues from 'lodash/mapValues'; import get from 'lodash/get'; +import values from 'lodash/values'; import { getDisplayName } from 'coral-framework/helpers/hoc'; import camelize from '../helpers/camelize'; @@ -205,9 +206,16 @@ class PluginsService { } getGraphQLExtensions() { - return this.plugins - .map(o => pick(o.module, ['mutations', 'queries', 'fragments'])) - .filter(o => !isEmpty(o)); + return flatten( + this.plugins.map(o => { + const extension = pick(o.module, ['mutations', 'queries', 'fragments']); + // Include extension defined in Slot Components. + const slotComponentExtensions = !o.module.slots + ? [] + : flatten(values(o.module.slots)).map(cmp => cmp.graphqlExtension); + return [extension, ...slotComponentExtensions]; + }) + ).filter(o => !isEmpty(o)); } getModQueueConfigs() { diff --git a/plugin-api/beta/client/hocs/index.js b/plugin-api/beta/client/hocs/index.js index ff4523084..215641f32 100644 --- a/plugin-api/beta/client/hocs/index.js +++ b/plugin-api/beta/client/hocs/index.js @@ -17,6 +17,7 @@ export { withFetchMore, withSubscribeToMore, withRefetch, + withGraphQLExtension, } from 'coral-framework/hocs'; export { withIgnoreUser, diff --git a/plugins/talk-plugin-notifications-category-reply/client/containers/Toggle.js b/plugins/talk-plugin-notifications-category-reply/client/containers/Toggle.js index d261946d0..c55be5f90 100644 --- a/plugins/talk-plugin-notifications-category-reply/client/containers/Toggle.js +++ b/plugins/talk-plugin-notifications-category-reply/client/containers/Toggle.js @@ -3,7 +3,10 @@ import PropTypes from 'prop-types'; import { compose, gql } from 'react-apollo'; import Toggle from 'talk-plugin-notifications/client/components/Toggle'; import { t } from 'plugin-api/beta/client/services'; -import { withFragments } from 'plugin-api/beta/client/hocs'; +import { + withFragments, + withGraphQLExtension, +} from 'plugin-api/beta/client/hocs'; class ToggleContainer extends React.Component { constructor(props) { @@ -57,6 +60,38 @@ ToggleContainer.propTypes = { disabled: PropTypes.bool.isRequired, }; +const extension = { + mutations: { + UpdateNotificationSettings: ({ + variables: { input }, + state: { auth: { user: { id } } }, + }) => ({ + update: proxy => { + if (input.onReply === undefined) { + return; + } + + const fragment = gql` + fragment TalkNotificationsCategoryReply_User_Fragment on User { + notificationSettings { + onReply + } + } + `; + const fragmentId = `User_${id}`; + const data = { + __typename: 'User', + notificationSettings: { + __typename: 'NotificationSettings', + onReply: input.onReply, + }, + }; + proxy.writeFragment({ fragment, id: fragmentId, data }); + }, + }), + }, +}; + const enhance = compose( withFragments({ root: gql` @@ -68,7 +103,8 @@ const enhance = compose( } } `, - }) + }), + withGraphQLExtension(extension) ); export default enhance(ToggleContainer); diff --git a/plugins/talk-plugin-notifications-category-reply/client/index.js b/plugins/talk-plugin-notifications-category-reply/client/index.js index 1e22c3a93..fa10c15e2 100644 --- a/plugins/talk-plugin-notifications-category-reply/client/index.js +++ b/plugins/talk-plugin-notifications-category-reply/client/index.js @@ -1,11 +1,8 @@ import Toggle from './containers/Toggle'; import translations from './translations.yml'; -import graphql from './graphql'; - export default { slots: { notificationSettings: [Toggle], }, translations, - ...graphql, };