Skip to content

Commit

Permalink
work on tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
narthur committed Nov 8, 2022
1 parent 4fb430c commit 1d7473e
Show file tree
Hide file tree
Showing 8 changed files with 62 additions and 170 deletions.
2 changes: 2 additions & 0 deletions global-setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ beforeEach(() => {
fetchMock.resetMocks();
deleteAllCookies();
window.localStorage.clear();
vi.setSystemTime(new Date('2020-01-01T00:00:00.000Z'));

vi.mocked(getCheckoutSession).mockResolvedValue({
id: 'session',
});
Expand Down
64 changes: 7 additions & 57 deletions src/App.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,22 +58,6 @@ describe('App', () => {
);
});

it('re-scrolls tasks list when today icon clicked', async () => {
vi.setSystemTime(new Date('1/1/2020'));

loadTasksApiData({
tasks: [makeTask({ due: '1/1/2020, 11:59 PM', task: 'task 1' })],
});

renderPage();

await userEvent.click(await screen.findByLabelText('today'));

await waitFor(() => {
expect(__listRef.scrollTo).toHaveBeenCalledWith(0);
});
});

it('has filter entries', async () => {
renderPage();

Expand Down Expand Up @@ -188,25 +172,6 @@ describe('App', () => {
resolve();
});

it('scrolls to today', async () => {
vi.setSystemTime(new Date('1/7/2020'));

loadTasksApiData({
tasks: [
makeTask({ due: '1/1/2020, 11:59 PM', task: 'task 1' }),
makeTask({ due: '1/7/2020, 11:59 PM', task: 'task 1' }),
],
});

renderPage();

await userEvent.click(await screen.findByLabelText('today'));

await waitFor(() => {
expect(__listRef.scrollTo).toHaveBeenCalledWith(2);
});
});

it('prevents adding task with due date in the past', async () => {
vi.setSystemTime(new Date('1/1/2023'));

Expand All @@ -233,9 +198,7 @@ describe('App', () => {
});

it('allows user to create new task based on existing task', async () => {
// User should be able to select "Copy" from a task's context menu. This
// should open the "New Task" form, prefilling the form with the existing
// task's title, due date, and stakes.
vi.setSystemTime(new Date('1/29/2020'));

loadTasksApiData({
tasks: [makeTask({ task: 'the_task' })],
Expand All @@ -254,6 +217,8 @@ describe('App', () => {
});

it('copies task name into form when copying task', async () => {
vi.setSystemTime(new Date('1/29/2020'));

loadTasksApiData({
tasks: [makeTask({ task: 'the_task' })],
});
Expand Down Expand Up @@ -292,6 +257,8 @@ describe('App', () => {
});

it('copies task stakes into form when copying task', async () => {
vi.setSystemTime(new Date('1/29/2020'));

loadTasksApiData({
tasks: [makeTask({ cents: 100 })],
});
Expand All @@ -308,26 +275,9 @@ describe('App', () => {
expect(await screen.findByLabelText('Stakes *')).toHaveValue(1);
});

it('sets date input to one week in future when copying task with due date in past', async () => {
vi.setSystemTime('2/1/2020');

loadTasksApiData({
tasks: [makeTask({ due: '1/1/2020, 11:59 PM' })],
});

renderPage();

await screen.findByText('the_task');

await userEvent.click(await screen.findByLabelText('Menu'));
await userEvent.click(screen.getByText('Copy'));

expect(await screen.findByLabelText('Due Date *')).toHaveValue(
'02/08/2020'
);
});

it('closes menu when clicking copy', async () => {
vi.setSystemTime(new Date('1/29/2020'));

loadTasksApiData({
tasks: [makeTask({ task: 'the_task' })],
});
Expand Down
11 changes: 5 additions & 6 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,15 +46,11 @@ function usePageViews(): void {
}

export function App(): JSX.Element {
const [lastToday, setLastToday] = useState<Date>();
const [lastToday] = useState<Date>();
const ref = useRef<HTMLElement>();
const location = useLocation();
const queryClient = getQueryClient();

const handleTodayClick = () => {
setLastToday(browser.getNowDate());
};

useEffect(() => {
document.title = 'TaskRatchet';
}, []);
Expand All @@ -80,7 +76,7 @@ export function App(): JSX.Element {
<QueryClientProvider client={queryClient}>
<CssBaseline />
<Stack sx={{ height: '100vh' }}>
<NavBar onTodayClick={handleTodayClick} />
<NavBar />
<Box ref={ref} overflow={'scroll'} flexGrow={1}>
<Container
maxWidth={'sm'}
Expand All @@ -90,6 +86,9 @@ export function App(): JSX.Element {
}}
>
<Routes>
<Route path="/maybe" element={<>maybe</>} />
<Route path="/archive" element={<>archive</>} />

<Route path={'/register'} element={<RegisterForm />} />

<Route
Expand Down
6 changes: 0 additions & 6 deletions src/components/organisms/NavBar.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -82,12 +82,6 @@ describe('NavBar', () => {
expect(screen.queryByText('Logout')).not.toBeInTheDocument();
});

it('has today button', async () => {
renderComponent();

await screen.findByLabelText('today');
});

it('closes drawer on navigate', async () => {
mockUseSession.mockReturnValue({
email: 'the_email',
Expand Down
79 changes: 41 additions & 38 deletions src/components/organisms/NavBar.tsx
Original file line number Diff line number Diff line change
@@ -1,25 +1,23 @@
import React, { useEffect, useState } from 'react';
import { Link } from 'react-router-dom';
import { useLocation, useNavigate } from 'react-router-dom';
import { useLocation } from 'react-router-dom';
import NavDrawer from '../molecules/NavDrawer';
import FilterButton from '../molecules/FilterButton';
import { AppBar, Box, IconButton, Toolbar, Tooltip } from '@mui/material';
import { Today, Menu } from '@mui/icons-material';
import {
AppBar,
Box,
Button,
IconButton,
Toolbar,
Tooltip,
} from '@mui/material';
import { Menu } from '@mui/icons-material';
import LoadingIndicator from '../molecules/LoadingIndicator';

interface NavBarProps {
onTodayClick?: () => void;
}

export default function NavBar({ onTodayClick }: NavBarProps): JSX.Element {
export default function NavBar(): JSX.Element {
const location = useLocation();
const navigate = useNavigate();
const [isOpen, setIsOpen] = useState<boolean>(false);
const toggleMenu = () => setIsOpen(!isOpen);
const handleTodayClick = () => {
onTodayClick && onTodayClick();
navigate('/');
};

useEffect(() => setIsOpen(false), [location]);

Expand All @@ -29,12 +27,15 @@ export default function NavBar({ onTodayClick }: NavBarProps): JSX.Element {
<LoadingIndicator />
</Box>

<Toolbar>
<Toolbar
sx={{
justifyContent: 'space-between',
}}
>
<Link
to={'/'}
style={{
display: 'flex',
flexGrow: 1,
}}
>
<img
Expand All @@ -45,31 +46,33 @@ export default function NavBar({ onTodayClick }: NavBarProps): JSX.Element {
/>
</Link>

<FilterButton />
<Box>
<Button color="inherit" component={Link} to={'/'}>
Next
</Button>
<Button color="inherit" component={Link} to={'/maybe'}>
Maybe
</Button>
<Button color="inherit" component={Link} to={'/archive'}>
Archive
</Button>
</Box>

<Tooltip title={'Jump to Today'}>
<IconButton
onClick={handleTodayClick}
edge="start"
color="inherit"
aria-label="today"
sx={{ m: 0.1 }}
>
<Today />
</IconButton>
</Tooltip>
<Box>
<FilterButton />

<Tooltip title={'Menu'}>
<IconButton
onClick={toggleMenu}
edge="start"
color="inherit"
aria-label="menu"
sx={{ m: 0.1 }}
>
<Menu />
</IconButton>
</Tooltip>
<Tooltip title={'Menu'}>
<IconButton
onClick={toggleMenu}
edge="start"
color="inherit"
aria-label="menu"
sx={{ m: 0.1 }}
>
<Menu />
</IconButton>
</Tooltip>
</Box>
</Toolbar>

<NavDrawer isOpen={isOpen} onClose={toggleMenu} />
Expand Down
20 changes: 4 additions & 16 deletions src/components/organisms/TaskList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,18 @@ import Task from '../molecules/Task';
import useFilters from '../../lib/useFilters';

interface TaskListProps {
lastToday?: Date;
newTask?: TaskType;
}

function isTask(value: unknown): value is TaskType {
return Object.prototype.hasOwnProperty.call(value || {}, 'task');
}

const TaskList = ({ lastToday, newTask }: TaskListProps): JSX.Element => {
const TaskList = ({ newTask }: TaskListProps): JSX.Element => {
const { data: tasks, isFetched } = useTasks();
const { filters } = useFilters();
const listRef = useRef<ReactList>(null);
const [entries, setEntries] = useState<(TaskType | string)[]>([]);
const [nextHeadingIndex, setNextHeadingIndex] = useState<number>();
const [newTaskIndex, setNewTaskIndex] = useState<number>();
const [index, setIndex] = useState<number>(0);
const [shouldScroll, setShouldScroll] = useState<boolean>(false);
Expand All @@ -30,22 +28,12 @@ const TaskList = ({ lastToday, newTask }: TaskListProps): JSX.Element => {
const sorted = sortTasks(tasks || []);
const filtered = filters ? sorted.filter((t) => filters[t.status]) : sorted;

const {
entries: newEntries,
nextHeadingIndex: headingIndexUpdate,
newTaskIndex: taskIndexUpdate,
} = createListItems(filtered, newTask);
const { entries: newEntries, newTaskIndex: taskIndexUpdate } =
createListItems(filtered, newTask);

setNextHeadingIndex(headingIndexUpdate);
setEntries(newEntries);
setNewTaskIndex(taskIndexUpdate);
}, [tasks, newTask, filters, nextHeadingIndex]);

useEffect(() => {
if (nextHeadingIndex === undefined) return;
setIndex(nextHeadingIndex);
setShouldScroll(true);
}, [nextHeadingIndex, isFetched, lastToday]);
}, [tasks, newTask, filters]);

useEffect(() => {
if (newTaskIndex === undefined) return;
Expand Down
42 changes: 1 addition & 41 deletions src/components/pages/Tasks.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ const renderTasksPage = () => {
describe('tasks page', () => {
beforeEach(() => {
vi.resetAllMocks();
vi.setSystemTime(new Date('10/29/2020'));
vi.setSystemTime(new Date('1/29/2020'));
vi.spyOn(browser, 'scrollIntoView').mockImplementation(() => undefined);
});

Expand Down Expand Up @@ -571,46 +571,6 @@ describe('tasks page', () => {
expect(screen.queryByText('Nothing here!')).not.toBeInTheDocument();
});

it('scrolls list', async () => {
vi.setSystemTime(new Date('1/1/2020'));

loadTasksApiData({
tasks: [makeTask()],
});

renderTasksPage();

await waitFor(() => {
expect(__listRef.scrollTo).toBeCalled();
});
});

it('does not scroll list on page refocus', async () => {
vi.setSystemTime(new Date('1/1/2020'));

loadTasksApiData({
tasks: [makeTask()],
});

const { queryClient } = renderTasksPage();

await waitFor(() => {
expect(__listRef.scrollTo).toBeCalled();
});

loadTasksApiData({
tasks: [makeTask()],
});

await queryClient.invalidateQueries('tasks');

await waitFor(() => {
expect(getTasks).toBeCalledTimes(2);
});

expect(__listRef.scrollTo).toBeCalledTimes(1);
});

it('reloads tasks on task edit save', async () => {
loadTasksApiData({
tasks: [makeTask()],
Expand Down
Loading

1 comment on commit 1d7473e

@github-actions
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.