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
+
-
);
}
+
AddUserComponent.propTypes = {
roles: PropTypes.array.isRequired,
addUserToRole: PropTypes.func.isRequired,
diff --git a/frontend/src/page/project/view.js b/frontend/src/page/project/view.js
new file mode 100644
index 0000000000..46c8b83739
--- /dev/null
+++ b/frontend/src/page/project/view.js
@@ -0,0 +1,14 @@
+import React from 'react';
+import ViewProject from '../../component/project/ViewProject';
+import PropTypes from 'prop-types';
+
+const render = ({ match: { params }, history }) => (
+
+);
+
+render.propTypes = {
+ match: PropTypes.object.isRequired,
+ history: PropTypes.object.isRequired,
+};
+
+export default render;