From 92937af2cbeca78e52272e1a752ca6b025d7ae8a Mon Sep 17 00:00:00 2001 From: Tord Austad Date: Wed, 4 Sep 2024 10:09:00 +0200 Subject: [PATCH] Navigate to All projects when removing context from evaluation view (#1134) * Navigate to All projects when removing context from evaluation view * Fix navigation between contexts in evaluation view * Remove error message when waiting for results from api * Make hidden evaluations show all hidden, remove error * Remove my tasks from project dashboard --- frontend/package-lock.json | 34 +++---- .../src/components/Header/Breadcrumbs.tsx | 4 +- frontend/src/context/AppContext.tsx | 90 ++++++++++--------- .../src/views/Evaluation/EvaluationView.tsx | 21 ++++- .../views/Project/Dashboard/DashboardView.tsx | 50 +++-------- frontend/src/views/Project/ProjectTabs.tsx | 2 +- 6 files changed, 103 insertions(+), 98 deletions(-) diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 3bddd44f..850e0cff 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -7535,9 +7535,9 @@ } }, "node_modules/@microsoft/signalr/node_modules/ws": { - "version": "7.5.9", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", - "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", "engines": { "node": ">=8.3.0" }, @@ -9978,11 +9978,11 @@ } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" @@ -12914,9 +12914,9 @@ } }, "node_modules/fill-range": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", - "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -17549,11 +17549,11 @@ } }, "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", + "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", "dependencies": { - "braces": "^3.0.2", + "braces": "^3.0.3", "picomatch": "^2.3.1" }, "engines": { @@ -21889,9 +21889,9 @@ } }, "node_modules/ws": { - "version": "8.16.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.16.0.tgz", - "integrity": "sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==", + "version": "8.18.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.18.0.tgz", + "integrity": "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==", "devOptional": true, "engines": { "node": ">=10.0.0" diff --git a/frontend/src/components/Header/Breadcrumbs.tsx b/frontend/src/components/Header/Breadcrumbs.tsx index ae183b09..d60379b9 100644 --- a/frontend/src/components/Header/Breadcrumbs.tsx +++ b/frontend/src/components/Header/Breadcrumbs.tsx @@ -35,7 +35,7 @@ const BreadCrumbs = () => { > All projects - {currentProject && + {currentProject && { {String(currentProject.title)} } - {currentEvaluation && + {currentEvaluation && diff --git a/frontend/src/context/AppContext.tsx b/frontend/src/context/AppContext.tsx index 1af8efd8..855772ec 100644 --- a/frontend/src/context/AppContext.tsx +++ b/frontend/src/context/AppContext.tsx @@ -16,7 +16,6 @@ import { useCurrentUser } from '@equinor/fusion-framework-react-app/framework' import { gql, useQuery, useApolloClient } from '@apollo/client' import { EVALUATION_DASHBOARD_FIELDS_FRAGMENT, PARTICIPANTS_ARRAY_FRAGMENT } from '../api/fragments' - interface ProjectOption { title: string id: string @@ -76,11 +75,11 @@ const GET_EVALUATIONS = gql` const GET_EVALUATIONS_BY_USER = gql` query ($status: Status!, $azureUniqueId: String!) { evaluations( - where: { - status: { + where: { + status: { eq: $status }, - participants: { + participants: { some: { azureUniqueId: { eq: $azureUniqueId @@ -97,18 +96,11 @@ const GET_EVALUATIONS_BY_USER = gql` ${PARTICIPANTS_ARRAY_FRAGMENT} ` const GET_EVALUATIONS_BY_USER_HIDDEN = gql` - query ($status: Status!, $azureUniqueId: String!) { + query ($status: Status!) { evaluations( - where: { - status: { + where: { + status: { eq: $status - }, - participants: { - some: { - azureUniqueId: { - eq: $azureUniqueId - } - } } } ) { @@ -123,8 +115,8 @@ const GET_EVALUATIONS_BY_USER_HIDDEN = gql` const GET_EVALUATIONS_BY_USER_PROJECT = gql` query ($status: Status!, $azureUniqueId: String!, $projectId: String!) { evaluations( - where: { - status: { + where: { + status: { eq: $status }, project: { @@ -132,7 +124,7 @@ const GET_EVALUATIONS_BY_USER_PROJECT = gql` eq: $projectId } } - participants: { + participants: { some: { azureUniqueId: { eq: $azureUniqueId @@ -151,16 +143,16 @@ const GET_EVALUATIONS_BY_USER_PROJECT = gql` const GET_EVALUATIONS_BY_USER_PROJECT_HIDDEN = gql` query ($status: Status!, $azureUniqueId: String!, $projectId: String!) { evaluations( - where: { - status: { - eq: $status + where: { + status: { + eq: $status }, project: { externalId: { eq: $projectId } } - participants: { + participants: { some: { azureUniqueId: { eq: $azureUniqueId @@ -180,8 +172,8 @@ const GET_EVALUATIONS_BY_USER_PROJECT_HIDDEN = gql` const GET_EVALUATIONS_BY_PROJECT = gql` query ($status: Status!, $projectId: String!) { evaluations( - where: { - status: { + where: { + status: { eq: $status }, project: { @@ -201,9 +193,9 @@ const GET_EVALUATIONS_BY_PROJECT = gql` const GET_EVALUATIONS_BY_PROJECT_HIDDEN = gql` query ($status: Status!, $projectId: String!) { evaluations( - where: { - status: { - eq: $status + where: { + status: { + eq: $status }, project: { externalId: { @@ -226,16 +218,19 @@ interface QueryProps { const useGetAllProjects = (): QueryProps => { const { data } = useQuery<{ projects: Project[] }>(GET_PROJECTS) - return { dbProjects: data?.projects ? data?.projects : []} + return { dbProjects: data?.projects ? data?.projects : [] } } const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => { const apiClients = useContextApi() const user = useCurrentUser() const apolloClient = useApolloClient() + const [pageReload, setPageReload] = useState(false) const [contexts, setContexts] = useState([]) + const { currentContext } = useModuleCurrentContext() + const [isFetchingProjects, setIsFetchingProjects] = useState(true) const { dbProjects } = useGetAllProjects() const [projects, setProjects] = useState([]) @@ -263,6 +258,18 @@ const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => { const [evaluationsByProjectHiddenFetched, setEvaluationsByProjectHiddenFetched] = useState(false) const [currentEvaluation, setCurrentEvaluation] = useState(undefined) + useEffect(() => { + setEvaluationsByProjectFetched(false) + setEvaluationsByProjectHiddenFetched(false) + setEvaluationsByUserProjectHiddenFetched(false) + setEvaluationsByUserProjectFetched(false) + setEvaluationsByUserHiddenFetched(false) + setEvaluationsByUserFetched(false) + setEvaluationsFetched(false) + setProjectsByUserHiddenFetched(false) + setProjectsByUserFetched(false) + }, [currentContext]) + useEffect(() => { setPageReload(currentContext !== undefined && currentContext !== null) if ((currentContext === undefined || currentContext === null) && pageReload) { @@ -292,9 +299,9 @@ const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => { }) tempProjects = tempProjects.filter((value, index, self) => index === self.findIndex((t) => ( - t.id === value.id || t.externalId === value.externalId || t.fusionProjectId === value.fusionProjectId + t.id === value.id || t.externalId === value.externalId || t.fusionProjectId === value.fusionProjectId )) - ) + ) setProjects(tempProjects) setIsFetchingProjects(false) } @@ -303,8 +310,8 @@ const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => { projects.forEach((project: Project) => { if (project.title && project.fusionProjectId !== '') { tempProjectOptions.push({ - title: project.title, - id: project.externalId, + title: project.title, + id: project.externalId, }) } }) @@ -342,7 +349,10 @@ const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => { let tempProjectsByUserHidden: Project[] = [] evaluationsByUserHidden.forEach((ebu: Evaluation) => { if (tempProjectsByUserHidden.filter((tpbu: Project) => tpbu.externalId === ebu.project.externalId).length === 0) { - tempProjectsByUserHidden.push(projects.filter((p: Project) => p.externalId === ebu.project.externalId)[0]) + const temp = projects.filter((p: Project) => p.externalId === ebu.project.externalId)[0] + if (temp) { + tempProjectsByUserHidden.push(temp) + } } }) setProjectsByUserHidden(tempProjectsByUserHidden) @@ -350,10 +360,10 @@ const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => { setLoadingProjects(false) } }, [projects, evaluationsByUserHidden, evaluationsByUserHiddenFetched, projectsByUserHiddenFetched]) - + useEffect(() => { if (!evaluationsFetched) { - apolloClient.query({ query: GET_EVALUATIONS}).then(data => { + apolloClient.query({ query: GET_EVALUATIONS }).then(data => { setLoadingEvaluations(true) if (data.data.evaluations) { setEvaluations(data.data.evaluations) @@ -366,7 +376,7 @@ const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => { useEffect(() => { if (user && !evaluationsByUserFetched) { - apolloClient.query({ query: GET_EVALUATIONS_BY_USER, variables: { status: Status.Active, azureUniqueId: user.localAccountId}}).then(data => { + apolloClient.query({ query: GET_EVALUATIONS_BY_USER, variables: { status: Status.Active, azureUniqueId: user.localAccountId } }).then(data => { setLoadingEvaluations(true) if (data.data.evaluations) { setEvaluationsByUser(data.data.evaluations) @@ -379,7 +389,7 @@ const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => { useEffect(() => { if (user && !evaluationsByUserHiddenFetched) { - apolloClient.query({ query: GET_EVALUATIONS_BY_USER_HIDDEN, variables: { status: Status.Voided, azureUniqueId: user.localAccountId}}).then(data => { + apolloClient.query({ query: GET_EVALUATIONS_BY_USER_HIDDEN, variables: { status: Status.Voided } }).then(data => { setLoadingEvaluations(true) if (data.data.evaluations) { setEvaluationsByUserHidden(data.data.evaluations) @@ -392,7 +402,7 @@ const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => { useEffect(() => { if (user && currentProject && !evaluationsByUserProjectFetched) { - apolloClient.query({ query: GET_EVALUATIONS_BY_USER_PROJECT, variables: { status: Status.Active, azureUniqueId: user.localAccountId, projectId: currentProject.externalId }}).then(data => { + apolloClient.query({ query: GET_EVALUATIONS_BY_USER_PROJECT, variables: { status: Status.Active, azureUniqueId: user.localAccountId, projectId: currentProject.externalId } }).then(data => { setLoadingEvaluations(true) if (data.data.evaluations) { setEvaluationsByUserProject(data.data.evaluations) @@ -405,7 +415,7 @@ const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => { useEffect(() => { if (user && currentProject && !evaluationsByUserProjectHiddenFetched) { - apolloClient.query({ query: GET_EVALUATIONS_BY_USER_PROJECT_HIDDEN, variables: { status: Status.Voided, azureUniqueId: user.localAccountId, projectId: currentProject.externalId }}).then(data => { + apolloClient.query({ query: GET_EVALUATIONS_BY_USER_PROJECT_HIDDEN, variables: { status: Status.Voided, azureUniqueId: user.localAccountId, projectId: currentProject.externalId } }).then(data => { setLoadingEvaluations(true) if (data.data.evaluations) { setEvaluationsByUserProjectHidden(data.data.evaluations) @@ -418,7 +428,7 @@ const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => { useEffect(() => { if (currentProject && !evaluationsByProjectFetched) { - apolloClient.query({ query: GET_EVALUATIONS_BY_PROJECT, variables: { status: Status.Active, projectId: currentProject.externalId }}).then(data => { + apolloClient.query({ query: GET_EVALUATIONS_BY_PROJECT, variables: { status: Status.Active, projectId: currentProject.externalId } }).then(data => { setLoadingEvaluations(true) if (data.data.evaluations) { setEvaluationsByProject(data.data.evaluations) @@ -431,7 +441,7 @@ const AppContextProvider: FC<{ children: ReactNode }> = ({ children }) => { useEffect(() => { if (currentProject && !evaluationsByProjectHiddenFetched) { - apolloClient.query({ query: GET_EVALUATIONS_BY_PROJECT_HIDDEN, variables: { status: Status.Voided, projectId: currentProject.externalId }}).then(data => { + apolloClient.query({ query: GET_EVALUATIONS_BY_PROJECT_HIDDEN, variables: { status: Status.Voided, projectId: currentProject.externalId } }).then(data => { setLoadingEvaluations(true) if (data.data.evaluations) { setEvaluationsByProjectHidden(data.data.evaluations) diff --git a/frontend/src/views/Evaluation/EvaluationView.tsx b/frontend/src/views/Evaluation/EvaluationView.tsx index 01e9627b..fe98956e 100644 --- a/frontend/src/views/Evaluation/EvaluationView.tsx +++ b/frontend/src/views/Evaluation/EvaluationView.tsx @@ -1,5 +1,5 @@ import { useState, useEffect } from 'react' -import { RouteComponentProps } from 'react-router-dom' +import { RouteComponentProps, useHistory } from 'react-router-dom' import { ApolloError, gql, useApolloClient, useMutation, useQuery } from '@apollo/client' import ErrorMessage from '../../components/ErrorMessage' import { CircularProgress } from '@equinor/eds-core-react' @@ -21,6 +21,7 @@ import { } from '../../api/fragments' import { centered } from '../../utils/styles' import { useAppContext } from '../../context/AppContext' +import { useModuleCurrentContext } from '@equinor/fusion-framework-react-module-context' interface Params { fusionProjectId: string @@ -28,7 +29,10 @@ interface Params { } const EvaluationView = ({ match }: RouteComponentProps) => { - const { setCurrentEvaluation } = useAppContext() + const { setCurrentEvaluation, setCurrentProject } = useAppContext() + const { currentContext } = useModuleCurrentContext() + const history = useHistory() + const evaluationId: string = match.params.evaluationId const azureUniqueId = useAzureUniqueId() @@ -38,6 +42,19 @@ const EvaluationView = ({ match }: RouteComponentProps) => { const [isProgressDialogOpen, setIsProgressDialogOpen] = useState(false) + useEffect(() => { + if (!currentContext) { + setCurrentProject(undefined) + setCurrentEvaluation(undefined) + history.push("/apps/bmt/") + } + else if (!loading && currentContext.externalId !== evaluation?.project.externalId) { + setCurrentProject(undefined) + setCurrentEvaluation(undefined) + history.push(`/apps/bmt/${currentContext.id}`) + } + }, [currentContext]) + const onConfirmProgressEvaluationClick = () => { const newProgression = getNextProgression(evaluation!.progression) progressEvaluation(evaluationId, newProgression) diff --git a/frontend/src/views/Project/Dashboard/DashboardView.tsx b/frontend/src/views/Project/Dashboard/DashboardView.tsx index beb5f83c..1f94d829 100644 --- a/frontend/src/views/Project/Dashboard/DashboardView.tsx +++ b/frontend/src/views/Project/Dashboard/DashboardView.tsx @@ -36,7 +36,6 @@ enum TableSelection { Project = 'PROJECT', User = 'USER', HiddenProject = 'HIDDEN_PROJECT', - HiddenUserProject = 'HIDDEN_USER_PROJECT', HiddenUser = 'HIDDEN_USER', } interface MapTableSelectionToTextProps { @@ -73,14 +72,6 @@ const MapTableSelectionToText: React.FC = ({ table ) } - case 'HIDDEN_USER_PROJECT': { - return ( - <> - - {`My project hidden evaluations`} - - ) - } case 'PORTFOLIO': { return 'All evaluations' } @@ -107,17 +98,12 @@ const DashboardView = ({ project }: Props) => { const { generateBMTScores, loading: loadingProgressEvaluation, error: errorProgressEvaluation } = useGenerateBMTScoresMutation() - if (!currentUser) { - return

Please log in.

- } - const [selectedProjectTable, setSelectedProjectTable] = React.useState(TableSelection.Portfolio) const userIsAdmin = currentUser && getCachedRoles()?.includes('Role.Admin') const myEvaluationsSelected = selectedProjectTable === TableSelection.User const projectEvaluationsSelected = selectedProjectTable === TableSelection.Project const hiddenUserEvaluationsSelected = selectedProjectTable === TableSelection.HiddenUser const hiddenProjectEvaluationsSelected = selectedProjectTable === TableSelection.HiddenProject - const hiddenUserProjectEvaluationsSelected = selectedProjectTable === TableSelection.HiddenUserProject const portfoliosSelected = selectedProjectTable === TableSelection.Portfolio const { @@ -131,7 +117,16 @@ const DashboardView = ({ project }: Props) => { const errorMessage = - const { projectsByUser, projectsByUserHidden, loadingEvaluations, evaluationsByUserProject, evaluationsByUserProjectHidden, evaluationsByUser, evaluationsByUserHidden, evaluationsByProject, evaluationsByProjectHidden } = useAppContext() + const { + projectsByUser, + projectsByUserHidden, + loadingEvaluations, + evaluationsByUserProject, + evaluationsByUser, + evaluationsByUserHidden, + evaluationsByProject, + evaluationsByProjectHidden, + } = useAppContext() useEffect(() => { const generateScore = async () => { @@ -160,12 +155,7 @@ const DashboardView = ({ project }: Props) => { (!userIsAdmin && value === TableSelection.HiddenProject) || (value === TableSelection.HiddenUser && currentContext) || (currentContext && value === TableSelection.Portfolio) || - (!currentContext && (value === TableSelection.Project || value === TableSelection.HiddenProject || value === TableSelection.HiddenUserProject)) || - (value === TableSelection.User && currentContext && evaluationsByUserProject.length === 0) || - (value === TableSelection.User && !currentContext && evaluationsByUser.length === 0) || - (value === TableSelection.HiddenProject && evaluationsByProjectHidden.length === 0) || - (value === TableSelection.HiddenUserProject && evaluationsByUserProjectHidden.length === 0) || - (value === TableSelection.HiddenUser && evaluationsByUserHidden.length === 0) + (!currentContext && (value === TableSelection.Project || value === TableSelection.HiddenProject)) ) { return undefined } else { @@ -202,46 +192,35 @@ const DashboardView = ({ project }: Props) => { <> {evaluationsByUserProject && } {loadingEvaluations && } - {evaluationsByUserProject.length === 0 && errorMessage} )} {projectEvaluationsSelected && ( <> {evaluationsByProject && } {loadingEvaluations && } - {evaluationsByProject.length === 0 && errorMessage} )} {(hiddenProjectEvaluationsSelected) && ( <> {evaluationsByProjectHidden && } {loadingEvaluations && } - {evaluationsByProjectHidden.length === 0 && errorMessage} )} {(hiddenUserEvaluationsSelected) && ( <> - {evaluationsByUserHidden && + {evaluationsByUserHidden && {projectsByUserHidden.map(projectByUserHidden => ( {projectByUserHidden.title} - ebuh.project.externalId === projectByUserHidden.externalId)} /> + ebuh.project.externalId === projectByUserHidden.externalId)} /> ))} } {loadingEvaluations && } - {evaluationsByUserHidden.length === 0 && errorMessage} - - )} - {(hiddenUserProjectEvaluationsSelected && currentContext) && ( - <> - {evaluationsByUserProjectHidden && } - {loadingEvaluations && } - {evaluationsByUserProjectHidden.length === 0 && errorMessage} )} {portfoliosSelected && ( @@ -254,7 +233,6 @@ const DashboardView = ({ project }: Props) => { /> )} {(loadingActiveEvaluations || !allActiveEvaluationsWithProjectMasterAndPortfolio) && } - {errorActiveEvaluations !== undefined && errorMessage} )} {(myEvaluationsSelected && !currentContext && evaluationsByUser) && ( @@ -280,7 +258,7 @@ interface EvaluationQueryProps { loading: boolean evaluations: Evaluation[] | undefined error: ApolloError | undefined - refetch?: () => Promise> + refetch?: () => Promise> } export const useUserEvaluationsQuery = (azureUniqueId: string): EvaluationQueryProps => { diff --git a/frontend/src/views/Project/ProjectTabs.tsx b/frontend/src/views/Project/ProjectTabs.tsx index e7a88da6..1c64cdda 100644 --- a/frontend/src/views/Project/ProjectTabs.tsx +++ b/frontend/src/views/Project/ProjectTabs.tsx @@ -53,7 +53,7 @@ const ProjectTabs = ({ match }: RouteComponentProps) => { Evaluations - My actions + {!currentContext ? My actions : <>} {isAdmin && !currentContext ? Questionnaire editor : <>}