diff --git a/client/packages/portal-core/src/context-relations/use-context-relations.ts b/client/packages/portal-core/src/context-relations/use-context-relations.ts index da314f2c7..3cdcd9559 100644 --- a/client/packages/portal-core/src/context-relations/use-context-relations.ts +++ b/client/packages/portal-core/src/context-relations/use-context-relations.ts @@ -2,6 +2,7 @@ import { useFramework } from '@equinor/fusion-framework-react'; import { useQuery } from 'react-query'; import { IHttpClient } from '@equinor/fusion-framework-module-http'; import { Relations } from './types'; +import { useEffect, useMemo, useState } from 'react'; export async function getContextRelations( client: IHttpClient, @@ -27,6 +28,19 @@ export const useContextRelationsQuery = (contextId?: string) => { type RelationsTypes = 'EquinorTask' | 'Contract' | 'ProjectMaster' | 'PimsDomain' | 'Project' | 'OrgChart'; export function useRelationsByType(type: RelationsTypes, contextId?: string) { - const { data } = useContextRelationsQuery(contextId); - return data?.filter((relation) => relation.type.id === type) || []; + const [error, setError] = useState(); + const { data, isLoading } = useContextRelationsQuery(contextId); + + const filteredRelations = useMemo(() => { + setError(undefined); + return data?.filter((relation) => relation.type.id === type) || []; + }, [data]); + + useEffect(() => { + if (!isLoading && filteredRelations?.length === 0) { + setError(Error(`No context relation found for ${type}`)); + } + }, [isLoading, filteredRelations]); + + return { data: filteredRelations, isLoading, error }; } diff --git a/client/packages/portal-pages/src/pages/project-page/Overvirew.tsx b/client/packages/portal-pages/src/pages/project-page/Overvirew.tsx index bfd546fb9..7d9ca84bd 100644 --- a/client/packages/portal-pages/src/pages/project-page/Overvirew.tsx +++ b/client/packages/portal-pages/src/pages/project-page/Overvirew.tsx @@ -8,7 +8,7 @@ import { useFrameworkFeature } from '@equinor/fusion-framework-react/feature-fla import { Phases } from './components/phases/Phases'; import { Milestones } from './components/milestones/Milestones'; -export const Overview = () => { +export const Overview = ({ openAllApps }: { openAllApps: () => void }) => { const { feature } = useFrameworkFeature('app-search'); const { feature: ccTabFeature } = useFrameworkFeature('cc-tab'); @@ -19,7 +19,7 @@ export const Overview = () => { - + {/* Todo remove when cc tab is not in feature flag mode */} {ccTabFeature?.enabled === false && } {feature?.enabled && } diff --git a/client/packages/portal-pages/src/pages/project-page/ProjectPage.tsx b/client/packages/portal-pages/src/pages/project-page/ProjectPage.tsx index fb6d75c04..9e8b0dd55 100644 --- a/client/packages/portal-pages/src/pages/project-page/ProjectPage.tsx +++ b/client/packages/portal-pages/src/pages/project-page/ProjectPage.tsx @@ -162,7 +162,7 @@ export const ProjectPage = () => { {feature?.enabled ? ( - + setActiveTab(2)} /> @@ -174,7 +174,7 @@ export const ProjectPage = () => { ) : ( - + setActiveTab(1)} /> diff --git a/client/packages/portal-pages/src/pages/project-page/components/contracts/Contracts.tsx b/client/packages/portal-pages/src/pages/project-page/components/contracts/Contracts.tsx index 13ed28d42..dd626696c 100644 --- a/client/packages/portal-pages/src/pages/project-page/components/contracts/Contracts.tsx +++ b/client/packages/portal-pages/src/pages/project-page/components/contracts/Contracts.tsx @@ -41,7 +41,7 @@ const sortByDate = (a: Relations, b: Relations) => export const Contracts = () => { const context = useFrameworkCurrentContext(); - const contracts = useRelationsByType('Contract', context?.id); + const { data: contracts } = useRelationsByType('Contract', context?.id); const contractGroups = useMemo(() => { return contracts.reduce( diff --git a/client/packages/portal-pages/src/pages/project-page/components/favorites/AppContainerEmpty.tsx b/client/packages/portal-pages/src/pages/project-page/components/favorites/AppContainerEmpty.tsx new file mode 100644 index 000000000..ea18e6d4c --- /dev/null +++ b/client/packages/portal-pages/src/pages/project-page/components/favorites/AppContainerEmpty.tsx @@ -0,0 +1,33 @@ +import styled from 'styled-components'; +import { tokens } from '@equinor/eds-tokens'; +import { Typography } from '@equinor/eds-core-react'; +import { PropsWithChildren } from 'react'; + +const emptyFrameHeight = '14.75rem'; + +const Styled = { + EmptyFrame: styled.div` + border: 1px dashed ${tokens.colors.ui.background__medium.hex}; + border-radius: 0.25rem; + width: 100%; + height: ${emptyFrameHeight}; + padding: ${tokens.spacings.comfortable.medium}; + display: flex; + align-items: center; + justify-content: center; + `, + FrameContent: styled(Typography)` + color: ${tokens.colors.text.static_icons__tertiary.hex}; + text-align: center; + `, +}; + +export const AppContainerEmpty = ({ children }: PropsWithChildren): JSX.Element => { + return ( + + + {children} + + + ); +}; diff --git a/client/packages/portal-pages/src/pages/project-page/components/favorites/Favorites.tsx b/client/packages/portal-pages/src/pages/project-page/components/favorites/Favorites.tsx index ed480b11f..0db5c8927 100644 --- a/client/packages/portal-pages/src/pages/project-page/components/favorites/Favorites.tsx +++ b/client/packages/portal-pages/src/pages/project-page/components/favorites/Favorites.tsx @@ -9,6 +9,8 @@ import { useRef, useState } from 'react'; import { useFavorites } from '@portal/core'; import FavoriteCard from './FavoriteCard'; import { sortByCategoryAndIsDisabled } from './utils/utils'; +import { AppContainerEmpty } from './AppContainerEmpty'; +import { useMenuContext } from '@equinor/portal-core'; type AppCardPops = { isDisabled?: boolean; @@ -33,6 +35,11 @@ const styles = { } `; }, + FrameLink: styled.span` + color: ${tokens.colors.interactive.primary__resting.hex}; + text-decoration: underline; + cursor: pointer; + `, cardList: css` display: grid; grid-auto-rows: auto; @@ -44,13 +51,14 @@ const styles = { grid-template-columns: repeat(1, 1fr); } `, - noData: css` + NoData: styled.div` display: flex; flex-direction: column; justify-content: center; align-items: center; gap: 0.5rem; grid-column: span 3; + padding: 0 1rem; `, fullHeight: css` height: 100%; @@ -62,17 +70,21 @@ const styles = { `, }; -export const Favorites = () => { +type FavoriteProps = { + openAllApps: () => void; +}; + +export const Favorites = ({ openAllApps }: FavoriteProps) => { + const { toggleMenu } = useMenuContext(); const referenceElement = useRef(null); const [isOpen, setIsOpen] = useState(false); - // const { dispatchEvent } = useTelemetry(); const { favorites, hasFavorites, isLoading, addFavorite, isDisabled } = useFavorites(); return (
- Pinned Apps + Favorites
{ setIsOpen(true); @@ -89,9 +101,9 @@ export const Favorites = () => {
- + ) : ( + + + You don't have any favourite apps yet. +
+ Choose your favourites in{' '} + All apps or{' '} + { + toggleMenu(); + }} + > + Menu + {' '} + by clicking on the star ★. +
+
+ )}
); diff --git a/client/packages/portal-pages/src/pages/project-page/components/one-equinor-link/OneEquinorLink.tsx b/client/packages/portal-pages/src/pages/project-page/components/one-equinor-link/OneEquinorLink.tsx index b6ee61860..9693ad557 100644 --- a/client/packages/portal-pages/src/pages/project-page/components/one-equinor-link/OneEquinorLink.tsx +++ b/client/packages/portal-pages/src/pages/project-page/components/one-equinor-link/OneEquinorLink.tsx @@ -44,7 +44,7 @@ const Styles = { export const OneEquinorLink = () => { const context = useFrameworkCurrentContext(); - const equinorTask = useRelationsByType('EquinorTask', context?.id); + const { data: equinorTask } = useRelationsByType('EquinorTask', context?.id); // https://fusion.equinor.com/apps/one-equinor/org-unit/53014029/task/673024d2-e311-44a7-733e-08dbc8a2fb29 if (equinorTask[0]?.value.orgUnitSapId) { diff --git a/client/packages/portal-pages/src/pages/project-page/components/phases/Phases.tsx b/client/packages/portal-pages/src/pages/project-page/components/phases/Phases.tsx index 635cb11a6..be374912f 100644 --- a/client/packages/portal-pages/src/pages/project-page/components/phases/Phases.tsx +++ b/client/packages/portal-pages/src/pages/project-page/components/phases/Phases.tsx @@ -20,11 +20,13 @@ import { NoProjectInfoAccessMessage } from '../messages/NoProjectInfoAccessMessa export const Phases = () => { const context = useFrameworkCurrentContext(); - const equinorTask = useRelationsByType('OrgChart', context?.id); + const { data: equinorTask, error: relationsError } = useRelationsByType('OrgChart', context?.id); const { data, isLoading, error } = useProjectDetails(equinorTask[0]?.externalId); const current = useMemo(() => findActiveDate(data?.dates.gates as DateObject), [data]); + if (relationsError && !equinorTask) return null; + return ( diff --git a/client/packages/portal-pages/src/pages/project-page/components/pro-org-link/ProOrgLink.tsx b/client/packages/portal-pages/src/pages/project-page/components/pro-org-link/ProOrgLink.tsx index 66e751225..c8b92b8c9 100644 --- a/client/packages/portal-pages/src/pages/project-page/components/pro-org-link/ProOrgLink.tsx +++ b/client/packages/portal-pages/src/pages/project-page/components/pro-org-link/ProOrgLink.tsx @@ -44,7 +44,7 @@ const Styles = { export const ProOrgLink = () => { const context = useFrameworkCurrentContext(); - const equinorTask = useRelationsByType('OrgChart', context?.id); + const { data: equinorTask } = useRelationsByType('OrgChart', context?.id); if (equinorTask[0]?.externalId) { return ( diff --git a/client/packages/portal-pages/src/pages/project-page/components/project-director/ProjectDirector.tsx b/client/packages/portal-pages/src/pages/project-page/components/project-director/ProjectDirector.tsx index 614b0dbad..5d02076b1 100644 --- a/client/packages/portal-pages/src/pages/project-page/components/project-director/ProjectDirector.tsx +++ b/client/packages/portal-pages/src/pages/project-page/components/project-director/ProjectDirector.tsx @@ -7,10 +7,14 @@ import { useCurrentDirector } from './hooks/use-current-director'; export const ProjectDirector = () => { const context = useFrameworkCurrentContext(); - const { director, error } = useCurrentDirector(context?.id); + const { director, error, isLoading } = useCurrentDirector(context?.id); const { data } = useUser(director?.assignedPerson?.azureUniqueId); + if (!director && !error && !isLoading) { + return null; + } + return ( diff --git a/client/packages/portal-pages/src/pages/project-page/components/project-director/hooks/use-current-director.ts b/client/packages/portal-pages/src/pages/project-page/components/project-director/hooks/use-current-director.ts index ed7c58ac1..01a6d7800 100644 --- a/client/packages/portal-pages/src/pages/project-page/components/project-director/hooks/use-current-director.ts +++ b/client/packages/portal-pages/src/pages/project-page/components/project-director/hooks/use-current-director.ts @@ -28,7 +28,8 @@ export const useProjectDetails = (projectId?: string) => { }; export const useCurrentDirector = (contextId?: string) => { - const equinorTask = useRelationsByType('OrgChart', contextId); + const { data: equinorTask } = useRelationsByType('OrgChart', contextId); + const { data, isLoading, error } = useProjectDetails(equinorTask[0]?.externalId); const director = useMemo(() => { diff --git a/client/packages/portal-pages/src/pages/project-page/components/user/UserCard.tsx b/client/packages/portal-pages/src/pages/project-page/components/user/UserCard.tsx index 2bb5a8cf6..80f6e17ba 100644 --- a/client/packages/portal-pages/src/pages/project-page/components/user/UserCard.tsx +++ b/client/packages/portal-pages/src/pages/project-page/components/user/UserCard.tsx @@ -58,7 +58,7 @@ const Style = { export const ProjectPosition = ({ positions }: { positions?: PersonPosition[] }) => { const context = useFrameworkCurrentContext(); - const equinorTask = useRelationsByType('OrgChart', context?.id); + const { data: equinorTask } = useRelationsByType('OrgChart', context?.id); const projectPositions = useMemo(() => { return (