Migrate to a monorepo structure (#2909)
This commit is contained in:
80
packages/twenty-front/src/pages/tasks/Tasks.tsx
Normal file
80
packages/twenty-front/src/pages/tasks/Tasks.tsx
Normal file
@ -0,0 +1,80 @@
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { TasksRecoilScopeContext } from '@/activities/states/recoil-scope-contexts/TasksRecoilScopeContext';
|
||||
import { PageAddTaskButton } from '@/activities/tasks/components/PageAddTaskButton';
|
||||
import { TaskGroups } from '@/activities/tasks/components/TaskGroups';
|
||||
import { ObjectFilterDropdownButton } from '@/object-record/object-filter-dropdown/components/ObjectFilterDropdownButton';
|
||||
import { RelationPickerHotkeyScope } from '@/object-record/relation-picker/types/RelationPickerHotkeyScope';
|
||||
import { IconArchive, IconCheck, IconCheckbox } from '@/ui/display/icon/index';
|
||||
import { PageBody } from '@/ui/layout/page/PageBody';
|
||||
import { PageContainer } from '@/ui/layout/page/PageContainer';
|
||||
import { PageHeader } from '@/ui/layout/page/PageHeader';
|
||||
import { TabList } from '@/ui/layout/tab/components/TabList';
|
||||
import { TopBar } from '@/ui/layout/top-bar/TopBar';
|
||||
import { RecoilScope } from '@/ui/utilities/recoil-scope/components/RecoilScope';
|
||||
|
||||
import { TasksEffect } from './TasksEffect';
|
||||
|
||||
const StyledTasksContainer = styled.div`
|
||||
display: flex;
|
||||
flex: 1;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
overflow: auto;
|
||||
`;
|
||||
|
||||
const StyledTabListContainer = styled.div`
|
||||
align-items: end;
|
||||
display: flex;
|
||||
height: 40px;
|
||||
margin-left: ${({ theme }) => `-${theme.spacing(2)}`};
|
||||
`;
|
||||
|
||||
export const Tasks = () => {
|
||||
const TASK_TABS = [
|
||||
{
|
||||
id: 'to-do',
|
||||
title: 'To do',
|
||||
Icon: IconCheck,
|
||||
},
|
||||
{
|
||||
id: 'done',
|
||||
title: 'Done',
|
||||
Icon: IconArchive,
|
||||
},
|
||||
];
|
||||
|
||||
const filterDropdownId = 'tasks-assignee-filter';
|
||||
|
||||
return (
|
||||
<PageContainer>
|
||||
<RecoilScope CustomRecoilScopeContext={TasksRecoilScopeContext}>
|
||||
<TasksEffect filterDropdownId={filterDropdownId} />
|
||||
<PageHeader title="Tasks" Icon={IconCheckbox}>
|
||||
<PageAddTaskButton filterDropdownId={filterDropdownId} />
|
||||
</PageHeader>
|
||||
<PageBody>
|
||||
<StyledTasksContainer>
|
||||
<TopBar
|
||||
leftComponent={
|
||||
<StyledTabListContainer>
|
||||
<TabList context={TasksRecoilScopeContext} tabs={TASK_TABS} />
|
||||
</StyledTabListContainer>
|
||||
}
|
||||
rightComponent={
|
||||
<ObjectFilterDropdownButton
|
||||
filterDropdownId={filterDropdownId}
|
||||
key="tasks-filter-dropdown-button"
|
||||
hotkeyScope={{
|
||||
scope: RelationPickerHotkeyScope.RelationPicker,
|
||||
}}
|
||||
/>
|
||||
}
|
||||
/>
|
||||
<TaskGroups filterDropdownId={filterDropdownId} />
|
||||
</StyledTasksContainer>
|
||||
</PageBody>
|
||||
</RecoilScope>
|
||||
</PageContainer>
|
||||
);
|
||||
};
|
||||
41
packages/twenty-front/src/pages/tasks/TasksEffect.tsx
Normal file
41
packages/twenty-front/src/pages/tasks/TasksEffect.tsx
Normal file
@ -0,0 +1,41 @@
|
||||
import { useEffect } from 'react';
|
||||
import { useRecoilValue } from 'recoil';
|
||||
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { useFilterDropdown } from '@/object-record/object-filter-dropdown/hooks/useFilterDropdown';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
|
||||
import { tasksFilterDefinitions } from './tasks-filter-definitions';
|
||||
|
||||
type TasksEffectProps = {
|
||||
filterDropdownId: string;
|
||||
};
|
||||
|
||||
export const TasksEffect = ({ filterDropdownId }: TasksEffectProps) => {
|
||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||
const { setSelectedFilter, setAvailableFilterDefinitions } =
|
||||
useFilterDropdown({
|
||||
filterDropdownId: filterDropdownId,
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
setAvailableFilterDefinitions(tasksFilterDefinitions);
|
||||
}, [setAvailableFilterDefinitions]);
|
||||
|
||||
useEffect(() => {
|
||||
if (currentWorkspaceMember) {
|
||||
setSelectedFilter({
|
||||
fieldMetadataId: 'assigneeId',
|
||||
value: currentWorkspaceMember.id,
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue:
|
||||
currentWorkspaceMember.name?.firstName +
|
||||
' ' +
|
||||
currentWorkspaceMember.name?.lastName,
|
||||
displayAvatarUrl: currentWorkspaceMember.avatarUrl ?? undefined,
|
||||
definition: tasksFilterDefinitions[0],
|
||||
});
|
||||
}
|
||||
}, [currentWorkspaceMember, setSelectedFilter]);
|
||||
return <></>;
|
||||
};
|
||||
@ -0,0 +1,31 @@
|
||||
import { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import { AppPath } from '@/types/AppPath';
|
||||
import {
|
||||
PageDecorator,
|
||||
PageDecoratorArgs,
|
||||
} from '~/testing/decorators/PageDecorator';
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
import { sleep } from '~/testing/sleep';
|
||||
|
||||
import { Tasks } from '../Tasks';
|
||||
|
||||
const meta: Meta<PageDecoratorArgs> = {
|
||||
title: 'Pages/Tasks/Default',
|
||||
component: Tasks,
|
||||
decorators: [PageDecorator],
|
||||
args: { routePath: AppPath.TasksPage },
|
||||
parameters: {
|
||||
msw: graphqlMocks,
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
|
||||
export type Story = StoryObj<typeof Tasks>;
|
||||
|
||||
export const Default: Story = {
|
||||
play: async () => {
|
||||
await sleep(100);
|
||||
},
|
||||
};
|
||||
@ -0,0 +1,16 @@
|
||||
import { Activity } from '@/activities/types/Activity';
|
||||
import { FilterDefinitionByEntity } from '@/object-record/object-filter-dropdown/types/FilterDefinitionByEntity';
|
||||
import { IconUserCircle } from '@/ui/display/icon';
|
||||
|
||||
export const tasksFilterDefinitions: FilterDefinitionByEntity<Activity>[] = [
|
||||
{
|
||||
fieldMetadataId: 'assigneeId',
|
||||
label: 'Assignee',
|
||||
iconName: 'IconUser',
|
||||
type: 'RELATION',
|
||||
relationObjectMetadataNamePlural: 'workspaceMembers',
|
||||
relationObjectMetadataNameSingular: 'workspaceMember',
|
||||
selectAllLabel: 'All assignees',
|
||||
SelectAllIcon: IconUserCircle,
|
||||
},
|
||||
];
|
||||
Reference in New Issue
Block a user