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,
+ },
+ });
+}