Skip to content

Commit

Permalink
Merge in main
Browse files Browse the repository at this point in the history
  • Loading branch information
marrobi committed Feb 13, 2025
1 parent f25ed99 commit 06dab06
Show file tree
Hide file tree
Showing 6 changed files with 4,177 additions and 10,916 deletions.
52 changes: 27 additions & 25 deletions ui/app/src/components/root/LeftNav.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React, { useContext } from 'react';
import { Nav, INavLinkGroup } from '@fluentui/react/lib/Nav';
import { useLocation, useNavigate } from 'react-router-dom';
import { AppRolesContext } from '../../contexts/AppRolesContext';
import { RoleName } from '../../models/roleNames';
import React, { useContext } from "react";
import { Nav, INavLinkGroup } from "@fluentui/react/lib/Nav";
import { useLocation, useNavigate } from "react-router-dom";
import { AppRolesContext } from "../../contexts/AppRolesContext";
import { RoleName } from "../../models/roleNames";

export const LeftNav: React.FunctionComponent = () => {
const navigate = useNavigate();
const location = useLocation();
const appRolesCtx = useContext(AppRolesContext);

const isRequestsRoute = location.pathname.startsWith('/requests'); // ← True if URL starts with /requests
const isRequestsRoute = location.pathname.startsWith("/requests"); // ← True if URL starts with /requests

const navLinkGroups: INavLinkGroup[] = [
{
Expand All @@ -34,27 +34,29 @@ export const LeftNav: React.FunctionComponent = () => {
});
}

const requestsLinkArray: { name: string; url: string; key: string; icon: string }[] = [];
const requestsLinkArray: {
name: string;
url: string;
key: string;
icon: string;
}[] = [];

requestsLinkArray.push(
{
name: 'Airlock',
url: '/requests/airlock',
key: 'airlock',
icon: 'Lock',

});
requestsLinkArray.push({
name: "Airlock",
url: "/requests/airlock",
key: "airlock",
icon: "Lock",
});

// add Requests link
navLinkGroups[0].links.push(
{
name: 'Requests',
url: '/requests',
key: 'requests',
icon: '',
links: requestsLinkArray,
isExpanded: isRequestsRoute
});
navLinkGroups[0].links.push({
name: "Requests",
url: "/requests",
key: "requests",
icon: "",
links: requestsLinkArray,
isExpanded: isRequestsRoute,
});

return (
<Nav
Expand All @@ -63,7 +65,7 @@ export const LeftNav: React.FunctionComponent = () => {
if (!item || !item.url) return;
item.isExpanded = true;
if (item.url !== "/requests") {
navigate(item.url)
navigate(item.url);
}
}}
ariaLabel="TRE Left Navigation"
Expand Down
126 changes: 81 additions & 45 deletions ui/app/src/components/root/RootLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,26 @@
import { Spinner, SpinnerSize, Stack } from '@fluentui/react';
import React, { useContext, useEffect, useRef, useState } from 'react';
import { Route, Routes } from 'react-router-dom';
import { Admin } from '../../App';
import { ApiEndpoint } from '../../models/apiEndpoints';
import { Workspace } from '../../models/workspace';
import { useAuthApiCall, HttpMethod, ResultType } from '../../hooks/useAuthApiCall';
import { RootDashboard } from './RootDashboard';
import { LeftNav } from './LeftNav';
import { LoadingState } from '../../models/loadingState';
import { RequestsList } from '../shared/RequestsList';
import { SharedServices } from '../shared/SharedServices';
import { SharedServiceItem } from '../shared/SharedServiceItem';
import { SecuredByRole } from '../shared/SecuredByRole';
import { RoleName } from '../../models/roleNames';
import { APIError } from '../../models/exceptions';
import { ExceptionLayout } from '../shared/ExceptionLayout';
import { AppRolesContext } from '../../contexts/AppRolesContext';
import { CostsContext } from '../../contexts/CostsContext';
import { Spinner, SpinnerSize, Stack } from "@fluentui/react";
import React, { useContext, useEffect, useRef, useState } from "react";
import { Route, Routes } from "react-router-dom";
import { Admin } from "../../App";
import { ApiEndpoint } from "../../models/apiEndpoints";
import { Workspace } from "../../models/workspace";
import {
useAuthApiCall,
HttpMethod,
ResultType,
} from "../../hooks/useAuthApiCall";
import { RootDashboard } from "./RootDashboard";
import { LeftNav } from "./LeftNav";
import { LoadingState } from "../../models/loadingState";
import { RequestsList } from "../shared/RequestsList";
import { SharedServices } from "../shared/SharedServices";
import { SharedServiceItem } from "../shared/SharedServiceItem";
import { SecuredByRole } from "../shared/SecuredByRole";
import { RoleName } from "../../models/roleNames";
import { APIError } from "../../models/exceptions";
import { ExceptionLayout } from "../shared/ExceptionLayout";
import { AppRolesContext } from "../../contexts/AppRolesContext";
import { CostsContext } from "../../contexts/CostsContext";
import config from "../../config.json";

export const RootLayout: React.FunctionComponent = () => {
Expand Down Expand Up @@ -44,7 +48,7 @@ export const RootLayout: React.FunctionComponent = () => {
setLoadingState(LoadingState.Ok);
r && r.workspaces && setWorkspaces(r.workspaces);
} catch (e: any) {
e.userMessage = 'Error retrieving resources';
e.userMessage = "Error retrieving resources";
setApiError(e);
setLoadingState(LoadingState.Error);
}
Expand Down Expand Up @@ -137,35 +141,67 @@ export const RootLayout: React.FunctionComponent = () => {
case LoadingState.Ok:
return (
<>
{
loadingCostState === LoadingState.Error &&
{loadingCostState === LoadingState.Error && (
<ExceptionLayout e={costApiError} />
}
<Stack horizontal className='tre-body-inner'>
<Stack.Item className='tre-left-nav' style={{ marginTop: 2 }}>
)}
<Stack horizontal className="tre-body-inner">
<Stack.Item className="tre-left-nav" style={{ marginTop: 2 }}>
<LeftNav />
</Stack.Item><Stack.Item id="tre-body" className='tre-body-content'>
</Stack.Item>
<Stack.Item id="tre-body" className="tre-body-content">
<Routes>
<Route path="/" element={
<RootDashboard
workspaces={workspaces}
addWorkspace={(w: Workspace) => addWorkspace(w)}
updateWorkspace={(w: Workspace) => updateWorkspace(w)}
removeWorkspace={(w: Workspace) => removeWorkspace(w)} />
} />
<Route
path="/"
element={
<RootDashboard
workspaces={workspaces}
addWorkspace={(w: Workspace) => addWorkspace(w)}
updateWorkspace={(w: Workspace) => updateWorkspace(w)}
removeWorkspace={(w: Workspace) => removeWorkspace(w)}
/>
}
/>
<Route path="/admin" element={<Admin />} />
<Route path="/shared-services/*" element={
<Routes>
<Route path="/" element={<SecuredByRole element={<SharedServices />} allowedAppRoles={[RoleName.TREAdmin]} errorString={"You must be a TRE Admin to access this area"} />} />
<Route path=":sharedServiceId" element={<SecuredByRole element={<SharedServiceItem />} allowedAppRoles={[RoleName.TREAdmin]} errorString={"You must be a TRE Admin to access this area"} />} />
</Routes>
} />
<Route path="/requests/*" element={
<Routes>
<Route path="/" />
<Route path="airlock/*" element={<RequestsList />} />
</Routes>
} />
<Route
path="/shared-services/*"
element={
<Routes>
<Route
path="/"
element={
<SecuredByRole
element={<SharedServices />}
allowedAppRoles={[RoleName.TREAdmin]}
errorString={
"You must be a TRE Admin to access this area"
}
/>
}
/>
<Route
path=":sharedServiceId"
element={
<SecuredByRole
element={<SharedServiceItem />}
allowedAppRoles={[RoleName.TREAdmin]}
errorString={
"You must be a TRE Admin to access this area"
}
/>
}
/>
</Routes>
}
/>
<Route
path="/requests/*"
element={
<Routes>
<Route path="/" />
<Route path="airlock/*" element={<RequestsList />} />
</Routes>
}
/>
</Routes>
</Stack.Item>
</Stack>
Expand Down
Loading

0 comments on commit 06dab06

Please sign in to comment.