mirror of
https://github.com/roleypoly/roleypoly-v1.git
synced 2025-06-16 10:19:10 +00:00
finish redux feature parity
This commit is contained in:
parent
f5220aa6dc
commit
5510d5a1c4
29 changed files with 220 additions and 100 deletions
|
@ -1,14 +1,17 @@
|
|||
import React, { Component } from 'react'
|
||||
import { BrowserRouter } from 'react-router-dom'
|
||||
import { Provider } from 'react-redux'
|
||||
import './App.css'
|
||||
import createHistory from 'history/createBrowserHistory'
|
||||
import { ConnectedRouter } from 'react-router-redux'
|
||||
import configureStore from './store/configureStore'
|
||||
import './App.css'
|
||||
|
||||
import Wrapper from './components/wrapper'
|
||||
import AppRouter from './router'
|
||||
import { userInit } from './actions'
|
||||
|
||||
const store = configureStore()
|
||||
const history = createHistory()
|
||||
const store = configureStore(undefined, history)
|
||||
|
||||
window.__APP_STORE__ = store
|
||||
|
||||
|
@ -20,11 +23,11 @@ class App extends Component {
|
|||
render () {
|
||||
return (
|
||||
<Provider store={store}>
|
||||
<BrowserRouter>
|
||||
<ConnectedRouter history={history}>
|
||||
<Wrapper>
|
||||
<AppRouter />
|
||||
</Wrapper>
|
||||
</BrowserRouter>
|
||||
</ConnectedRouter>
|
||||
</Provider>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -14,19 +14,23 @@ export const fetchServers = async dispatch => {
|
|||
}
|
||||
|
||||
export const userInit = async dispatch => {
|
||||
try {
|
||||
const rsp = await superagent.get('/api/auth/user')
|
||||
|
||||
dispatch({
|
||||
type: Symbol.for('set user'),
|
||||
data: rsp.body
|
||||
})
|
||||
if (!window.location.pathname.startsWith('/oauth')) {
|
||||
try {
|
||||
const rsp = await superagent.get('/api/auth/user')
|
||||
|
||||
dispatch(fetchServers)
|
||||
} catch (e) {
|
||||
if (!window.location.pathname.startsWith('/oauth')) {
|
||||
dispatch({
|
||||
type: Symbol.for('set user'),
|
||||
data: rsp.body
|
||||
})
|
||||
|
||||
dispatch(fetchServers)
|
||||
} catch (e) {
|
||||
window.location.href = '/oauth/flow'
|
||||
}
|
||||
} else {
|
||||
dispatch({
|
||||
type: Symbol.for('app ready')
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,16 +12,16 @@ export const roleUpdate = (id, oldState) => (dispatch, getState) => {
|
|||
}
|
||||
|
||||
export const setup = id => async dispatch => {
|
||||
const rsp = await superagent.get(`/api/server/${id}`)
|
||||
const data = rsp.body
|
||||
// const rsp = await superagent.get(`/api/server/${id}`)
|
||||
// const data = rsp.body
|
||||
|
||||
dispatch({
|
||||
type: Symbol.for('update server roles'),
|
||||
data: {
|
||||
id,
|
||||
roles: data
|
||||
}
|
||||
})
|
||||
// dispatch({
|
||||
// type: Symbol.for('update server roles'),
|
||||
// data: {
|
||||
// id,
|
||||
// roles: data
|
||||
// }
|
||||
// })
|
||||
|
||||
dispatch(constructView(id))
|
||||
}
|
||||
|
@ -31,9 +31,7 @@ export const constructView = id => (dispatch, getState) => {
|
|||
const roles = server.get('roles')
|
||||
|
||||
const categories = roles.groupBy(x => x.get('category'))
|
||||
const selected = roles.reduce((acc, r) => {
|
||||
return acc.set(r.id, r.selected)
|
||||
}, Map())
|
||||
const selected = roles.reduce((acc, r) => acc.set(r.get('id'), r.get('selected')), Map())
|
||||
|
||||
console.log(categories, selected)
|
||||
dispatch({
|
||||
|
|
|
@ -7,7 +7,6 @@ import './RolePicker.sass'
|
|||
import Role from '../role'
|
||||
|
||||
const mapState = ({ rolePicker, servers }, ownProps) => {
|
||||
console.log(servers)
|
||||
return {
|
||||
data: rolePicker,
|
||||
server: servers.get(ownProps.match.params.server)
|
||||
|
@ -21,8 +20,12 @@ class RolePicker extends Component {
|
|||
dispatch(Actions.setup(server))
|
||||
}
|
||||
|
||||
isSelected (id) {
|
||||
return this.props.data.getIn([ 'rolesSelected', id ])
|
||||
}
|
||||
|
||||
render () {
|
||||
console.log(this.props)
|
||||
console.log(this.constructor.name, this.props)
|
||||
if (this.props.server === undefined) {
|
||||
return null
|
||||
}
|
||||
|
@ -37,11 +40,11 @@ class RolePicker extends Component {
|
|||
}
|
||||
<section>
|
||||
<h3>Roles</h3>
|
||||
{/* {
|
||||
this.props.data.roles.map((r, k) => {
|
||||
return <Role key={k} role={r} onToggle={this.dispatch(Actions.roleUpdate(r.id, r.selected))} />
|
||||
{
|
||||
this.props.server.get('roles').map((r, k) => {
|
||||
return <Role key={k} role={r} selected={this.isSelected(r.get('id'))} onToggle={() => this.props.dispatch(Actions.roleUpdate(r.get('id'), this.isSelected(r.get('id'))))} />
|
||||
})
|
||||
} */}
|
||||
}
|
||||
</section>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -20,7 +20,11 @@
|
|||
border-color: var(--role-color-hover)
|
||||
background-color: transparent
|
||||
&:active
|
||||
box-shadow: none
|
||||
box-shadow: none
|
||||
|
||||
&:active .role__option
|
||||
box-shadow: none
|
||||
|
||||
|
||||
&__option
|
||||
border-radius: 50%
|
||||
|
|
|
@ -9,12 +9,14 @@ class Role extends Component {
|
|||
static propTypes = {
|
||||
role: PropTypes.object.isRequired,
|
||||
onToggle: PropTypes.func,
|
||||
type: PropTypes.string
|
||||
type: PropTypes.string,
|
||||
selected: PropTypes.bool.isRequired
|
||||
}
|
||||
|
||||
render () {
|
||||
const { role } = this.props
|
||||
let color = Color(role.color)
|
||||
let { role, selected } = this.props
|
||||
|
||||
let color = Color(role.get('color'))
|
||||
|
||||
if (color.rgbNumber() === 0) {
|
||||
color = whiteColor
|
||||
|
@ -24,17 +26,16 @@ class Role extends Component {
|
|||
let hc = color.lighten(0.1)
|
||||
|
||||
return <div
|
||||
onClick={this.props.onToggle.bind(null, !role.selected, role.selected)}
|
||||
className='role'
|
||||
onClick={this.props.onToggle.bind(null, !selected, selected)}
|
||||
className='role font-sans-serif'
|
||||
style={{
|
||||
'--role-color-hex': c.string(),
|
||||
'--role-color-hover': hc.string(),
|
||||
'--role-color-rgba': `rgba(${c.red()}, ${c.green()}, ${c.blue()}, 0.7)`
|
||||
}}>
|
||||
{/* circle svg */}
|
||||
<div className={`role__option ${(role.selected) ? 'selected' : ''}`}/>
|
||||
<div className={`role__option ${(selected) ? 'selected' : ''}`}/>
|
||||
<div className='role__name'>
|
||||
{role.name}
|
||||
{role.get('name')}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -5,10 +5,9 @@ import ServerCard from './ServerCard'
|
|||
import UserCard from './UserCard'
|
||||
|
||||
class ServersNavigation extends Component {
|
||||
|
||||
static propTypes = {
|
||||
user: ImmutablePropTypes.map.isRequired,
|
||||
servers: ImmutablePropTypes.setOf(ImmutablePropTypes.orderedMap).isRequired,
|
||||
servers: ImmutablePropTypes.orderedMapOf(ImmutablePropTypes.map).isRequired,
|
||||
className: PropTypes.string
|
||||
}
|
||||
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import React, { Component } from 'react'
|
||||
import { connect } from 'react-redux'
|
||||
import ImmutablePropTypes from 'react-immutable-proptypes'
|
||||
import { NavLink } from 'react-router-dom'
|
||||
import Radium from 'radium'
|
||||
import './ServerCard.sass'
|
||||
import { withRouter } from 'react-router';
|
||||
|
||||
class ServerCard extends Component {
|
||||
static propTypes = {
|
||||
|
|
|
@ -5,6 +5,7 @@ import './index.sass'
|
|||
|
||||
import Navigation from './Navigation'
|
||||
import RolePicker from '../role-picker'
|
||||
import { withRouter } from 'react-router';
|
||||
|
||||
// import mockData from './mockData'
|
||||
|
||||
|
|
|
@ -7,6 +7,10 @@ body {
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.font-sans-serif {
|
||||
font-family: sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
|
||||
}
|
||||
|
||||
:root {
|
||||
--c-white: #efefef;
|
||||
--c-9: #EBD6D4;
|
||||
|
|
|
@ -3,6 +3,7 @@ import { combineReducers } from 'redux'
|
|||
import servers from './servers'
|
||||
import user from './user'
|
||||
import rolePicker from './role-picker'
|
||||
import { routerMiddleware } from 'react-router-redux';
|
||||
// import roles from './roles'
|
||||
|
||||
const initialState = {
|
||||
|
@ -25,6 +26,7 @@ const rootReducer = combineReducers({
|
|||
appState,
|
||||
servers,
|
||||
user,
|
||||
router: routerMiddleware,
|
||||
// roles,
|
||||
rolePicker
|
||||
})
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
import { Map, Set } from 'immutable'
|
||||
import { Map, OrderedMap } from 'immutable'
|
||||
|
||||
const initialState = Map({
|
||||
hidden: true, // should the view be hidden?
|
||||
emptyRoles: true, // helps derender roles so there's no visible element state change
|
||||
viewMap: Set([]), // roles in categories
|
||||
viewMap: OrderedMap({}), // roles in categories
|
||||
originalRolesSelected: Map({}), // Map<role id, bool> -- original roles for diffing against selected
|
||||
rolesSelected: Map({}) // Map<role id, bool> -- new roles for diffing
|
||||
})
|
||||
|
@ -11,8 +11,8 @@ const initialState = Map({
|
|||
export default (state = initialState, { type, data }) => {
|
||||
switch (type) {
|
||||
case Symbol.for('setup role picker'):
|
||||
return state.merge(data)
|
||||
|
||||
return state.mergeDeep(data)
|
||||
|
||||
case Symbol.for('hide role picker ui'):
|
||||
return {
|
||||
...state,
|
||||
|
@ -24,12 +24,12 @@ export default (state = initialState, { type, data }) => {
|
|||
...state,
|
||||
emptyRoles: data
|
||||
}
|
||||
|
||||
case Symbol.for('zero role picker'):
|
||||
return initialState
|
||||
|
||||
case Symbol.for('update selected roles'):
|
||||
return state.set('rolesSelected', state.get('rolesSelected').set(data.id, data.state))
|
||||
return state.setIn(['rolesSelected', data.id], data.state)
|
||||
|
||||
case Symbol.for('zero role picker'):
|
||||
return initialState
|
||||
|
||||
default:
|
||||
return state
|
||||
|
|
|
@ -5,9 +5,11 @@ import { connect } from 'react-redux'
|
|||
import Servers from '../components/servers'
|
||||
import OauthCallback from '../components/oauth-callback'
|
||||
import OauthFlow from '../components/oauth-flow'
|
||||
import { withRouter } from 'react-router';
|
||||
|
||||
const aaa = (props) => (<div>{ JSON.stringify(props) }</div>)
|
||||
|
||||
@withRouter
|
||||
@connect(({ appState }) => ({ ready: appState.ready }))
|
||||
export default class AppRouter extends Component {
|
||||
render () {
|
||||
|
|
|
@ -5,13 +5,14 @@ import { createLogger } from 'redux-logger'
|
|||
// import api from '../middleware/api'
|
||||
import rootReducer from '../reducers'
|
||||
import DevTools from '../components/dev-tools'
|
||||
import { routerMiddleware } from 'react-router-redux'
|
||||
|
||||
const configureStore = preloadedState => {
|
||||
const configureStore = (preloadedState, history) => {
|
||||
const store = createStore(
|
||||
rootReducer,
|
||||
preloadedState,
|
||||
compose(
|
||||
applyMiddleware(thunk, createLogger()),
|
||||
applyMiddleware(thunk, routerMiddleware(history), createLogger()),
|
||||
DevTools.instrument()
|
||||
)
|
||||
)
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
import { createStore, applyMiddleware } from 'redux'
|
||||
import { routerMiddleware } from 'react-router-redux'
|
||||
|
||||
import thunk from 'redux-thunk'
|
||||
// import api from '../middleware/api'
|
||||
import rootReducer from '../reducers'
|
||||
|
||||
const configureStore = preloadedState => createStore(
|
||||
const configureStore = (preloadedState, history) => createStore(
|
||||
rootReducer,
|
||||
preloadedState,
|
||||
applyMiddleware(thunk)
|
||||
applyMiddleware(thunk, routerMiddleware(history))
|
||||
)
|
||||
|
||||
export default configureStore
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue