From 5bdb7b7c89827bb447832203b092b46043477c6c Mon Sep 17 00:00:00 2001 From: dalemcgrew Date: Mon, 3 Feb 2025 11:07:31 -0800 Subject: [PATCH 1/3] =?UTF-8?q?Introduced=20ConnectDispatch=20and=20apiDat?= =?UTF-8?q?aCacheReducer.=20Organizing=20organized=20API=20data=20into=20?= =?UTF-8?q?=E2=80=98apiDataCache=E2=80=99=20dictionary.=20Temporarily=20fo?= =?UTF-8?q?rcing=20react-query=20to=20always=20go=20to=20the=20network=20w?= =?UTF-8?q?hile=20we=20stabilize=20new=20data=20flow.=20Still=20upgrading?= =?UTF-8?q?=20Questionnaire=20to=20new=20approach.=20Still=20reviewing=20a?= =?UTF-8?q?nd=20moving=20edit=20mutations=20into=20models=20folder.=20Comm?= =?UTF-8?q?ented=20out=20many=20console.log=20lines.=20Reordered=20attribu?= =?UTF-8?q?tes=20in=20TextFields=20in=20EditPersonForm=20to=20alphabetical?= =?UTF-8?q?.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.jsx | 9 +- src/js/components/Drawers/DrawerTemplateA.jsx | 10 +- src/js/components/Drawers/Drawers.jsx | 4 +- .../components/Drawers/EditPersonDrawer.jsx | 1 - .../components/Drawers/EditQuestionDrawer.jsx | 15 +- .../Drawers/EditQuestionnaireDrawer.jsx | 5 +- src/js/components/Navigation/HeaderBar.jsx | 14 +- .../Person/AddPersonDrawerMainContent.jsx | 34 ++-- src/js/components/Person/AddPersonForm.jsx | 5 +- .../Person/EditPersonDrawerMainContent.jsx | 5 +- src/js/components/Person/EditPersonForm.jsx | 75 ++++---- src/js/components/Person/PersonProfile.jsx | 9 +- .../Person/PersonProfileDrawerMainContent.jsx | 2 +- .../components/Person/PersonSummaryHeader.jsx | 18 +- src/js/components/Person/PersonSummaryRow.jsx | 26 ++- .../Questionnaire/CopyQuestionnaireLink.jsx | 4 +- .../QuestionnaireResponsesList.jsx | 4 +- src/js/components/Task/TaskListForPerson.jsx | 29 ++-- src/js/components/Task/TaskSummaryRow.jsx | 22 +-- src/js/components/Team/TeamMemberList.jsx | 56 +++--- src/js/contexts/ConnectAppContext.jsx | 72 ++++++-- src/js/models/PersonModel.jsx | 126 ++++++++++++++ src/js/models/TaskModel.jsx | 152 +++++++++++++++++ src/js/models/TeamModel.jsx | 160 ++++++++++++++++++ src/js/pages/QuestionnaireAnswers.jsx | 10 +- src/js/pages/Tasks.jsx | 86 ++++++---- src/js/pages/TeamHome.jsx | 64 +++++-- src/js/pages/Teams.jsx | 66 +++++--- src/js/react-query/PersonQueryProcessing.js | 32 ---- src/js/react-query/WeConnectQuery.js | 5 +- src/js/react-query/mutations.jsx | 4 +- ...s => useGetFullNamePreferredReactQuery.js} | 4 +- src/js/stores/PersonStore.js | 54 +++--- src/js/stores/QuestionnaireStore.js | 78 ++++----- src/js/stores/TaskStore.js | 92 +++++----- src/js/stores/TeamStore.js | 64 +++---- 36 files changed, 999 insertions(+), 417 deletions(-) create mode 100644 src/js/models/PersonModel.jsx create mode 100644 src/js/models/TaskModel.jsx create mode 100644 src/js/models/TeamModel.jsx delete mode 100644 src/js/react-query/PersonQueryProcessing.js rename src/js/react-query/{useGetFullNamePreferred.js => useGetFullNamePreferredReactQuery.js} (90%) diff --git a/src/App.jsx b/src/App.jsx index 1b78b52..ed163e7 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -42,6 +42,7 @@ function App () { const queryClient = new QueryClient({ defaultOptions: { queries: { + networkMode: 'always', // Send queries to the server even if the cache has the data refetchOnWindowFocus: false, refetchOnMount: true, staleTime: 1000 * 60 * 5, // 5 minutes @@ -50,9 +51,9 @@ function App () { }); useEffect(() => { - console.log('--------- initializejQuery() ---------'); + // console.log('--------- initializejQuery() ---------'); initializejQuery(() => { - console.log('--------- jQuery has been initialized ---------'); + // console.log('--------- jQuery has been initialized ---------'); }); return () => { // Anything in here is fired on component unmount, equiv to componentDidUnmount() @@ -61,7 +62,7 @@ function App () { const isAuth = localStorage.getItem('isAuthenticated'); - console.log('======================================== isAuthenticated: " ', isAuth, ' ============================='); + // console.log('======================================== isAuthenticated: " ', isAuth, ' ============================='); return ( <> @@ -79,7 +80,7 @@ function App () { } /> } /> - } /> + {/* } /> */} } /> } /> } /> diff --git a/src/js/components/Drawers/DrawerTemplateA.jsx b/src/js/components/Drawers/DrawerTemplateA.jsx index 44105dd..ec169a1 100644 --- a/src/js/components/Drawers/DrawerTemplateA.jsx +++ b/src/js/components/Drawers/DrawerTemplateA.jsx @@ -18,7 +18,7 @@ const DrawerTemplateA = ({ classes, drawerId, drawerOpenGlobalVariableName, head const [scrolledDown, setScrolledDown] = useState(false); const drawerOpen = getAppContextValue(drawerOpenGlobalVariableName); - console.log('DrawerTemplateA drawerOpen: ', drawerOpenGlobalVariableName, drawerOpen); + // console.log('DrawerTemplateA drawerOpen: ', drawerOpenGlobalVariableName, drawerOpen); const handleScrolledDownDrawer = (evt) => { const { scrollTop } = evt.target; @@ -31,9 +31,9 @@ const DrawerTemplateA = ({ classes, drawerId, drawerOpenGlobalVariableName, head }; useEffect(() => { - console.log('DrawerTemplateA: Context value changed: ', - drawerId, drawerOpenGlobalVariableName, getAppContextValue(drawerOpenGlobalVariableName)); - setScrolledDown(getAppContextValue('scrolledDownDrawer')); + // console.log('DrawerTemplateA: Context value changed: ', + // drawerId, drawerOpenGlobalVariableName, getAppContextValue(drawerOpenGlobalVariableName)); + // TEMP DALE: setScrolledDown(getAppContextValue('scrolledDownDrawer')); }, [getAppContextData]); React.useEffect(() => { @@ -42,7 +42,7 @@ const DrawerTemplateA = ({ classes, drawerId, drawerOpenGlobalVariableName, head if (drawer) { drawer.addEventListener('scroll', handleScrolledDownDrawer); } else { - console.log('Drawer element NOT found make timeout longer.'); + // console.log('Drawer element NOT found make timeout longer.'); } }, 100); diff --git a/src/js/components/Drawers/Drawers.jsx b/src/js/components/Drawers/Drawers.jsx index 4773d62..807945e 100644 --- a/src/js/components/Drawers/Drawers.jsx +++ b/src/js/components/Drawers/Drawers.jsx @@ -4,7 +4,7 @@ import AddPersonDrawer from './AddPersonDrawer'; import AddTeamDrawer from './AddTeamDrawer'; import EditPersonDrawer from './EditPersonDrawer'; import EditQuestionDrawer from './EditQuestionDrawer'; -import EditQuestionnaireDrawer from './EditQuestionnaireDrawer'; +// import EditQuestionnaireDrawer from './EditQuestionnaireDrawer'; import EditTaskDefinitionDrawer from './EditTaskDefinitionDrawer'; import EditTaskGroupDrawer from './EditTaskGroupDrawer'; import PersonProfileDrawer from './PersonProfileDrawer'; @@ -20,7 +20,7 @@ const Drawers = () => { - + {/* TODO: Still causing infinite loop: */} diff --git a/src/js/components/Drawers/EditPersonDrawer.jsx b/src/js/components/Drawers/EditPersonDrawer.jsx index 3044c43..488a96d 100644 --- a/src/js/components/Drawers/EditPersonDrawer.jsx +++ b/src/js/components/Drawers/EditPersonDrawer.jsx @@ -9,7 +9,6 @@ const EditPersonDrawer = () => { const [headerTitleJsx] = useState(<>); const [headerFixedJsx] = useState(<>); - return ( { const [headerFixedJsx] = useState(<>); useEffect(() => { - console.log('EditQuestionDrawer: Context value changed:', true); + // console.log('EditQuestionDrawer: Context value changed:', true); const question = getAppContextValue('selectedQuestion'); - if (question && question.id >= 0) { - setHeaderTitleJsx(<>Edit Question); - } else { - setHeaderTitleJsx(<>Add Question); - } - }, [getAppContextValue]); + // if (question && question.id >= 0) { + // setHeaderTitleJsx(<>Edit Question); + // } else { + // setHeaderTitleJsx(<>Add Question); + // } + }); + // }, [getAppContextValue]); // TODO DALE: commented out for now to avoid infinite loop return ( { useEffect(() => { if (getAppContextValue('editQuestionnaireDrawerOpen')) { - console.log('EditQuestionnaireDrawer: Context value changed:', true); + // console.log('EditQuestionnaireDrawer: Context value changed:', true); const questionnaire = getAppContextValue('selectedQuestionnaire'); if (questionnaire) { setHeaderTitleJsx(<>Edit Questionnaire); @@ -23,7 +23,8 @@ const EditQuestionnaireDrawer = () => { setHeaderTitleJsx(<>Add Questionnaire); } } - }, [getAppContextValue]); + }); + // }, [getAppContextValue]); // TODO DALE: commented out for now to avoid infinite loop return ( { // }; const initializeTabValue = () => { - console.log('initializeTabValue normalizedHrefPage():', normalizedHrefPage()); + // console.log('initializeTabValue normalizedHrefPage():', normalizedHrefPage()); switch (normalizedHrefPage()) { case 'tasks': setTabsValue('1'); - console.log('initializeTabValue setTabsValue: 1'); + // console.log('initializeTabValue setTabsValue: 1'); break; case 'team-home': case 'teams': setTabsValue('2'); - console.log('initializeTabValue setTabsValue: 2'); + // console.log('initializeTabValue setTabsValue: 2'); break; case 'questionnaire': case 'system-settings': case 'task-group': setTabsValue('3'); - console.log('initializeTabValue setTabsValue: 3'); + // console.log('initializeTabValue setTabsValue: 3'); break; default: setTabsValue('1'); - console.log('initializeTabValue setTabsValue default: 1'); + // console.log('initializeTabValue setTabsValue default: 1'); break; } }; const handleTabChange = (event, newValue) => { - console.log(`handleTabChange newValue: ${newValue}`); + // console.log(`handleTabChange newValue: ${newValue}`); // setTabsValue(newValue); switch (newValue) { case '1': @@ -96,7 +96,7 @@ const HeaderBar = () => { // // console.log('------ HeaderBar, onAppObservableStoreChange received: ', msg); // setScrolledDown(false); // }; - console.log('tabs value ==== ', tabsValue); + // console.log('tabs value ==== ', tabsValue); return ( { @@ -16,8 +17,8 @@ const AddPersonDrawerMainContent = () => { const { getAppContextValue } = useConnectAppContext(); const { mutate } = useAddPersonToTeamMutation(); - const params = useParams(); - console.log('AddPersonDrawerMainContent params: ', params); + // const params = useParams(); + // console.log('AddPersonDrawerMainContent params: ', params); const [allStaffList] = useState(getAppContextValue('allStaffList')); const [remainingStaffToAdd, setRemainingStaffToAdd] = useState(getAppContextValue('allStaffList')); @@ -32,19 +33,20 @@ const AddPersonDrawerMainContent = () => { const searchStringRef = useRef(''); let memberList = []; - const teamListFromContext = getAppContextValue('teamListNested'); - if (teamListFromContext && thisTeamsCurrentMembersList.length === 0 && teamName === '') { - const oneTeam = teamListFromContext.find((team) => team.id === parseInt(teamId)); - setTeamName(oneTeam.teamName); - setTeamId(oneTeam.id); - - if (oneTeam && oneTeam.teamMemberList.length > 0) { - memberList = oneTeam.teamMemberList; - setThisTeamsCurrentMembersList(memberList); - } - } else { - // console.log('no teamListFromContext yet!'); - } + // const teamListFromContext = getAppContextValue('teamListNested'); + // const teamListFromContext = GetTeamListArray(); + // if (teamListFromContext && thisTeamsCurrentMembersList.length === 0 && teamName === '') { + // const oneTeam = teamListFromContext.find((team) => team.id === parseInt(teamId)); + // setTeamName(oneTeam.teamName); + // setTeamId(oneTeam.id); + // + // if (oneTeam && oneTeam.teamMemberList.length > 0) { + // memberList = oneTeam.teamMemberList; + // setThisTeamsCurrentMembersList(memberList); + // } + // } else { + // // console.log('no teamListFromContext yet!'); + // } const initializeRemainingStaffToAddList = () => { console.log('initializeTheRemainingStaffToAddListList in AddPersonDrawerMainContent'); @@ -84,7 +86,7 @@ const AddPersonDrawerMainContent = () => { if (matchingElements && matchingElements.length) { setSearchResultsList(matchingElements); setMatchingCounter(matchingElements); - console.log(matchingElements); + // console.log(matchingElements); } else { setMatchingCountText(''); } diff --git a/src/js/components/Person/AddPersonForm.jsx b/src/js/components/Person/AddPersonForm.jsx index a43802e..a80b76e 100644 --- a/src/js/components/Person/AddPersonForm.jsx +++ b/src/js/components/Person/AddPersonForm.jsx @@ -22,10 +22,11 @@ const AddPersonForm = ({ classes }) => { // classes, teamId const emailFldRef = useRef(''); useEffect(() => { // Replaces onAppObservableStoreChange and will be called whenever the context value changes - console.log('AddPersonForm: Context value changed:', true); + // console.log('AddPersonForm: Context value changed:', true); setTeamId(getAppContextValue('addPersonDrawerTeam').id); setTeamName(getAppContextValue('addPersonDrawerTeam').teamName); - }, [getAppContextValue]); + }, []); + // }, [getAppContextValue]); // TODO DALE: commented out for now to avoid infinite loop const saveNewPerson = () => { diff --git a/src/js/components/Person/EditPersonDrawerMainContent.jsx b/src/js/components/Person/EditPersonDrawerMainContent.jsx index ca56648..be1a4e4 100644 --- a/src/js/components/Person/EditPersonDrawerMainContent.jsx +++ b/src/js/components/Person/EditPersonDrawerMainContent.jsx @@ -13,10 +13,11 @@ const EditPersonDrawerMainContent = () => { const [teamId, setTeamId] = useState(-1); useEffect(() => { // Replaces onAppObservableStoreChange and will be called whenever the context value changes - console.log('EditPersonDrawerMainContent: Context value changed:', true); + // console.log('EditPersonDrawerMainContent: Context value changed:', true); const teamIdTemp = getAppContextValue('editPersonDrawerTeamId'); setTeamId(teamIdTemp); - }, [getAppContextValue]); + }); + // }, [getAppContextValue]); // TODO DALE: commented out for now to avoid infinite loop return ( diff --git a/src/js/components/Person/EditPersonForm.jsx b/src/js/components/Person/EditPersonForm.jsx index bdf8dcf..7dacdb0 100644 --- a/src/js/components/Person/EditPersonForm.jsx +++ b/src/js/components/Person/EditPersonForm.jsx @@ -7,15 +7,18 @@ import { renderLog } from '../../common/utils/logging'; import webAppConfig from '../../config'; import { useConnectAppContext } from '../../contexts/ConnectAppContext'; import makeRequestParams from '../../react-query/makeRequestParams'; -import { usePersonSaveMutation } from '../../react-query/mutations'; +// import { usePersonSaveMutation } from '../../react-query/mutations'; +import { useGetPersonById, usePersonSave } from '../../models/PersonModel'; const EditPersonForm = ({ classes }) => { renderLog('EditPersonForm'); const { getAppContextValue } = useConnectAppContext(); - const { mutate } = usePersonSaveMutation(); + // const { mutate } = usePersonSaveMutation(); + const { mutate: personSave } = usePersonSave(); const [saveButtonActive, setSaveButtonActive] = useState(false); - const [initialPerson] = useState(getAppContextValue('personDrawersPerson')); + // const [initialPerson] = useState(getAppContextValue('personDrawersPerson')); + const [initialPerson] = useState(useGetPersonById(getAppContextValue('personDrawersPersonId'))); const [activePerson, setActivePerson] = useState({ ...initialPerson }); const emailPersonal = useRef(''); @@ -24,6 +27,7 @@ const EditPersonForm = ({ classes }) => { const jobTitle = useRef(''); const lastName = useRef(''); const location = useRef(''); + const stateCode = useRef(''); const savePerson = () => { activePerson.emailPersonal = emailPersonal.current.value; @@ -32,9 +36,10 @@ const EditPersonForm = ({ classes }) => { activePerson.jobTitle = jobTitle.current.value; activePerson.lastName = lastName.current.value; activePerson.location = location.current.value; + activePerson.stateCode = stateCode.current.value; setActivePerson(activePerson); - console.log('savePerson data:', JSON.stringify(activePerson)); + // console.log('savePerson data:', JSON.stringify(activePerson)); const data = {}; // for (const key in activePerson) { @@ -49,7 +54,8 @@ const EditPersonForm = ({ classes }) => { personId: activePerson.id, }; - mutate(makeRequestParams(plainParams, data)); + // mutate(makeRequestParams(plainParams, data)); + personSave(makeRequestParams(plainParams, data)); setSaveButtonActive(false); }; @@ -58,77 +64,88 @@ const EditPersonForm = ({ classes }) => { setSaveButtonActive(true)} placeholder="First Name (legal name)" - defaultValue={activePerson.firstName || ''} variant="outlined" /> setSaveButtonActive(true)} + placeholder="First Name to use in meetings" + variant="outlined" /> setSaveButtonActive(true)} + placeholder="Last Name" + variant="outlined" /> setSaveButtonActive(true)} placeholder="Email Address, Personal" - defaultValue={activePerson.emailPersonal || ''} - onChange={() => setSaveButtonActive(true)} /> setSaveButtonActive(true)} placeholder="City, State" - defaultValue={activePerson.location || ''} + variant="outlined" + /> + setSaveButtonActive(true)} + placeholder="State Code (2 characters)" + variant="outlined" /> setSaveButtonActive(true)} + placeholder={`Job Title here at ${webAppConfig.ORGANIZATION_NAME}`} + variant="outlined" /> diff --git a/src/js/components/Person/PersonProfile.jsx b/src/js/components/Person/PersonProfile.jsx index d535911..8c70eed 100644 --- a/src/js/components/Person/PersonProfile.jsx +++ b/src/js/components/Person/PersonProfile.jsx @@ -2,24 +2,27 @@ import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import { renderLog } from '../../common/utils/logging'; import { useConnectAppContext } from '../../contexts/ConnectAppContext'; -import useGetFullNamePreferred from '../../react-query/useGetFullNamePreferred'; +// import useGetFullNamePreferredReactQuery from '../../react-query/useGetFullNamePreferredReactQuery'; import CopyQuestionnaireLink from '../Questionnaire/CopyQuestionnaireLink'; +import { useGetFullNamePreferred, useGetPersonById } from '../../models/PersonModel'; const PersonProfile = () => { renderLog('PersonProfile'); // Set LOG_RENDER_EVENTS to log all renders const { getAppContextValue, setAppContextValue } = useConnectAppContext(); - const [person] = useState(getAppContextValue('personDrawersPerson')); + // const [person] = useState(getAppContextValue('personDrawersPerson')); + const [person] = useState(useGetPersonById(getAppContextValue('personDrawersPersonId'))); useEffect(() => { + // Hard coded temporarily while we are in development setAppContextValue('QuestionnaireId', 1); }, []); return ( - {useGetFullNamePreferred(person)} + {useGetFullNamePreferred(person.personId)} {/* This was commented out as of January 28th, 2025 */} diff --git a/src/js/components/Person/PersonProfileDrawerMainContent.jsx b/src/js/components/Person/PersonProfileDrawerMainContent.jsx index d545209..4049850 100644 --- a/src/js/components/Person/PersonProfileDrawerMainContent.jsx +++ b/src/js/components/Person/PersonProfileDrawerMainContent.jsx @@ -11,7 +11,7 @@ const PersonProfileDrawerMainContent = () => { return ( - + {/* */} ); }; diff --git a/src/js/components/Person/PersonSummaryHeader.jsx b/src/js/components/Person/PersonSummaryHeader.jsx index ff8056a..de1dd37 100644 --- a/src/js/components/Person/PersonSummaryHeader.jsx +++ b/src/js/components/Person/PersonSummaryHeader.jsx @@ -9,17 +9,17 @@ const PersonSummaryHeader = () => { return ( {/* Width (below) of this PersonHeaderCell comes from the combined widths of the first x columns in PersonMemberList */} - {/* Name */} +   - + Location - + Title / Volunteering Love {/* Edit icon */} - + ); }; @@ -32,18 +32,18 @@ const OnePersonHeader = styled('div')` `; const PersonHeaderCell = styled('div', { - shouldForwardProp: (prop) => !['largeFont', 'titleCell', 'width'].includes(prop), -})(({ largeFont, titleCell, width }) => (` + shouldForwardProp: (prop) => !['largeFont', 'titleCell', 'cellwidth'].includes(prop), +})(({ largeFont, titleCell, cellwidth }) => (` align-content: center; ${(titleCell) ? '' : 'border-bottom: 1px solid #ccc;'} ${(largeFont) ? 'font-size: 1.1em;' : 'font-size: .8em;'}; ${(titleCell) ? '' : 'font-weight: 550;'} height: 22px; - ${width ? `max-width: ${width}px;` : ''}; - ${width ? `min-width: ${width}px;` : ''}; + ${cellwidth ? `max-width: ${cellwidth}px;` : ''}; + ${cellwidth ? `min-width: ${cellwidth}px;` : ''}; overflow: hidden; white-space: nowrap; - ${width ? `width: ${width}px;` : ''}; + ${cellwidth ? `width: ${cellwidth}px;` : ''}; `)); export default PersonSummaryHeader; diff --git a/src/js/components/Person/PersonSummaryRow.jsx b/src/js/components/Person/PersonSummaryRow.jsx index 8977190..7d70a0c 100644 --- a/src/js/components/Person/PersonSummaryRow.jsx +++ b/src/js/components/Person/PersonSummaryRow.jsx @@ -5,34 +5,46 @@ import styled from 'styled-components'; import DesignTokenColors from '../../common/components/Style/DesignTokenColors'; import { renderLog } from '../../common/utils/logging'; import { useConnectAppContext } from '../../contexts/ConnectAppContext'; -import useGetFullNamePreferred from '../../react-query/useGetFullNamePreferred'; -import { useRemoveTeamMemberMutation } from '../../react-query/mutations'; +import { useGetFullNamePreferred } from '../../models/PersonModel'; +import { useRemoveTeamMemberMutation } from '../../models/TeamModel'; +// import useGetFullNamePreferredReactQuery from '../../react-query/useGetFullNamePreferredReactQuery'; +// import { useRemoveTeamMemberMutation } from '../../react-query/mutations'; import { DeleteStyled, EditStyled } from '../Style/iconStyles'; const PersonSummaryRow = ({ person, rowNumberForDisplay, teamId }) => { renderLog('PersonSummaryRow'); // Set LOG_RENDER_EVENTS to log all renders + // const [person, setPerson] = useState(useGetPersonById(personId)); const { setAppContextValue } = useConnectAppContext(); const { mutate } = useRemoveTeamMemberMutation(); const removeTeamMemberClick = () => { - const personId = person.id; - const params = { personId, teamId }; + const params = { personId: person.personId, teamId }; mutate(params); }; const editPersonClick = (hasEditRights = true) => { if (hasEditRights) { setAppContextValue('editPersonDrawerOpen', true); - setAppContextValue('personDrawersPerson', person); + // setAppContextValue('personDrawersPerson', person); + setAppContextValue('personDrawersPersonId', person.personId); } }; const personProfileClick = () => { setAppContextValue('personProfileDrawerOpen', true); - setAppContextValue('personDrawersPerson', person); + // setAppContextValue('personDrawersPerson', person); + setAppContextValue('personDrawersPersonId', person.personId); }; + // useEffect(() => { + // console.log('PersonSummaryRow person: ', person, ' useEffect apiDataCache:', apiDataCache); + // const { allPeopleCache } = apiDataCache; + // if (allPeopleCache) { + // setPerson(allPeopleCache[personId] || {}); + // } + // }, [apiDataCache]); + const hasEditRights = true; return ( @@ -53,7 +65,7 @@ const PersonSummaryRow = ({ person, rowNumberForDisplay, teamId }) => { }} width={200} > - {useGetFullNamePreferred(person)} + {useGetFullNamePreferred(person.personId)} {person.location} diff --git a/src/js/components/Questionnaire/CopyQuestionnaireLink.jsx b/src/js/components/Questionnaire/CopyQuestionnaireLink.jsx index 87335ef..bea256e 100644 --- a/src/js/components/Questionnaire/CopyQuestionnaireLink.jsx +++ b/src/js/components/Questionnaire/CopyQuestionnaireLink.jsx @@ -6,13 +6,15 @@ import { renderLog } from '../../common/utils/logging'; import webAppConfig from '../../config'; import { useConnectAppContext } from '../../contexts/ConnectAppContext'; import { SpanWithLinkStyle } from '../Style/linkStyles'; +import { useGetPersonById } from '../../models/PersonModel'; const CopyQuestionnaireLink = () => { renderLog('CopyQuestionnaireLink'); const { getAppContextValue } = useConnectAppContext(); - const [person] = useState(getAppContextValue('personDrawersPerson')); + // const [person] = useState(getAppContextValue('personDrawersPerson')); + const [person] = useState(useGetPersonById(getAppContextValue('personDrawersPersonId'))); const [questionnaireId] = useState(getAppContextValue('QuestionnaireId')); const [linkCopied, setLinkCopied] = useState(false); const [linkToBeShared] = useState(`${webAppConfig.PROTOCOL}${webAppConfig.HOSTNAME}/q/${questionnaireId}/${person.id}`); diff --git a/src/js/components/Questionnaire/QuestionnaireResponsesList.jsx b/src/js/components/Questionnaire/QuestionnaireResponsesList.jsx index a3aa4b8..c50221c 100644 --- a/src/js/components/Questionnaire/QuestionnaireResponsesList.jsx +++ b/src/js/components/Questionnaire/QuestionnaireResponsesList.jsx @@ -9,6 +9,7 @@ import webAppConfig from '../../config'; import { useConnectAppContext } from '../../contexts/ConnectAppContext'; import { useFetchData } from '../../react-query/WeConnectQuery'; import CopyQuestionnaireLink from './CopyQuestionnaireLink'; +import { useGetPersonById } from '../../models/PersonModel'; const OpenExternalWebSite = React.lazy(() => import(/* webpackChunkName: 'OpenExternalWebSite' */ '../../common/components/Widgets/OpenExternalWebSite')); @@ -16,7 +17,8 @@ const QuestionnaireResponsesList = ({ personId }) => { renderLog('QuestionnaireList'); // Set LOG_RENDER_EVENTS to log all renders const { getAppContextValue } = useConnectAppContext(); - const [person] = useState(getAppContextValue('personDrawersPerson')); + // const [person] = useState(getAppContextValue('personDrawersPerson')); + const [person] = useState(useGetPersonById(getAppContextValue('personDrawersPersonId'))); const [questionnaireList, setQuestionnaireList] = useState([]); // Although we are sending a list, there will only be one person id, if there were more, just append them with commas diff --git a/src/js/components/Task/TaskListForPerson.jsx b/src/js/components/Task/TaskListForPerson.jsx index 6728582..dbedb02 100644 --- a/src/js/components/Task/TaskListForPerson.jsx +++ b/src/js/components/Task/TaskListForPerson.jsx @@ -7,27 +7,30 @@ import TaskSummaryRow from './TaskSummaryRow'; const TaskListForPerson = ({ personId, showCompletedTasks, taskDefinitionList, taskListForPersonId }) => { renderLog('TaskListForPerson'); // Set LOG_RENDER_EVENTS to log all renders - + let taskDefinition = {}; return ( - {taskListForPersonId.map((task, index) => ( - taskDefEntry.taskDefinitionId === task.taskDefinitionId)} - task={task} - rowNumberForDisplay={index + 1} - /> - ))} + {taskListForPersonId.map((task, index) => { + taskDefinition = taskDefinitionList.find((taskDef) => taskDef.taskDefinitionId === task.taskDefinitionId) || {}; + return ( + + ); + })} ); }; TaskListForPerson.propTypes = { personId: PropTypes.number.isRequired, showCompletedTasks: PropTypes.bool, - taskDefinitionList: PropTypes.object, - taskListForPersonId: PropTypes.object, + taskDefinitionList: PropTypes.array, + taskListForPersonId: PropTypes.array, }; const TaskListWrapper = styled('div')` diff --git a/src/js/components/Task/TaskSummaryRow.jsx b/src/js/components/Task/TaskSummaryRow.jsx index 304df4c..1eea952 100644 --- a/src/js/components/Task/TaskSummaryRow.jsx +++ b/src/js/components/Task/TaskSummaryRow.jsx @@ -36,7 +36,7 @@ const TaskSummaryRow = ({ classes, hideIfCompleted, personId, rowNumberForDispla if (hideIfCompleted && task.statusDone) { return null; } - const taskDef = taskDefinition[0]; + // console.log('TaskSummaryRow taskDefinition:', taskDefinition); return ( {rowNumberForDisplay && ( @@ -46,13 +46,13 @@ const TaskSummaryRow = ({ classes, hideIfCompleted, personId, rowNumberForDispla )} - - {taskDef.taskDescription ? ( - - {taskDef.taskName} + + {taskDefinition.taskDescription ? ( + + {taskDefinition.taskName} ) : ( - {taskDef.taskName} + {taskDefinition.taskName} )} @@ -87,27 +87,27 @@ const TaskSummaryRow = ({ classes, hideIfCompleted, personId, rowNumberForDispla )} - {(taskDef.taskInstructions) && ( + {(taskDefinition.taskInstructions) && ( )} - {(taskDef.taskActionUrl) && ( + {(taskDefinition.taskActionUrl) && ( }> + )} diff --git a/src/js/components/Team/TeamMemberList.jsx b/src/js/components/Team/TeamMemberList.jsx index 91d0210..67116cf 100644 --- a/src/js/components/Team/TeamMemberList.jsx +++ b/src/js/components/Team/TeamMemberList.jsx @@ -1,36 +1,48 @@ import { withStyles } from '@mui/styles'; import PropTypes from 'prop-types'; -import React from 'react'; +import React, { useEffect, useState } from 'react'; import styled from 'styled-components'; import { renderLog } from '../../common/utils/logging'; -import { useConnectAppContext } from '../../contexts/ConnectAppContext'; import PersonSummaryRow from '../Person/PersonSummaryRow'; +import { + GetTeamMembersListByTeamId, + // useGetTeamMembersListByTeamId, +} from '../../models/TeamModel'; +import { useConnectAppContext } from '../../contexts/ConnectAppContext'; -const TeamMemberList = ({ teamId }) => { +const TeamMemberList = ({ teamId }) => { // teamMemberList renderLog('TeamMemberList'); - const { getAppContextValue } = useConnectAppContext(); + const { apiDataCache } = useConnectAppContext(); + const { allPeopleCache, allTeamsCache } = apiDataCache; + // const [teamMemberList, setTeamMemberList] = useState(useGetTeamMembersListByTeamId(teamId)); + const [teamMemberList, setTeamMemberList] = useState([]); + // const teamMemberList = useGetTeamMembersListByTeamId(teamId); + // console.log('TeamMemberList teamMemberList:', teamMemberList); - let teamMemberList = []; - const teamListFromContext = getAppContextValue('teamListNested'); - if (teamListFromContext) { - const oneTeam = teamListFromContext.find((staff) => staff.teamId === parseInt(teamId)); - if (oneTeam && oneTeam.teamMemberList.length > 0) { - teamMemberList = oneTeam.teamMemberList; - } - } else { - console.log('no teamListFromContext yet!'); - } + useEffect(() => { + // console.log(`TeamMemberList useEffect teamId: ${teamId} apiDataCache:`, apiDataCache); + const updatedTeamMemberList = GetTeamMembersListByTeamId(teamId, apiDataCache); + // console.log(`TeamMemberList useEffect teamId: ${teamId} updatedTeamMemberList:`, updatedTeamMemberList); + setTeamMemberList(updatedTeamMemberList); + }, [allPeopleCache, allTeamsCache, teamId]); return ( - {teamMemberList.map((person, index) => ( - - ))} + {teamMemberList.map((person, index) => { + // console.log(`TeamMemberList teamId: ${teamId}, person:`, person); + if (person) { + return ( + + ); + } else { + return null; // Empty row for non-existing members + } + })} ); }; diff --git a/src/js/contexts/ConnectAppContext.jsx b/src/js/contexts/ConnectAppContext.jsx index ce7f6dd..c27be42 100644 --- a/src/js/contexts/ConnectAppContext.jsx +++ b/src/js/contexts/ConnectAppContext.jsx @@ -1,19 +1,48 @@ -import React, { createContext, useContext, useEffect, useState } from 'react'; +import React, { createContext, useContext, useEffect, useReducer, useState } from 'react'; import PropTypes from 'prop-types'; import { useFetchData } from '../react-query/WeConnectQuery'; +import { getInitialGlobalPersonVariables, PersonListRetrieveDataCapture } from '../models/PersonModel'; +import { getInitialGlobalTaskVariables } from '../models/TaskModel'; +import { getInitialGlobalTeamVariables } from '../models/TeamModel'; // Replaces AppObservableStore.js // Create the context const ConnectAppContext = createContext({}); +const ConnectDispatch = createContext(null); +const initialCachedApiPersonVariables = getInitialGlobalPersonVariables(); +const initialCachedApiTaskVariables = getInitialGlobalTaskVariables(); +const initialCachedApiTeamVariables = getInitialGlobalTeamVariables(); + +function apiDataCacheReducer (apiDataCache, action) { + let revisedApiDataCache = { ...apiDataCache }; + switch (action.type) { + case 'updateByKeyValue': { + revisedApiDataCache = { ...revisedApiDataCache, [action.key]: action.value }; + return revisedApiDataCache; + } + default: { + return revisedApiDataCache; + } + } +} + +const initialApiDataCache = { + ...initialCachedApiPersonVariables, + ...initialCachedApiTaskVariables, + ...initialCachedApiTeamVariables, +}; // Create the provider component // eslint-disable-next-line no-unused-vars export const ConnectAppContextProvider = ({ children }) => { - console.log('initialization of ConnectAppContextProvider ==============='); + // console.log('initialization of ConnectAppContextProvider ==============='); const [data, setData] = useState({}); - + const [apiDataCache, dispatch] = useReducer( + apiDataCacheReducer, + initialApiDataCache, + ); const setAppContextValue = (key, value) => { - console.log('------------ setAppContextValue ', key, ' : ', value); + // console.log('------------ setAppContextValue ', key, ' : ', value); setData((prevStore) => ({ ...prevStore, [key]: value })); }; @@ -29,19 +58,40 @@ export const ConnectAppContextProvider = ({ children }) => { } }; - const { data: dataP, isSuccess: isSuccessP, isFetching: isFetchingP, isStale: isStaleP } = useFetchData(['person-list-retrieve'], {}); + // const { data: dataP, isSuccess: isSuccessP, isFetching: isFetchingP, isStale: isStaleP } = useFetchData(['person-list-retrieve'], {}); + const personListRetrieveResults = useFetchData(['person-list-retrieve'], { + cacheTime: 0, + networkMode: 'no-cache', + refetchOnMount: true, + refetchOnWindowFocus: true, + refetchInterval: 0, + staleTime: 0, + }); + const { data: dataP, isSuccess: isSuccessP, isFetching: isFetchingP, isStale: isStaleP } = personListRetrieveResults; + useEffect(() => { + // console.log('useFetchData person-list-retrieve in Teams useEffect:', personListRetrieveResults); + if (personListRetrieveResults) { + // console.log('In useEffect apiDataCache:', apiDataCache); + // const changeResults = + PersonListRetrieveDataCapture(personListRetrieveResults, apiDataCache, dispatch); + // console.log('ConnectAppContext useEffect PersonListRetrieveDataCapture changeResults:', changeResults); + } + }, [personListRetrieveResults]); + useEffect(() => { - console.log('useFetchData in TeamHome (person-list-retrieve) useEffect:', dataP, isSuccessP, isFetchingP, isStaleP); + // console.log('useFetchData in TeamHome (person-list-retrieve) useEffect:', dataP, isSuccessP, isFetchingP, isStaleP); if (isSuccessP) { // console.log('useFetchData in TeamHome (person-list-retrieve)useEffect data good:', dataP, isSuccessP, isFetchingP, isStaleP); setAppContextValue('allStaffList', dataP ? dataP.personList : []); - console.log('allStaffList fetched in ConnectAppContext'); + // console.log('ConnectAppContext useEffect allStaffList fetched'); } }, [dataP, isSuccessP, isFetchingP]); return ( - - {children} + + + {children} + ); }; @@ -54,7 +104,9 @@ export function useConnectAppContext () { return useContext(ConnectAppContext); } - +export function useConnectDispatch () { + return useContext(ConnectDispatch); +} diff --git a/src/js/models/PersonModel.jsx b/src/js/models/PersonModel.jsx new file mode 100644 index 0000000..12d9936 --- /dev/null +++ b/src/js/models/PersonModel.jsx @@ -0,0 +1,126 @@ +import isEqual from 'lodash-es/isEqual'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import weConnectQueryFn from '../react-query/WeConnectQuery'; +import { useConnectAppContext } from '../contexts/ConnectAppContext'; + +// These are the "AppContextValues" (i.e., global state variables) used in the PersonModel +export function getInitialGlobalPersonVariables () { + return { + allPeopleCache: {}, // This is a dictionary key: personId, value: person dict + mostRecentPersonIdSaved: -1, + mostRecentPersonSaved: { + firstName: '', + lastName: '', + personId: '', + }, + searchResults: [], + }; +} + +export const useGetPersonById = (personId) => { + const { apiDataCache } = useConnectAppContext(); + const { allPeopleCache } = apiDataCache; + // console.log('useGetPersonById personId:', personId, ', allPeopleCache:', allPeopleCache); + if (allPeopleCache) { + return allPeopleCache[personId] || {}; + } else { + return {}; + } +}; + +export const useGetFullNamePreferred = (personId) => { + const person = useGetPersonById(personId); + let fullName = ''; + if (person.id >= 0) { + if (person.firstNamePreferred) { + fullName += person.firstNamePreferred; + } else if (person.firstName) { + fullName += person.firstName; + } + if (fullName.length > 0 && person.lastName) { + fullName += ' '; + } + if (person.lastName) { + fullName += person.lastName; + } + } + return fullName; +}; + +export function PersonListRetrieveDataCapture (incomingResults = {}, apiDataCache = {}, dispatch) { + const { data, isSuccess } = incomingResults; + const allPeopleCache = apiDataCache.allPeopleCache || {}; + let changeResults = { + allPeopleCache, + allPeopleCacheChanged: false, + }; + const allPeopleCacheNew = { ...allPeopleCache }; + // console.log('PersonListRetrieve data: ', data, ', isFetching:', isFetching, ', isSuccess:', isSuccess); + // We need to only update allPeopleCache the first time we have received new data from the API server + if (data && data.personList && isSuccess === true) { + let newDataReceived = false; + data.personList.forEach((person) => { + if (person && person.personId && person.personId >= 0) { + if (!allPeopleCacheNew[person.personId]) { + allPeopleCacheNew[person.personId] = person; + newDataReceived = true; + } else if (!isEqual(person, allPeopleCacheNew[person.personId])) { + allPeopleCacheNew[person.personId] = person; + newDataReceived = true; + } + } + }); + // console.log('person-list-retrieve setting allPeopleCacheNew:', allPeopleCacheNew, ', newDataReceived:', newDataReceived); + if (newDataReceived) { + // setAppContextValue('allPeopleCache', allPeopleCache); + dispatch({ type: 'updateByKeyValue', key: 'allPeopleCache', value: allPeopleCacheNew }); + changeResults = { + allPeopleCache: allPeopleCacheNew, + allPeopleCacheChanged: true, + }; + } + } + return changeResults; +} + +export const usePersonSave = () => { + // PLEASE DO NOT REMOVE + // const { apiDataCache } = useConnectAppContext(); + // const dispatch = useConnectDispatch(); + + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: (params) => weConnectQueryFn('person-save', params), + networkMode: 'always', // Send queries to the server even if the cache has the data + onError: (error) => { + console.log('onError in usePersonSave: ', error); + queryClient.refetchQueries({ queryKey: ['person-list-retrieve'], refetchType: 'active', exact: true, force: true }) + .then(() => console.log('PersonModel API call error recovery refetch completed')) + .catch((error2) => console.error('PersonModel API call refetch failed:', error2)); + }, + onSuccess: (results) => { + // console.log('person-save onSuccess true, results: ', results); + + // PLEASE DO NOT REMOVE + // const { allPeopleCache } = apiDataCache; + // const allPeopleCacheNew = { ...allPeopleCache }; + // console.log('useGetPersonById personId:', personId, ', allPeopleCacheNew:', allPeopleCacheNew); + if (results.success === false) { + console.log('usePersonSave onSuccess failed results:', results); + } else if (results.personId >= 0) { + // PLEASE DO NOT REMOVE + // console.log('usePersonSave personId:', results.personId, ', results: ', results); + // allPeopleCacheNew[results.personId] = results; + // dispatch({ type: 'updateByKeyValue', key: 'allPeopleCache', value: allPeopleCacheNew }); + + // setTimeout(() => { + queryClient.refetchQueries({ queryKey: ['person-list-retrieve'], refetchType: 'active', exact: true, force: true }) + .then(() => console.log('PersonModel refetch completed')) + .catch((error) => console.error('PersonModel refetch failed:', error)); + // }, 1000); // 1 second delay + } else { + console.log('usePersonSave personId not >= 0:', results); + } + }, + }); +}; diff --git a/src/js/models/TaskModel.jsx b/src/js/models/TaskModel.jsx new file mode 100644 index 0000000..4d5fb28 --- /dev/null +++ b/src/js/models/TaskModel.jsx @@ -0,0 +1,152 @@ +import isEqual from 'lodash-es/isEqual'; +// import { useMutation, useQueryClient } from '@tanstack/react-query'; +// import weConnectQueryFn from '../react-query/WeConnectQuery'; +// import { useConnectAppContext } from '../contexts/ConnectAppContext'; + +// These are the "AppContextValues" (i.e., global state variables) used in the PersonModel +export function getInitialGlobalTaskVariables () { + return { + allTaskGroupsCache: {}, // This is a dictionary key: taskGroupId, value: TaskGroup dict + allTaskDefinitionsCache: {}, // This is a dictionary key: taskDefinitionId, value: TaskDefinition dict + allTaskDependenciesCache: {}, // This is a dictionary key: taskDependencyId, value: TaskDependency dict + allTasksCache: {}, // This is a dictionary key: personId, value: another dictionary key: taskDefinitionId, value: Task dict + mostRecentTaskDefinitionIdSaved: -1, + mostRecentTaskDefinitionSaved: { + taskDefinitionId: -1, + }, + mostRecentTaskGroupIdSaved: -1, + mostRecentTaskGroupSaved: { + firstName: '', + lastName: '', + taskDefinitionId: -1, + }, + taskDefinitionsCompletedPersonIdList: {}, // This is a dictionary key: taskDefinitionId, value: list of personIds who have completed the TaskDefinition + taskGroupCompletedByPersonList: {}, // This is a dictionary key: taskGroupId, value: list of personIds who have completed the TaskGroup + searchResults: [], + }; +} + +// This is called after making this fetchData request: +// const taskStatusListRetrieveResults = useFetchData(['task-status-list-retrieve'], { personIdList: personIdsList }); +export function TaskStatusListRetrieveDataCapture ( + incomingRetrieveResults = {}, + apiDataCache = {}, + dispatch, +) { + const { data, isSuccess } = incomingRetrieveResults; + const allTaskDefinitionsCache = apiDataCache.allTaskDefinitionsCache || {}; + const allTaskDependenciesCache = apiDataCache.allTaskDependenciesCache || {}; + const allTaskGroupsCache = apiDataCache.allTaskGroupsCache || {}; + const allTasksCache = apiDataCache.allTasksCache || {}; + const changeResults = { + allTaskDefinitionsCache, + allTaskDefinitionsCacheChanged: false, + allTaskDependenciesCache, + allTaskDependenciesCacheChanged: false, + allTaskGroupsCache, + allTaskGroupsCacheChanged: false, + allTasksCache, + allTasksCacheChanged: false, + }; + const allTaskDefinitionsCacheNew = { ...allTaskDefinitionsCache }; + // const allTaskDependenciesCacheNew = { ...allTaskDependenciesCache }; + const allTaskGroupsCacheNew = { ...allTaskGroupsCache }; + const allTasksCacheNew = { ...allTasksCache }; + let newTaskDefinitionListDataReceived = false; + if (data && data.taskDefinitionList && isSuccess === true) { + data.taskDefinitionList.forEach((taskDefinition) => { + if (taskDefinition && taskDefinition.taskDefinitionId && taskDefinition.taskDefinitionId >= 0) { + if (!allTaskDefinitionsCacheNew[taskDefinition.taskDefinitionId]) { + allTaskDefinitionsCacheNew[taskDefinition.taskDefinitionId] = taskDefinition; + newTaskDefinitionListDataReceived = true; + } else if (!isEqual(taskDefinition, allTaskDefinitionsCacheNew[taskDefinition.taskDefinitionId])) { + allTaskDefinitionsCacheNew[taskDefinition.taskDefinitionId] = taskDefinition; + newTaskDefinitionListDataReceived = true; + } + } + }); + } + // let newTaskDependenciesListDataReceived = false; + // TODO TaskDependencies API processing when data available + let newTaskGroupListDataReceived = false; + if (data && data.taskGroupList && isSuccess === true) { + data.taskGroupList.forEach((taskGroup) => { + if (taskGroup && taskGroup.taskGroupId && taskGroup.taskGroupId >= 0) { + if (!allTaskGroupsCacheNew[taskGroup.taskGroupId]) { + allTaskGroupsCacheNew[taskGroup.taskGroupId] = taskGroup; + newTaskGroupListDataReceived = true; + } else if (!isEqual(taskGroup, allTaskGroupsCacheNew[taskGroup.taskGroupId])) { + allTaskGroupsCacheNew[taskGroup.taskGroupId] = taskGroup; + newTaskGroupListDataReceived = true; + } + } + }); + } + let newTaskListDataReceived = false; + if (data && data.taskList && isSuccess === true) { + data.taskList.forEach((task) => { + if (task && task.personId && task.personId >= 0 && task.taskDefinitionId && task.taskDefinitionId >= 0) { + if (!allTasksCacheNew[task.personId]) { + allTasksCacheNew[task.personId] = {}; + } + if (!allTasksCacheNew[task.personId][task.taskDefinitionId]) { + allTasksCacheNew[task.personId][task.taskDefinitionId] = task; + newTaskListDataReceived = true; + } else if (!isEqual(task, allTasksCacheNew[task.personId][task.taskDefinitionId])) { + allTasksCacheNew[task.personId][task.taskDefinitionId] = task; + newTaskListDataReceived = true; + } + } + }); + if (newTaskDefinitionListDataReceived) { + // console.log('TaskStatusListRetrieve setting allTaskDefinitionsCacheNew:', allTaskDefinitionsCacheNew); + dispatch({ type: 'updateByKeyValue', key: 'allTaskDefinitionsCache', value: allTaskDefinitionsCacheNew }); + changeResults.allTaskDefinitionsCache = allTaskDefinitionsCacheNew; + changeResults.allTaskDefinitionsCacheChanged = true; + } + // if (newTaskDependenciesListDataReceived) { + // // console.log('TaskStatusListRetrieve setting allTaskDependenciesCacheNew:', allTaskDependenciesCacheNew); + // dispatch({ type: 'updateByKeyValue', key: 'allTaskDependenciesCache', value: allTaskDependenciesCacheNew }); + // changeResults.allTaskDependenciesCache = allTaskDependenciesCacheNew; + // changeResults.allTaskDependenciesCacheChanged = true; + // } + if (newTaskListDataReceived) { + // console.log('TaskStatusListRetrieve setting allTasksCacheNew:', allTasksCacheNew); + dispatch({ type: 'updateByKeyValue', key: 'allTasksCache', value: allTasksCacheNew }); + changeResults.allTasksCache = allTasksCacheNew; + changeResults.allTasksCacheChanged = true; + } + if (newTaskGroupListDataReceived) { + // console.log('TaskStatusListRetrieve setting allTaskGroupsCacheNew:', allTaskGroupsCacheNew); + dispatch({ type: 'updateByKeyValue', key: 'allTaskGroupsCache', value: allTaskGroupsCacheNew }); + changeResults.allTaskGroupsCache = allTaskGroupsCacheNew; + changeResults.allTaskGroupsCacheChanged = true; + } + } + return changeResults; +} + +// TODO Update to task-definition-save +// export function TaskDefinitionSave () { +// // Transferred from react-query/mutation.jsx to test a new approach +// const { getAppContextValue, setAppContextValue } = useConnectAppContext(); +// const queryClient = useQueryClient(); +// +// // We want to add to onSuccess below a function that stores in the Context the person data which was stored on the API server +// return useMutation({ +// mutationFn: (params) => weConnectQueryFn('person-save', params), +// onError: (error) => console.log('error in personSaveMutation: ', error), +// onSuccess: (results) => { +// // Update the cached people with the new/changed person data, stored in allPeopleCache +// // console.log('person-save onSuccess true, results: ', results); +// const allPeopleCache = getAppContextValue('allPeopleCache'); +// if (results.personId >= 0) { +// allPeopleCache[results.personId] = results; +// setAppContextValue('allPeopleCache', allPeopleCache); +// } +// // And now invalidate other queries that pulled in this data +// queryClient.invalidateQueries('person-list-retrieve'); +// queryClient.invalidateQueries('team-list-retrieve'); +// }, +// }); +// } diff --git a/src/js/models/TeamModel.jsx b/src/js/models/TeamModel.jsx new file mode 100644 index 0000000..fec1b46 --- /dev/null +++ b/src/js/models/TeamModel.jsx @@ -0,0 +1,160 @@ +import { useMemo } from 'react'; +import isEqual from 'lodash-es/isEqual'; +import { useMutation, useQueryClient } from '@tanstack/react-query'; +import weConnectQueryFn from '../react-query/WeConnectQuery'; +import { useConnectAppContext } from '../contexts/ConnectAppContext'; + +// These are the "AppContextValues" (i.e., global state variables) used in the TeamModel +export function getInitialGlobalTeamVariables () { + return { + allTeamsCache: {}, // This is a dictionary key: teamId, value: team dict + allTeamMembersCache: {}, // This is a dictionary key: teamId, value: list of personIds in the team + mostRecentTeamIdSaved: -1, + mostRecentTeamMemberIdSaved: -1, + mostRecentTeamSaved: { + teamName: '', + teamId: '', + }, + }; +} + +export const useGetTeamById = (teamId) => { + const { apiDataCache } = useConnectAppContext(); + const { allTeamsCache } = apiDataCache; + // console.log('useGetTeamById teamId:', teamId, ', allTeamsCache:', allTeamsCache); + if (allTeamsCache) { + return allTeamsCache[teamId] || {}; + } else { + return {}; + } +}; + +export const GetTeamMembersListByTeamId = (teamId, apiDataCache) => { + const { allPeopleCache, allTeamMembersCache } = apiDataCache; + if (!allTeamMembersCache || !allTeamMembersCache[teamId]) { + return []; + } + const personIds = allTeamMembersCache[teamId]; + return personIds.map((personId) => allPeopleCache[personId] || null); +}; + +export const useGetTeamMembersListByTeamId = (teamId) => { + const { apiDataCache } = useConnectAppContext(); + const { allPeopleCache, allTeamMembersCache } = apiDataCache; + return useMemo(() => { + if (!allTeamMembersCache || !allTeamMembersCache[teamId]) { + return []; + } + const personIds = allTeamMembersCache[teamId]; + return personIds.map((personId) => allPeopleCache[personId] || null); + }, [allTeamMembersCache, teamId]); +}; + +// This is called following: +// const teamListRetrieveResults = useFetchData(['team-list-retrieve'], {}); +export function TeamListRetrieveDataCapture ( + incomingRetrieveResults = {}, + apiDataCache = {}, + dispatch, +) { + const { data, isSuccess } = incomingRetrieveResults; + const allTeamMembersCache = apiDataCache.allTeamMembersCache || {}; + const allTeamsCache = apiDataCache.allTeamsCache || {}; + // console.log('TeamListRetrieve data: ', data, ', isFetching:', isFetching, ', isSuccess:', isSuccess); + const changeResults = { + allTeamMembersCache, + allTeamMembersCacheChanged: false, + allTeamsCache, + allTeamsCacheChanged: false, + }; + const allTeamMembersCacheNew = { ...allTeamMembersCache }; + const allTeamsCacheNew = { ...allTeamsCache }; + if (data && data.teamList && isSuccess === true) { + let newTeamDataReceived = false; + let teamTrimmed; + let newTeamMemberDataReceived = false; + let teamMemberListOfPersonIdsAtStart = []; + + data.teamList.forEach((team) => { + if (team && team.teamId && team.teamId >= 0) { + teamTrimmed = { ...team }; + delete teamTrimmed.teamMemberList; + if (!allTeamsCacheNew[teamTrimmed.teamId]) { + allTeamsCacheNew[teamTrimmed.teamId] = teamTrimmed; + newTeamDataReceived = true; + } else if (!isEqual(teamTrimmed, allTeamsCacheNew[teamTrimmed.teamId])) { + allTeamsCacheNew[teamTrimmed.teamId] = teamTrimmed; + newTeamDataReceived = true; + } + } + if (team && team.teamMemberList) { + if (!allTeamMembersCacheNew[team.teamId]) { + allTeamMembersCacheNew[team.teamId] = []; + } + // Reset this list, so we can see if any former team members have been removed + teamMemberListOfPersonIdsAtStart = [...allTeamMembersCacheNew[team.teamId]]; + team.teamMemberList.forEach((person) => { + if (person && person.personId && person.personId >= 0) { + // Capture which team this person is in + if (!allTeamMembersCacheNew[team.teamId].includes(person.personId)) { + allTeamMembersCacheNew[team.teamId].push(person.personId); + newTeamMemberDataReceived = true; + } + // Remove the person from the list of team members in the cache so we know if anyone has been removed + if (teamMemberListOfPersonIdsAtStart.includes(person.personId)) { + try { + const index = teamMemberListOfPersonIdsAtStart.indexOf(person.personId); + teamMemberListOfPersonIdsAtStart.splice(index, 1); + } catch (error) { + console.error('Error removing team member from teamMemberListOfPersonIdsAtStart:', error); + } + } + } + }); + if (teamMemberListOfPersonIdsAtStart.length > 0) { + // We need to remove these people from the cache as they have been removed from the team + // console.log('+++ team members leftover in teamMemberListOfPersonIdsAtStart'); + allTeamMembersCacheNew[team.teamId] = allTeamMembersCacheNew[team.teamId].filter( + (personId) => !teamMemberListOfPersonIdsAtStart.includes(personId), + ); + newTeamMemberDataReceived = true; + } + } + if (newTeamMemberDataReceived) { + dispatch({ type: 'updateByKeyValue', key: 'allTeamMembersCache', value: allTeamMembersCacheNew }); + changeResults.allTeamMembersCache = allTeamMembersCacheNew; + changeResults.allTeamMembersCacheChanged = true; + } + if (newTeamDataReceived) { + dispatch({ type: 'updateByKeyValue', key: 'allTeamsCache', value: allTeamsCacheNew }); + changeResults.allTeamsCache = allTeamsCacheNew; + changeResults.allTeamsCacheChanged = true; + } + }); + } + return changeResults; +} + +export const useRemoveTeamMemberMutation = () => { + const queryClient = useQueryClient(); + return useMutation({ + mutationFn: (params) => weConnectQueryFn('remove-person-from-team', params), + networkMode: 'always', // Send queries to the server even if the cache has the data + onError: (error) => { + console.log('onError in useRemoveTeamMemberMutation: ', error); + queryClient.refetchQueries({ queryKey: ['team-list-retrieve'], refetchType: 'active', exact: true, force: true }) + .then(() => console.log('TeamModel team-list-retrieve API call error recovery refetch completed')) + .catch((error2) => console.error('TeamModel team-list-retrieve API call refetch failed:', error2)); + }, + onSuccess: (results) => { + // console.log('team-list-retrieve onSuccess true, results: ', results); + if (results.success === false) { + console.log('useRemoveTeamMemberMutation onSuccess failed results:', results); + } else { + queryClient.refetchQueries({ queryKey: ['team-list-retrieve'], refetchType: 'active', exact: true, force: true }) + .then(() => console.log('TeamModel team-list-retrieve refetch completed')) + .catch((error) => console.error('TeamModel team-list-retrieve refetch failed:', error)); + } + }, + }); +}; diff --git a/src/js/pages/QuestionnaireAnswers.jsx b/src/js/pages/QuestionnaireAnswers.jsx index e54b4f5..cf70ddf 100644 --- a/src/js/pages/QuestionnaireAnswers.jsx +++ b/src/js/pages/QuestionnaireAnswers.jsx @@ -9,8 +9,9 @@ import DesignTokenColors from '../common/components/Style/DesignTokenColors'; import { renderLog } from '../common/utils/logging'; import { PageContentContainer } from '../components/Style/pageLayoutStyles'; import webAppConfig from '../config'; -import useGetFullNamePreferred from '../react-query/useGetFullNamePreferred'; +// import useGetFullNamePreferred from '../react-query/useGetFullNamePreferred'; import { useFetchData } from '../react-query/WeConnectQuery'; +import { useGetFullNamePreferred } from '../models/PersonModel'; // eslint-disable-next-line no-unused-vars @@ -53,8 +54,8 @@ const QuestionnaireAnswers = ({ classes, match }) => { /* eslint-disable arrow-body-style */ // eslint-disable-next-line no-unused-vars const getAnswerValue = (questionId) => { - // if (allCachedAnswersDict && allCachedAnswersDict[questionId]) { - // const questionAnswer = allCachedAnswersDict[questionId]; + // if (allAnswersCache && allAnswersCache[questionId]) { + // const questionAnswer = allAnswersCache[questionId]; // return getAnswerValueFromAnswerDict(questionAnswer); // } return ''; @@ -79,7 +80,8 @@ const QuestionnaireAnswers = ({ classes, match }) => { Answered by: {' '} - {useGetFullNamePreferred(person)} + {/* {useGetFullNamePreferred(person)} */} + {person ? useGetFullNamePreferred(person.personId) : 'tbd'} {questionList && questionList.map((question) => ( diff --git a/src/js/pages/Tasks.jsx b/src/js/pages/Tasks.jsx index 6ecc100..02cfc1b 100644 --- a/src/js/pages/Tasks.jsx +++ b/src/js/pages/Tasks.jsx @@ -1,4 +1,3 @@ -import { CircularProgress } from '@mui/material'; import { withStyles } from '@mui/styles'; import PropTypes from 'prop-types'; import React, { useEffect, useState } from 'react'; @@ -11,44 +10,72 @@ import { SpanWithLinkStyle } from '../components/Style/linkStyles'; import { PageContentContainer } from '../components/Style/pageLayoutStyles'; import TaskListForPerson from '../components/Task/TaskListForPerson'; import webAppConfig from '../config'; +import { useConnectAppContext, useConnectDispatch } from '../contexts/ConnectAppContext'; +import { TaskStatusListRetrieveDataCapture } from '../models/TaskModel'; +import { TeamListRetrieveDataCapture } from '../models/TeamModel'; import { useFetchData } from '../react-query/WeConnectQuery'; // eslint-disable-next-line no-unused-vars const Tasks = ({ classes, match }) => { renderLog('Tasks'); // Set LOG_RENDER_EVENTS to log all renders + const { apiDataCache } = useConnectAppContext(); + const { allPeopleCache, allTaskDefinitionsCache, allTasksCache } = apiDataCache; + const dispatch = useConnectDispatch(); const [showCompletedTasks, setShowCompletedTasks] = useState(false); - const [taskList, setTaskList] = useState(undefined); - const [taskDefinitionList, setTaskDefinitionList] = useState(undefined); - const [allStaffList, setAllStaffList] = useState([]); - const [isFetching, setIsFetching] = useState([false]); - const [personIdsList, setPersonIdsList] = useState(); + const [taskListByPersonId, setTaskListByPersonId] = useState({}); + const [taskDefinitionList, setTaskDefinitionList] = useState([]); + const [selectedPersonList, setSelectedPersonList] = useState([]); + const [personIdsList, setPersonIdsList] = useState([]); - // Roughly equivalent to PersonStore.getAllCachedPeopleList(); and TaskActions.taskStatusListRetrieve(); - const { data: dataPerson, isSuccess: isSuccessPerson, isFetching: isFetchingPerson } = useFetchData(['person-list-retrieve'], {}); + const taskStatusListRetrieveResults = useFetchData(['task-status-list-retrieve'], { personIdList: personIdsList }); useEffect(() => { - if (dataPerson) { - setPersonIdsList(dataPerson.personList.map((dataPersonObj) => dataPersonObj.id)); - setAllStaffList(dataPerson.personList); + if (taskStatusListRetrieveResults) { + // const changeResults = + TaskStatusListRetrieveDataCapture(taskStatusListRetrieveResults, apiDataCache, dispatch); + // console.log('Tasks useEffect changeResults:', changeResults); } - }, [dataPerson, isSuccessPerson]); + }, [personIdsList, taskStatusListRetrieveResults]); - const { data: dataTask, isSuccess: isSuccessTask, isFetching: isFetchingTask } = useFetchData(['task-status-list-retrieve'], { personIdList: personIdsList }); useEffect(() => { - console.log('useFetchData in Tasks (person-list-retrieve) useEffect:', isSuccessPerson, isFetchingPerson, dataPerson); - console.log('useFetchData in Tasks (task-status-list-retrieve) useEffect:', isSuccessTask, isFetchingTask, dataTask); - setIsFetching(isFetchingTask || isFetchingPerson); - if (isSuccessPerson && isSuccessTask) { - setTaskDefinitionList(dataTask.taskDefinitionList); - setTaskList(dataTask.taskList); + // console.log('Tasks useEffect allTaskDefinitionsCache:', allTaskDefinitionsCache); + if (allTaskDefinitionsCache) { + setTaskDefinitionList(Object.values(allTaskDefinitionsCache)); } - }, [personIdsList, dataTask, isSuccessPerson, isSuccessTask]); + }, [allTaskDefinitionsCache]); + + const teamListRetrieveResults = useFetchData(['team-list-retrieve'], {}); + useEffect(() => { + // console.log('useFetchData team-list-retrieve in Teams useEffect:', teamListRetrieveResults); + if (teamListRetrieveResults) { + // console.log('In useEffect apiDataCache:', apiDataCache); + // const changeResults = + TeamListRetrieveDataCapture(teamListRetrieveResults, apiDataCache, dispatch); + // console.log('Teams useEffect changeResults:', changeResults); + } + }, [teamListRetrieveResults]); + + useEffect(() => { + // console.log('Tasks useEffect allPeopleCache:', allPeopleCache); + if (allPeopleCache) { + const allCachedPeopleList = Object.values(allPeopleCache); + setPersonIdsList(allCachedPeopleList.map((person) => person.personId)); + setSelectedPersonList(allCachedPeopleList); + } + }, [allPeopleCache]); + + useEffect(() => { + const taskListByPersonIdTemp = {}; + if (allTasksCache) { + Object.entries(allTasksCache).forEach(([personIdTemp, taskDictByDefinitionId]) => { + taskListByPersonIdTemp[personIdTemp] = Object.values(taskDictByDefinitionId); + }); + } + setTaskListByPersonId(taskListByPersonIdTemp); + // console.log('=== taskListByPersonIdTemp:', taskListByPersonIdTemp); + }, [allTasksCache]); - if (taskDefinitionList) { - const test = taskDefinitionList.filter((taskDefEntry) => taskDefEntry.personId === 1); - console.log(test); - } const teamId = 0; // hack 1/15/25 return (
@@ -58,7 +85,7 @@ const Tasks = ({ classes, match }) => { {' '} {webAppConfig.NAME_FOR_BROWSER_TAB_TITLE} - {/* Executing a link to a full url restarts the session, */} + {/* Executing a link to a full url restarts the session, */} {/* Latest Helmet wont take a link or Link, Home */} {/* browser.js:38 Uncaught Invariant Violation: Only elements types base, body, head, html, link, meta, noscript, script, style, title, Symbol(react.fragment) are allowed. Helmet does not support rendering <[object Object]> elements. Refer to our API for more information. */} @@ -72,19 +99,14 @@ const Tasks = ({ classes, match }) => { )}
- {isFetching && ( -
- -
- )} - {taskList && allStaffList.map((person) => ( + {taskListByPersonId && selectedPersonList.map((person) => ( taskEntry.personId === person.personId)} + taskListForPersonId={taskListByPersonId[person.personId] || []} /> ))} diff --git a/src/js/pages/TeamHome.jsx b/src/js/pages/TeamHome.jsx index 2eb6edb..7e7495b 100644 --- a/src/js/pages/TeamHome.jsx +++ b/src/js/pages/TeamHome.jsx @@ -9,35 +9,56 @@ import { PageContentContainer } from '../components/Style/pageLayoutStyles'; import TeamHeader from '../components/Team/TeamHeader'; import TeamMemberList from '../components/Team/TeamMemberList'; import webAppConfig from '../config'; -import { useConnectAppContext } from '../contexts/ConnectAppContext'; -import { getTeamList } from '../react-query/TeamsQueryProcessing'; +import { useConnectAppContext, useConnectDispatch } from '../contexts/ConnectAppContext'; +import { TeamListRetrieveDataCapture, useGetTeamById } from '../models/TeamModel'; import { useFetchData } from '../react-query/WeConnectQuery'; +import convertToInteger from '../common/utils/convertToInteger'; const TeamHome = ({ classes }) => { renderLog('TeamHome'); - const { setAppContextValue } = useConnectAppContext(); + const { apiDataCache, setAppContextValue } = useConnectAppContext(); + const dispatch = useConnectDispatch(); const params = useParams(); - const [team, setTeam] = useState({}); - const [teamId] = useState(params.teamId); + const [team, setTeam] = useState(useGetTeamById(convertToInteger(params.teamId))); + const [teamId] = useState(convertToInteger(params.teamId)); const updateTeam = (tList) => { const oneTeam = tList.find((staff) => staff.teamId === parseInt(teamId)); setTeam(oneTeam); }; - const isAddPersonDrawerOpen = document.getElementById('addPersonDrawer'); - const { data, isSuccess, isFetching } = useFetchData(['team-list-retrieve'], {}); + // const isAddPersonDrawerOpen = document.getElementById('addPersonDrawer'); + + const teamListRetrieveResults = useFetchData(['team-list-retrieve'], {}); + useEffect(() => { + // console.log('useFetchData team-list-retrieve in TeamHome useEffect:', teamListRetrieveResults); + if (teamListRetrieveResults) { + // console.log('In useEffect apiDataCache:', apiDataCache); + // const changeResults = + TeamListRetrieveDataCapture(teamListRetrieveResults, apiDataCache, dispatch); + // console.log('Teams useEffect changeResults:', changeResults); + } + }, [teamListRetrieveResults]); + + // useEffect(() => { + // // console.log('In useEffect apiDataCache:', apiDataCache); + // const { allTeamsCache } = apiDataCache; + // if (allTeamsCache) { + // const teamListSimple = Object.values(allTeamsCache); + // setTeamList(teamListSimple); + // } + // }, [apiDataCache]); + useEffect(() => { - console.log('useFetchData in TeamHome (team-list-retrieve) useEffect:', data, isSuccess, isFetching); - if (isSuccess) { - console.log('useFetchData in TeamHome useEffect data good:', data, isSuccess, isFetching); - const tList = getTeamList(data); - setAppContextValue('teamListNested', tList); - updateTeam(tList); + // console.log('In useEffect apiDataCache:', apiDataCache); + const { allTeamsCache } = apiDataCache; + // console.log('TeamHome teamId: ', teamId, ', allTeamsCache:', allTeamsCache); + if (allTeamsCache && teamId && allTeamsCache[teamId]) { + setTeam(allTeamsCache[teamId]); } - }, [isAddPersonDrawerOpen, data, isSuccess]); + }, [apiDataCache, teamId]); const addTeamMemberClick = () => { // console.log('TeamHome addTeamMemberClick, teamId:', teamId); @@ -55,7 +76,7 @@ const TeamHome = ({ classes }) => { {webAppConfig.NAME_FOR_BROWSER_TAB_TITLE} {/* TODO 1/12/25: The following line might be reloading the app, consider using navigate() */} - + {/* */}

{team ? team.teamName : 'none'}

@@ -68,6 +89,17 @@ const TeamHome = ({ classes }) => { {' '} team list + {(teamId && team) && ( + <> + 0)} + showIcons={false} + /> + + + )} - 0)} showIcons={false} /> -
); diff --git a/src/js/pages/Teams.jsx b/src/js/pages/Teams.jsx index 315b0bd..bc15a3f 100644 --- a/src/js/pages/Teams.jsx +++ b/src/js/pages/Teams.jsx @@ -11,35 +11,40 @@ import { PageContentContainer } from '../components/Style/pageLayoutStyles'; import TeamHeader from '../components/Team/TeamHeader'; import TeamMemberList from '../components/Team/TeamMemberList'; import webAppConfig from '../config'; -import { useConnectAppContext } from '../contexts/ConnectAppContext'; -import { getTeamList } from '../react-query/TeamsQueryProcessing'; +import { useConnectAppContext, useConnectDispatch } from '../contexts/ConnectAppContext'; +import { TeamListRetrieveDataCapture } from '../models/TeamModel'; import { useFetchData } from '../react-query/WeConnectQuery'; // eslint-disable-next-line no-unused-vars const Teams = ({ classes, match }) => { renderLog('Teams'); - const { setAppContextValue, getAppContextValue } = useConnectAppContext(); + const { apiDataCache, setAppContextValue, getAppContextValue } = useConnectAppContext(); + const { allPeopleCache, allTeamsCache } = apiDataCache; + const dispatch = useConnectDispatch(); - const [showAllTeamMembers, setShowAllTeamMembers] = useState(false); + const [showAllTeamMembers, setShowAllTeamMembers] = useState(true); const [teamList, setTeamList] = useState([]); - const { data, isSuccess, isFetching, isStale } = useFetchData(['team-list-retrieve'], {}); - console.log('useFetchData in Teams:', data, isSuccess, isFetching, isStale); - if (isFetching) { - console.log('isFetching ------------'); - } + const teamListRetrieveResults = useFetchData(['team-list-retrieve'], {}); + useEffect(() => { + // console.log('useFetchData team-list-retrieve in Teams useEffect:', teamListRetrieveResults); + if (teamListRetrieveResults) { + // console.log('In useEffect apiDataCache:', apiDataCache); + // TODO Consider making this useTeamListRetrieveDataCapture so we don't have to pass in the apiDataCache or dispatch + // const changeResults = + TeamListRetrieveDataCapture(teamListRetrieveResults, apiDataCache, dispatch); + // console.log('Teams useEffect changeResults:', changeResults); + } + }, [teamListRetrieveResults]); + useEffect(() => { - console.log('useFetchData in Teams useEffect:', data, isSuccess, isFetching, isStale); - if (data !== undefined && isFetching === false && isStale === false) { - console.log('useFetchData in Teams useEffect data is good:', data, isSuccess, isFetching, isStale); - console.log('Successfully retrieved teams...'); - const teamListTemp = getTeamList(data); - setShowAllTeamMembers(true); - setTeamList(teamListTemp); - setAppContextValue('teamListNested', teamListTemp); + // console.log('In useEffect apiDataCache:', apiDataCache); + if (allTeamsCache) { + const teamListSimple = Object.values(allTeamsCache); + setTeamList(teamListSimple); } - }, [data]); + }, [allPeopleCache, allTeamsCache]); const addTeamClick = () => { setAppContextValue('addTeamDrawerOpen', true); @@ -48,8 +53,8 @@ const Teams = ({ classes, match }) => { const personProfile = getAppContextValue('personProfileDrawerOpen'); if (personProfile === undefined) { - setAppContextValue('personProfileDrawerOpen', false); - setAppContextValue('addTeamDrawerOpen', false); + // setAppContextValue('personProfileDrawerOpen', false); + // setAppContextValue('addTeamDrawerOpen', false); } return ( @@ -74,6 +79,19 @@ const Teams = ({ classes, match }) => { setShowAllTeamMembers(true)}>show people )} + {teamList.map((team, index) => ( + + 0)} + showIcons + /> + {showAllTeamMembers && ( + + )} + + ))} - {teamList.map((team, index) => ( - - 0)} showIcons /> - {showAllTeamMembers && ( - - )} - - ))}
Sign in diff --git a/src/js/react-query/PersonQueryProcessing.js b/src/js/react-query/PersonQueryProcessing.js deleted file mode 100644 index 1609973..0000000 --- a/src/js/react-query/PersonQueryProcessing.js +++ /dev/null @@ -1,32 +0,0 @@ -export const personListRetrieve = (data, teamId) => { - const personListRaw = data.personList; - - const personList = []; - let personFiltered; - let personRaw; - for (let i = 0; i < personListRaw.length; i++) { - console.log('teamId: ', teamId); - personRaw = personListRaw[i]; - personFiltered = personRaw; - personList.push(personFiltered); - } - return personList; -}; - -export const getFullNamePreferred = (personMember) => { - let fullName = ''; - if (personMember.id >= 0) { - if (personMember.firstNamePreferred) { - fullName += personMember.firstNamePreferred; - } else if (personMember.firstName) { - fullName += personMember.firstName; - } - if (fullName.length > 0 && personMember.lastName) { - fullName += ' '; - } - if (personMember.lastName) { - fullName += personMember.lastName; - } - } - return fullName; -}; diff --git a/src/js/react-query/WeConnectQuery.js b/src/js/react-query/WeConnectQuery.js index 1637c77..decbc14 100644 --- a/src/js/react-query/WeConnectQuery.js +++ b/src/js/react-query/WeConnectQuery.js @@ -6,10 +6,10 @@ import webAppConfig from '../config'; // https://refine.dev/blog/react-query-guide/#performing-basic-data-fetching // Define a default query function that will receive the query key const weConnectQueryFn = async (queryKey, params) => { - console.log('weConnectQueryFn params: ', params); + // console.log('weConnectQueryFn params: ', params); const url = new URL(`${queryKey}/`, webAppConfig.STAFF_API_SERVER_API_ROOT_URL); url.search = new URLSearchParams(params); - console.log('weConnectQueryFn ZZZ url.href: ', url.href); + // console.log('weConnectQueryFn ZZZ url.href: ', url.href); const response = await axios.get(url.href); // console.log('weConnectQueryFn response.data: ', JSON.stringify(response.data)); @@ -22,6 +22,7 @@ const useFetchData = (queryKey, fetchParams) => { const { data, isSuccess, isFetching, isStale, refetch, error } = useQuery({ queryKey, queryFn: () => weConnectQueryFn(queryKey, fetchParams), + networkMode: 'always', // We can back this off once we achieve MVP version 1 }); if (error) { console.log(`An error occurred with ${queryKey}: ${error.message}`); diff --git a/src/js/react-query/mutations.jsx b/src/js/react-query/mutations.jsx index 73c8878..5695e39 100644 --- a/src/js/react-query/mutations.jsx +++ b/src/js/react-query/mutations.jsx @@ -10,6 +10,7 @@ const useRemoveTeamMutation = () => { }); }; +// Moved to TeamModel.jsx const useRemoveTeamMemberMutation = () => { const queryClient = useQueryClient(); return useMutation({ @@ -72,6 +73,7 @@ const useGroupSaveMutation = () => { }); }; +// Moved to /models/PersonModel.jsx const usePersonSaveMutation = () => { const queryClient = useQueryClient(); @@ -94,7 +96,7 @@ const useSaveTaskMutation = () => { -export { useRemoveTeamMutation, useRemoveTeamMemberMutation, useAddPersonToTeamMutation, +export { useRemoveTeamMutation, useRemoveTeamMemberMutation, useAddPersonToTeamMutation, useQuestionnaireSaveMutation, useTaskDefinitionSaveMutation, useGroupSaveMutation, useQuestionSaveMutation, usePersonSaveMutation, useSaveTaskMutation, useQuestionnaireAnswersSaveMutation }; diff --git a/src/js/react-query/useGetFullNamePreferred.js b/src/js/react-query/useGetFullNamePreferredReactQuery.js similarity index 90% rename from src/js/react-query/useGetFullNamePreferred.js rename to src/js/react-query/useGetFullNamePreferredReactQuery.js index f648e54..da219fe 100644 --- a/src/js/react-query/useGetFullNamePreferred.js +++ b/src/js/react-query/useGetFullNamePreferredReactQuery.js @@ -2,7 +2,7 @@ import { useState } from 'react'; import { useConnectAppContext } from '../contexts/ConnectAppContext'; // When the function name starts with 'use' React treats it as a custom hook, and it can then access Context variables -const useGetFullNamePreferred = (person) => { +const useGetFullNamePreferredReactQuery = (person) => { const { getAppContextValue } = useConnectAppContext(); const [allStaffList] = useState(getAppContextValue('allStaffList')); const [personId] = Object.values(person); // This is silly, but this is a proof of concept @@ -24,4 +24,4 @@ const useGetFullNamePreferred = (person) => { return fullName; }; -export default useGetFullNamePreferred; +export default useGetFullNamePreferredReactQuery; diff --git a/src/js/stores/PersonStore.js b/src/js/stores/PersonStore.js index d32d29d..b4dff90 100644 --- a/src/js/stores/PersonStore.js +++ b/src/js/stores/PersonStore.js @@ -6,7 +6,7 @@ import arrayContains from '../common/utils/arrayContains'; class PersonStore extends ReduceStore { getInitialState () { return { - allCachedPeopleDict: {}, // This is a dictionary key: personId, value: person dict + allPeopleCache: {}, // This is a dictionary key: personId, value: person dict mostRecentPersonIdSaved: -1, mostRecentPersonSaved: { firstName: '', @@ -18,8 +18,8 @@ class PersonStore extends ReduceStore { } getAllCachedPeopleList () { - const { allCachedPeopleDict } = this.getState(); - const personListRaw = Object.values(allCachedPeopleDict); + const { allPeopleCache } = this.getState(); + const personListRaw = Object.values(allPeopleCache); const personList = []; let personFiltered; @@ -87,9 +87,9 @@ class PersonStore extends ReduceStore { } getPersonById (personId) { - const { allCachedPeopleDict } = this.getState(); - // console.log('PersonStore getPersonById:', personId, ', allCachedPeopleDict:', allCachedPeopleDict); - return allCachedPeopleDict[personId] || {}; + const { allPeopleCache } = this.getState(); + // console.log('PersonStore getPersonById:', personId, ', allPeopleCache:', allPeopleCache); + return allPeopleCache[personId] || {}; } getPersonDeviceId () { @@ -111,7 +111,7 @@ class PersonStore extends ReduceStore { } reduce (state, action) { - const { allCachedPeopleDict } = state; + const { allPeopleCache } = state; let personTemp = {}; let personId = -1; let revisedState = state; @@ -137,14 +137,14 @@ class PersonStore extends ReduceStore { if (action.res) { personTemp = action.res; // console.log('PersonStore add-person-to-team:', personTemp); - // Only add to allCachedPeopleDict if they aren't already in the dictionary, since the person data that comes back with this API response is partial data - if (personTemp && (personTemp.personId >= 0) && !arrayContains(personTemp.personId, allCachedPeopleDict)) { - allCachedPeopleDict[personTemp.personId] = personTemp; + // Only add to allPeopleCache if they aren't already in the dictionary, since the person data that comes back with this API response is partial data + if (personTemp && (personTemp.personId >= 0) && !arrayContains(personTemp.personId, allPeopleCache)) { + allPeopleCache[personTemp.personId] = personTemp; } - // console.log('allCachedPeopleDict:', allCachedPeopleDict); + // console.log('allPeopleCache:', allPeopleCache); revisedState = { ...revisedState, - allCachedPeopleDict, + allPeopleCache, }; } return revisedState; @@ -169,13 +169,13 @@ class PersonStore extends ReduceStore { action.res.personList.forEach((person) => { // console.log('PersonStore team-retrieve adding person:', person); if (person && (person.id >= 0)) { - allCachedPeopleDict[person.id] = person; + allPeopleCache[person.id] = person; } }); - // console.log('allCachedPeopleDict:', allCachedPeopleDict); + // console.log('allPeopleCache:', allPeopleCache); revisedState = { ...revisedState, - allCachedPeopleDict, + allPeopleCache, }; } // console.log('PersonStore revisedState:', revisedState); @@ -195,10 +195,10 @@ class PersonStore extends ReduceStore { if (personId >= 0) { // console.log('PersonStore person-save personId:', personId); - allCachedPeopleDict[personId] = action.res; + allPeopleCache[personId] = action.res; revisedState = { ...revisedState, - allCachedPeopleDict, + allPeopleCache, }; } else { console.log('PersonStore person-retrieve MISSING personId:', personId); @@ -219,10 +219,10 @@ class PersonStore extends ReduceStore { if (personId >= 0) { // console.log('PersonStore person-save personId:', personId); - allCachedPeopleDict[personId] = action.res; + allPeopleCache[personId] = action.res; revisedState = { ...revisedState, - allCachedPeopleDict, + allPeopleCache, mostRecentPersonIdSaved: personId, }; } else { @@ -243,8 +243,8 @@ class PersonStore extends ReduceStore { teamMemberList = team.teamMemberList || []; teamMemberList.forEach((person) => { // console.log('PersonStore team-retrieve adding person:', person); - if (person && (person.id >= 0) && !arrayContains(person.id, allCachedPeopleDict)) { - allCachedPeopleDict[person.id] = person; + if (person && (person.id >= 0) && !arrayContains(person.id, allPeopleCache)) { + allPeopleCache[person.id] = person; } }); } @@ -253,7 +253,7 @@ class PersonStore extends ReduceStore { revisedState = { ...revisedState, - allCachedPeopleDict, + allPeopleCache, }; return revisedState; @@ -270,19 +270,19 @@ class PersonStore extends ReduceStore { teamId = -1; } - // console.log('PersonStore ', action.type, ' start allCachedPeopleDict:', allCachedPeopleDict); + // console.log('PersonStore ', action.type, ' start allPeopleCache:', allPeopleCache); if (teamId >= 0 && action.res.teamMemberList) { teamMemberList = action.res.teamMemberList || []; teamMemberList.forEach((person) => { // console.log('PersonStore team-retrieve adding person:', person); - if (person && (person.id >= 0) && !arrayContains(person.id, allCachedPeopleDict)) { - allCachedPeopleDict[person.id] = person; + if (person && (person.id >= 0) && !arrayContains(person.id, allPeopleCache)) { + allPeopleCache[person.id] = person; } }); - // console.log('allCachedPeopleDict:', allCachedPeopleDict); + // console.log('allPeopleCache:', allPeopleCache); revisedState = { ...revisedState, - allCachedPeopleDict, + allPeopleCache, }; } return revisedState; diff --git a/src/js/stores/QuestionnaireStore.js b/src/js/stores/QuestionnaireStore.js index 874f207..9d17753 100644 --- a/src/js/stores/QuestionnaireStore.js +++ b/src/js/stores/QuestionnaireStore.js @@ -5,9 +5,9 @@ import arrayContains from '../common/utils/arrayContains'; class QuestionnaireStore extends ReduceStore { getInitialState () { return { - allCachedQuestionnairesDict: {}, // This is a dictionary key: questionnaireId, value: questionnaire dict - allCachedQuestionsDict: {}, // This is a dictionary key: questionId, value: question dict - allCachedAnswersDict: {}, // This is a dictionary key: personId, value: another dictionary key: questionId, value: answer dict + allQuestionnairesCache: {}, // This is a dictionary key: questionnaireId, value: questionnaire dict + allQuestionsCache: {}, // This is a dictionary key: questionId, value: question dict + allAnswersCache: {}, // This is a dictionary key: personId, value: another dictionary key: questionId, value: answer dict dateQuestionnaireCompletedDict: {}, // This is a dictionary key: personId, value: another dictionary key: questionnaireId, value: dateQuestionnaireCompleted mostRecentQuestionIdSaved: -1, mostRecentQuestionSaved: { @@ -28,16 +28,16 @@ class QuestionnaireStore extends ReduceStore { getAllCachedAnswersDictByPersonId (personId) { // This lets us know when the person answered the questionnaire - const { allCachedAnswersDict } = this.getState(); - if (allCachedAnswersDict[personId]) { - return allCachedAnswersDict[personId]; + const { allAnswersCache } = this.getState(); + if (allAnswersCache[personId]) { + return allAnswersCache[personId]; } return {}; } getAllCachedQuestionnairesList () { - const { allCachedQuestionnairesDict } = this.getState(); - const questionnaireListRaw = Object.values(allCachedQuestionnairesDict); + const { allQuestionnairesCache } = this.getState(); + const questionnaireListRaw = Object.values(allQuestionnairesCache); const questionnaireList = []; let questionnaireFiltered; @@ -84,8 +84,8 @@ class QuestionnaireStore extends ReduceStore { } getQuestionListByQuestionnaireId (questionnaireId) { - const { allCachedQuestionsDict } = this.getState(); - const questionListRaw = Object.values(allCachedQuestionsDict); + const { allQuestionsCache } = this.getState(); + const questionListRaw = Object.values(allQuestionsCache); const questionListForQuestionnaire = []; for (let i = 0; i < questionListRaw.length; i++) { if (questionListRaw[i].questionnaireId === questionnaireId) { @@ -97,20 +97,20 @@ class QuestionnaireStore extends ReduceStore { } getQuestionById (questionId) { - const { allCachedQuestionsDict } = this.getState(); - // console.log('QuestionnaireStore getQuestionById:', questionId, ', allCachedQuestionsDict:', allCachedQuestionsDict); - return allCachedQuestionsDict[questionId] || {}; + const { allQuestionsCache } = this.getState(); + // console.log('QuestionnaireStore getQuestionById:', questionId, ', allQuestionsCache:', allQuestionsCache); + return allQuestionsCache[questionId] || {}; } getQuestionnaireById (questionnaireId) { - const { allCachedQuestionnairesDict } = this.getState(); - // console.log('QuestionnaireStore getQuestionnaireById:', questionnaireId, ', allCachedQuestionnairesDict:', allCachedQuestionnairesDict); - return allCachedQuestionnairesDict[questionnaireId] || {}; + const { allQuestionnairesCache } = this.getState(); + // console.log('QuestionnaireStore getQuestionnaireById:', questionnaireId, ', allQuestionnairesCache:', allQuestionnairesCache); + return allQuestionnairesCache[questionnaireId] || {}; } getQuestionnaireListByPersonId (personId) { const { questionnairesAnsweredListByPersonId } = this.getState(); - // console.log('QuestionnaireStore getQuestionnaireById:', questionnaireId, ', allCachedQuestionnairesDict:', allCachedQuestionnairesDict); + // console.log('QuestionnaireStore getQuestionnaireById:', questionnaireId, ', allQuestionnairesCache:', allQuestionnairesCache); const questionnairesAnsweredIdList = questionnairesAnsweredListByPersonId[personId] || []; const questionnairesAnsweredListForPerson = []; for (let i = 0; i < questionnairesAnsweredIdList.length; i++) { @@ -126,7 +126,7 @@ class QuestionnaireStore extends ReduceStore { reduce (state, action) { const { - allCachedAnswersDict, allCachedQuestionsDict, allCachedQuestionnairesDict, + allAnswersCache, allQuestionsCache, allQuestionnairesCache, dateQuestionnaireCompletedDict, questionnairesAnsweredByPersonList, questionnairesAnsweredListByPersonId, questionsAnsweredPersonIdList, } = state; @@ -157,13 +157,13 @@ class QuestionnaireStore extends ReduceStore { action.res.questionList.forEach((question) => { // console.log('QuestionnaireStore question-list-retrieve adding question:', question); if (question && (question.id >= 0)) { - allCachedQuestionsDict[question.id] = question; + allQuestionsCache[question.id] = question; } }); - // console.log('allCachedQuestionsDict:', allCachedQuestionsDict); + // console.log('allQuestionsCache:', allQuestionsCache); revisedState = { ...revisedState, - allCachedQuestionsDict, + allQuestionsCache, }; } // console.log('QuestionnaireStore revisedState:', revisedState); @@ -184,10 +184,10 @@ class QuestionnaireStore extends ReduceStore { if (questionId >= 0) { if (action.res.questionCreated || action.res.questionUpdated) { // console.log('QuestionnaireStore question-save questionId:', questionId); - allCachedQuestionsDict[questionId] = action.res; + allQuestionsCache[questionId] = action.res; revisedState = { ...revisedState, - allCachedQuestionsDict, + allQuestionsCache, mostRecentQuestionIdSaved: questionId, }; } else { @@ -212,10 +212,10 @@ class QuestionnaireStore extends ReduceStore { // console.log('QuestionnaireStore questionnaire-responses-list-retrieve adding answer:', answer); if (answer && (answer.personId >= 0)) { if (answer.questionId >= 0) { - if (!allCachedAnswersDict[answer.personId]) { - allCachedAnswersDict[answer.personId] = {}; + if (!allAnswersCache[answer.personId]) { + allAnswersCache[answer.personId] = {}; } - allCachedAnswersDict[answer.personId][answer.questionId] = answer; + allAnswersCache[answer.personId][answer.questionId] = answer; // // Add personId to questionnairesAnsweredByPersonList if (!Array.isArray(questionnairesAnsweredByPersonList[answer.questionnaireId])) { @@ -259,10 +259,10 @@ class QuestionnaireStore extends ReduceStore { } } }); - // console.log('allCachedAnswersDict:', allCachedAnswersDict); + // console.log('allAnswersCache:', allAnswersCache); revisedState = { ...revisedState, - allCachedAnswersDict, + allAnswersCache, questionnairesAnsweredByPersonList, questionnairesAnsweredListByPersonId, questionsAnsweredPersonIdList, @@ -272,13 +272,13 @@ class QuestionnaireStore extends ReduceStore { action.res.questionList.forEach((question) => { // console.log('QuestionnaireStore questionnaire-responses-list-retrieve adding question:', question); if (question && (question.id >= 0)) { - allCachedQuestionsDict[question.id] = question; + allQuestionsCache[question.id] = question; } }); - // console.log('allCachedQuestionsDict:', allCachedQuestionsDict); + // console.log('allQuestionsCache:', allQuestionsCache); revisedState = { ...revisedState, - allCachedQuestionsDict, + allQuestionsCache, }; } // console.log('QuestionnaireStore questionnaire-responses-list-retrieve questionnaireList:', action.res.questionnaireList); @@ -286,13 +286,13 @@ class QuestionnaireStore extends ReduceStore { action.res.questionnaireList.forEach((questionnaire) => { // console.log('QuestionnaireStore questionnaire-responses-list-retrieve adding questionnaire:', questionnaire); if (questionnaire && (questionnaire.id >= 0)) { - allCachedQuestionnairesDict[questionnaire.id] = questionnaire; + allQuestionnairesCache[questionnaire.id] = questionnaire; } }); - // console.log('allCachedQuestionnairesDict:', allCachedQuestionnairesDict); + // console.log('allQuestionnairesCache:', allQuestionnairesCache); revisedState = { ...revisedState, - allCachedQuestionnairesDict, + allQuestionnairesCache, }; } // console.log('QuestionnaireStore revisedState:', revisedState); @@ -318,13 +318,13 @@ class QuestionnaireStore extends ReduceStore { action.res.questionnaireList.forEach((questionnaire) => { // console.log('QuestionnaireStore questionnaire-list-retrieve adding questionnaire:', questionnaire); if (questionnaire && (questionnaire.id >= 0)) { - allCachedQuestionnairesDict[questionnaire.id] = questionnaire; + allQuestionnairesCache[questionnaire.id] = questionnaire; } }); - // console.log('allCachedQuestionnairesDict:', allCachedQuestionnairesDict); + // console.log('allQuestionnairesCache:', allQuestionnairesCache); revisedState = { ...revisedState, - allCachedQuestionnairesDict, + allQuestionnairesCache, }; } // console.log('QuestionnaireStore revisedState:', revisedState); @@ -344,10 +344,10 @@ class QuestionnaireStore extends ReduceStore { if (questionnaireId >= 0) { // console.log('QuestionnaireStore questionnaire-save questionnaireId:', questionnaireId); - allCachedQuestionnairesDict[questionnaireId] = action.res; + allQuestionnairesCache[questionnaireId] = action.res; revisedState = { ...revisedState, - allCachedQuestionnairesDict, + allQuestionnairesCache, mostRecentQuestionnaireIdSaved: questionnaireId, }; } else { diff --git a/src/js/stores/TaskStore.js b/src/js/stores/TaskStore.js index 6ce9df3..c59701a 100644 --- a/src/js/stores/TaskStore.js +++ b/src/js/stores/TaskStore.js @@ -4,10 +4,10 @@ import Dispatcher from '../common/dispatcher/Dispatcher'; class TaskStore extends ReduceStore { getInitialState () { return { - allCachedTaskGroupsDict: {}, // This is a dictionary key: taskGroupId, value: TaskGroup dict - allCachedTaskDefinitionsDict: {}, // This is a dictionary key: taskDefinitionId, value: TaskDefinition dict - allCachedTaskDependenciesDict: {}, // This is a dictionary key: taskDependencyId, value: TaskDependency dict - allCachedTasksDict: {}, // This is a dictionary key: personId, value: another dictionary key: taskDefinitionId, value: Task dict + allTaskGroupsCache: {}, // This is a dictionary key: taskGroupId, value: TaskGroup dict + allTaskDefinitionsCache: {}, // This is a dictionary key: taskDefinitionId, value: TaskDefinition dict + allTaskDependenciesCache: {}, // This is a dictionary key: taskDependencyId, value: TaskDependency dict + allTasksCache: {}, // This is a dictionary key: personId, value: another dictionary key: taskDefinitionId, value: Task dict mostRecentTaskDefinitionIdSaved: -1, mostRecentTaskDefinitionSaved: { taskDefinitionId: -1, @@ -25,8 +25,8 @@ class TaskStore extends ReduceStore { } getAllCachedTaskDefinitionsList () { - const { allCachedTaskDefinitionsDict } = this.getState(); - const taskDefinitionListRaw = Object.values(allCachedTaskDefinitionsDict); + const { allTaskDefinitionsCache } = this.getState(); + const taskDefinitionListRaw = Object.values(allTaskDefinitionsCache); const taskDefinitionList = []; let taskDefinitionFiltered; @@ -41,8 +41,8 @@ class TaskStore extends ReduceStore { } getAllCachedTaskGroupList () { - const { allCachedTaskGroupsDict } = this.getState(); - const taskGroupListRaw = Object.values(allCachedTaskGroupsDict); + const { allTaskGroupsCache } = this.getState(); + const taskGroupListRaw = Object.values(allTaskGroupsCache); const taskGroupList = []; let taskGroupFiltered; @@ -70,14 +70,14 @@ class TaskStore extends ReduceStore { } getTask (personId, taskDefinitionId) { - const { allCachedTasksDict } = this.getState(); - // console.log('TaskStore getTaskListDictByPersonId:', personId, ', allCachedTasksDict:', allCachedTasksDict); - return allCachedTasksDict[personId][taskDefinitionId] || {}; + const { allTasksCache } = this.getState(); + // console.log('TaskStore getTaskListDictByPersonId:', personId, ', allTasksCache:', allTasksCache); + return allTasksCache[personId][taskDefinitionId] || {}; } getTaskDefinitionListByTaskGroupId (taskGroupId) { - const { allCachedTaskDefinitionsDict } = this.getState(); - const taskDefinitionListRaw = Object.values(allCachedTaskDefinitionsDict); + const { allTaskDefinitionsCache } = this.getState(); + const taskDefinitionListRaw = Object.values(allTaskDefinitionsCache); const taskDefinitionListForTaskDefinition = []; for (let i = 0; i < taskDefinitionListRaw.length; i++) { if (taskDefinitionListRaw[i].taskGroupId === taskGroupId) { @@ -89,9 +89,9 @@ class TaskStore extends ReduceStore { } getTaskGroupById (taskGroupId) { - const { allCachedTaskGroupsDict } = this.getState(); - // console.log('TaskStore getTaskGroupById:', taskGroupId, ', allCachedTaskGroupsDict:', allCachedTaskGroupsDict); - return allCachedTaskGroupsDict[taskGroupId] || {}; + const { allTaskGroupsCache } = this.getState(); + // console.log('TaskStore getTaskGroupById:', taskGroupId, ', allTaskGroupsCache:', allTaskGroupsCache); + return allTaskGroupsCache[taskGroupId] || {}; } getTaskGroupIdByTaskDefinitionId (taskDefinitionId) { @@ -100,15 +100,15 @@ class TaskStore extends ReduceStore { } getTaskDefinitionById (taskDefinitionId) { - const { allCachedTaskDefinitionsDict } = this.getState(); - // console.log('TaskStore getTaskDefinitionById:', taskDefinitionId, ', allCachedTaskDefinitionsDict:', allCachedTaskDefinitionsDict); - return allCachedTaskDefinitionsDict[taskDefinitionId] || {}; + const { allTaskDefinitionsCache } = this.getState(); + // console.log('TaskStore getTaskDefinitionById:', taskDefinitionId, ', allTaskDefinitionsCache:', allTaskDefinitionsCache); + return allTaskDefinitionsCache[taskDefinitionId] || {}; } getTaskListDictByPersonId (personId) { - const { allCachedTasksDict } = this.getState(); - // console.log('TaskStore getTaskListDictByPersonId:', personId, ', allCachedTasksDict:', allCachedTasksDict); - return allCachedTasksDict[personId] || {}; + const { allTasksCache } = this.getState(); + // console.log('TaskStore getTaskListDictByPersonId:', personId, ', allTasksCache:', allTasksCache); + return allTasksCache[personId] || {}; } getTaskListForPerson (personId) { @@ -125,7 +125,7 @@ class TaskStore extends ReduceStore { reduce (state, action) { const { - allCachedTaskGroupsDict, allCachedTaskDefinitionsDict, allCachedTasksDict, + allTaskGroupsCache, allTaskDefinitionsCache, allTasksCache, } = state; let missingRequiredVariable = false; let personId = -1; @@ -155,13 +155,13 @@ class TaskStore extends ReduceStore { action.res.taskDefinitionList.forEach((taskDefinition) => { // console.log('TaskStore task-definition-list-retrieve adding taskDefinition:', taskDefinition); if (taskDefinition && (taskDefinition.id >= 0)) { - allCachedTaskDefinitionsDict[taskDefinition.id] = taskDefinition; + allTaskDefinitionsCache[taskDefinition.id] = taskDefinition; } }); - // console.log('allCachedTaskDefinitionsDict:', allCachedTaskDefinitionsDict); + // console.log('allTaskDefinitionsCache:', allTaskDefinitionsCache); revisedState = { ...revisedState, - allCachedTaskDefinitionsDict, + allTaskDefinitionsCache, }; } // console.log('TaskStore revisedState:', revisedState); @@ -182,10 +182,10 @@ class TaskStore extends ReduceStore { if (taskDefinitionId >= 0) { if (action.res.taskDefinitionCreated || action.res.taskDefinitionUpdated) { // console.log('TaskStore taskDefinition-save taskDefinitionId:', taskDefinitionId); - allCachedTaskDefinitionsDict[taskDefinitionId] = action.res; + allTaskDefinitionsCache[taskDefinitionId] = action.res; revisedState = { ...revisedState, - allCachedTaskDefinitionsDict, + allTaskDefinitionsCache, mostRecentTaskDefinitionIdSaved: taskDefinitionId, }; } else { @@ -216,13 +216,13 @@ class TaskStore extends ReduceStore { action.res.taskGroupList.forEach((taskGroup) => { // console.log('TaskStore task-group-list-retrieve adding taskGroup:', taskGroup); if (taskGroup && (taskGroup.id >= 0)) { - allCachedTaskGroupsDict[taskGroup.id] = taskGroup; + allTaskGroupsCache[taskGroup.id] = taskGroup; } }); - // console.log('allCachedTaskGroupsDict:', allCachedTaskGroupsDict); + // console.log('allTaskGroupsCache:', allTaskGroupsCache); revisedState = { ...revisedState, - allCachedTaskGroupsDict, + allTaskGroupsCache, }; } // console.log('TaskStore revisedState:', revisedState); @@ -242,10 +242,10 @@ class TaskStore extends ReduceStore { if (taskGroupId >= 0) { // console.log('TaskStore task-group-save taskGroupId:', taskGroupId); - allCachedTaskGroupsDict[taskGroupId] = action.res; + allTaskGroupsCache[taskGroupId] = action.res; revisedState = { ...revisedState, - allCachedTaskGroupsDict, + allTaskGroupsCache, mostRecentTaskGroupIdSaved: taskGroupId, }; } else { @@ -275,10 +275,10 @@ class TaskStore extends ReduceStore { if (!missingRequiredVariable) { // console.log('TaskStore task-save personId:', personId, ', taskDefinitionId:', taskDefinitionId); - allCachedTasksDict[personId][taskDefinitionId] = action.res; + allTasksCache[personId][taskDefinitionId] = action.res; revisedState = { ...revisedState, - allCachedTasksDict, + allTasksCache, }; } else { console.log('TaskStore task-save MISSING_REQUIRED_VARIABLE personId:', personId, ', taskDefinitionId:', taskDefinitionId); @@ -296,37 +296,37 @@ class TaskStore extends ReduceStore { action.res.taskDefinitionList.forEach((taskDefinition) => { // console.log('TaskStore task-definition-list-retrieve adding taskDefinition:', taskDefinition); if (taskDefinition && (taskDefinition.id >= 0)) { - allCachedTaskDefinitionsDict[taskDefinition.id] = taskDefinition; + allTaskDefinitionsCache[taskDefinition.id] = taskDefinition; } }); - // console.log('allCachedTaskDefinitionsDict:', allCachedTaskDefinitionsDict); + // console.log('allTaskDefinitionsCache:', allTaskDefinitionsCache); revisedState = { ...revisedState, - allCachedTaskDefinitionsDict, + allTaskDefinitionsCache, }; } if (action.res.taskGroupList) { action.res.taskGroupList.forEach((taskGroup) => { // console.log('TaskStore task-group-list-retrieve adding taskGroup:', taskGroup); if (taskGroup && (taskGroup.id >= 0)) { - allCachedTaskGroupsDict[taskGroup.id] = taskGroup; + allTaskGroupsCache[taskGroup.id] = taskGroup; } }); - // console.log('allCachedTaskGroupsDict:', allCachedTaskGroupsDict); + // console.log('allTaskGroupsCache:', allTaskGroupsCache); revisedState = { ...revisedState, - allCachedTaskGroupsDict, + allTaskGroupsCache, }; } if (action.res.taskList) { action.res.taskList.forEach((task) => { // console.log('TaskStore task-group-list-retrieve adding taskGroup:', taskGroup); if (task && (task.personId >= 0)) { - if (!allCachedTasksDict[task.personId]) { - allCachedTasksDict[task.personId] = {}; + if (!allTasksCache[task.personId]) { + allTasksCache[task.personId] = {}; } if (task && (task.taskDefinitionId >= 0)) { - allCachedTasksDict[task.personId][task.taskDefinitionId] = task; + allTasksCache[task.personId][task.taskDefinitionId] = task; } else { console.log('TaskStore task-group-list-retrieve skipping task with missing personId:', task); } @@ -334,10 +334,10 @@ class TaskStore extends ReduceStore { console.log('TaskStore task-group-list-retrieve skipping task with missing taskDefinitionId:', task); } }); - // console.log('allCachedTasksDict:', allCachedTasksDict); + // console.log('allTasksCache:', allTasksCache); revisedState = { ...revisedState, - allCachedTasksDict, + allTasksCache, }; } // console.log('TaskStore revisedState:', revisedState); diff --git a/src/js/stores/TeamStore.js b/src/js/stores/TeamStore.js index b46797e..780490f 100644 --- a/src/js/stores/TeamStore.js +++ b/src/js/stores/TeamStore.js @@ -7,8 +7,8 @@ import convertToInteger from '../common/utils/convertToInteger'; class TeamStore extends ReduceStore { getInitialState () { return { - allCachedTeamsDict: {}, // This is a dictionary key: teamId, value: team dict - allCachedTeamMembersDict: {}, // This is a dictionary key: teamId, value: list of personIds in the team + allTeamsCache: {}, // This is a dictionary key: teamId, value: team dict + allTeamMembersCache: {}, // This is a dictionary key: teamId, value: list of personIds in the team mostRecentTeamIdSaved: -1, mostRecentTeamMemberIdSaved: -1, mostRecentTeamSaved: { @@ -27,14 +27,14 @@ class TeamStore extends ReduceStore { } getTeamById (teamId) { - const { allCachedTeamsDict } = this.getState(); - // console.log('TeamStore getTeamById:', teamId, ', allCachedTeamsDict:', allCachedTeamsDict); - return allCachedTeamsDict[teamId] || {}; + const { allTeamsCache } = this.getState(); + // console.log('TeamStore getTeamById:', teamId, ', allTeamsCache:', allTeamsCache); + return allTeamsCache[teamId] || {}; } getTeamList () { - const { allCachedTeamsDict } = this.getState(); - const teamListRaw = Object.values(allCachedTeamsDict); + const { allTeamsCache } = this.getState(); + const teamListRaw = Object.values(allTeamsCache); const teamList = []; let teamFiltered; @@ -49,9 +49,9 @@ class TeamStore extends ReduceStore { } getTeamMemberList (teamId) { - const { allCachedTeamMembersDict } = this.getState(); - // console.log('TeamStore getTeamMemberList teamId:', teamId, ', allCachedTeamMembersDict:', allCachedTeamMembersDict); - const personIdList = allCachedTeamMembersDict[teamId] || []; + const { allTeamMembersCache } = this.getState(); + // console.log('TeamStore getTeamMemberList teamId:', teamId, ', allTeamMembersCache:', allTeamMembersCache); + const personIdList = allTeamMembersCache[teamId] || []; const teamMemberList = []; for (let i = 0; i < personIdList.length; i++) { const person = PersonStore.getPersonById(personIdList[i]); @@ -64,8 +64,8 @@ class TeamStore extends ReduceStore { } getTeamMemberPersonIdList (teamId) { - const { allCachedTeamMembersDict } = this.getState(); - return allCachedTeamMembersDict[teamId] || []; + const { allTeamMembersCache } = this.getState(); + return allTeamMembersCache[teamId] || []; } getTeamName (teamId) { @@ -74,7 +74,7 @@ class TeamStore extends ReduceStore { } reduce (state, action) { - const { allCachedTeamMembersDict, allCachedTeamsDict } = state; + const { allTeamMembersCache, allTeamsCache } = state; let personId = -1; let personIdTemp = -1; let revisedState = state; @@ -106,14 +106,14 @@ class TeamStore extends ReduceStore { if (personId >= 0 && teamId >= 0) { // console.log('TeamStore add-person-to-team personId: ', personId, ', teamId:', teamId); // Start with existing teamMemberList - teamMemberIdList = allCachedTeamMembersDict[teamId] || []; + teamMemberIdList = allTeamMembersCache[teamId] || []; // Check if personId is already in teamMemberListAdd personId to teamMemberList if (!arrayContains(personId, teamMemberIdList)) { teamMemberIdList.push(personId); - allCachedTeamMembersDict[teamId] = teamMemberIdList; + allTeamMembersCache[teamId] = teamMemberIdList; revisedState = { ...revisedState, - allCachedTeamMembersDict, + allTeamMembersCache, mostRecentTeamMemberIdSaved: personId, }; } @@ -145,14 +145,14 @@ class TeamStore extends ReduceStore { if (personId >= 0 && teamId >= 0) { // console.log('TeamStore remove-person-from-team personId: ', personId, ', teamId:', teamId); // Start with existing teamMemberList - teamMemberIdList = allCachedTeamMembersDict[teamId] || []; + teamMemberIdList = allTeamMembersCache[teamId] || []; // If personId is in teamMemberListAdd, remove it if (arrayContains(personId, teamMemberIdList)) { teamMemberIdList = teamMemberIdList.filter((item) => item !== personId); - allCachedTeamMembersDict[teamId] = teamMemberIdList; + allTeamMembersCache[teamId] = teamMemberIdList; revisedState = { ...revisedState, - allCachedTeamMembersDict, + allTeamMembersCache, mostRecentTeamMemberIdSaved: personId, }; } @@ -170,7 +170,7 @@ class TeamStore extends ReduceStore { revisedState = state; teamList.forEach((team) => { if (team && (team.id >= 0)) { - allCachedTeamsDict[team.id] = team; + allTeamsCache[team.id] = team; if (team.teamMemberList) { teamMemberIdList = []; teamMemberList = team.teamMemberList || []; @@ -179,15 +179,15 @@ class TeamStore extends ReduceStore { teamMemberIdList.push(person.id); } }); - allCachedTeamMembersDict[team.id] = teamMemberIdList; + allTeamMembersCache[team.id] = teamMemberIdList; } } }); revisedState = { ...revisedState, - allCachedTeamMembersDict, - allCachedTeamsDict, + allTeamMembersCache, + allTeamsCache, }; return revisedState; @@ -209,7 +209,7 @@ class TeamStore extends ReduceStore { // console.log('OrganizationStore issueDescriptionsRetrieve issueList:', issueList); if (teamId >= 0) { - allCachedTeamsDict[teamId] = action.res; + allTeamsCache[teamId] = action.res; if (action.res.teamMemberList) { // If missing teamMemberList do not alter data in the store teamMemberList = action.res.teamMemberList || []; @@ -218,17 +218,17 @@ class TeamStore extends ReduceStore { teamMemberIdList.push(person.id); } }); - allCachedTeamMembersDict[teamId] = teamMemberIdList; + allTeamMembersCache[teamId] = teamMemberIdList; revisedState = { ...revisedState, - allCachedTeamMembersDict, + allTeamMembersCache, }; } - // console.log('allCachedTeamMembersDict:', allCachedTeamMembersDict); + // console.log('allTeamMembersCache:', allTeamMembersCache); // console.log('allCachedOrganizationsDict:', allCachedOrganizationsDict); revisedState = { ...revisedState, - allCachedTeamsDict, + allTeamsCache, }; } return revisedState; @@ -247,7 +247,7 @@ class TeamStore extends ReduceStore { } if (teamId >= 0) { // console.log('TeamStore team-save teamId:', teamId); - allCachedTeamsDict[teamId] = action.res; + allTeamsCache[teamId] = action.res; if (action.res.teamMemberList) { // If missing teamMemberList do not alter data in the store teamMemberList = action.res.teamMemberList || []; @@ -256,15 +256,15 @@ class TeamStore extends ReduceStore { teamMemberIdList.push(person.id); } }); - allCachedTeamMembersDict[teamId] = teamMemberIdList; + allTeamMembersCache[teamId] = teamMemberIdList; revisedState = { ...revisedState, - allCachedTeamMembersDict, + allTeamMembersCache, }; } revisedState = { ...revisedState, - allCachedTeamsDict, + allTeamsCache, mostRecentTeamIdSaved: teamId, }; } else { From 2c4ae57be0baa1d0dfccc7a23b383ed0803717e2 Mon Sep 17 00:00:00 2001 From: dalemcgrew Date: Mon, 3 Feb 2025 13:46:53 -0800 Subject: [PATCH 2/3] Turned back on "App.jsx loading" console.log message. --- src/App.jsx | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/App.jsx b/src/App.jsx index ed163e7..a46de93 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -51,9 +51,9 @@ function App () { }); useEffect(() => { - // console.log('--------- initializejQuery() ---------'); + console.log('--------- App.jsx loading ---------'); initializejQuery(() => { - // console.log('--------- jQuery has been initialized ---------'); + console.log('--------- jQuery has been initialized ---------'); }); return () => { // Anything in here is fired on component unmount, equiv to componentDidUnmount() @@ -62,7 +62,9 @@ function App () { const isAuth = localStorage.getItem('isAuthenticated'); - // console.log('======================================== isAuthenticated: " ', isAuth, ' ============================='); + if (isAuth) { + console.log('======================================== isAuthenticated: " ', isAuth, ' ============================='); + } return ( <> From 318c5968778aa00046277bc58eb39d94a23621af Mon Sep 17 00:00:00 2001 From: dalemcgrew Date: Mon, 3 Feb 2025 14:41:13 -0800 Subject: [PATCH 3/3] Removing incorrect passing in of react-query settings. --- src/js/contexts/ConnectAppContext.jsx | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/src/js/contexts/ConnectAppContext.jsx b/src/js/contexts/ConnectAppContext.jsx index c27be42..b44c5b4 100644 --- a/src/js/contexts/ConnectAppContext.jsx +++ b/src/js/contexts/ConnectAppContext.jsx @@ -59,14 +59,16 @@ export const ConnectAppContextProvider = ({ children }) => { }; // const { data: dataP, isSuccess: isSuccessP, isFetching: isFetchingP, isStale: isStaleP } = useFetchData(['person-list-retrieve'], {}); - const personListRetrieveResults = useFetchData(['person-list-retrieve'], { - cacheTime: 0, - networkMode: 'no-cache', - refetchOnMount: true, - refetchOnWindowFocus: true, - refetchInterval: 0, - staleTime: 0, - }); + const personListRetrieveResults = useFetchData(['person-list-retrieve'], {}); + // This is not currently the right place to pass these values, but I'm saving these here for the next 30 days until we work out the correct place. + // { + // cacheTime: 0, + // networkMode: 'no-cache', + // refetchOnMount: true, + // refetchOnWindowFocus: true, + // refetchInterval: 0, + // staleTime: 0, + // } const { data: dataP, isSuccess: isSuccessP, isFetching: isFetchingP, isStale: isStaleP } = personListRetrieveResults; useEffect(() => { // console.log('useFetchData person-list-retrieve in Teams useEffect:', personListRetrieveResults);