Skip to content
Snippets Groups Projects
Commit 4ecd7cbf authored by Jure's avatar Jure
Browse files

Merge branch 'selectors' into 'master'

Create entity selectors

See merge request pubsweet/pubsweet!19
parents e1f5277f 67131333
No related branches found
No related tags found
No related merge requests found
......@@ -31,7 +31,8 @@
"redux": "^3.6.0",
"redux-form": "^7.0.3",
"redux-logger": "^3.0.1",
"redux-thunk": "^2.2.0"
"redux-thunk": "^2.2.0",
"reselect": "^3.0.1"
},
"devDependencies": {
"babel-cli": "^6.26.0",
......
......@@ -5,6 +5,7 @@ import { push } from 'react-router-redux'
import PropTypes from 'prop-types'
import actions from '../actions'
import { selectCurrentUser } from '../selectors'
export class AuthenticatedComponent extends React.Component {
componentWillMount() {
......@@ -39,7 +40,7 @@ AuthenticatedComponent.propTypes = {
function mapState(state) {
return {
isFetching: state.currentUser.isFetching,
isAuthenticated: state.currentUser.isAuthenticated,
isAuthenticated: !!selectCurrentUser(state),
}
}
......
......@@ -7,6 +7,7 @@ import 'event-source-polyfill'
import * as T from '../actions/types'
import token from '../helpers/token'
import { selectCurrentUser } from '../selectors'
const actionMap = {
'collection:create': T.CREATE_COLLECTION_SUCCESS,
......@@ -160,7 +161,7 @@ UpdateSubscriber.propTypes = {
export default connect(
state => ({
currentUser: state.currentUser,
currentUser: selectCurrentUser(state),
}),
dispatch => ({
handleUpdate: (type, body) => dispatch({ type, ...body }),
......
......@@ -4,6 +4,7 @@ import { connect } from 'react-redux'
import { compose } from 'redux'
import withAuthsome from './withAuthsome'
import { selectCurrentUser } from '../selectors'
export class Authorize extends React.Component {
constructor(props) {
......@@ -55,10 +56,7 @@ Authorize.propTypes = {
function mapState(state) {
return {
teams: state.teams,
collections: state.collections,
fragments: state.fragments,
currentUser: state.currentUser.user,
currentUser: selectCurrentUser(state),
}
}
......
import Authsome from 'authsome'
import { connect } from 'react-redux'
import config from 'config'
import {
selectCollection,
selectFragment,
selectTeam,
selectUser,
} from '../selectors'
const mode = require(config.authsome.mode)
......@@ -12,19 +18,10 @@ export default function withAuthsome() {
authsome.context = {
// fetch entities from store instead of database
models: {
Collection: {
find: id =>
state.collections.find(collection => collection.id === id),
},
Fragment: {
find: id => state.fragments[id],
},
Team: {
find: id => state.teams.find(team => team.id === id),
},
User: {
find: id => state.users.users.find(user => user.id === id),
},
Collection: { find: id => selectCollection(state, { id }) },
Fragment: { find: id => selectFragment(state, { id }) },
Team: { find: id => selectTeam(state, { id }) },
User: { find: id => selectUser(state, { id }) },
},
}
......
......@@ -5,19 +5,19 @@ import {
LOGOUT_SUCCESS,
} from '../actions/types'
export default function(
state = {
isFetching: false,
isAuthenticated: false,
},
action,
) {
const initialState = {
isFetching: false,
// TODO remove isAuthenticated in favour of !!user
isAuthenticated: false,
user: null,
}
export default function(state = initialState, action) {
switch (action.type) {
case GET_CURRENT_USER_REQUEST:
return {
...state,
isFetching: true,
isAuthenticated: false,
}
case GET_CURRENT_USER_SUCCESS:
......@@ -33,6 +33,7 @@ export default function(
...state,
isFetching: false,
isAuthenticated: false,
user: null,
}
case LOGOUT_SUCCESS:
......
import { createSelector } from 'reselect'
export const selectCollections = state => state.collections
export const selectTeams = state => state.teams
export const selectUsers = state => state.users.users
export const selectFragments = state => state.fragments
export const selectCollection = createSelector(
selectCollections,
(_, { id }) => id,
(collections, id) => collections.find(collection => collection.id === id),
)
export const selectFragment = createSelector(
selectFragments,
(_, { id }) => id,
(fragments, id) => fragments[id],
)
export const selectTeam = createSelector(
selectTeams,
(_, { id }) => id,
(teams, id) => teams.find(team => team.id === id),
)
export const selectUser = createSelector(
selectUsers,
(_, { id }) => id,
(users, id) => users.find(user => user.id === id),
)
export const selectCurrentUser = state => state.currentUser.user
......@@ -34,7 +34,11 @@ describe('currentUser reducers', () => {
type: T.GET_CURRENT_USER_FAILURE,
},
)
expect(actual).toEqual({ isFetching: false, isAuthenticated: false })
expect(actual).toEqual({
isFetching: false,
isAuthenticated: false,
user: null,
})
})
it('currentUser request', () => {
......@@ -44,7 +48,7 @@ describe('currentUser reducers', () => {
type: T.GET_CURRENT_USER_REQUEST,
},
)
expect(actual).toEqual({ isFetching: true, isAuthenticated: false })
expect(actual).toEqual({ isFetching: true })
})
it('logout success', () => {
......
import { selectUser } from '../../packages/client/src/selectors'
describe('Selectors', () => {
it('selectUser', () => {
const user2 = { id: 2, foo: 'bar' }
const state = {
users: {
users: [{ id: 1 }, user2],
},
}
expect(selectUser(state, { id: 2 })).toEqual(user2)
})
})
......@@ -9768,6 +9768,10 @@ requires-port@1.0.x, requires-port@1.x.x, requires-port@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
reselect@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/reselect/-/reselect-3.0.1.tgz#efdaa98ea7451324d092b2b2163a6a1d7a9a2147"
resolve-cwd@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a"
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment