From e1034a458bb7469a21fc5c5c1219e7565706866d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivar=20Conradi=20=C3=98sthus?= Date: Tue, 18 May 2021 12:13:52 +0200 Subject: [PATCH] feat: simple project view (#295) Co-authored-by: Fredrik Oseberg --- frontend/src/component/menu/routes.js | 9 ++ .../project/ProjectList/ProjectList.jsx | 2 +- .../project/ViewProject/ViewProject.js | 90 +++++++++++++++++++ .../component/project/ViewProject/index.js | 39 ++++++++ .../src/component/project/access-add-user.js | 27 ++++-- frontend/src/page/project/view.js | 14 +++ 6 files changed, 175 insertions(+), 6 deletions(-) create mode 100644 frontend/src/component/project/ViewProject/ViewProject.js create mode 100644 frontend/src/component/project/ViewProject/index.js create mode 100644 frontend/src/page/project/view.js diff --git a/frontend/src/component/menu/routes.js b/frontend/src/component/menu/routes.js index c111c14433..39b9c0f1ab 100644 --- a/frontend/src/component/menu/routes.js +++ b/frontend/src/component/menu/routes.js @@ -18,6 +18,7 @@ import LogoutFeatures from '../../page/user/logout'; import ListProjects from '../../page/project'; import CreateProject from '../../page/project/create'; import EditProject from '../../page/project/edit'; +import ViewProject from '../../page/project/view'; import EditProjectAccess from '../../page/project/access'; import ListTagTypes from '../../page/tag-types'; import CreateTagType from '../../page/tag-types/create'; @@ -197,6 +198,14 @@ export const routes = [ type: 'protected', layout: 'main', }, + { + path: '/projects/view/:id', + parent: '/projects', + title: ':id', + component: ViewProject, + type: 'protected', + layout: 'main', + }, { path: '/projects/:id/access', parent: '/projects', diff --git a/frontend/src/component/project/ProjectList/ProjectList.jsx b/frontend/src/component/project/ProjectList/ProjectList.jsx index 043c70fb8a..725c3c01e6 100644 --- a/frontend/src/component/project/ProjectList/ProjectList.jsx +++ b/frontend/src/component/project/ProjectList/ProjectList.jsx @@ -48,7 +48,7 @@ const ProjectList = ({ projects, fetchProjects, removeProject, history }) => { ); const projectLink = ({ id, name }) => ( - + {name} ); diff --git a/frontend/src/component/project/ViewProject/ViewProject.js b/frontend/src/component/project/ViewProject/ViewProject.js new file mode 100644 index 0000000000..161192c7fa --- /dev/null +++ b/frontend/src/component/project/ViewProject/ViewProject.js @@ -0,0 +1,90 @@ +import { useContext, useEffect } from 'react'; +import { Typography, Button, List } from '@material-ui/core'; +import { Link } from 'react-router-dom'; +import AccessContext from '../../../contexts/AccessContext'; +import HeaderTitle from '../../common/HeaderTitle'; +import PageContent from '../../common/PageContent'; + +import FeatureToggleListItem from '../../feature/FeatureToggleList/FeatureToggleListItem'; +import ConditionallyRender from '../../common/ConditionallyRender'; + +const ViewProject = ({ + project, + features, + settings, + toggleFeature, + featureMetrics, + revive, + fetchFeatureToggles, +}) => { + const { hasAccess } = useContext(AccessContext); + + useEffect(() => { + fetchFeatureToggles(); + /* eslint-disable-next-line */ + }, []); + + const renderProjectFeatures = () => { + return features.map(feature => { + return ( + + ); + }); + }; + + return ( +
+ + + + + } + /> + } + > + + + Description + + {project.description} +
+ } + /> + + + Feature toggles in this project + + {renderProjectFeatures()} + + + ); +}; + +export default ViewProject; diff --git a/frontend/src/component/project/ViewProject/index.js b/frontend/src/component/project/ViewProject/index.js new file mode 100644 index 0000000000..382b74a998 --- /dev/null +++ b/frontend/src/component/project/ViewProject/index.js @@ -0,0 +1,39 @@ +import { connect } from 'react-redux'; +import { + fetchFeatureToggles, + toggleFeature, +} from '../../../store/feature-toggle/actions'; +import ViewProject from './ViewProject'; + +const mapStateToProps = (state, props) => { + const projectBase = { id: '', name: '', description: '' }; + const realProject = state.projects + .toJS() + .find(n => n.id === props.projectId); + const project = Object.assign(projectBase, realProject); + const features = state.features + .toJS() + .filter(feature => feature.project === project.id); + + const settings = state.settings.toJS(); + const featureMetrics = state.featureMetrics.toJS(); + + return { + project, + features, + settings, + featureMetrics, + }; +}; + +const mapDispatchToProps = { + toggleFeature, + fetchFeatureToggles, +}; + +const FormAddContainer = connect( + mapStateToProps, + mapDispatchToProps +)(ViewProject); + +export default FormAddContainer; diff --git a/frontend/src/component/project/access-add-user.js b/frontend/src/component/project/access-add-user.js index 3e6c843c77..deec0fa062 100644 --- a/frontend/src/component/project/access-add-user.js +++ b/frontend/src/component/project/access-add-user.js @@ -24,7 +24,9 @@ function AddUserComponent({ roles, addUserToRole }) { useEffect(() => { if (roles.length > 0) { - const regularRole = roles.find(r => r.name.toLowerCase() === 'regular'); + const regularRole = roles.find( + r => r.name.toLowerCase() === 'regular' + ); setRole(regularRole || roles[0]); } }, [roles]); @@ -80,7 +82,9 @@ function AddUserComponent({ roles, addUserToRole }) { filterOptions={o => o} getOptionLabel={option => { if (option) { - return `${option.name || '(Empty name)'} <${option.email || option.username}>`; + return `${option.name || '(Empty name)'} <${ + option.email || option.username + }>`; } else return ''; }} options={options} @@ -100,7 +104,12 @@ function AddUserComponent({ roles, addUserToRole }) { ), endAdornment: ( - {loading ? : null} + {loading ? ( + + ) : null} {params.InputProps.endAdornment} ), @@ -111,7 +120,9 @@ function AddUserComponent({ roles, addUserToRole }) { - Role + + Role +