Skip to content

Commit

Permalink
feat(website): organism selector on mobile navigation #543
Browse files Browse the repository at this point in the history
  • Loading branch information
fengelniederhammer committed Nov 27, 2023
1 parent 5a573be commit 1851d8d
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 53 deletions.
30 changes: 5 additions & 25 deletions website/src/components/Navigation/Navigation.astro
Original file line number Diff line number Diff line change
@@ -1,37 +1,17 @@
---
import { SandwichMenu } from './SandwichMenu.tsx';
import { getConfiguredOrganisms } from '../../config';
import { navigationItems, routes } from '../../routes';
import { cleanOrganism } from './cleanOrganism';
import { navigationItems } from '../../routes';
let organism = Astro.params.organism;
const organisms = getConfiguredOrganisms();
if (organism !== undefined && !organisms.includes(organism)) {
organism = undefined;
}
const label = organism === undefined ? 'Choose Organism' : `Organism ${organism}`;
const { organism, knownOrganisms } = cleanOrganism(Astro.params.organism);
---

<div class='flex justify-end'>
<div class='dropdown dropdown-hover'>
<label tabindex='0' class='btn m-1'>{label}</label>
<ul tabindex='0' class='dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52'>
{
organisms.map((organism) => (
<li>
<a href={routes.organismStartPage(organism)}>{organism}</a>
</li>
))
}
</ul>
</div>
<div class='subtitle hidden sm:flex sm:z-6 gap-4'>
{navigationItems.top(organism).map(({ text, path }) => <a href={path}>{text}</a>)}
{navigationItems.top(organism?.key).map(({ text, path }) => <a href={path}>{text}</a>)}
</div>

<div class='sm:hidden fixed z-0'>
<SandwichMenu top={16} right={28} organism={organism} client:load />
<SandwichMenu top={16} right={28} organism={organism} knownOrganisms={knownOrganisms} client:load />
</div>
</div>
25 changes: 25 additions & 0 deletions website/src/components/Navigation/OrganismSelector.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
import { cleanOrganism } from './cleanOrganism';
import { routes } from '../../routes';
import Arrow from '~icons/ic/sharp-keyboard-arrow-down';
const { knownOrganisms, organism } = cleanOrganism(Astro.params.organism);
const label = organism === undefined ? 'Choose Organism' : organism.displayName;
---

<div class='dropdown dropdown-hover'>
<label tabindex='0' class='btn btn-sm m-1 py-2'>
{label}
<Arrow />
</label>
<ul tabindex='0' class='dropdown-content z-[1] menu p-2 shadow bg-base-100 rounded-box w-52'>
{
knownOrganisms.map((knownOrganism) => (
<li>
<a href={routes.organismStartPage(knownOrganism.key)}>{knownOrganism.displayName}</a>
</li>
))
}
</ul>
</div>
36 changes: 23 additions & 13 deletions website/src/components/Navigation/SandwichMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
import type { FC } from 'react';

import type { Organism } from '../../config.ts';
import { useOffCanvas } from '../../hooks/useOffCanvas';
import { navigationItems } from '../../routes.ts';
import { navigationItems, routes } from '../../routes.ts';
import { OffCanvasOverlay } from '../OffCanvasOverlay';
import { SandwichIcon } from '../SandwichIcon';

type SandwichMenuProps = {
top: number;
right: number;
organism: string | undefined;
organism: Organism | undefined;
knownOrganisms: Organism[];
};

export const SandwichMenu: FC<SandwichMenuProps> = ({ organism, top, right }) => {
export const SandwichMenu: FC<SandwichMenuProps> = ({ top, right, organism, knownOrganisms }) => {
const { isOpen, toggle: toggleMenu, close: closeMenu } = useOffCanvas();

return (
Expand All @@ -37,8 +39,17 @@ export const SandwichMenu: FC<SandwichMenuProps> = ({ organism, top, right }) =>
<a href='/'>Pathoplexus</a>
</div>
<div className='flex-grow divide-y-2 divide-gray-300 divide-solid border-t-2 border-b-2 border-gray-300 border-solid '>
{navigationItems.top(organism).map(({ text, path }) => (
<OffCanvasNavItem key={path} text={text} path={path} />
<OffCanvasNavItem key='organism-selector' text='Select organism' level={1} path={false} />
{knownOrganisms.map((organism) => (
<OffCanvasNavItem
key={organism.key}
text={organism.displayName}
level={2}
path={routes.organismStartPage(organism.key)}
/>
))}
{navigationItems.top(organism?.key).map(({ text, path }) => (
<OffCanvasNavItem key={path} text={text} level={1} path={path} />
))}
</div>
</div>
Expand All @@ -52,7 +63,7 @@ export const SandwichMenu: FC<SandwichMenuProps> = ({ organism, top, right }) =>

<div className='font-light divide-y-2 divide-gray-300 divide-solid border-t-2 border-b-2 border-gray-300 border-solid '>
{navigationItems.bottom.map(({ text, path }) => (
<OffCanvasNavItem key={path} text={text} path={path} type='small' />
<OffCanvasNavItem key={path} text={text} level={1} path={path} type='small' />
))}
</div>
</div>
Expand All @@ -64,20 +75,19 @@ export const SandwichMenu: FC<SandwichMenuProps> = ({ organism, top, right }) =>

type OffCanvasNavItemProps = {
text: string;
path: string;
path: string | false;
level: 1 | 2;
type?: 'small';
};

const OffCanvasNavItem: FC<OffCanvasNavItemProps> = ({ text, path, type }) => {
const OffCanvasNavItem: FC<OffCanvasNavItemProps> = ({ text, level, path, type }) => {
const height = type === 'small' ? 'py-1' : 'py-3';

return (
<div>
<a href={path}>
<div className={` flex items-center`}>
<div className={`pl-4 ${height} `}>{text}</div>
</div>
</a>
<div className='flex items-center'>
<div className={`ml-${4 * level} ${height}`}>{path === false ? text : <a href={path}> {text}</a>}</div>

This comment has been minimized.

Copy link
@corneliusroemer

corneliusroemer Feb 25, 2024

Contributor

dynamic classes don't work with tailwind, see #1107

@fengelniederhammer for the future ;)

</div>
</div>
);
};
10 changes: 10 additions & 0 deletions website/src/components/Navigation/cleanOrganism.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { getConfiguredOrganisms } from '../../config.ts';

export function cleanOrganism(organism: string | undefined) {
const knownOrganisms = getConfiguredOrganisms();

return {
knownOrganisms,
organism: knownOrganisms.find((it) => it.key === organism),
};
}
2 changes: 1 addition & 1 deletion website/src/components/User/UserPage.astro
Original file line number Diff line number Diff line change
Expand Up @@ -20,5 +20,5 @@ const organism: string | undefined = Astro.params.organism;
)
}

<a href={routes.userPage(organism, 'testuser')}>Login as testuser</a>
{organism !== undefined && <a href={routes.userPage(organism, 'testuser')}>Login as testuser</a>}
</BaseLayout>
10 changes: 9 additions & 1 deletion website/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,16 @@ function getWebsiteConfig(): WebsiteConfig {
return _config;
}

export type Organism = {
key: string;
displayName: string;
};

export function getConfiguredOrganisms() {
return Object.keys(getWebsiteConfig().instances);
return Object.entries(getWebsiteConfig().instances).map(([key, instance]) => ({
key,
displayName: instance.schema.instanceName,
}));
}

function getConfig(organism: string): InstanceConfig {
Expand Down
10 changes: 7 additions & 3 deletions website/src/layouts/BaseLayout.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
---
import '../styles/base.scss';
import Navigation from '../components/Navigation/Navigation.astro';
import OrganismSelector from '../components/Navigation/OrganismSelector.astro';
import { navigationItems } from '../routes';
const { title } = Astro.props;
Expand All @@ -19,8 +20,11 @@ const { title } = Astro.props;
<header class='sticky z-30 top-0 bg-white h-20'>
<nav class='flex justify-between items-center p-4'>
<div class='flex justify-start'>
<a href='/'><img class='h-8 mr-4' src='/favicon.svg' /></a>
<a href='/' class='fancytitle'>Pathoplexus</a>
<a href='/'><img class='h-8 mr-4' src='/favicon.svg' alt='icon' /></a>
<a href='/' class='fancytitle mr-4'>Pathoplexus</a>
<div class='hidden sm:flex'>
<OrganismSelector />
</div>
</div>
<Navigation />
</nav>
Expand All @@ -44,7 +48,7 @@ const { title } = Astro.props;
</div>

<a href='https://github.com/pathoplexus' class='h-full py-6'>
<img src='/github-mark.svg' class='h-full object-scale-down' />
<img src='/github-mark.svg' class='h-full object-scale-down' alt='github-icon' />
</a>
</footer>
</div>
Expand Down
6 changes: 5 additions & 1 deletion website/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,11 @@ export async function getKeycloakClient() {
export const onRequest = defineMiddleware(async (context, next) => {
let token = await getTokenFromCookie(context);

if (isPublicRoute(context.url.pathname, getConfiguredOrganisms())) {
const urlIsPublicRoute = isPublicRoute(
context.url.pathname,
getConfiguredOrganisms().map((it) => it.key),
);
if (urlIsPublicRoute) {
if (token === undefined) {
context.locals.session = {
isLoggedIn: false,
Expand Down
7 changes: 6 additions & 1 deletion website/src/pages/[organism]/index.astro
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
---
import { BackButton } from '../../components/Navigation/BackButton';
import BaseLayout from '../../layouts/BaseLayout.astro';
const organism = Astro.params.organism;
---

<BaseLayout title={organism}>
Hello {organism}
<div class='flex items-center'>
<BackButton marginRight={2} client:load />
<h1 class='title'>Organism {organism}</h1>
</div>
</BaseLayout>
11 changes: 3 additions & 8 deletions website/src/pages/index.astro
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
---
import { getConfiguredOrganisms, getSchema } from '../config';
import { getConfiguredOrganisms } from '../config';
import BaseLayout from '../layouts/BaseLayout.astro';
import { routes } from '../routes';
const organisms = getConfiguredOrganisms().map((organism) => ({
organism,
name: getSchema(organism).instanceName,
}));
---

<BaseLayout title='Home'>
<h1 class='title'>Pathoplexus</h1>
<h2 class='font-bold'>Explore the data</h2>
{
organisms.map(({ organism, name }) => (
getConfiguredOrganisms().map(({ key, displayName }) => (
<p>
<a href={routes.organismStartPage(organism)}>{name}</a>
<a href={routes.organismStartPage(key)}>{displayName}</a>
</p>
))
}
Expand Down

0 comments on commit 1851d8d

Please sign in to comment.