Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Continued extending viewerCanSeeOrDo & viewerAccessRights implementation. We can now control ability to edit a person based on whether they are in a team the viewer is a teamAdmin for. Now displaying Answers to questionnaires again. Moved ability to delete a team onto the TeamHome page, so it's harder to delete accidentally. #33

Merged
merged 1 commit into from
Feb 23, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/js/components/Drawers/DrawerTemplateA.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const DrawerTemplateA = (props) => {

// eslint-disable-next-line no-unused-vars
const [scrolledDown, setScrolledDown] = useState(false);
const drawerOpen = getAppContextValue(drawerOpenGlobalVariableName);
const drawerOpen = getAppContextValue(drawerOpenGlobalVariableName) || false;

// console.log('DrawerTemplateA drawerOpen: ', drawerOpenGlobalVariableName, drawerOpen);

Expand Down
8 changes: 6 additions & 2 deletions src/js/components/Navigation/HeaderBar.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { normalizedHrefPage } from '../../common/utils/hrefUtils';
import { renderLog } from '../../common/utils/logging';
import { useConnectAppContext } from '../../contexts/ConnectAppContext';
import { clearSignedInGlobals } from '../../contexts/contextFunctions';
import { viewerCanSeeOrDo } from '../../models/AuthModel';
import { useLogoutMutation } from '../../react-query/mutations';
import weConnectQueryFn, { METHOD } from '../../react-query/WeConnectQuery';
import { displayTopMenuShadow } from '../../utils/applicationUtils';
Expand All @@ -21,7 +22,8 @@ import HeaderBarLogo from './HeaderBarLogo';
const HeaderBar = ({ hideTabs }) => {
renderLog('HeaderBar');
const navigate = useNavigate();
const { getAppContextValue, setAppContextValue } = useConnectAppContext();
const { apiDataCache, getAppContextValue, setAppContextValue } = useConnectAppContext();
const { viewerAccessRights } = apiDataCache;
const { mutate: mutateLogout } = useLogoutMutation();

const [scrolledDown] = useState(false);
Expand Down Expand Up @@ -141,7 +143,9 @@ const HeaderBar = ({ hideTabs }) => {
>
<Tab value="1" label="Dashboard" onClick={() => handleTabChangeClick('1')} />
<Tab value="2" label="Teams" onClick={() => handleTabChangeClick('2')} />
<Tab value="3" label="Settings" onClick={() => handleTabChangeClick('3')} />
{viewerCanSeeOrDo('canViewSystemSettings', viewerAccessRights) && (
<Tab value="3" label="Settings" onClick={() => handleTabChangeClick('3')} />
)}
</Tabs>
)}
</TopRowOneMiddleContainer>
Expand Down
7 changes: 4 additions & 3 deletions src/js/components/Person/PersonSummaryRow.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ import {
} from '../../models/PersonModel';
import { useRemoveTeamMemberMutation } from '../../react-query/mutations';
import { DeleteStyled, EditStyled } from '../Style/iconStyles';
import { viewerCanSeeOrDo } from '../../models/AuthModel';
import { viewerCanSeeOrDo, viewerCanSeeOrDoForThisTeam } from '../../models/AuthModel';
// import { useRemoveTeamMemberMutationDiverged } from '../../models/TeamModel';


const PersonSummaryRow = ({ person, rowNumberForDisplay, teamId }) => {
renderLog('PersonSummaryRow'); // Set LOG_RENDER_EVENTS to log all renders
const { apiDataCache, setAppContextValue } = useConnectAppContext();
const { viewerAccessRights } = apiDataCache;
const { viewerAccessRights, viewerTeamAccessRights } = apiDataCache;
const { mutate } = useRemoveTeamMemberMutation();

// const [person, setPerson] = useState(useGetPersonById(personId)); 2/5/2025 does not work
Expand Down Expand Up @@ -50,6 +50,7 @@ const PersonSummaryRow = ({ person, rowNumberForDisplay, teamId }) => {
// }
// }, [apiDataCache]);

const canEditPerson = viewerCanSeeOrDo('canEditPersonAnyone', viewerAccessRights) || viewerCanSeeOrDoForThisTeam('canEditPersonThisTeam', teamId, viewerTeamAccessRights);
const hasEditRights = true;
return (
<OnePersonWrapper key={`teamMember-${person.personId}`}>
Expand Down Expand Up @@ -91,7 +92,7 @@ const PersonSummaryRow = ({ person, rowNumberForDisplay, teamId }) => {
>
{person.jobTitle}
</PersonCell>
{viewerCanSeeOrDo('canEditPersonAnyone', viewerAccessRights) ? (
{canEditPerson ? (
<PersonCell
id={`editPerson-personId-${person.personId}`}
onClick={() => editPersonClick(hasEditRights)}
Expand Down
2 changes: 1 addition & 1 deletion src/js/components/PrivateRoute.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const PrivateRoute = () => {
const { data: dataAuth, isSuccess: isSuccessAuth } = useFetchData(['get-auth'], {}, METHOD.POST);
useEffect(() => {
if (isSuccessAuth) {
console.log('useFetchData in PrivateRoute useEffect dataAuth good:', dataAuth, isSuccessAuth);
// console.log('useFetchData in PrivateRoute useEffect dataAuth good:', dataAuth, isSuccessAuth);
setIsAuthenticated(dataAuth.isAuthenticated);
// setAppContextValue('loggedInPersonIsAdmin', dataAuth.loggedInPersonIsAdmin);
captureAccessRightsData(dataAuth, isSuccessAuth, apiDataCache, dispatch);
Expand Down
36 changes: 24 additions & 12 deletions src/js/components/Questionnaire/QuestionnaireResponsesList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,18 @@ import styled from 'styled-components';
import DesignTokenColors from '../../common/components/Style/DesignTokenColors';
import { renderLog } from '../../common/utils/logging';
import webAppConfig from '../../config';
import { useConnectAppContext } from '../../contexts/ConnectAppContext';
import { useConnectAppContext, useConnectDispatch } from '../../contexts/ConnectAppContext';
import { useGetPersonById } from '../../models/PersonModel';
import { METHOD, useFetchData } from '../../react-query/WeConnectQuery';
import CopyQuestionnaireLink from './CopyQuestionnaireLink';
import { captureQuestionnaireListRetrieveData } from '../../models/QuestionnaireModel';

const OpenExternalWebSite = React.lazy(() => import(/* webpackChunkName: 'OpenExternalWebSite' */ '../../common/components/Widgets/OpenExternalWebSite'));

const QuestionnaireResponsesList = ({ personId }) => {
renderLog('QuestionnaireList'); // Set LOG_RENDER_EVENTS to log all renders
const { getAppContextValue } = useConnectAppContext();
const { apiDataCache, getAppContextValue } = useConnectAppContext();
const { allQuestionsCache } = apiDataCache;
const dispatch = useConnectDispatch();

// const [person] = useState(getAppContextValue('personDrawersPerson'));
const [person] = useState(useGetPersonById(getAppContextValue('personDrawersPersonId')));
Expand All @@ -24,17 +26,27 @@ const QuestionnaireResponsesList = ({ personId }) => {
// Although we are sending a list, there will only be one person id, if there were more, just append them with commas
const requestParams = `personIdList[]=${person.id}`;

const { data: dataQRL, isSuccess: isSuccessQRL, isFetching: isFetchingQRL } = useFetchData(['questionnaire-responses-list-retrieve'], requestParams, METHOD.GET);
if (isFetchingQRL) {
console.log('isFetching ------------ \'questionnaire-responses-list-retrieve\'');
}
const questionnaireResponsesListRetrieveResults = useFetchData(['questionnaire-responses-list-retrieve'], requestParams, METHOD.GET);
// const { data: dataQRL, isSuccess: isSuccessQRL, isFetching: isFetchingQRL } = responsesRetrieveResults;
const { data: dataQRL, isFetching: isFetchingQRL } = questionnaireResponsesListRetrieveResults;
// if (isFetchingQRL) {
// console.log('isFetching ------------ \'questionnaire-responses-list-retrieve\'');
// }
// useEffect(() => {
// if (dataQRL !== undefined && isFetchingQRL === false && person) {
// console.log('useFetchData in QuestionnaireResponsesList useEffect dataQRL is good:', dataQRL, isSuccessQRL, isFetchingQRL);
// console.log('Successfully retrieved QuestionnaireResponsesList...');
// setQuestionnaireList(dataQRL.questionnaireList);
// }
// }, [dataQRL, isFetchingQRL, isSuccessQRL, person]);
useEffect(() => {
if (dataQRL !== undefined && isFetchingQRL === false && person) {
console.log('useFetchData in QuestionnaireResponsesList useEffect dataQRL is good:', dataQRL, isSuccessQRL, isFetchingQRL);
console.log('Successfully retrieved QuestionnaireResponsesList...');
setQuestionnaireList(dataQRL.questionnaireList);
if (questionnaireResponsesListRetrieveResults) {
captureQuestionnaireListRetrieveData(questionnaireResponsesListRetrieveResults, apiDataCache, dispatch);
if (dataQRL && dataQRL.questionnaireList && isFetchingQRL === false) {
setQuestionnaireList(dataQRL.questionnaireList);
}
}
}, [dataQRL, isFetchingQRL, isSuccessQRL, person]);
}, [questionnaireResponsesListRetrieveResults, allQuestionsCache]);

return (
<div>
Expand Down
25 changes: 5 additions & 20 deletions src/js/components/Team/TeamHeader.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,21 @@ import styled from 'styled-components';
import { renderLog } from '../../common/utils/logging';
import { useConnectAppContext } from '../../contexts/ConnectAppContext';
import { viewerCanSeeOrDo } from '../../models/AuthModel';
import { useRemoveTeamMutation } from '../../react-query/mutations';
import { DeleteStyled, EditStyled } from '../Style/iconStyles';
import { EditStyled } from '../Style/iconStyles';


// eslint-disable-next-line no-unused-vars
const TeamHeader = ({ classes, showHeaderLabels, showIcons, team }) => {
const TeamHeader = ({ showHeaderLabels, showIcons, team }) => {
renderLog('TeamHeader');
const { apiDataCache, getAppContextValue, setAppContextValue } = useConnectAppContext();
const { viewerAccessRights } = apiDataCache;
const { mutate } = useRemoveTeamMutation();

let teamLocal = team;
if (!teamLocal || !teamLocal.teamName) {
teamLocal = getAppContextValue('teamForAddTeamDrawer');
}

const removeTeamClick = () => {
console.log('removeTeamMutation team: ', teamLocal.id);
mutate({ teamId: teamLocal.id });
};

const editTeamClick = () => {
console.log('editTeamClick: ', teamLocal);
// console.log('editTeamClick: ', teamLocal);
setAppContextValue('addTeamDrawerOpen', true);
setAppContextValue('AddTeamDrawerLabel', 'Edit Team Name');
setAppContextValue('teamForAddTeamDrawer', teamLocal);
Expand Down Expand Up @@ -61,21 +53,14 @@ const TeamHeader = ({ classes, showHeaderLabels, showIcons, team }) => {
)}
</>
)}
{/* Delete icon */}
{/* Delete icon - Moved to TeamHome */}
{showIcons && (
<>
{viewerCanSeeOrDo('canRemoveTeam', viewerAccessRights) && (
<TeamHeaderCell cellwidth={20} onClick={removeTeamClick}>
<DeleteStyled />
</TeamHeaderCell>
)}
</>
<></>
)}
</OneTeamHeader>
);
};
TeamHeader.propTypes = {
classes: PropTypes.object.isRequired,
showHeaderLabels: PropTypes.bool,
team: PropTypes.object,
showIcons: PropTypes.bool,
Expand Down
14 changes: 12 additions & 2 deletions src/js/components/Team/TeamMemberList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import React, { useEffect, useState } from 'react';
import styled from 'styled-components';
import { renderLog } from '../../common/utils/logging';
import { isSearchTextFoundInPerson } from '../../controllers/PersonController';
import { useConnectAppContext } from '../../contexts/ConnectAppContext';
import { useConnectAppContext, useConnectDispatch } from '../../contexts/ConnectAppContext';
import capturePersonListRetrieveData from '../../models/capturePersonListRetrieveData';
import { getTeamMembersListByTeamId } from '../../models/TeamModel';
import { METHOD, useFetchData } from '../../react-query/WeConnectQuery';
import PersonSummaryRow from '../Person/PersonSummaryRow';
Expand All @@ -13,12 +14,21 @@ import PersonSummaryRow from '../Person/PersonSummaryRow';
const TeamMemberList = ({ searchText, teamId, team }) => { // teamMemberList
renderLog('TeamMemberList');
const { apiDataCache } = useConnectAppContext();
// const { allPeopleCache, allTeamsCache } = apiDataCache;
const { allPeopleCache } = apiDataCache;
const dispatch = useConnectDispatch();

const [teamMemberListApiDataCache, setTeamMemberListApiDataCache] = useState([]);
const [teamMemberListReactQuery, setTeamMemberListReactQuery] = useState(team.teamMemberList || []);
// const teamMemberList = useGetTeamMembersListByTeamId(teamId);
// console.log('TeamMemberList teamMemberList:', teamMemberList);

const personListRetrieveResults = useFetchData(['person-list-retrieve'], {}, METHOD.GET);
useEffect(() => {
if (personListRetrieveResults) {
capturePersonListRetrieveData(personListRetrieveResults, apiDataCache, dispatch);
}
}, [personListRetrieveResults, allPeopleCache, dispatch]);

const { data: dataTLR, isSuccess: isSuccessTLR, isFetching: isFetchingTLR } = useFetchData(['team-list-retrieve'], {}, METHOD.GET);
// console.log('useFetchData in TeamMemberList:', dataTLR, isSuccessTLR, isFetchingTLR);
useEffect(() => {
Expand Down
2 changes: 1 addition & 1 deletion src/js/contexts/ConnectAppContext.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ export const ConnectAppContextProvider = ({ children }) => {
const { data: dataAuth, isSuccess: isSuccessAuth, isFetching: isFetchingAuth } = useFetchData(['get-auth'], {}, METHOD.POST);
useEffect(() => {
if (isSuccessAuth) {
console.log('useFetchData in ConnectAppContext useEffect dataAuth good:', dataAuth, isSuccessAuth, isFetchingAuth);
// console.log('useFetchData in ConnectAppContext useEffect dataAuth good:', dataAuth, isSuccessAuth, isFetchingAuth);
const { isAuthenticated } = dataAuth;
setAppContextValue('authenticatedPerson', dataAuth.person);
setAppContextValue('authenticatedPersonId', dataAuth.personId);
Expand Down
37 changes: 37 additions & 0 deletions src/js/models/AuthModel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,32 @@ export const viewerCanSeeOrDo = (accessRightName, viewerAccessRights) => {
return viewerAccessRights[accessRightName] || false;
};

export const viewerCanSeeOrDoForThisTeam = (accessRightName, teamId = -1, teamAccessRights = {}) => {
if (!accessRightName || !teamId || !teamAccessRights) {
return false;
}
if (teamId > -1 && teamAccessRights && teamAccessRights[teamId] && teamAccessRights[teamId][accessRightName]) {
return teamAccessRights[teamId][accessRightName] || false;
}
return false;
};

export function captureAccessRightsData (data = {}, isSuccess = false, apiDataCache = {}, dispatch) {
const viewerTeamAccessRights = apiDataCache.viewerTeamAccessRights || {};
const viewerAccessRights = apiDataCache.viewerAccessRights || {};
let changeResults = {
viewerAccessRights,
viewerAccessRightsChanged: false,
viewerTeamAccessRights,
viewerTeamAccessRightsChanged: false,
};
let viewerAccessRightsNew = { ...viewerAccessRights };
let viewerTeamAccessRightsNew = { ...viewerTeamAccessRights };
// console.log('captureAccessRightsData data:', data);
if (data && data.accessRights && isSuccess === true) {
let newDataReceived = false;
const { accessRights } = data;
// Checking to make sure common access right exists so we know results were returned
if (accessRights && !('canAddPerson' in accessRights)) {
viewerAccessRightsNew = accessRights;
newDataReceived = true;
Expand All @@ -33,10 +48,32 @@ export function captureAccessRightsData (data = {}, isSuccess = false, apiDataCa
// console.log('=== captureAccessRightsData viewerAccessRightsNew:', viewerAccessRightsNew, ', newDataReceived:', newDataReceived);
dispatch({ type: 'updateByKeyValue', key: 'viewerAccessRights', value: viewerAccessRightsNew });
changeResults = {
...changeResults,
viewerAccessRights: viewerAccessRightsNew,
viewerAccessRightsChanged: true,
};
}
}
if (data && data.teamAccessRights && isSuccess === true) {
let newDataReceived = false;
const { teamAccessRights } = data;
// Checking to make sure common access right exists so we know results were returned
if (teamAccessRights && !('canEditPersonThisTeam' in teamAccessRights)) {
viewerTeamAccessRightsNew = teamAccessRights;
newDataReceived = true;
} else if (!isEqual(teamAccessRights, viewerTeamAccessRightsNew)) {
viewerTeamAccessRightsNew = teamAccessRights;
newDataReceived = true;
}
if (newDataReceived) {
// console.log('=== captureAccessRightsData viewerTeamAccessRightsNew:', viewerTeamAccessRightsNew, ', newDataReceived:', newDataReceived);
dispatch({ type: 'updateByKeyValue', key: 'viewerTeamAccessRights', value: viewerTeamAccessRightsNew });
changeResults = {
...changeResults,
viewerTeamAccessRights: viewerTeamAccessRightsNew,
viewerTeamAccessRightsChanged: true,
};
}
}
return changeResults;
}
2 changes: 1 addition & 1 deletion src/js/models/QuestionnaireModel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ export const getAnswerToQuestion = (personId, questionId, allAnswersCache) => {
return answer;
};

export const getAnswerValueToQuestion = (personId, questionId, allAnswersCache) => {
export const getAnswerValueToQuestion = (questionId, personId, allAnswersCache) => {
const answer = getAnswerToQuestion(personId, questionId, allAnswersCache) || {};
if (!answer || !answer.answerType) {
// console.log(`No answer found for questionId: ${questionId}`);
Expand Down
6 changes: 3 additions & 3 deletions src/js/pages/AnswerQuestions.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ const AnswerQuestions = ({ classes, setShowHeaderFooter }) => {
if (`questionAnswer-${question.id}` in inputValuesRevised) {
answerValue = inputValuesRevised[`questionAnswer-${question.id}`];
} else {
answerValue = getAnswerValueToQuestion(personId, question.id, allAnswersCache);
answerValue = getAnswerValueToQuestion(question.id, personId, allAnswersCache);
}
if (answerValue === undefined || answerValue === null || answerValue === '') {
requiredValueMissing = true;
Expand Down Expand Up @@ -253,13 +253,13 @@ const AnswerQuestions = ({ classes, setShowHeaderFooter }) => {
<AnswerText>
YOU ANSWERED:
{' '}
{getAnswerValueToQuestion(personId, question.id, allAnswersCache)}
{getAnswerValueToQuestion(question.id, personId, allAnswersCache)}
</AnswerText>
) : (
<QuestionFormWrapper>
<TextField
classes={(question.answerType === 'INTEGER') ? {} : { root: classes.formControl }}
defaultValue={getAnswerValueToQuestion(personId, question.id, allAnswersCache)}
defaultValue={getAnswerValueToQuestion(question.id, personId, allAnswersCache)}
error={isQuestionIdInError(question.id)}
helperText={isQuestionIdInError(question.id) ? helperTextIfQuestionIdInError(question.id) : ''}
id={`questionAnswer-${question.id}`}
Expand Down
Loading
Loading