parent
1049ed88b6
commit
c6dd90a0e5
@ -21,8 +21,10 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"constant-case": "^2.0.0",
|
"constant-case": "^2.0.0",
|
||||||
"express": "^4.14.0",
|
"express": "^4.14.0",
|
||||||
|
"force-array": "^3.1.0",
|
||||||
"inherits": "^2.0.3",
|
"inherits": "^2.0.3",
|
||||||
"locale": "^0.1.0",
|
"locale": "^0.1.0",
|
||||||
|
"lodash.find": "^4.6.0",
|
||||||
"lodash.isempty": "^4.4.0",
|
"lodash.isempty": "^4.4.0",
|
||||||
"lodash.template": "^4.4.0",
|
"lodash.template": "^4.4.0",
|
||||||
"lodash.uniq": "^4.5.0",
|
"lodash.uniq": "^4.5.0",
|
||||||
@ -43,6 +45,7 @@
|
|||||||
"redux-logger": "^2.7.4",
|
"redux-logger": "^2.7.4",
|
||||||
"redux-promise-middleware": "^4.2.0",
|
"redux-promise-middleware": "^4.2.0",
|
||||||
"redux-thunk": "^2.1.0",
|
"redux-thunk": "^2.1.0",
|
||||||
|
"reselect": "^2.5.4",
|
||||||
"st": "^1.2.0",
|
"st": "^1.2.0",
|
||||||
"styled-components": "^1.1.3",
|
"styled-components": "^1.1.3",
|
||||||
"url-loader": "^0.5.7"
|
"url-loader": "^0.5.7"
|
||||||
|
@ -1,72 +0,0 @@
|
|||||||
const React = require('react');
|
|
||||||
const ReactIntl = require('react-intl');
|
|
||||||
const ReactRedux = require('react-redux');
|
|
||||||
const ReactRouter = require('react-router');
|
|
||||||
|
|
||||||
const H1 = require('@ui/components/h1');
|
|
||||||
const Li = require('@ui/components/horizontal-list/li');
|
|
||||||
const Redirect = require('@components/redirect');
|
|
||||||
const Ul = require('@ui/components/horizontal-list/ul');
|
|
||||||
|
|
||||||
const Projects = require('./projects');
|
|
||||||
const Settings = require('./settings');
|
|
||||||
|
|
||||||
const {
|
|
||||||
FormattedMessage
|
|
||||||
} = ReactIntl;
|
|
||||||
|
|
||||||
const {
|
|
||||||
connect
|
|
||||||
} = ReactRedux;
|
|
||||||
|
|
||||||
const {
|
|
||||||
Link,
|
|
||||||
Match,
|
|
||||||
Miss
|
|
||||||
} = ReactRouter;
|
|
||||||
|
|
||||||
const Dashboard = ({
|
|
||||||
pathname = '',
|
|
||||||
user = {}
|
|
||||||
}) => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<H1>
|
|
||||||
<FormattedMessage id='your-dashboard' />
|
|
||||||
</H1>
|
|
||||||
<Ul>
|
|
||||||
<Li>
|
|
||||||
<Link activeClassName='active' to={`/${user.id}/projects`}>
|
|
||||||
<FormattedMessage id='projects' />
|
|
||||||
</Link>
|
|
||||||
</Li>
|
|
||||||
<Li>
|
|
||||||
<Link activeClassName='active' to={`/${user.id}/settings`}>
|
|
||||||
<FormattedMessage id='settings' />
|
|
||||||
</Link>
|
|
||||||
</Li>
|
|
||||||
</Ul>
|
|
||||||
<Match component={Projects} pattern={`/${user.id}/projects`} />
|
|
||||||
<Match component={Settings} pattern={`/${user.id}/settings`} />
|
|
||||||
<Miss component={Redirect(`/${user.id}/projects`)} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Dashboard.propTypes = {
|
|
||||||
pathname: React.PropTypes.string,
|
|
||||||
user: React.PropTypes.shape({
|
|
||||||
id: React.PropTypes.string,
|
|
||||||
name: React.PropTypes.string
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
|
||||||
projects: state.session.data.projects,
|
|
||||||
user: {
|
|
||||||
id: state.session.data.name,
|
|
||||||
name: state.session.data.name
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(Dashboard);
|
|
@ -1,13 +0,0 @@
|
|||||||
const ReactRedux = require('react-redux');
|
|
||||||
|
|
||||||
const Projects = require('@components/projects');
|
|
||||||
|
|
||||||
const {
|
|
||||||
connect
|
|
||||||
} = ReactRedux;
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
|
||||||
projects: state.session.data.projects
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(Projects);
|
|
@ -1,43 +0,0 @@
|
|||||||
const React = require('react');
|
|
||||||
const ReactIntl = require('react-intl');
|
|
||||||
const ReactRedux = require('react-redux');
|
|
||||||
// const ReactRouter = require('react-router');
|
|
||||||
//
|
|
||||||
const Column = require('@ui/components/column');
|
|
||||||
// const Button = require('@ui/components/button');
|
|
||||||
const Row = require('@ui/components/row');
|
|
||||||
|
|
||||||
const {
|
|
||||||
FormattedMessage
|
|
||||||
} = ReactIntl;
|
|
||||||
|
|
||||||
const {
|
|
||||||
connect
|
|
||||||
} = ReactRedux;
|
|
||||||
|
|
||||||
// const {
|
|
||||||
// Link,
|
|
||||||
// Match,
|
|
||||||
// Miss,
|
|
||||||
// Redirect
|
|
||||||
// } = ReactRouter;
|
|
||||||
|
|
||||||
const Settings = () => {
|
|
||||||
return (
|
|
||||||
<Row>
|
|
||||||
<Column xs={12}>
|
|
||||||
<FormattedMessage id='your-settings' />
|
|
||||||
</Column>
|
|
||||||
</Row>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
Settings.propTypes = {
|
|
||||||
Settings: React.PropTypes.array
|
|
||||||
};
|
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
|
||||||
Settings: state.session.data.Settings
|
|
||||||
});
|
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(Settings);
|
|
@ -1,19 +1,16 @@
|
|||||||
const React = require('react');
|
const React = require('react');
|
||||||
const ReactIntl = require('react-intl');
|
|
||||||
const ReactRedux = require('react-redux');
|
const ReactRedux = require('react-redux');
|
||||||
const ReactRouter = require('react-router');
|
const ReactRouter = require('react-router');
|
||||||
const Styled = require('styled-components');
|
const Styled = require('styled-components');
|
||||||
|
|
||||||
|
const selectors = require('@state/selectors');
|
||||||
|
|
||||||
const Container = require('@ui/components/container');
|
const Container = require('@ui/components/container');
|
||||||
const Dashboard = require('@containers/dashboard');
|
|
||||||
const Li = require('@ui/components/horizontal-list/li');
|
const Li = require('@ui/components/horizontal-list/li');
|
||||||
const Org = require('@containers/org');
|
const Org = require('@containers/org');
|
||||||
const Redirect = require('@components/redirect');
|
const Redirect = require('@components/redirect');
|
||||||
const Ul = require('@ui/components/horizontal-list/ul');
|
const Ul = require('@ui/components/horizontal-list/ul');
|
||||||
|
const NotFound = require('@containers/not-found');
|
||||||
const {
|
|
||||||
FormattedMessage
|
|
||||||
} = ReactIntl;
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
connect
|
connect
|
||||||
@ -29,14 +26,16 @@ const {
|
|||||||
default: styled
|
default: styled
|
||||||
} = Styled;
|
} = Styled;
|
||||||
|
|
||||||
|
const {
|
||||||
|
orgsSelector
|
||||||
|
} = selectors;
|
||||||
|
|
||||||
const StyledNav = styled.div`
|
const StyledNav = styled.div`
|
||||||
background-color: #f2f2f2;
|
background-color: #f2f2f2;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const Home = ({
|
const Home = ({
|
||||||
orgs = [],
|
orgs = []
|
||||||
pathname = '/',
|
|
||||||
user = {}
|
|
||||||
}) => {
|
}) => {
|
||||||
const navLinks = orgs.map(({
|
const navLinks = orgs.map(({
|
||||||
id,
|
id,
|
||||||
@ -53,47 +52,40 @@ const Home = ({
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const notFound = !orgs.length
|
||||||
|
? <NotFound />
|
||||||
|
: Redirect(`/${orgs[0].id}`);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<StyledNav>
|
<StyledNav>
|
||||||
<Container>
|
<Container>
|
||||||
<Ul>
|
<Ul>
|
||||||
<Li key={pathname}>
|
|
||||||
<Link activeClassName='active' to={`/${user.id}`}>
|
|
||||||
<FormattedMessage id='your-dashboard' />
|
|
||||||
</Link>
|
|
||||||
</Li>
|
|
||||||
{navLinks}
|
{navLinks}
|
||||||
</Ul>
|
</Ul>
|
||||||
</Container>
|
</Container>
|
||||||
</StyledNav>
|
</StyledNav>
|
||||||
<Container>
|
<Container>
|
||||||
<Match component={Dashboard} pattern={`/${user.id}/:section?`} />
|
<Match component={Org} pattern='/:org/:section?' />
|
||||||
<Match component={Org} pattern='/:org' />
|
<Miss component={notFound} />
|
||||||
<Miss component={Redirect(`/${user.id}`)} />
|
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Home.propTypes = {
|
Home.propTypes = {
|
||||||
orgs: React.PropTypes.arrayOf(React.PropTypes.shape({
|
orgs: React.PropTypes.arrayOf(
|
||||||
id: React.PropTypes.string,
|
React.PropTypes.shape({
|
||||||
name: React.PropTypes.string
|
owner: React.PropTypes.string,
|
||||||
})),
|
uuid: React.PropTypes.string,
|
||||||
pathname: React.PropTypes.string,
|
|
||||||
user: React.PropTypes.shape({
|
|
||||||
id: React.PropTypes.string,
|
id: React.PropTypes.string,
|
||||||
name: React.PropTypes.string
|
name: React.PropTypes.string
|
||||||
})
|
})
|
||||||
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state) => ({
|
const mapStateToProps = (state) => ({
|
||||||
orgs: state.session.data.orgs,
|
orgs: orgsSelector(state)
|
||||||
user: {
|
|
||||||
id: state.session.data.name,
|
|
||||||
name: state.session.data.name
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(Home);
|
module.exports = connect(mapStateToProps)(Home);
|
||||||
|
@ -4,15 +4,19 @@ const ReactIntl = require('react-intl');
|
|||||||
const ReactRedux = require('react-redux');
|
const ReactRedux = require('react-redux');
|
||||||
const ReactRouter = require('react-router');
|
const ReactRouter = require('react-router');
|
||||||
|
|
||||||
|
const selectors = require('@state/selectors');
|
||||||
|
|
||||||
const H1 = require('@ui/components/h1');
|
const H1 = require('@ui/components/h1');
|
||||||
const Li = require('@ui/components/horizontal-list/li');
|
const Li = require('@ui/components/horizontal-list/li');
|
||||||
const Ul = require('@ui/components/horizontal-list/ul');
|
const Ul = require('@ui/components/horizontal-list/ul');
|
||||||
|
|
||||||
const NotFound = require('@containers/not-found');
|
const NotFound = require('@containers/not-found');
|
||||||
|
const Redirect = require('@components/redirect');
|
||||||
|
|
||||||
const People = require('./people');
|
const SectionComponents = {
|
||||||
const Projects = require('./projects');
|
people: require('./people'),
|
||||||
const Settings = require('./settings');
|
projects: require('./projects'),
|
||||||
|
settings: require('./settings'),
|
||||||
|
};
|
||||||
|
|
||||||
const {
|
const {
|
||||||
FormattedMessage
|
FormattedMessage
|
||||||
@ -25,75 +29,71 @@ const {
|
|||||||
const {
|
const {
|
||||||
Link,
|
Link,
|
||||||
Match,
|
Match,
|
||||||
Miss,
|
Miss
|
||||||
Redirect
|
|
||||||
} = ReactRouter;
|
} = ReactRouter;
|
||||||
|
|
||||||
|
const {
|
||||||
|
orgByIdSelector,
|
||||||
|
orgSectionsSelector
|
||||||
|
} = selectors;
|
||||||
|
|
||||||
const Org = ({
|
const Org = ({
|
||||||
org = {},
|
org = {},
|
||||||
params = {},
|
sections = []
|
||||||
user = {}
|
|
||||||
}) => {
|
}) => {
|
||||||
if (user.id === params.org) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isEmpty(org)) {
|
if (isEmpty(org)) {
|
||||||
return (
|
return (
|
||||||
<NotFound />
|
<NotFound />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const navLinks = sections.map((name) => (
|
||||||
|
<Li key={name}>
|
||||||
|
<Link activeClassName='active' to={`/${org.id}/${name}`}>
|
||||||
|
<FormattedMessage id={name} />
|
||||||
|
</Link>
|
||||||
|
</Li>
|
||||||
|
));
|
||||||
|
|
||||||
|
const navMatches = sections.map((name) => (
|
||||||
|
<Match
|
||||||
|
component={SectionComponents[name]}
|
||||||
|
key={name}
|
||||||
|
pattern={`/:org/${name}`}
|
||||||
|
/>
|
||||||
|
));
|
||||||
|
|
||||||
|
const missMatch = !sections.length ? null : (
|
||||||
|
<Miss component={Redirect(`/${org.id}/${sections[0]}`)} />
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<H1>{org.name}</H1>
|
<H1>{org.name}</H1>
|
||||||
<Ul>
|
<Ul>
|
||||||
<Li>
|
{navLinks}
|
||||||
<Link activeClassName='active' to={`/${org.id}/projects`}>
|
|
||||||
<FormattedMessage id='projects' />
|
|
||||||
</Link>
|
|
||||||
</Li>
|
|
||||||
<Li>
|
|
||||||
<Link activeClassName='active' to={`/${org.id}/people`}>
|
|
||||||
<FormattedMessage id='people' />
|
|
||||||
</Link>
|
|
||||||
</Li>
|
|
||||||
<Li>
|
|
||||||
<Link activeClassName='active' to={`/${org.id}/settings`}>
|
|
||||||
<FormattedMessage id='settings' />
|
|
||||||
</Link>
|
|
||||||
</Li>
|
|
||||||
</Ul>
|
</Ul>
|
||||||
<Match component={Projects} pattern='/:org/projects' />
|
{navMatches}
|
||||||
<Match component={People} pattern='/:org/people' />
|
{missMatch}
|
||||||
<Match component={Settings} pattern='/:org/settings' />
|
|
||||||
<Miss component={Redirect(`/${org.id}/projects`)} />
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
Org.propTypes = {
|
Org.propTypes = {
|
||||||
org: React.PropTypes.shape({
|
org: React.PropTypes.shape({
|
||||||
|
owner: React.PropTypes.string,
|
||||||
|
uuid: React.PropTypes.string,
|
||||||
id: React.PropTypes.string,
|
id: React.PropTypes.string,
|
||||||
name: React.PropTypes.string
|
name: React.PropTypes.string
|
||||||
}),
|
}),
|
||||||
params: React.PropTypes.shape({
|
sections: React.PropTypes.arrayOf(
|
||||||
org: React.PropTypes.string
|
React.PropTypes.string
|
||||||
}),
|
)
|
||||||
user: React.PropTypes.shape({
|
|
||||||
id: React.PropTypes.string,
|
|
||||||
name: React.PropTypes.string
|
|
||||||
})
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => ({
|
const mapStateToProps = (state, ownProps) => ({
|
||||||
org: state.session.data.orgs.filter((org) => {
|
org: orgByIdSelector(ownProps.params.org)(state),
|
||||||
return org.id === ownProps.params.org;
|
sections: orgSectionsSelector(ownProps.params.org)(state)
|
||||||
}).pop(),
|
|
||||||
user: {
|
|
||||||
id: state.session.data.name,
|
|
||||||
name: state.session.data.name
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(Org);
|
module.exports = connect(mapStateToProps)(Org);
|
||||||
|
@ -1,17 +1,18 @@
|
|||||||
const ReactRedux = require('react-redux');
|
|
||||||
|
|
||||||
const Projects = require('@components/projects');
|
const Projects = require('@components/projects');
|
||||||
|
const ReactRedux = require('react-redux');
|
||||||
|
const selectors = require('@state/selectors');
|
||||||
|
|
||||||
const {
|
const {
|
||||||
connect
|
connect
|
||||||
} = ReactRedux;
|
} = ReactRedux;
|
||||||
|
|
||||||
const mapStateToProps = (state, ownProps) => {
|
const {
|
||||||
return {
|
projectsByOrgIdSelector
|
||||||
projects: (state.session.data.orgs.filter((org) => {
|
} = selectors;
|
||||||
return org.id === ownProps.params.org;
|
|
||||||
}).pop() || {}).projects
|
|
||||||
};
|
const mapStateToProps = (state, ownProps) => ({
|
||||||
};
|
projects: projectsByOrgIdSelector(ownProps.params.org)(state)
|
||||||
|
});
|
||||||
|
|
||||||
module.exports = connect(mapStateToProps)(Projects);
|
module.exports = connect(mapStateToProps)(Projects);
|
||||||
|
@ -24,32 +24,57 @@ const {
|
|||||||
} = ReactRouter;
|
} = ReactRouter;
|
||||||
|
|
||||||
const store = Store({
|
const store = Store({
|
||||||
session: {
|
projects: {
|
||||||
data: {
|
data: [{
|
||||||
id: 'nicola',
|
uuid: 'e0ea0c02-55cc-45fe-8064-3e5176a59401',
|
||||||
name: 'Nicola',
|
org: 'e12ad7db-91b2-4154-83dd-40dcfc700dcc',
|
||||||
projects: [],
|
|
||||||
orgs: [{
|
|
||||||
id: 'biz-tech',
|
|
||||||
name: 'BizTech',
|
|
||||||
pinned: true,
|
|
||||||
projects: [{
|
|
||||||
id: 'forest-foundation-dev',
|
id: 'forest-foundation-dev',
|
||||||
name: 'Forest Foundation Dev',
|
name: 'Forest Foundation Dev',
|
||||||
plan: '20.05$ per day'
|
plan: '20.05$ per day'
|
||||||
}, {
|
}, {
|
||||||
|
uuid: '9fcb374d-a267-4c2a-9d9c-ba469b804639',
|
||||||
|
org: 'e12ad7db-91b2-4154-83dd-40dcfc700dcc',
|
||||||
id: 'forest-foundation-testing',
|
id: 'forest-foundation-testing',
|
||||||
name: 'Forest Foundation Testing',
|
name: 'Forest Foundation Testing',
|
||||||
plan: '20.05$ per day'
|
plan: '20.05$ per day'
|
||||||
}, {
|
}, {
|
||||||
|
uuid: 'ac2c2498-e865-4ee3-9e26-8c75a81cbe25',
|
||||||
|
org: 'e12ad7db-91b2-4154-83dd-40dcfc700dcc',
|
||||||
id: 'forest-foundation-production',
|
id: 'forest-foundation-production',
|
||||||
name: 'Forest Foundation Production',
|
name: 'Forest Foundation Production',
|
||||||
plan: '100.17$ per day'
|
plan: '100.17$ per day'
|
||||||
}],
|
}]
|
||||||
|
},
|
||||||
|
orgs: {
|
||||||
|
ui: {
|
||||||
|
sections: [
|
||||||
|
'projects',
|
||||||
|
'people',
|
||||||
|
'settings'
|
||||||
|
]
|
||||||
|
},
|
||||||
|
data: [{
|
||||||
|
hide: ['people'],
|
||||||
|
owner: 'b94033c1-3665-4c36-afab-d9c3d0b51c01',
|
||||||
|
id: 'nicola',
|
||||||
|
name: 'Your Dashboard'
|
||||||
}, {
|
}, {
|
||||||
|
owner: 'b94033c1-3665-4c36-afab-d9c3d0b51c01',
|
||||||
|
uuid: 'e12ad7db-91b2-4154-83dd-40dcfc700dcc',
|
||||||
|
id: 'biz-tech',
|
||||||
|
name: 'BizTech'
|
||||||
|
}, {
|
||||||
|
owner: 'b94033c1-3665-4c36-afab-d9c3d0b51c01',
|
||||||
|
uuid: '551f316d-e414-480f-9787-b4c408db3edd',
|
||||||
id: 'make-us-proud',
|
id: 'make-us-proud',
|
||||||
name: 'Make Us Proud',
|
name: 'Make Us Proud',
|
||||||
}]
|
}]
|
||||||
|
},
|
||||||
|
account: {
|
||||||
|
data: {
|
||||||
|
uuid: 'b94033c1-3665-4c36-afab-d9c3d0b51c01',
|
||||||
|
id: 'nicola',
|
||||||
|
name: 'Nicola'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -6,8 +6,10 @@ const {
|
|||||||
|
|
||||||
module.exports = () => {
|
module.exports = () => {
|
||||||
return combineReducers({
|
return combineReducers({
|
||||||
|
account: require('@state/reducers/account'),
|
||||||
app: require('@state/reducers/app'),
|
app: require('@state/reducers/app'),
|
||||||
intl: require('@state/reducers/intl'),
|
intl: require('@state/reducers/intl'),
|
||||||
session: require('@state/reducers/session')
|
orgs: require('@state/reducers/orgs'),
|
||||||
|
projects: require('@state/reducers/projects')
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
9
frontend/src/state/reducers/orgs.js
Normal file
9
frontend/src/state/reducers/orgs.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
const ReduxActions = require('redux-actions');
|
||||||
|
|
||||||
|
const {
|
||||||
|
handleActions
|
||||||
|
} = ReduxActions;
|
||||||
|
|
||||||
|
module.exports = handleActions({
|
||||||
|
'x': (state) => state // somehow handleActions needs at least one reducer
|
||||||
|
}, {});
|
9
frontend/src/state/reducers/projects.js
Normal file
9
frontend/src/state/reducers/projects.js
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
const ReduxActions = require('redux-actions');
|
||||||
|
|
||||||
|
const {
|
||||||
|
handleActions
|
||||||
|
} = ReduxActions;
|
||||||
|
|
||||||
|
module.exports = handleActions({
|
||||||
|
'x': (state) => state // somehow handleActions needs at least one reducer
|
||||||
|
}, {});
|
37
frontend/src/state/selectors.js
Normal file
37
frontend/src/state/selectors.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
const find = require('lodash.find');
|
||||||
|
const forceArray = require('force-array');
|
||||||
|
const reselect = require('reselect');
|
||||||
|
|
||||||
|
const {
|
||||||
|
createSelector
|
||||||
|
} = reselect;
|
||||||
|
|
||||||
|
const account = (state) => state.account.data;
|
||||||
|
const orgUiSections = (state) => state.orgs.ui.sections;
|
||||||
|
const orgs = (state) => state.orgs.data;
|
||||||
|
const projects = (state) => state.projects.data;
|
||||||
|
|
||||||
|
const orgById = (id) => createSelector(
|
||||||
|
orgs,
|
||||||
|
(orgs) => find(orgs, ['id', id])
|
||||||
|
);
|
||||||
|
|
||||||
|
const projectsByOrgId = (orgId) => createSelector(
|
||||||
|
[projects, orgById(orgId)],
|
||||||
|
(projects, org) => projects.filter((p) => p.org === org.uuid)
|
||||||
|
);
|
||||||
|
|
||||||
|
const orgSections = (orgId) => createSelector(
|
||||||
|
[orgById(orgId), orgUiSections],
|
||||||
|
(org, sections) => sections.filter(
|
||||||
|
(section) => forceArray(org.hide).indexOf(section) < 0
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
accountSelector: account,
|
||||||
|
orgByIdSelector: orgById,
|
||||||
|
orgsSelector: orgs,
|
||||||
|
orgSectionsSelector: orgSections,
|
||||||
|
projectsByOrgIdSelector: projectsByOrgId
|
||||||
|
};
|
@ -2480,6 +2480,12 @@ for-own@^0.1.4:
|
|||||||
dependencies:
|
dependencies:
|
||||||
for-in "^0.1.5"
|
for-in "^0.1.5"
|
||||||
|
|
||||||
|
force-array:
|
||||||
|
version "3.1.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/force-array/-/force-array-3.1.0.tgz#a060f6d4188dc7daa6fe562df39aeaabca404784"
|
||||||
|
dependencies:
|
||||||
|
is-array "^1.0.1"
|
||||||
|
|
||||||
foreach@^2.0.5:
|
foreach@^2.0.5:
|
||||||
version "2.0.5"
|
version "2.0.5"
|
||||||
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
|
resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99"
|
||||||
@ -2961,6 +2967,10 @@ irregular-plurals@^1.0.0:
|
|||||||
version "1.2.0"
|
version "1.2.0"
|
||||||
resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.2.0.tgz#38f299834ba8c00c30be9c554e137269752ff3ac"
|
resolved "https://registry.yarnpkg.com/irregular-plurals/-/irregular-plurals-1.2.0.tgz#38f299834ba8c00c30be9c554e137269752ff3ac"
|
||||||
|
|
||||||
|
is-array@^1.0.1:
|
||||||
|
version "1.0.1"
|
||||||
|
resolved "https://registry.yarnpkg.com/is-array/-/is-array-1.0.1.tgz#e9850cc2cc860c3bc0977e84ccf0dd464584279a"
|
||||||
|
|
||||||
is-arrayish@^0.2.1:
|
is-arrayish@^0.2.1:
|
||||||
version "0.2.1"
|
version "0.2.1"
|
||||||
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
|
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
|
||||||
@ -3434,6 +3444,10 @@ lodash.filter@^4.4.0:
|
|||||||
version "4.6.0"
|
version "4.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
|
resolved "https://registry.yarnpkg.com/lodash.filter/-/lodash.filter-4.6.0.tgz#668b1d4981603ae1cc5a6fa760143e480b4c4ace"
|
||||||
|
|
||||||
|
lodash.find:
|
||||||
|
version "4.6.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/lodash.find/-/lodash.find-4.6.0.tgz#cb0704d47ab71789ffa0de8b97dd926fb88b13b1"
|
||||||
|
|
||||||
lodash.flatten@^4.2.0:
|
lodash.flatten@^4.2.0:
|
||||||
version "4.4.0"
|
version "4.4.0"
|
||||||
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
|
resolved "https://registry.yarnpkg.com/lodash.flatten/-/lodash.flatten-4.4.0.tgz#f31c22225a9632d2bbf8e4addbef240aa765a61f"
|
||||||
@ -4742,6 +4756,10 @@ requires-port@1.0.x, requires-port@1.x.x:
|
|||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff"
|
||||||
|
|
||||||
|
reselect:
|
||||||
|
version "2.5.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/reselect/-/reselect-2.5.4.tgz#b7d23fdf00b83fa7ad0279546f8dbbbd765c7047"
|
||||||
|
|
||||||
resolve-cwd@^1.0.0:
|
resolve-cwd@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-1.0.0.tgz#4eaeea41ed040d1702457df64a42b2b07d246f9f"
|
resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-1.0.0.tgz#4eaeea41ed040d1702457df64a42b2b07d246f9f"
|
||||||
|
Loading…
Reference in New Issue
Block a user