Skip to content

Commit

Permalink
Merge pull request #721 from joshunrau/v1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
joshunrau authored Feb 26, 2024
2 parents a598cd1 + 49dfe77 commit 49c3f2b
Show file tree
Hide file tree
Showing 31 changed files with 321 additions and 505 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/issues.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ jobs:
label:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v4
- name: Run Script
uses: actions/github-script@v7
with:
script: |
require('./.github/scripts/issues.cjs')()
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
</a>
<h3 align="center">Open Data Capture</h3>
<p align="center">
A modern, user-friendly web application for standardized data capture in medical research
An electronic data capture platform designed for administering remote and in-person clinical instruments, including both interactive tasks and forms
<br />
<a href="https://opendatacapture.org/docs">
<strong>Explore the docs »
Expand Down
14 changes: 10 additions & 4 deletions apps/gateway/src/Root.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { NotificationHub, useNotificationsStore } from '@douglasneuroinformatics/ui';
import { BaseLanguageToggle, NotificationHub, ThemeToggle, useNotificationsStore } from '@douglasneuroinformatics/ui';
import type { UpdateAssignmentData } from '@open-data-capture/common/assignment';
import { $Json } from '@open-data-capture/common/core';
import { InstrumentRenderer } from '@open-data-capture/instrument-renderer';
import { Navbar } from '@open-data-capture/react-core';
import { Branding } from '@open-data-capture/react-core';
import axios from 'axios';
import { useTranslation } from 'react-i18next';

Expand Down Expand Up @@ -43,8 +43,14 @@ export const Root = ({ bundle, id, token }: RootProps) => {

return (
<div className="flex h-screen flex-col">
<header>
<Navbar i18n={i18n} />
<header className="fixed top-0 z-10 w-full bg-white/80 text-slate-700 shadow backdrop-blur-lg dark:bg-slate-800/75 dark:text-slate-300">
<div className="container flex items-center justify-between bg-inherit py-3 font-medium">
<Branding className="[&>span]:hidden sm:[&>span]:block" />
<div className="flex gap-3 bg-inherit">
<ThemeToggle />
<BaseLanguageToggle i18n={i18n} options={['en', 'fr']} />
</div>
</div>
</header>
<main className="container flex max-w-3xl flex-grow flex-col pb-16 pt-32 xl:max-w-5xl">
<InstrumentRenderer bundle={bundle} className="min-h-full w-full" onSubmit={handleSubmit} />
Expand Down
2 changes: 0 additions & 2 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,8 @@
"@open-data-capture/instrument-renderer": "workspace:*",
"@open-data-capture/instrument-utils": "workspace:*",
"@open-data-capture/react-core": "workspace:*",
"@react-spring/web": "^9.7.3",
"@tanstack/react-query": "^5.17.9",
"@tanstack/react-query-devtools": "^5.17.9",
"@use-gesture/react": "^10.3.0",
"axios": "^1.6.5",
"clsx": "^2.1.0",
"framer-motion": "^10.18.0",
Expand Down
2 changes: 0 additions & 2 deletions apps/web/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import { ErrorBoundary } from 'react-error-boundary';

import { Router } from '@/Router';
import { ActiveVisit } from '@/components/ActiveVisit';
import { LoadingFallback } from '@/components/LoadingFallback';
import { SetupProvider } from '@/features/setup';
import { queryClient } from '@/services/react-query';
Expand All @@ -21,7 +20,6 @@ export const App = () => {
<React.Suspense fallback={<LoadingFallback />}>
<ErrorBoundary FallbackComponent={ErrorFallback}>
<QueryClientProvider client={queryClient}>
<ActiveVisit />
<NotificationHub />
<SetupProvider>
<Router />
Expand Down
41 changes: 0 additions & 41 deletions apps/web/src/components/ActiveVisit/ActiveVisit.stories.tsx

This file was deleted.

74 changes: 0 additions & 74 deletions apps/web/src/components/ActiveVisit/ActiveVisit.tsx

This file was deleted.

1 change: 0 additions & 1 deletion apps/web/src/components/ActiveVisit/index.ts

This file was deleted.

68 changes: 6 additions & 62 deletions apps/web/src/components/Layout/Layout.tsx
Original file line number Diff line number Diff line change
@@ -1,73 +1,17 @@
import { useEffect, useState } from 'react';

import { AdjustmentsHorizontalIcon, ChartBarIcon, EyeIcon, UserPlusIcon } from '@heroicons/react/24/solid';
import { type NavItem, Navbar } from '@open-data-capture/react-core';
import { useTranslation } from 'react-i18next';
import { Outlet, useLocation, useNavigate } from 'react-router-dom';

import { useAuthStore } from '@/stores/auth-store';
import { Outlet } from 'react-router-dom';

import { Footer } from './Footer';
import { Navbar } from './Navbar';
import { Sidebar } from './Sidebar';

export const Layout = () => {
const { currentUser } = useAuthStore();
const [navItems, setNavItems] = useState<NavItem[]>([]);
const { i18n, t } = useTranslation('layout');
const navigate = useNavigate();
const location = useLocation();

useEffect(() => {
const items: NavItem[] = [
{
'data-cy': 'overview',
icon: ChartBarIcon,
id: '/overview',
label: t('navLinks.overview')
}
];
if (currentUser?.ability.can('create', 'Visit')) {
items.push({
'data-cy': 'add-visit',
icon: UserPlusIcon,
id: '/visits/add-visit',
label: t('navLinks.addVisit')
});
}
if (currentUser?.ability.can('read', 'Subject') && currentUser.ability.can('read', 'InstrumentRecord')) {
items.push({
'data-cy': 'view-subjects',
icon: EyeIcon,
id: '/subjects',
label: t(`navLinks.viewSubjects`)
});
}
if (currentUser?.ability.can('manage', 'Instrument')) {
items.push({
'data-cy': 'manage-instrument',
icon: AdjustmentsHorizontalIcon,
id: '/instruments/manage-instruments',
label: t('navLinks.manageInstruments')
});
}
if (currentUser?.ability.can('create', 'InstrumentRecord')) {
items.push({
'data-cy': 'view-instrument',
icon: EyeIcon,
id: '/instruments/available-instruments',
label: t('navLinks.availableInstruments')
});
}
setNavItems(items);
}, [currentUser, i18n.resolvedLanguage]);

return (
<div className="flex h-screen w-screen flex-col md:flex-row">
<div className="print:hidden md:hidden">
<Navbar activeItemId={location.pathname} i18n={i18n} items={navItems} onNavigate={navigate} />
<div className="md:hidden print:hidden">
<Navbar />
</div>
<div className="hidden print:hidden md:flex md:flex-shrink-0">
<Sidebar activeItemId={location.pathname} items={navItems} onNavigate={navigate} />
<div className="hidden md:flex md:flex-shrink-0 print:hidden">
<Sidebar />
</div>
<div className="scrollbar-none flex flex-grow flex-col overflow-y-scroll pt-16 md:pt-0">
<main className="container flex flex-grow flex-col">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,25 +1,22 @@
import { Slider, ThemeToggle } from '@douglasneuroinformatics/ui';
import { Branding } from '@open-data-capture/react-core';
import { useTranslation } from 'react-i18next';

import { Branding } from '../Branding';
import { Navigation } from './Navigation';

import type { NavI18Next, NavItem } from './types';

export type MobileSliderProps = {
activeItemId?: string;
i18n: NavI18Next;
isOpen: boolean;
items: NavItem[];
onNavigate?: (id: string) => void;
setIsOpen: (isOpen: boolean) => void;
};

export const MobileSlider = ({ activeItemId, i18n, isOpen, items, onNavigate, setIsOpen }: MobileSliderProps) => {
export const MobileSlider = ({ isOpen, onNavigate, setIsOpen }: MobileSliderProps) => {
const { i18n } = useTranslation();
return (
<Slider isOpen={isOpen} setIsOpen={setIsOpen} title={<Branding />}>
<div className="flex h-full flex-col">
<div className="flex-grow">
<Navigation activeItemId={activeItemId} items={items} orientation="vertical" onNavigate={onNavigate} />
<Navigation isAlwaysDark={false} orientation="vertical" onNavigate={onNavigate} />
</div>
<div className="flex items-center justify-between text-slate-700 dark:text-slate-300">
<button
Expand Down
50 changes: 50 additions & 0 deletions apps/web/src/components/Layout/NavButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { cn } from '@douglasneuroinformatics/ui';

export type NavButtonProps = {
[key: `data-${string}`]: unknown;
activeClassName?: string;
className?: string;
disabled?: boolean;
icon?: React.ComponentType<Omit<React.SVGProps<SVGSVGElement>, 'ref'>>;
isActive: boolean;
label: string;
onClick?: () => void;
variant: 'horizontal' | 'vertical';
};

export const NavButton = ({
activeClassName,
className,
icon: Icon,
isActive,
label,
variant,
...props
}: NavButtonProps) => {
return (
<button
className={cn(
'flex w-full items-center p-2 text-slate-700 hover:text-slate-900 disabled:opacity-75 disabled:hover:cursor-not-allowed dark:text-slate-300 dark:hover:text-slate-100',
{
'justify-start': variant === 'vertical',
'mx-1 justify-center': variant === 'horizontal'
},
className,
isActive && (activeClassName ?? 'text-slate-900 dark:text-slate-100')
)}
type="button"
{...props}
>
{Icon && (
<Icon
className={cn('mr-2', {
hidden: variant === 'horizontal'
})}
height={16}
width={16}
/>
)}
{label}
</button>
);
};
Loading

0 comments on commit 49c3f2b

Please sign in to comment.