Migrate activities (#2545)
* Start * Migrate activities to flexible schema
This commit is contained in:
@ -8,8 +8,6 @@ import { ComponentWithRouterDecorator } from '~/testing/decorators/ComponentWith
|
||||
import { graphqlMocks } from '~/testing/graphqlMocks';
|
||||
import { mockedTasks } from '~/testing/mock-data/activities';
|
||||
|
||||
import { ActivityTargetableEntityType } from '../../types/ActivityTargetableEntity';
|
||||
|
||||
const meta: Meta<typeof TaskGroups> = {
|
||||
title: 'Modules/Activity/TaskGroups',
|
||||
component: TaskGroups,
|
||||
@ -37,7 +35,7 @@ export const WithTasks: Story = {
|
||||
args: {
|
||||
entity: {
|
||||
id: mockedTasks[0].authorId,
|
||||
type: ActivityTargetableEntityType.Person,
|
||||
type: 'Person',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import { ReactElement } from 'react';
|
||||
import styled from '@emotion/styled';
|
||||
|
||||
import { TaskForList } from '@/activities/types/TaskForList';
|
||||
import { Activity } from '@/activities/types/Activity';
|
||||
|
||||
import { TaskRow } from './TaskRow';
|
||||
|
||||
type TaskListProps = {
|
||||
title?: string;
|
||||
tasks: TaskForList[];
|
||||
tasks: Omit<Activity, 'assigneeId'>[];
|
||||
button?: ReactElement | false;
|
||||
};
|
||||
|
||||
|
||||
@ -3,12 +3,12 @@ import styled from '@emotion/styled';
|
||||
|
||||
import { ActivityTargetChips } from '@/activities/components/ActivityTargetChips';
|
||||
import { useOpenActivityRightDrawer } from '@/activities/hooks/useOpenActivityRightDrawer';
|
||||
import { Activity } from '@/activities/types/Activity';
|
||||
import { IconCalendar, IconComment } from '@/ui/display/icon';
|
||||
import { OverflowingTextWithTooltip } from '@/ui/display/tooltip/OverflowingTextWithTooltip';
|
||||
import { Checkbox, CheckboxShape } from '@/ui/input/components/Checkbox';
|
||||
import { beautifyExactDate, hasDatePassed } from '~/utils/date-utils';
|
||||
|
||||
import { TaskForList } from '../../types/TaskForList';
|
||||
import { useCompleteTask } from '../hooks/useCompleteTask';
|
||||
|
||||
const StyledContainer = styled.div`
|
||||
@ -61,7 +61,7 @@ const StyledFieldsContainer = styled.div`
|
||||
display: flex;
|
||||
`;
|
||||
|
||||
export const TaskRow = ({ task }: { task: TaskForList }) => {
|
||||
export const TaskRow = ({ task }: { task: Omit<Activity, 'assigneeId'> }) => {
|
||||
const theme = useTheme();
|
||||
const openActivityRightDrawer = useOpenActivityRightDrawer();
|
||||
|
||||
|
||||
@ -1,44 +1,26 @@
|
||||
import { useCallback } from 'react';
|
||||
import { useApolloClient } from '@apollo/client';
|
||||
import { getOperationName } from '@apollo/client/utilities';
|
||||
|
||||
import { Activity, useUpdateActivityMutation } from '~/generated/graphql';
|
||||
|
||||
import { ACTIVITY_UPDATE_FRAGMENT } from '../../graphql/fragments/activityUpdateFragment';
|
||||
import { GET_ACTIVITIES } from '../../graphql/queries/getActivities';
|
||||
import { useUpdateOneObjectRecord } from '@/object-record/hooks/useUpdateOneObjectRecord';
|
||||
import { Activity } from '~/generated/graphql';
|
||||
|
||||
type Task = Pick<Activity, 'id' | 'completedAt'>;
|
||||
|
||||
export const useCompleteTask = (task: Task) => {
|
||||
const [updateActivityMutation] = useUpdateActivityMutation();
|
||||
|
||||
const client = useApolloClient();
|
||||
const cachedTask = client.readFragment({
|
||||
id: `Activity:${task.id}`,
|
||||
fragment: ACTIVITY_UPDATE_FRAGMENT,
|
||||
const { updateOneObject } = useUpdateOneObjectRecord({
|
||||
objectNameSingular: 'activityV2',
|
||||
});
|
||||
|
||||
const completeTask = useCallback(
|
||||
(value: boolean) => {
|
||||
const completedAt = value ? new Date().toISOString() : null;
|
||||
updateActivityMutation({
|
||||
variables: {
|
||||
where: { id: task.id },
|
||||
data: {
|
||||
completedAt,
|
||||
},
|
||||
updateOneObject?.({
|
||||
idToUpdate: task.id,
|
||||
input: {
|
||||
completedAt,
|
||||
},
|
||||
optimisticResponse: {
|
||||
__typename: 'Mutation',
|
||||
updateOneActivity: {
|
||||
...cachedTask,
|
||||
completedAt,
|
||||
},
|
||||
},
|
||||
refetchQueries: [getOperationName(GET_ACTIVITIES) ?? ''],
|
||||
});
|
||||
},
|
||||
[cachedTask, task.id, updateActivityMutation],
|
||||
[task.id, updateOneObject],
|
||||
);
|
||||
|
||||
return {
|
||||
|
||||
@ -3,40 +3,46 @@ import { useRecoilState, useRecoilValue } from 'recoil';
|
||||
|
||||
import { currentUserState } from '@/auth/states/currentUserState';
|
||||
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
|
||||
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
||||
import { turnFilterIntoWhereClause } from '@/ui/object/object-filter-dropdown/utils/turnFilterIntoWhereClause';
|
||||
import { ViewFilterOperand } from '@/views/types/ViewFilterOperand';
|
||||
import { ActivityType, useGetActivitiesQuery } from '~/generated/graphql';
|
||||
import { SortOrder } from '~/generated/graphql';
|
||||
import { ActivityType } from '~/generated-metadata/graphql';
|
||||
import { parseDate } from '~/utils/date-utils';
|
||||
|
||||
export const useCurrentUserTaskCount = () => {
|
||||
const [currentUser] = useRecoilState(currentUserState);
|
||||
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
|
||||
|
||||
const { data } = useGetActivitiesQuery({
|
||||
variables: {
|
||||
where: {
|
||||
type: { equals: ActivityType.Task },
|
||||
completedAt: { equals: null },
|
||||
...(currentUser
|
||||
? turnFilterIntoWhereClause({
|
||||
fieldMetadataId: 'assigneeId',
|
||||
value: currentUser.id,
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue:
|
||||
currentWorkspaceMember?.firstName +
|
||||
' ' +
|
||||
currentWorkspaceMember?.lastName,
|
||||
displayAvatarUrl: currentWorkspaceMember?.avatarUrl ?? undefined,
|
||||
definition: {
|
||||
type: 'ENTITY',
|
||||
},
|
||||
})
|
||||
: {}),
|
||||
},
|
||||
const { objects } = useFindManyObjectRecords({
|
||||
objectNamePlural: 'activitiesV2',
|
||||
filter: {
|
||||
type: { equals: ActivityType.Task },
|
||||
completedAt: { equals: null },
|
||||
...(currentUser
|
||||
? turnFilterIntoWhereClause({
|
||||
fieldMetadataId: 'assigneeId',
|
||||
value: currentUser.id,
|
||||
operand: ViewFilterOperand.Is,
|
||||
displayValue:
|
||||
currentWorkspaceMember?.firstName +
|
||||
' ' +
|
||||
currentWorkspaceMember?.lastName,
|
||||
displayAvatarUrl: currentWorkspaceMember?.avatarUrl ?? undefined,
|
||||
definition: {
|
||||
type: 'ENTITY',
|
||||
},
|
||||
})
|
||||
: {}),
|
||||
},
|
||||
orderBy: [
|
||||
{
|
||||
createdAt: SortOrder.Desc,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const currentUserDueTaskCount = data?.findManyActivities.filter((task) => {
|
||||
const currentUserDueTaskCount = objects.filter((task) => {
|
||||
if (!task.dueAt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -1,9 +1,11 @@
|
||||
import { DateTime } from 'luxon';
|
||||
|
||||
import { Activity } from '@/activities/types/Activity';
|
||||
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
|
||||
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
|
||||
import { useFilter } from '@/ui/object/object-filter-dropdown/hooks/useFilter';
|
||||
import { turnFilterIntoWhereClause } from '@/ui/object/object-filter-dropdown/utils/turnFilterIntoWhereClause';
|
||||
import { ActivityType, useGetActivitiesQuery } from '~/generated/graphql';
|
||||
import { SortOrder } from '~/generated/graphql';
|
||||
import { parseDate } from '~/utils/date-utils';
|
||||
|
||||
export const useTasks = (entity?: ActivityTargetableEntity) => {
|
||||
@ -22,62 +24,64 @@ export const useTasks = (entity?: ActivityTargetableEntity) => {
|
||||
}
|
||||
: Object.assign({}, turnFilterIntoWhereClause(selectedFilter));
|
||||
|
||||
const { data: completeTasksData } = useGetActivitiesQuery({
|
||||
variables: {
|
||||
where: {
|
||||
type: { equals: ActivityType.Task },
|
||||
completedAt: { not: { equals: null } },
|
||||
...whereFilters,
|
||||
},
|
||||
},
|
||||
const { objects: completeTasksData } = useFindManyObjectRecords({
|
||||
objectNamePlural: 'activitiesV2',
|
||||
skip: !entity && !selectedFilter,
|
||||
filter: {
|
||||
type: { equals: 'Task' },
|
||||
completedAt: { not: { equals: null } },
|
||||
...whereFilters,
|
||||
},
|
||||
orderBy: [
|
||||
{
|
||||
createdAt: SortOrder.Desc,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const { data: incompleteTaskData } = useGetActivitiesQuery({
|
||||
variables: {
|
||||
where: {
|
||||
type: { equals: ActivityType.Task },
|
||||
completedAt: { equals: null },
|
||||
...whereFilters,
|
||||
},
|
||||
},
|
||||
const { objects: incompleteTaskData } = useFindManyObjectRecords({
|
||||
objectNamePlural: 'activitiesV2',
|
||||
skip: !entity && !selectedFilter,
|
||||
filter: {
|
||||
type: { equals: 'Task' },
|
||||
completedAt: { equals: null },
|
||||
...whereFilters,
|
||||
},
|
||||
orderBy: [
|
||||
{
|
||||
createdAt: SortOrder.Desc,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
const todayOrPreviousTasks = incompleteTaskData?.findManyActivities.filter(
|
||||
(task) => {
|
||||
if (!task.dueAt) {
|
||||
return false;
|
||||
}
|
||||
const dueDate = parseDate(task.dueAt).toJSDate();
|
||||
const today = DateTime.now().endOf('day').toJSDate();
|
||||
return dueDate <= today;
|
||||
},
|
||||
);
|
||||
const todayOrPreviousTasks = incompleteTaskData?.filter((task) => {
|
||||
if (!task.dueAt) {
|
||||
return false;
|
||||
}
|
||||
const dueDate = parseDate(task.dueAt).toJSDate();
|
||||
const today = DateTime.now().endOf('day').toJSDate();
|
||||
return dueDate <= today;
|
||||
});
|
||||
|
||||
const upcomingTasks = incompleteTaskData?.findManyActivities.filter(
|
||||
(task) => {
|
||||
if (!task.dueAt) {
|
||||
return false;
|
||||
}
|
||||
const dueDate = parseDate(task.dueAt).toJSDate();
|
||||
const today = DateTime.now().endOf('day').toJSDate();
|
||||
return dueDate > today;
|
||||
},
|
||||
);
|
||||
const upcomingTasks = incompleteTaskData?.filter((task) => {
|
||||
if (!task.dueAt) {
|
||||
return false;
|
||||
}
|
||||
const dueDate = parseDate(task.dueAt).toJSDate();
|
||||
const today = DateTime.now().endOf('day').toJSDate();
|
||||
return dueDate > today;
|
||||
});
|
||||
|
||||
const unscheduledTasks = incompleteTaskData?.findManyActivities.filter(
|
||||
(task) => {
|
||||
return !task.dueAt;
|
||||
},
|
||||
);
|
||||
const unscheduledTasks = incompleteTaskData?.filter((task) => {
|
||||
return !task.dueAt;
|
||||
});
|
||||
|
||||
const completedTasks = completeTasksData?.findManyActivities;
|
||||
const completedTasks = completeTasksData;
|
||||
|
||||
return {
|
||||
todayOrPreviousTasks: todayOrPreviousTasks ?? [],
|
||||
upcomingTasks: upcomingTasks ?? [],
|
||||
unscheduledTasks: unscheduledTasks ?? [],
|
||||
completedTasks: completedTasks ?? [],
|
||||
todayOrPreviousTasks: (todayOrPreviousTasks ?? []) as Activity[],
|
||||
upcomingTasks: (upcomingTasks ?? []) as Activity[],
|
||||
unscheduledTasks: (unscheduledTasks ?? []) as Activity[],
|
||||
completedTasks: (completedTasks ?? []) as Activity[],
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user