diff --git a/frontend/src/containers/project/people.js b/frontend/src/containers/project/people.js
index 5abef63e..0115ee6f 100644
--- a/frontend/src/containers/project/people.js
+++ b/frontend/src/containers/project/people.js
@@ -1,9 +1,59 @@
const React = require('react');
-
+const ReactRedux = require('react-redux');
+const PeopleSection = require('@components/people-list');
+const selectors = require('@state/selectors');
const Section = require('./section');
+const actions = require('@state/actions');
-module.exports = (props) => (
-
-);
+const {
+ connect
+} = ReactRedux;
+
+const {
+ peopleByProjectIdSelector,
+ projectUISelector,
+ projectIndexByIdSelect,
+ membersSelector,
+} = selectors;
+
+const {
+ projecthandleInviteToggle,
+ projecthandlePeopleRoleTooltip,
+ projecthandlePeopleStatusTooltip,
+ projecthandleMemberUpdate,
+ projectremoveMember,
+} = actions;
+
+const People = (props) => {
+
+ return (
+
+ );
+};
+
+const mapStateToProps = (state, {
+ params = {}
+}) => ({
+ people: peopleByProjectIdSelector(params.projectId)(state),
+ UI: projectUISelector(state),
+ parentIndex: projectIndexByIdSelect(params.projectId)(state),
+ platformMembers: membersSelector(state)
+});
+
+const mapDispatchToProps = (dispatch) => ({
+ handleToggle: () => dispatch(projecthandleInviteToggle()),
+ handleStatusTooltip: (id) => dispatch(projecthandlePeopleStatusTooltip(id)),
+ handleRoleTooltip: (id) => dispatch(projecthandlePeopleRoleTooltip(id)),
+ handleMemberUpdate: (updatedMember) =>
+ dispatch(projecthandleMemberUpdate(updatedMember)),
+ removeMember: (removeData) =>
+ dispatch(projectremoveMember(removeData)),
+
+});
+
+module.exports = connect(
+ mapStateToProps,
+ mapDispatchToProps
+)(People);
diff --git a/frontend/src/mock-state.json b/frontend/src/mock-state.json
index c00677d4..181efda4 100644
--- a/frontend/src/mock-state.json
+++ b/frontend/src/mock-state.json
@@ -541,6 +541,16 @@
"people",
"settings",
"manifest"
+ ],
+ "members_status": [
+ "Active",
+ "Inactive",
+ "Invitation Sent"
+ ],
+ "members_roles": [
+ "Owner",
+ "Unassigned",
+ "Read Only"
]
},
"data": [{
@@ -548,7 +558,17 @@
"org": "e12ad7db-91b2-4154-83dd-40dcfc700dcc",
"id": "forest-foundation-dev",
"name": "Forest Foundation Dev",
- "plan": "20.05$ per day"
+ "plan": "20.05$ per day",
+ "members": [{
+ "uuid": "fd853d8f-e1dd-49b5-b7b3-ae9adfea1e2f",
+ "role": "Owner",
+ "status": "Active"
+ },
+ {
+ "uuid": "6deddbaa-3b94-4373-8cf7-97129507a872",
+ "role": "Unassigned",
+ "status": "Sent invitation"
+ }]
}, {
"uuid": "9fcb374d-a267-4c2a-9d9c-ba469b804639",
"org": "e12ad7db-91b2-4154-83dd-40dcfc700dcc",
diff --git a/frontend/src/state/actions.js b/frontend/src/state/actions.js
index 7f32be8f..77f9cc3c 100644
--- a/frontend/src/state/actions.js
+++ b/frontend/src/state/actions.js
@@ -7,6 +7,32 @@ const {
const APP = constantCase(process.env['APP_NAME']);
+const projectMemberActions = {
+ projecthandleInviteToggle:
+ createAction(`${APP}/PROJECT_HANDLE_INVITE_MEMBER_TOGGLE`),
+ projecthandlePeopleStatusTooltip:
+ createAction(`${APP}/PROJECT_HANDLE_PERSON_STATUS_TOOLTIP`),
+ projecthandlePeopleRoleTooltip:
+ createAction(`${APP}/PROJECT_HANDLE_PERSON_ROLE_TOOLTIP`),
+ projecthandleMemberUpdate:
+ createAction(`${APP}/PROJECT_HANDLE_MEMBER_UPDATE`),
+ projectremoveMember:
+ createAction(`${APP}/PROJECT_REMOVE_MEMBER_FROM_ROLE`),
+};
+
+const orgMemberActions = {
+ handleInviteToggle:
+ createAction(`${APP}/HANDLE_INVITE_MEMBER_TOGGLE`),
+ handlePeopleStatusTooltip:
+ createAction(`${APP}/HANDLE_PERSON_STATUS_TOOLTIP`),
+ handlePeopleRoleTooltip:
+ createAction(`${APP}/HANDLE_PERSON_ROLE_TOOLTIP`),
+ handleMemberUpdate:
+ createAction(`${APP}/HANDLE_MEMBER_UPDATE`),
+ removeMember:
+ createAction(`${APP}/REMOVE_MEMBER_FROM_ROLE`),
+};
+
module.exports = {
...require('@state/thunks'),
updateRouter: createAction(`${APP}/UPDATE_ROUTER`),
@@ -17,11 +43,6 @@ module.exports = {
toggleInstanceCollapsed: createAction(`${APP}/TOGGLE_INSTANCE_COLLAPSED`),
toggleMonitorView: createAction(`${APP}/TOGGLE_MONITOR_VIEW`),
switchMonitorViewPage: createAction(`${APP}/SWITCH_MONITOR_VIEW_PAGE`),
- handleInviteToggle: createAction(`${APP}/HANDLE_INVITE_MEMBER_TOGGLE`),
- handlePeopleStatusTooltip:
- createAction(`${APP}/HANDLE_PERSON_STATUS_TOOLTIP`),
- handlePeopleRoleTooltip:
- createAction(`${APP}/HANDLE_PERSON_ROLE_TOOLTIP`),
- handleMemberUpdate: createAction(`${APP}/HANDLE_MEMBER_UPDATE`),
- removeMember: createAction(`${APP}/REMOVE_MEMBER_FROM_ROLE`),
+ ...orgMemberActions,
+ ...projectMemberActions,
};
diff --git a/frontend/src/state/reducers/projects.js b/frontend/src/state/reducers/projects.js
index 7fec06fb..e4730190 100644
--- a/frontend/src/state/reducers/projects.js
+++ b/frontend/src/state/reducers/projects.js
@@ -1,9 +1,101 @@
const ReduxActions = require('redux-actions');
+const actions = require('@state/actions');
+
const {
handleActions
} = ReduxActions;
+const {
+ projecthandleInviteToggle,
+ projecthandlePeopleRoleTooltip,
+ projecthandlePeopleStatusTooltip,
+ projecthandleMemberUpdate,
+ projectremoveMember,
+} = actions;
+
module.exports = handleActions({
- 'x': (state) => state // somehow handleActions needs at least one reducer
+ [projecthandleInviteToggle.toString()]: (state, action) => {
+ return {
+ ...state,
+ ui: {
+ ...state.ui,
+ invite_toggled: !state.ui.invite_toggled
+ }
+ };
+ },
+ [projecthandlePeopleStatusTooltip.toString()]: (state, action) => {
+ return {
+ ...state,
+ ui: {
+ ...state.ui,
+ member_status_tooltip:
+ action.payload === state.ui.member_status_tooltip
+ ? ''
+ : action.payload
+ }
+ };
+ },
+ [projecthandlePeopleRoleTooltip.toString()]: (state, action) => {
+ return {
+ ...state,
+ ui: {
+ ...state.ui,
+ member_role_tooltip:
+ action.payload === state.ui.member_role_tooltip
+ ? ''
+ : action.payload
+ }
+ };
+ },
+ [projecthandleMemberUpdate.toString()]: (state, action) => {
+ const {
+ parentIndex,
+ person,
+ personIndex,
+ } = action.payload;
+ return {
+ ...state,
+ ui: {
+ ...state.ui,
+ member_status_tooltip: false,
+ member_role_tooltip: false
+ },
+ data: [
+ ...state.data.slice(0, parentIndex),
+ {
+ ...state.data[parentIndex],
+ members: [
+ ...state.data[parentIndex].members.slice(0, personIndex),
+ {
+ ...person,
+ },
+ ...state.data[parentIndex].members.slice(personIndex + 1)
+ ]
+ },
+ ...state.data.slice(parentIndex + 1),
+ ]
+ };
+ },
+ [projectremoveMember.toString()]: (state, action) => {
+ const {
+ parentIndex,
+ personIndex,
+ } = action.payload;
+
+ return {
+ ...state,
+ data: [
+ ...state.data.slice(0, parentIndex),
+ {
+ ...state.data[parentIndex],
+ members: [
+ ...state.data[parentIndex].members.slice(0, personIndex),
+ ...state.data[parentIndex].members.slice(personIndex + 1)
+ ]
+ },
+ ...state.data.slice(parentIndex + 1),
+ ]
+ };
+ },
}, {});
diff --git a/frontend/src/state/selectors.js b/frontend/src/state/selectors.js
index da739a6e..e13eb62c 100644
--- a/frontend/src/state/selectors.js
+++ b/frontend/src/state/selectors.js
@@ -15,6 +15,7 @@ const serviceUiSections = (state) => get(state, 'services.ui.sections', []);
const orgs = (state) => get(state, 'orgs.data', []);
const orgUI = (state) => get(state, 'orgs.ui', []);
const projects = (state) => get(state, 'projects.data', []);
+const projectsUI = (state) => get(state, 'projects.ui', []);
const services = (state) => get(state, 'services.data', []);
const collapsedServices = (state) => get(state, 'services.ui.collapsed', []);
const collapsedInstances = (state) => get(state, 'instances.ui.collapsed', []);
@@ -40,6 +41,11 @@ const orgIndexById = (orgId) => createSelector(
(orgs) => orgs.map((o) => o.id).indexOf(orgId)
);
+const projectIndexById = (projectId) => createSelector(
+ projects,
+ (projects) => projects.map((p) => p.id).indexOf(projectId)
+);
+
const serviceById = (serviceId) => createSelector(
[services],
(services) => find(services, ['id', serviceId])
@@ -141,6 +147,21 @@ const peopleByOrgId = (orgId) => createSelector(
}
);
+const peopleByProjectId = (projectId) => createSelector(
+ [members, projectById(projectId)], (members, prj) => {
+ const matched = [];
+ if (Object.keys(prj.members).length > 0) {
+ prj.members.filter((m) => {
+ matched.push({
+ ...find(members, ['uuid', m.uuid]),
+ ...m
+ });
+ });
+ }
+ return matched;
+ }
+);
+
module.exports = {
accountSelector: account,
accountUISelector: accountUi,
@@ -163,4 +184,7 @@ module.exports = {
metricTypeByUuidSelector: metricTypeByUuid,
peopleByOrgIdSelector: peopleByOrgId,
membersSelector: members,
+ peopleByProjectIdSelector: peopleByProjectId,
+ projectUISelector: projectsUI,
+ projectIndexByIdSelect: projectIndexById,
};