diff --git a/app/src/components/Layout.tsx b/app/src/components/Layout.tsx
index 6044216a..92d64f4a 100644
--- a/app/src/components/Layout.tsx
+++ b/app/src/components/Layout.tsx
@@ -1,31 +1,39 @@
+import { useSelector } from 'react-redux';
import { Outlet } from 'react-router-dom';
-import { AppShell, Box } from '@mantine/core';
-import { spacing } from '../designTokens';
+import { AppShell } from '@mantine/core';
+import { spacing } from '@/designTokens';
+import { RootState } from '@/store';
+import HeaderBar from './shared/HeaderBar';
import Sidebar from './Sidebar';
export default function Layout() {
+ const { currentFrame } = useSelector((state: RootState) => state.flow);
+
+ // If PolicyParameterSelectorFrame is active, let it manage its own layout completely
+ if (currentFrame === 'PolicyParameterSelectorFrame') {
+ return ;
+ }
+
+ // Otherwise, render the normal layout with AppShell
return (
-
+
+
+
+
+
-
-
-
+
);
diff --git a/app/src/components/Sidebar.tsx b/app/src/components/Sidebar.tsx
index 53e38ec6..d0cae8ce 100644
--- a/app/src/components/Sidebar.tsx
+++ b/app/src/components/Sidebar.tsx
@@ -12,7 +12,6 @@ import { useLocation } from 'react-router-dom';
import { Box, Button, Divider, Stack, Text } from '@mantine/core';
import { colors, spacing, typography } from '../designTokens';
import SidebarDivider from './sidebar/SidebarDivider';
-import SidebarLogo from './sidebar/SidebarLogo';
import SidebarNavItem from './sidebar/SidebarNavItem';
import SidebarSection from './sidebar/SidebarSection';
import SidebarUser from './sidebar/SidebarUser';
@@ -55,8 +54,7 @@ export default function Sidebar({ isOpen = true }: SidebarProps) {
bg="white"
style={{
borderRight: `1px solid ${colors.border.light}`,
- width: parseInt(spacing.layout.sidebarWidth, 10),
- position: 'fixed',
+ width: parseInt(spacing.appShell.navbar.width, 10),
left: 0,
top: 0,
overflowY: 'auto',
@@ -64,9 +62,6 @@ export default function Sidebar({ isOpen = true }: SidebarProps) {
gap={0}
>
-
-
-
}
@@ -76,12 +71,9 @@ export default function Sidebar({ isOpen = true }: SidebarProps) {
h={36}
styles={{
root: {
- backgroundColor: colors.primary[500],
+ backgroundColor: colors.primary[600],
fontSize: typography.fontSize.sm,
fontWeight: typography.fontWeight.medium,
- '&:hover': {
- backgroundColor: colors.primary[600],
- },
},
}}
>
@@ -127,7 +119,7 @@ export default function Sidebar({ isOpen = true }: SidebarProps) {
-
+
Running 2 items
@@ -165,7 +157,7 @@ export default function Sidebar({ isOpen = true }: SidebarProps) {
View Report
-
+
diff --git a/app/src/components/policyParameterSelectorFrame/Header.tsx b/app/src/components/policyParameterSelectorFrame/Footer.tsx
similarity index 78%
rename from app/src/components/policyParameterSelectorFrame/Header.tsx
rename to app/src/components/policyParameterSelectorFrame/Footer.tsx
index 86b797b8..9826e15b 100644
--- a/app/src/components/policyParameterSelectorFrame/Header.tsx
+++ b/app/src/components/policyParameterSelectorFrame/Footer.tsx
@@ -1,14 +1,12 @@
import { useDispatch } from 'react-redux';
-import { Button, Group, Text } from '@mantine/core';
+import { Button, Group } from '@mantine/core';
import { clearPolicy } from '@/reducers/policyReducer';
import { FlowComponentProps } from '@/types/flow';
-export default function PolicyParameterSelectorHeader({
+export default function PolicyParameterSelectorFooter({
onNavigate,
onReturn,
}: FlowComponentProps) {
- // TODO: Determine how to handle policy number
-
const dispatch = useDispatch();
function handleNext() {
@@ -27,7 +25,6 @@ export default function PolicyParameterSelectorHeader({
- Policy #NUMBER
diff --git a/app/src/components/shared/HeaderBar.tsx b/app/src/components/shared/HeaderBar.tsx
new file mode 100644
index 00000000..3f7b4fb8
--- /dev/null
+++ b/app/src/components/shared/HeaderBar.tsx
@@ -0,0 +1,45 @@
+import { Box, Text } from '@mantine/core';
+import PolicyEngineLogo from '@/assets/policyengine-logo.svg';
+import { colors, spacing } from '@/designTokens';
+
+interface HeaderBarProps {
+ title?: string;
+ children?: React.ReactNode;
+ showLogo?: boolean;
+}
+
+export default function HeaderBar({ title, children, showLogo = false }: HeaderBarProps) {
+ return (
+
+
+ {showLogo && (
+
+ )}
+ {title && (
+
+ {title}
+
+ )}
+
+ {children}
+
+ );
+}
diff --git a/app/src/designTokens/spacing.ts b/app/src/designTokens/spacing.ts
index fd07bbbd..1868b9f9 100644
--- a/app/src/designTokens/spacing.ts
+++ b/app/src/designTokens/spacing.ts
@@ -46,6 +46,32 @@ export const spacing = {
sideGutter: '200px', // TODO: Make this responsive/attempt to use 'container'
},
+ // AppShell design tokens
+ appShell: {
+ header: {
+ height: '40px',
+ padding: '8px 16px',
+ },
+ navbar: {
+ width: '300px',
+ padding: '0px',
+ breakpoint: 'sm',
+ },
+ aside: {
+ width: '300px',
+ padding: '16px',
+ breakpoint: 'md',
+ },
+ footer: {
+ height: '60px',
+ padding: '12px 24px',
+ },
+ main: {
+ padding: '24px',
+ minHeight: '100vh',
+ },
+ },
+
// Container padding
container: {
xs: '16px',
diff --git a/app/src/frames/policy/PolicyParameterSelectorFrame.tsx b/app/src/frames/policy/PolicyParameterSelectorFrame.tsx
index cf7972b0..23d9d0e4 100644
--- a/app/src/frames/policy/PolicyParameterSelectorFrame.tsx
+++ b/app/src/frames/policy/PolicyParameterSelectorFrame.tsx
@@ -2,10 +2,12 @@ import { useState } from 'react';
import { useSelector } from 'react-redux';
import { AppShell, Text } from '@mantine/core';
import { useDisclosure } from '@mantine/hooks';
-import Header from '@/components/policyParameterSelectorFrame/Header';
+import Footer from '@/components/policyParameterSelectorFrame/Footer';
import Main from '@/components/policyParameterSelectorFrame/Main';
import MainEmpty from '@/components/policyParameterSelectorFrame/MainEmpty';
import Menu from '@/components/policyParameterSelectorFrame/Menu';
+import HeaderBar from '@/components/shared/HeaderBar';
+import { spacing } from '@/designTokens';
import { RootState } from '@/store';
import { FlowComponentProps } from '@/types/flow';
import { ParameterMetadata } from '@/types/metadata/parameterMetadata';
@@ -49,23 +51,17 @@ export default function PolicyParameterSelectorFrame({
return (
-
-
+
+
@@ -87,7 +83,13 @@ export default function PolicyParameterSelectorFrame({
- TODO: Footer
+
);
diff --git a/app/src/styles/components.ts b/app/src/styles/components.ts
index fac89698..28f896f9 100644
--- a/app/src/styles/components.ts
+++ b/app/src/styles/components.ts
@@ -1,5 +1,5 @@
// Components submodule for Mantine theme
-import { Card, Container, Title } from '@mantine/core';
+import { AppShell, Card, Container, Title } from '@mantine/core';
import { colors, spacing, typography } from '../designTokens';
import { themeDefaults } from './defaults';
@@ -217,4 +217,20 @@ export const themeComponents = {
return {};
},
}),
+
+ AppShell: AppShell.extend({
+ defaultProps: {
+ padding: spacing.appShell.main.padding,
+ withBorder: true,
+ },
+ styles: {
+ main: {
+ minHeight: spacing.appShell.main.minHeight,
+ backgroundColor: colors.gray[50],
+ },
+ navbar: {
+ padding: spacing.appShell.navbar.padding,
+ },
+ },
+ }),
};