diff --git a/client/coral-admin/src/actions/moderation.js b/client/coral-admin/src/actions/moderation.js index 25a9aed73..425628abe 100644 --- a/client/coral-admin/src/actions/moderation.js +++ b/client/coral-admin/src/actions/moderation.js @@ -2,4 +2,4 @@ import * as actions from 'constants/moderation'; export const setActiveTab = activeTab => ({type: actions.SET_ACTIVE_TAB, activeTab}); export const toggleModal = open => ({type: actions.TOGGLE_MODAL, open}); -export const singleView = open => ({type: actions.SINGLE_VIEW}); +export const singleView = () => ({type: actions.SINGLE_VIEW}); diff --git a/client/coral-admin/src/constants/moderation.js b/client/coral-admin/src/constants/moderation.js index 1ef27eddd..0fa51dc7b 100644 --- a/client/coral-admin/src/constants/moderation.js +++ b/client/coral-admin/src/constants/moderation.js @@ -1,3 +1,3 @@ export const SET_ACTIVE_TAB = 'SET_ACTIVE_TAB'; export const TOGGLE_MODAL = 'TOGGLE_MODAL'; -export const SINGLE_VIEW = 'SINGLE_VIEW' +export const SINGLE_VIEW = 'SINGLE_VIEW'; diff --git a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js index 095321e42..074d071e5 100644 --- a/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js +++ b/client/coral-admin/src/containers/ModerationQueue/ModerationContainer.js @@ -1,6 +1,9 @@ import React from 'react'; -import {connect} from 'react-redux'; import key from 'keymaster'; +import {connect} from 'react-redux'; +import {compose} from 'react-apollo'; + +import {modQueueQuery} from '../../graphql/queries'; import { updateStatus, @@ -19,6 +22,7 @@ import {setActiveTab, toggleModal, singleView} from 'actions/moderation'; import ModerationQueue from './ModerationQueue'; class ModerationContainer extends React.Component { + componentWillMount() { const {toggleModal, singleView} = this.props; @@ -88,6 +92,10 @@ class ModerationContainer extends React.Component { } } +ModerationContainer.contextTypes = { + router: React.PropTypes.func.isRequired +}; + const mapStateToProps = state => ({ moderation: state.moderation.toJS(), comments: state.comments.toJS(), @@ -101,7 +109,6 @@ const mapDispatchToProps = dispatch => ({ toggleModal: open => dispatch(toggleModal(open)), singleView: () => dispatch(singleView()), - fetchSettings: () => dispatch(fetchSettings()), fetchModerationQueueComments: () => dispatch(fetchModerationQueueComments()), fetchPremodQueue: () => dispatch(fetchPremodQueue()), @@ -119,4 +126,7 @@ const mapDispatchToProps = dispatch => ({ updateStatus: (action, comment) => dispatch(updateStatus(action, comment)) }); -export default connect(mapStateToProps, mapDispatchToProps)(ModerationContainer); +export default compose( + connect(mapStateToProps, mapDispatchToProps), + modQueueQuery +)(ModerationContainer); diff --git a/client/coral-admin/src/graphql/queries/index.js b/client/coral-admin/src/graphql/queries/index.js new file mode 100644 index 000000000..20cf1af8f --- /dev/null +++ b/client/coral-admin/src/graphql/queries/index.js @@ -0,0 +1,10 @@ +import {graphql} from 'react-apollo'; +import MOD_QUEUE_QUERY from './modQueueQuery.graphql'; + +export const modQueueQuery = graphql(MOD_QUEUE_QUERY, { + options: () => ({ + variables: { + asset_url: 'id' + } + }) +}); diff --git a/client/coral-admin/src/index.js b/client/coral-admin/src/index.js index 84d1b84ad..38b441992 100644 --- a/client/coral-admin/src/index.js +++ b/client/coral-admin/src/index.js @@ -1,6 +1,15 @@ import React from 'react'; -import ReactDOM from 'react-dom'; +import {render} from 'react-dom'; +import {ApolloProvider} from 'react-apollo'; + +import {client} from 'services/client'; +import store from 'services/store'; + import App from './components/App'; -// Render the application into the DOM -ReactDOM.render(, document.querySelector('#root')); +render( + + + + , document.querySelector('#root') +); diff --git a/client/coral-admin/src/reducers/index.js b/client/coral-admin/src/reducers/index.js index 415d0f581..53256fac5 100644 --- a/client/coral-admin/src/reducers/index.js +++ b/client/coral-admin/src/reducers/index.js @@ -1,5 +1,3 @@ -import {combineReducers} from 'redux'; - import auth from './auth'; import users from './users'; import assets from './assets'; @@ -9,7 +7,7 @@ import settings from './settings'; import community from './community'; import moderation from './moderation'; -export default combineReducers({ +export default { auth, users, assets, @@ -18,4 +16,4 @@ export default combineReducers({ comments, community, moderation -}); +}; diff --git a/client/coral-framework/PymConnection.js b/client/coral-admin/src/services/PymConnection.js similarity index 100% rename from client/coral-framework/PymConnection.js rename to client/coral-admin/src/services/PymConnection.js diff --git a/client/coral-framework/client.js b/client/coral-admin/src/services/client.js similarity index 100% rename from client/coral-framework/client.js rename to client/coral-admin/src/services/client.js diff --git a/client/coral-admin/src/services/store.js b/client/coral-admin/src/services/store.js index 0700dc579..8b9529e82 100644 --- a/client/coral-admin/src/services/store.js +++ b/client/coral-admin/src/services/store.js @@ -1,17 +1,23 @@ - -import {createStore, applyMiddleware} from 'redux'; +import {createStore, combineReducers, applyMiddleware, compose} from 'redux'; import thunk from 'redux-thunk'; -import mainReducer from 'reducers'; +import mainReducer from '../reducers'; +import {client} from './client'; -/** - * Create the store by merging the app reducers with - * the talk adapter. The talk adapter is the wire between - * this client and the coral backend. The idea is we can - * write different adapters for other platforms if we want - */ +const middlewares = [ + applyMiddleware(client.middleware()), + applyMiddleware(thunk) +]; + +if (window.devToolsExtension) { + + // we can't have the last argument of compose() be undefined + middlewares.push(window.devToolsExtension()); +} export default createStore( - mainReducer, - window.devToolsExtension && window.devToolsExtension(), - applyMiddleware(thunk) + combineReducers({ + ...mainReducer, + apollo: client.reducer() + }), + compose(...middlewares) ); diff --git a/client/coral-framework/subscriptions.js b/client/coral-admin/src/services/subscriptions.js similarity index 100% rename from client/coral-framework/subscriptions.js rename to client/coral-admin/src/services/subscriptions.js diff --git a/client/coral-framework/transport.js b/client/coral-admin/src/services/transport.js similarity index 100% rename from client/coral-framework/transport.js rename to client/coral-admin/src/services/transport.js diff --git a/client/coral-framework/services/PymConnection.js b/client/coral-framework/services/PymConnection.js new file mode 100644 index 000000000..ca592b824 --- /dev/null +++ b/client/coral-framework/services/PymConnection.js @@ -0,0 +1,9 @@ +import Pym from '../../node_modules/pym.js'; + +const pym = new Pym.Child({polling: 100}); +export default pym; + +export const link = (url) => (e) => { + e.preventDefault(); + pym.sendMessage('navigate', url); +}; diff --git a/client/coral-framework/services/client.js b/client/coral-framework/services/client.js new file mode 100644 index 000000000..b4a7a38df --- /dev/null +++ b/client/coral-framework/services/client.js @@ -0,0 +1,14 @@ +import ApolloClient, {addTypename} from 'apollo-client'; +import getNetworkInterface from './transport'; + +export const client = new ApolloClient({ + connectToDevTools: true, + queryTransformer: addTypename, + dataIdFromObject: (result) => { + if (result.id && result.__typename) { // eslint-disable-line no-underscore-dangle + return result.__typename + result.id; // eslint-disable-line no-underscore-dangle + } + return null; + }, + networkInterface: getNetworkInterface() +}); diff --git a/client/coral-framework/store.js b/client/coral-framework/services/store.js similarity index 100% rename from client/coral-framework/store.js rename to client/coral-framework/services/store.js diff --git a/client/coral-framework/services/subscriptions.js b/client/coral-framework/services/subscriptions.js new file mode 100644 index 000000000..f514ea18b --- /dev/null +++ b/client/coral-framework/services/subscriptions.js @@ -0,0 +1,14 @@ +import {print} from 'graphql-tag/printer'; + +// quick way to add the subscribe and unsubscribe functions to the network interface +const addGraphQLSubscriptions = (networkInterface, wsClient) => Object.assign(networkInterface, { + subscribe: (request, handler) => wsClient.subscribe({ + query: print(request.query), + variables: request.variables, + }, handler), + unsubscribe: (id) => { + wsClient.unsubscribe(id); + }, +}); + +export default addGraphQLSubscriptions; diff --git a/client/coral-framework/services/transport.js b/client/coral-framework/services/transport.js new file mode 100644 index 000000000..2bd6ac636 --- /dev/null +++ b/client/coral-framework/services/transport.js @@ -0,0 +1,11 @@ +import {createNetworkInterface} from 'apollo-client'; + +export default function getNetworkInterface(apiUrl = '/api/v1/graph/ql', headers = {}) { + return new createNetworkInterface({ + uri: apiUrl, + opts: { + credentials: 'same-origin', + headers, + }, + }); +}