From c489e42e03217322f2a9acaa02ac21b57f552c86 Mon Sep 17 00:00:00 2001 From: Katiuska Alicea Date: Sat, 11 Dec 2021 14:29:56 -0800 Subject: [PATCH 1/8] added state in editableField.js for user access level to implement conditional renderng --- .../components/manageProjects/editProject.js | 161 ++++++++++-------- .../manageProjects/editableField.js | 146 +++++++++++----- 2 files changed, 190 insertions(+), 117 deletions(-) diff --git a/client/src/components/manageProjects/editProject.js b/client/src/components/manageProjects/editProject.js index ec576decb..43ec78575 100644 --- a/client/src/components/manageProjects/editProject.js +++ b/client/src/components/manageProjects/editProject.js @@ -1,207 +1,226 @@ -import React, { useState } from 'react'; +import React, { useState } from 'react'; import '../../sass/ManageProjects.scss'; import EditableField from './editableField'; -import { REACT_APP_CUSTOM_REQUEST_HEADER } from "../../utils/globalSettings"; +import { REACT_APP_CUSTOM_REQUEST_HEADER } from '../../utils/globalSettings'; +// Need to hold user state to check which type of user they are and conditionally render editing fields in this component +//for user level block access to all except for the ones checked -const EditProjectInfo = ( props ) => { +const EditProject = (props) => { + console.log('editProject.js: props:', props); const headerToSend = REACT_APP_CUSTOM_REQUEST_HEADER; //const [currentProjectData, setCurrentProjectData] = useState(props.projectToEdit); const updateProject = async (projectId, fieldName, fieldValue) => { - // These field are arrays, but the form makes them comma separated strings, so this adds it back to db as an arrray. - if (fieldName === 'partners' || fieldName === 'recruitingCategories') { + if (fieldName === 'partners' || fieldName === 'recruitingCategories') { if (!Array.isArray(fieldValue)) { fieldValue = fieldValue - .split(',') - .filter(x => x !== "") - .map(y => y.trim()); + .split(',') + .filter((x) => x !== '') + .map((y) => y.trim()); } } - + // Update database const url = `/api/projects/${projectId}`; const requestOptions = { - method: 'PATCH', - headers: { - "Content-Type": "application/json", - "x-customrequired-header": headerToSend - }, - body: JSON.stringify({ [fieldName]: fieldValue }) + method: 'PATCH', + headers: { + 'Content-Type': 'application/json', + 'x-customrequired-header': headerToSend, + }, + body: JSON.stringify({ [fieldName]: fieldValue }), }; try { - const response = await fetch(url, requestOptions); - const resJson = await response.json(); + const response = await fetch(url, requestOptions); + const resJson = await response.json(); - return resJson; + return resJson; } catch (error) { - console.log(`update user error: `, error); - alert("Server not responding. Please try again."); + console.log(`update user error: `, error); + alert('Server not responding. Please try again.'); } }; - // Add commas to arrays for display - const partnerDataFormatted = props.projectToEdit.partners.join(", "); - const recrutingDataFormatted = props.projectToEdit.recruitingCategories.join(", "); - + const partnerDataFormatted = props.projectToEdit.partners.join(', '); + const recrutingDataFormatted = + props.projectToEdit.recruitingCategories.join(', '); return (
-
Project: {props.projectToEdit.name}
+
+ Project: {props.projectToEdit.name} +
-
-
-
- -
+
-
-
-
-
-
-
-
- -
+
- -
- - -
+ + +
+ +
); }; -export default EditProjectInfo; +export default EditProject; diff --git a/client/src/components/manageProjects/editableField.js b/client/src/components/manageProjects/editableField.js index 9bcd051e5..ead3de795 100644 --- a/client/src/components/manageProjects/editableField.js +++ b/client/src/components/manageProjects/editableField.js @@ -1,72 +1,126 @@ import React, { useState, useRef, useEffect } from 'react'; import '../../sass/ManageProjects.scss'; - - -const EditableField = ( - { projId, fieldData, fieldName, updateProject, renderUpdatedProj, fieldType, fieldTitle } -) => { +const EditableField = ({ + projId, + fieldData, + fieldName, + updateProject, + renderUpdatedProj, + fieldType, + fieldTitle, + accessLevel, +}) => { const [fieldValue, setFieldValue] = useState(fieldData); const [editable, setEditable] = useState(false); - const ref = useRef(); + const [userAccessLevel] = useState(accessLevel); + const [userCanEdit, setUserCanEdit] = useState(false); + const ref = useRef(); + + console.log('editableField: props: editable:', editable); + console.log('editableFields: props: accessLevel: ', userAccessLevel); + console.log('editableFields: props: accessLevel: ', accessLevel); + console.log('usercanedit', userCanEdit); + + // create function that checks the user has access to edit all fields + + const canEdit = () => { + // get user accessLevel + console.log( + `editableField: canEdit: activated onClick: editable?: ${editable} : and accessLevel: ${accessLevel}` + ); + + if (userAccessLevel === 'user') { + setUserCanEdit(true); + } + }; // Update the displayed results to match the change just made to the db - useEffect(() => { + useEffect(() => { + canEdit(); if (editable) { ref.current.focus(); setFieldValue(fieldData); - } - },[editable]); + } + }, [editable, userCanEdit]); return ( + // here goes the conditional rendering + // this button will be disabled if user !admin
-
{fieldTitle} setEditable(true)} > [edit]
- {editable ? - - (fieldType === "textarea") ? +
+ {fieldTitle} + {userCanEdit === true ? ( + { + setEditable(true); + }} + > + {' '} + [edit] + + ) : ( + + {' '} + [only certain users can edit this field] + + )} +
+ + {editable ? ( + fieldType === 'textarea' ? ( + ) : ( + { + updateProject(projId, fieldName, fieldValue).then((proj) => { + renderUpdatedProj(proj); + setEditable(false); + }); }} - onChange={e=>{ - setFieldValue(e.target.value) + onChange={(e) => { + setFieldValue(e.target.value); const input = e.target; const onEnterKey = (e) => { if (e.keyCode === 13) { - input.removeEventListener('keydown', onEnterKey) + input.removeEventListener('keydown', onEnterKey); input.blur(); } - } - input.addEventListener('keydown', onEnterKey) + }; + input.addEventListener('keydown', onEnterKey); }} - >{fieldValue} - : - { - updateProject(projId, fieldName, fieldValue) - .then(proj => {renderUpdatedProj(proj); setEditable(false)}) - }} - onChange={e=>{ - setFieldValue(e.target.value) - const input = e.target; - const onEnterKey = (e) => { - if (e.keyCode === 13) { - input.removeEventListener('keydown', onEnterKey) - input.blur(); - } - } - input.addEventListener('keydown', onEnterKey) - }} - /> - :
{fieldData}
- } + /> + ) + ) : ( +
{fieldData}
+ )}
); }; From 61ad08f1e16e024cbbb97564fce4fa974bdc1e8f Mon Sep 17 00:00:00 2001 From: Katiuska Alicea Date: Sat, 11 Dec 2021 14:35:25 -0800 Subject: [PATCH 2/8] modified component variable name to match the component file name. Created state for access user info and sent as props to EditProject component --- client/src/pages/ManageProjects.js | 57 ++++++++++++++++-------------- 1 file changed, 30 insertions(+), 27 deletions(-) diff --git a/client/src/pages/ManageProjects.js b/client/src/pages/ManageProjects.js index 0e9f636a7..592aa302e 100644 --- a/client/src/pages/ManageProjects.js +++ b/client/src/pages/ManageProjects.js @@ -2,21 +2,24 @@ import React, { useState, useEffect } from 'react'; import { Redirect } from 'react-router-dom'; import '../sass/ManageProjects.scss'; import useAuth from '../hooks/useAuth'; -import { REACT_APP_CUSTOM_REQUEST_HEADER } from "../utils/globalSettings"; +import { REACT_APP_CUSTOM_REQUEST_HEADER } from '../utils/globalSettings'; import SelectProject from '../components/manageProjects/selectProject.js'; -import EditProjectInfo from '../components/manageProjects/editProject.js'; +import EditProject from '../components/manageProjects/editProject.js'; const ManageProjects = () => { - const headerToSend = REACT_APP_CUSTOM_REQUEST_HEADER; const [auth] = useAuth(); + console.log('ManageProjects: auth', auth.isAdmin); const [projects, setProjects] = useState([]); const [projectToEdit, setProjectToEdit] = useState([]); const [recurringEvents, setRecurringEvents] = useState([]); - const [componentToDisplay, setComponentToDisplay] = useState (''); // displayProjectInfo, editMeetingTime or editProjectInfor + const [componentToDisplay, setComponentToDisplay] = useState(''); // displayProjectInfo, editMeetingTime or editProjectInfor + const [accessLevel, setAccessLevel] = useState(); const user = auth?.user; + console.log('ManageProjects: user: accessLevel: ', user.accessLevel); + // Fetch projects from db async function fetchProjects() { try { @@ -33,21 +36,21 @@ const ManageProjects = () => { } } - // Fetch recurringEvents - async function fetchRecurringEvents() { - try { - const res = await fetch('/api/recurringEvents/', { - headers: { - 'x-customrequired-header': headerToSend, - }, - }); - const resJson = await res.json(); - setRecurringEvents(resJson); - } catch (error) { - console.log(`fetchProjects error: ${error}`); - alert('Server not responding. Please refresh the page.'); - } + // Fetch recurringEvents + async function fetchRecurringEvents() { + try { + const res = await fetch('/api/recurringEvents/', { + headers: { + 'x-customrequired-header': headerToSend, + }, + }); + const resJson = await res.json(); + setRecurringEvents(resJson); + } catch (error) { + console.log(`fetchProjects error: ${error}`); + alert('Server not responding. Please refresh the page.'); } + } useEffect(() => { fetchProjects(); @@ -70,15 +73,14 @@ const ManageProjects = () => { return ; } - const projectSelectClickHandler = project => event => { + const projectSelectClickHandler = (project) => (event) => { setProjectToEdit(project); setComponentToDisplay('editProjectInfo'); }; const goSelectProject = () => { setComponentToDisplay('selectProject'); -} - + }; switch (componentToDisplay) { case 'editMeetingTime': @@ -86,21 +88,22 @@ const ManageProjects = () => { break; case 'editProjectInfo': return ( - ); break; default: return ( - ); } From 0c40c53c0a42e047125f6781732f3c434943a2f9 Mon Sep 17 00:00:00 2001 From: Katiuska Alicea Date: Sat, 11 Dec 2021 16:56:12 -0800 Subject: [PATCH 3/8] added canEdit property to editableField, an array that includes which type of user can edit the field. In the editableFiled.js set up a restricted state and function that checks whether the users access level is is included in the canEdit array and thru conditional rendering the edit button is enabled/disabled --- .../components/manageProjects/editProject.js | 33 +++++++++++++------ .../manageProjects/editableField.js | 26 +++++---------- 2 files changed, 31 insertions(+), 28 deletions(-) diff --git a/client/src/components/manageProjects/editProject.js b/client/src/components/manageProjects/editProject.js index 43ec78575..ff76e9a5b 100644 --- a/client/src/components/manageProjects/editProject.js +++ b/client/src/components/manageProjects/editProject.js @@ -66,7 +66,8 @@ const EditProject = (props) => { projId={props.projectToEdit._id} fieldType="text" fieldTitle="Name:" - // accessLevel={props.userAccessLevel} + accessLevel={props.userAccessLevel} + canEdit={['admin']} />
@@ -78,7 +79,8 @@ const EditProject = (props) => { projId={props.projectToEdit._id} fieldType="textarea" fieldTitle="Description:" - // accessLevel={props.userAccessLevel} + accessLevel={props.userAccessLevel} + canEdit={['admin']} />
@@ -90,7 +92,8 @@ const EditProject = (props) => { projId={props.projectToEdit._id} fieldType="text" fieldTitle="Location:" - // accessLevel={props.userAccessLevel} + accessLevel={props.userAccessLevel} + canEdit={['admin']} />
@@ -102,7 +105,8 @@ const EditProject = (props) => { projId={props.projectToEdit._id} fieldType="text" fieldTitle="GitHub Identifier:" - // accessLevel={props.userAccessLevel} + accessLevel={props.userAccessLevel} + canEdit={['admin']} />
@@ -114,7 +118,8 @@ const EditProject = (props) => { projId={props.projectToEdit._id} fieldType="text" fieldTitle="GitHib URL:" - // accessLevel={props.userAccessLevel} + accessLevel={props.userAccessLevel} + canEdit={['admin']} />
@@ -126,7 +131,8 @@ const EditProject = (props) => { projId={props.projectToEdit._id} fieldType="text" fieldTitle="Slack URL:" - // accessLevel={props.userAccessLevel} + accessLevel={props.userAccessLevel} + canEdit={['admin']} />
@@ -139,6 +145,7 @@ const EditProject = (props) => { fieldType="text" fieldTitle="Google Drive URL:" accessLevel={props.userAccessLevel} + canEdit={['admin', 'user']} />
@@ -150,7 +157,8 @@ const EditProject = (props) => { projId={props.projectToEdit._id} fieldType="text" fieldTitle="Google Drive ID:" - // accessLevel={props.userAccessLevel} + accessLevel={props.userAccessLevel} + canEdit={['admin']} />
@@ -162,7 +170,8 @@ const EditProject = (props) => { projId={props.projectToEdit._id} fieldType="text" fieldTitle="HfLA Website URL:" - // accessLevel={props.userAccessLevel} + accessLevel={props.userAccessLevel} + canEdit={['admin']} />
@@ -175,6 +184,7 @@ const EditProject = (props) => { fieldType="text" fieldTitle="Video Conference Link:" accessLevel={props.userAccessLevel} + canEdit={['admin', 'user']} />
@@ -186,7 +196,8 @@ const EditProject = (props) => { projId={props.projectToEdit._id} fieldType="text" fieldTitle="Looking For Description:" - // accessLevel={props.userAccessLevel} + accessLevel={props.userAccessLevel} + canEdit={['admin']} />
@@ -199,6 +210,7 @@ const EditProject = (props) => { fieldType="text" fieldTitle="Partners (comma separated):" accessLevel={props.userAccessLevel} + canEdit={['admin', 'user']} />
@@ -210,7 +222,8 @@ const EditProject = (props) => { projId={props.projectToEdit._id} fieldType="text" fieldTitle="Recruiting Categories (comma separated):" - // accessLevel={props.userAccessLevel} + accessLevel={props.userAccessLevel} + canEdit={['admin']} />
diff --git a/client/src/components/manageProjects/editableField.js b/client/src/components/manageProjects/editableField.js index ead3de795..4c3e44e6d 100644 --- a/client/src/components/manageProjects/editableField.js +++ b/client/src/components/manageProjects/editableField.js @@ -10,39 +10,29 @@ const EditableField = ({ fieldType, fieldTitle, accessLevel, + canEdit, }) => { const [fieldValue, setFieldValue] = useState(fieldData); const [editable, setEditable] = useState(false); - const [userAccessLevel] = useState(accessLevel); - const [userCanEdit, setUserCanEdit] = useState(false); + const [notRestricted, setNotRestricted] = useState(false); const ref = useRef(); - - console.log('editableField: props: editable:', editable); - console.log('editableFields: props: accessLevel: ', userAccessLevel); console.log('editableFields: props: accessLevel: ', accessLevel); - console.log('usercanedit', userCanEdit); // create function that checks the user has access to edit all fields - const canEdit = () => { - // get user accessLevel - console.log( - `editableField: canEdit: activated onClick: editable?: ${editable} : and accessLevel: ${accessLevel}` - ); - - if (userAccessLevel === 'user') { - setUserCanEdit(true); - } + const checkUser = () => { + const permitted = canEdit.includes(accessLevel); + setNotRestricted(permitted); }; // Update the displayed results to match the change just made to the db useEffect(() => { - canEdit(); + checkUser(); if (editable) { ref.current.focus(); setFieldValue(fieldData); } - }, [editable, userCanEdit]); + }, [editable]); return ( // here goes the conditional rendering @@ -50,7 +40,7 @@ const EditableField = ({
{fieldTitle} - {userCanEdit === true ? ( + {notRestricted ? ( { From d7c755968160aa820c063ce075f81031d30d450e Mon Sep 17 00:00:00 2001 From: Katiuska Alicea Date: Sat, 11 Dec 2021 17:20:28 -0800 Subject: [PATCH 4/8] cleared logged comments --- client/src/components/manageProjects/editProject.js | 2 -- client/src/components/manageProjects/editableField.js | 1 - client/src/pages/ManageProjects.js | 3 --- 3 files changed, 6 deletions(-) diff --git a/client/src/components/manageProjects/editProject.js b/client/src/components/manageProjects/editProject.js index ff76e9a5b..6fcffc5a8 100644 --- a/client/src/components/manageProjects/editProject.js +++ b/client/src/components/manageProjects/editProject.js @@ -7,8 +7,6 @@ import { REACT_APP_CUSTOM_REQUEST_HEADER } from '../../utils/globalSettings'; //for user level block access to all except for the ones checked const EditProject = (props) => { - console.log('editProject.js: props:', props); - const headerToSend = REACT_APP_CUSTOM_REQUEST_HEADER; //const [currentProjectData, setCurrentProjectData] = useState(props.projectToEdit); diff --git a/client/src/components/manageProjects/editableField.js b/client/src/components/manageProjects/editableField.js index 4c3e44e6d..4709078d1 100644 --- a/client/src/components/manageProjects/editableField.js +++ b/client/src/components/manageProjects/editableField.js @@ -16,7 +16,6 @@ const EditableField = ({ const [editable, setEditable] = useState(false); const [notRestricted, setNotRestricted] = useState(false); const ref = useRef(); - console.log('editableFields: props: accessLevel: ', accessLevel); // create function that checks the user has access to edit all fields diff --git a/client/src/pages/ManageProjects.js b/client/src/pages/ManageProjects.js index 592aa302e..642c49218 100644 --- a/client/src/pages/ManageProjects.js +++ b/client/src/pages/ManageProjects.js @@ -10,7 +10,6 @@ const ManageProjects = () => { const headerToSend = REACT_APP_CUSTOM_REQUEST_HEADER; const [auth] = useAuth(); - console.log('ManageProjects: auth', auth.isAdmin); const [projects, setProjects] = useState([]); const [projectToEdit, setProjectToEdit] = useState([]); const [recurringEvents, setRecurringEvents] = useState([]); @@ -18,8 +17,6 @@ const ManageProjects = () => { const [accessLevel, setAccessLevel] = useState(); const user = auth?.user; - console.log('ManageProjects: user: accessLevel: ', user.accessLevel); - // Fetch projects from db async function fetchProjects() { try { From 69b5dab91f38737006691c8b7022ab4edc737318 Mon Sep 17 00:00:00 2001 From: Katiuska Alicea Date: Sat, 11 Dec 2021 17:36:24 -0800 Subject: [PATCH 5/8] removed unused vars --- client/src/components/manageProjects/editProject.js | 2 +- client/src/pages/ManageProjects.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/client/src/components/manageProjects/editProject.js b/client/src/components/manageProjects/editProject.js index 6fcffc5a8..561bcfa43 100644 --- a/client/src/components/manageProjects/editProject.js +++ b/client/src/components/manageProjects/editProject.js @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React from 'react'; import '../../sass/ManageProjects.scss'; import EditableField from './editableField'; import { REACT_APP_CUSTOM_REQUEST_HEADER } from '../../utils/globalSettings'; diff --git a/client/src/pages/ManageProjects.js b/client/src/pages/ManageProjects.js index 642c49218..88a874b96 100644 --- a/client/src/pages/ManageProjects.js +++ b/client/src/pages/ManageProjects.js @@ -14,7 +14,6 @@ const ManageProjects = () => { const [projectToEdit, setProjectToEdit] = useState([]); const [recurringEvents, setRecurringEvents] = useState([]); const [componentToDisplay, setComponentToDisplay] = useState(''); // displayProjectInfo, editMeetingTime or editProjectInfor - const [accessLevel, setAccessLevel] = useState(); const user = auth?.user; // Fetch projects from db From ac45e1bf35b714b7e3da65f09487152a6722026a Mon Sep 17 00:00:00 2001 From: Katiuska Alicea Date: Mon, 13 Dec 2021 23:27:10 -0800 Subject: [PATCH 6/8] added readme document that will be linked to the disabled edit button --- team-lead-contact-info.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 team-lead-contact-info.md diff --git a/team-lead-contact-info.md b/team-lead-contact-info.md new file mode 100644 index 000000000..39669ea5a --- /dev/null +++ b/team-lead-contact-info.md @@ -0,0 +1 @@ +## Team Lead Contact Sheet From 933afe82459c695537d74b413ba2e7e17694baef Mon Sep 17 00:00:00 2001 From: Katiuska Alicea Date: Mon, 13 Dec 2021 23:55:27 -0800 Subject: [PATCH 7/8] Added empty table for contacts in the .md file and added a link to it on the disabled edit button --- client/src/components/manageProjects/editableField.js | 4 +++- team-lead-contact-info.md | 10 ++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/client/src/components/manageProjects/editableField.js b/client/src/components/manageProjects/editableField.js index 4709078d1..2395169b8 100644 --- a/client/src/components/manageProjects/editableField.js +++ b/client/src/components/manageProjects/editableField.js @@ -52,7 +52,9 @@ const EditableField = ({ ) : ( {' '} - [only certain users can edit this field] + + [Contact your team lead to make changes to this field] + )}
diff --git a/team-lead-contact-info.md b/team-lead-contact-info.md index 39669ea5a..e71379435 100644 --- a/team-lead-contact-info.md +++ b/team-lead-contact-info.md @@ -1 +1,11 @@ ## Team Lead Contact Sheet + +# Please find your team lead's email from the table below to request the desired changes. + +| Team Lead | Email | +| :-------: | :---: | +| | | +| | | +| | | +| | | +| | | From 80fb8d4195cdc9caef52508af282257eb54f53e5 Mon Sep 17 00:00:00 2001 From: Katiuska Alicea Date: Mon, 13 Dec 2021 23:57:43 -0800 Subject: [PATCH 8/8] corrected heading in .md file --- team-lead-contact-info.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/team-lead-contact-info.md b/team-lead-contact-info.md index e71379435..cef9148f0 100644 --- a/team-lead-contact-info.md +++ b/team-lead-contact-info.md @@ -1,6 +1,6 @@ ## Team Lead Contact Sheet -# Please find your team lead's email from the table below to request the desired changes. +### Please find your team lead's email from the table below to request the desired changes. | Team Lead | Email | | :-------: | :---: |