Skip to content

Commit

Permalink
feat: list reordering (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
Razboy20 authored Mar 13, 2024
1 parent 91f62e1 commit 038ebaa
Show file tree
Hide file tree
Showing 7 changed files with 187 additions and 98 deletions.
52 changes: 35 additions & 17 deletions src/stories/components/Dropdown.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import type { Meta, StoryObj } from '@storybook/react';
import List from '@views/components/common/List/List';
import ScheduleDropdown from '@views/components/common/ScheduleDropdown/ScheduleDropdown';
import ScheduleListItem from '@views/components/common/ScheduleListItem/ScheduleListItem';
import useSchedules, { switchSchedule } from '@views/hooks/useSchedules';
import useSchedules, { getActiveSchedule, switchSchedule } from '@views/hooks/useSchedules';
import type { Serialized } from 'chrome-extension-toolkit';
import React from 'react';
import React, { useEffect } from 'react';

import { exampleSchedule } from '../injected/mocked';

Expand Down Expand Up @@ -47,27 +47,45 @@ const meta: Meta<typeof ScheduleDropdown> = {
},
},
},
render: (args: any) => (
<div className='w-80'>
<ScheduleDropdown {...args}>
<List
draggableElements={schedules.map((schedule, index) => {
const [activeSchedule] = useSchedules();
return (
render: (args: any) => {
// eslint-disable-next-line react-hooks/rules-of-hooks
const [activeSchedule, schedules] = useSchedules();

// eslint-disable-next-line react-hooks/rules-of-hooks
useEffect(() => {
console.log(activeSchedule);
}, [activeSchedule]);

return (
<div className='w-80'>
<ScheduleDropdown {...args}>
<List
draggables={schedules}
equalityCheck={(a, b) => a.name === b.name}
onReordered={reordered => {
const activeSchedule = getActiveSchedule();
const activeIndex = reordered.findIndex(s => s.name === activeSchedule.name);

// don't care about the promise
UserScheduleStore.set('schedules', reordered);
UserScheduleStore.set('activeIndex', activeIndex);
}}
gap={10}
>
{(schedule, handleProps) => (
<ScheduleListItem
active={activeSchedule?.name === schedule.name}
name={schedule.name}
onClick={() => {
switchSchedule(schedule.name);
}}
dragHandleProps={handleProps}
/>
);
})}
gap={10}
/>
</ScheduleDropdown>
</div>
),
)}
</List>
</ScheduleDropdown>
</div>
);
},
} satisfies Meta<typeof ScheduleDropdown>;
export default meta;

Expand Down
12 changes: 7 additions & 5 deletions src/stories/components/List.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { DraggableProvidedDragHandleProps } from '@hello-pangea/dnd';
import { Course, Status } from '@shared/types/Course';
import { CourseMeeting } from '@shared/types/CourseMeeting';
import Instructor from '@shared/types/Instructor';
Expand Down Expand Up @@ -71,9 +72,10 @@ const generateCourses = (count: number): Course[] => {
};

const exampleCourses = generateCourses(numberOfCourses);
const generateCourseBlocks = (exampleCourses: Course[], colors: CourseColors[]) =>
exampleCourses.map((course, i) => <PopupCourseBlock key={course.uniqueId} course={course} colors={colors[i]} />);
const ExampleCourseBlocks = generateCourseBlocks(exampleCourses, tailwindColorways);
const generateCourseBlocks = (
{ course, colors }: { course: Course; colors: CourseColors },
dragHandleProps: DraggableProvidedDragHandleProps
) => <PopupCourseBlock key={course.uniqueId} course={course} colors={colors} dragHandleProps={dragHandleProps} />;

const meta = {
title: 'Components/Common/List',
Expand All @@ -83,7 +85,6 @@ const meta = {
},
tags: ['autodocs'],
argTypes: {
draggableElements: { control: 'object' },
gap: { control: 'number' },
},
} satisfies Meta<typeof List>;
Expand All @@ -93,7 +94,8 @@ type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
draggableElements: ExampleCourseBlocks,
draggables: exampleCourses.map((course, i) => ({ course, colors: tailwindColorways[i] })),
children: generateCourseBlocks,
gap: 12,
},
render: args => (
Expand Down
49 changes: 38 additions & 11 deletions src/views/components/PopupMain.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { UserScheduleStore } from '@shared/storage/UserScheduleStore';
import { tailwindColorways } from '@shared/util/storybook';
import Divider from '@views/components/common/Divider/Divider';
import ExtensionRoot from '@views/components/common/ExtensionRoot/ExtensionRoot';
import List from '@views/components/common/List/List';
import PopupCourseBlock from '@views/components/common/PopupCourseBlock/PopupCourseBlock';
import Text from '@views/components/common/Text/Text';
import { handleOpenCalendar } from '@views/components/injected/CourseCatalogInjectedPopup/HeadingAndActions';
import useSchedules, { switchSchedule } from '@views/hooks/useSchedules';
import useSchedules, { getActiveSchedule, replaceSchedule, switchSchedule } from '@views/hooks/useSchedules';
import { openTabFromContentScript } from '@views/lib/openNewTabFromContentScript';
import clsx from 'clsx';
import React, { useState } from 'react';
Expand All @@ -16,6 +16,7 @@ import SettingsIcon from '~icons/material-symbols/settings';

import CourseStatus from './common/CourseStatus/CourseStatus';
import { LogoIcon } from './common/LogoIcon';
import PopupCourseBlock from './common/PopupCourseBlock/PopupCourseBlock';
import ScheduleDropdown from './common/ScheduleDropdown/ScheduleDropdown';
import ScheduleListItem from './common/ScheduleListItem/ScheduleListItem';

Expand Down Expand Up @@ -61,27 +62,53 @@ export default function PopupMain(): JSX.Element {
<div className='px-5 pb-2.5 pt-3.75'>
<ScheduleDropdown>
<List
draggableElements={schedules.map((schedule, index) => (
draggables={schedules}
equalityCheck={(a, b) => a.name === b.name}
onReordered={reordered => {
const activeSchedule = getActiveSchedule();
const activeIndex = reordered.findIndex(s => s.name === activeSchedule.name);

// don't care about the promise
UserScheduleStore.set('schedules', reordered);
UserScheduleStore.set('activeIndex', activeIndex);
}}
gap={10}
>
{(schedule, handleProps) => (
<ScheduleListItem
active={false}
name={schedule.name}
onClick={() => {
switchSchedule(schedule.name);
}}
dragHandleProps={handleProps}
/>
))}
gap={10}
/>
)}
</List>
</ScheduleDropdown>
</div>
<div className='flex-1 self-stretch overflow-y-auto px-5'>
{activeSchedule?.courses?.length > 0 && (
<List
draggableElements={activeSchedule?.courses.map((course, i) => (
<PopupCourseBlock key={course.uniqueId} course={course} colors={tailwindColorways[i]} />
))}
draggables={activeSchedule.courses.map((course, i) => ({
course,
colors: tailwindColorways[i],
}))}
onReordered={reordered => {
activeSchedule.courses = reordered.map(c => c.course);
replaceSchedule(getActiveSchedule(), activeSchedule);
}}
equalityCheck={(a, b) => a.course.uniqueId === b.course.uniqueId}
gap={10}
/>
>
{({ course, colors }, handleProps) => (
<PopupCourseBlock
key={course.uniqueId}
course={course}
colors={colors}
dragHandleProps={handleProps}
/>
)}
</List>
)}
</div>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { background } from '@shared/messages';
import { UserScheduleStore } from '@shared/storage/UserScheduleStore';
import type { UserSchedule } from '@shared/types/UserSchedule';
import List from '@views/components/common/List/List';
import ScheduleListItem from '@views/components/common/ScheduleListItem/ScheduleListItem';
import Text from '@views/components/common/Text/Text';
import useSchedules from '@views/hooks/useSchedules';
import useSchedules, { getActiveSchedule, switchSchedule } from '@views/hooks/useSchedules';
import React, { useEffect, useState } from 'react';

import AddSchedule from '~icons/material-symbols/add';
Expand Down Expand Up @@ -47,20 +48,6 @@ export function CalendarSchedules({ style, dummySchedules, dummyActiveIndex }: P
setNewSchedule(e.target.value);
};

const selectItem = (index: number) => {
background.switchSchedule({ scheduleName: schedules[index].name }).then(() => {
setActiveScheduleIndex(index);
});
};

const scheduleComponents = schedules.map((schedule, index) => (
<ScheduleListItem
active={index === activeScheduleIndex}
name={schedule.name}
onClick={() => selectItem(index)}
/>
));

const fixBuildError = {
dummySchedules,
dummyActiveIndex,
Expand All @@ -78,7 +65,29 @@ export function CalendarSchedules({ style, dummySchedules, dummyActiveIndex }: P
</div>
</div>
<div className='flex flex-col space-y-2.5'>
<List gap={10} draggableElements={scheduleComponents} />
<List
gap={10}
draggables={schedules}
equalityCheck={(a, b) => a.name === b.name}
onReordered={reordered => {
const activeSchedule = getActiveSchedule();
const activeIndex = reordered.findIndex(s => s.name === activeSchedule.name);

// don't care about the promise
UserScheduleStore.set('schedules', reordered);
UserScheduleStore.set('activeIndex', activeIndex);
}}
>
{(schedule, handleProps) => (
<ScheduleListItem
name={schedule.name}
onClick={() => {
switchSchedule(schedule.name);
}}
dragHandleProps={handleProps}
/>
)}
</List>
<input
type='text'
placeholder='Enter new schedule'
Expand Down
Loading

0 comments on commit 038ebaa

Please sign in to comment.