Fix Activities and Tasks modules (#2561)

* Fix activities

* Fix Timeline

* Refactor useCreateOne and useUpdateOne records

* Fix seeds
This commit is contained in:
Charles Bochet
2023-11-17 16:24:58 +01:00
committed by GitHub
parent a6d8cdb116
commit baf1260443
23 changed files with 259 additions and 222 deletions

View File

@ -63,7 +63,7 @@ export const ActivityComments = ({
}: ActivityCommentsProps) => {
const currentUser = useRecoilValue(currentUserState);
const { createOneObject } = useCreateOneObjectRecord({
objectNamePlural: 'commentsV2',
objectNameSingular: 'commentV2',
});
if (!currentUser) {

View File

@ -86,8 +86,8 @@ export const ActivityEditor = ({
activity.completedAt ?? '',
);
const containerRef = useRef<HTMLDivElement>(null);
const { updateOneObject } = useUpdateOneObjectRecord({
objectNamePlural: 'activitiesV2',
const { updateOneObject } = useUpdateOneObjectRecord<Activity>({
objectNameSingular: 'activityV2',
});
const updateTitle = useCallback(

View File

@ -16,8 +16,8 @@ export const useHandleCheckableActivityTargetChange = ({
> | null;
};
}) => {
const { createOneObject } = useCreateOneObjectRecord({
objectNamePlural: 'activityTargetV2',
const { createOneObject } = useCreateOneObjectRecord<ActivityTarget>({
objectNameSingular: 'activityTargetV2',
});
const { deleteOneObject } = useDeleteOneObjectRecord({
objectNamePlural: 'activityTargetV2',

View File

@ -1,8 +1,7 @@
import { useRecoilState, useRecoilValue } from 'recoil';
import { v4 } from 'uuid';
import { Activity, ActivityType } from '@/activities/types/Activity';
import { currentUserState } from '@/auth/states/currentUserState';
import { ActivityTarget } from '@/activities/types/ActivityTarget';
import { currentWorkspaceMemberState } from '@/auth/states/currentWorkspaceMemberState';
import { useCreateOneObjectRecord } from '@/object-record/hooks/useCreateOneObjectRecord';
import { useRightDrawer } from '@/ui/layout/right-drawer/hooks/useRightDrawer';
@ -13,14 +12,18 @@ import { useSetHotkeyScope } from '@/ui/utilities/hotkey/hooks/useSetHotkeyScope
import { activityTargetableEntityArrayState } from '../states/activityTargetableEntityArrayState';
import { viewableActivityIdState } from '../states/viewableActivityIdState';
import { ActivityTargetableEntity } from '../types/ActivityTargetableEntity';
import { getRelationData } from '../utils/getRelationData';
import { getTargetableEntitiesWithParents } from '../utils/getTargetableEntitiesWithParents';
export const useOpenCreateActivityDrawer = () => {
const { openRightDrawer } = useRightDrawer();
const { createOneObject } = useCreateOneObjectRecord({
objectNamePlural: 'activitiesV2',
});
const currentUser = useRecoilValue(currentUserState);
const { createOneObject: createOneActivityTarget } =
useCreateOneObjectRecord<ActivityTarget>({
objectNameSingular: 'activityTargetV2',
});
const { createOneObject: createOneActivity } =
useCreateOneObjectRecord<Activity>({
objectNameSingular: 'activityV2',
});
const currentWorkspaceMember = useRecoilValue(currentWorkspaceMemberState);
const setHotkeyScope = useSetHotkeyScope();
@ -29,7 +32,7 @@ export const useOpenCreateActivityDrawer = () => {
);
const [, setViewableActivityId] = useRecoilState(viewableActivityIdState);
return ({
return async ({
type,
targetableEntities,
assigneeId,
@ -38,33 +41,35 @@ export const useOpenCreateActivityDrawer = () => {
targetableEntities?: ActivityTargetableEntity[];
assigneeId?: string;
}) => {
const now = new Date().toISOString();
const targetableEntitiesWithRelations = targetableEntities
? getTargetableEntitiesWithParents(targetableEntities)
: [];
createOneObject?.({
id: v4(),
createdAt: now,
updatedAt: now,
author: { connect: { id: currentUser?.id ?? '' } },
workspaceMemberAuthor: {
connect: { id: currentWorkspaceMember?.id ?? '' },
},
assignee: { connect: { id: assigneeId ?? currentUser?.id ?? '' } },
workspaceMemberAssignee: {
connect: { id: currentWorkspaceMember?.id ?? '' },
},
const createdActivity = await createOneActivity?.({
authorId: currentWorkspaceMember?.id,
assigneeId: assigneeId ?? currentWorkspaceMember?.id,
type: type,
activityTargets: {
createMany: {
data: targetableEntities ? getRelationData(targetableEntities) : [],
skipDuplicates: true,
},
},
onCompleted: (data: Activity) => {
setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false });
setViewableActivityId(data.id);
setActivityTargetableEntityArray(targetableEntities ?? []);
openRightDrawer(RightDrawerPages.CreateActivity);
},
});
if (!createdActivity) {
return;
}
await Promise.all(
targetableEntitiesWithRelations.map(async (targetableEntity) => {
await createOneActivityTarget?.({
companyId:
targetableEntity.type === 'Company' ? targetableEntity.id : null,
personId:
targetableEntity.type === 'Person' ? targetableEntity.id : null,
activityId: createdActivity.id,
});
}),
);
setHotkeyScope(RightDrawerHotkeyScope.RightDrawer, { goto: false });
setViewableActivityId(createdActivity.id);
setActivityTargetableEntityArray(targetableEntities ?? []);
openRightDrawer(RightDrawerPages.CreateActivity);
};
};

View File

@ -1,45 +1,20 @@
import { DateTime } from 'luxon';
import { useRecoilState, useRecoilValue } from 'recoil';
import { 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 { 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 { objects } = useFindManyObjectRecords({
objectNamePlural: 'activitiesV2',
filter: {
type: { equals: ActivityType.Task },
type: { eq: 'Task' },
completedAt: { eq: null },
...(currentUser
? turnFilterIntoWhereClause({
fieldMetadataId: 'assigneeId',
value: currentUser.id,
operand: ViewFilterOperand.Is,
displayValue:
currentWorkspaceMember?.firstName +
' ' +
currentWorkspaceMember?.lastName,
displayAvatarUrl: currentWorkspaceMember?.avatarUrl ?? undefined,
definition: {
type: 'ENTITY',
},
})
: {}),
assigneeId: { eq: currentWorkspaceMember?.id },
},
orderBy: [
{
createdAt: SortOrder.Desc,
},
],
});
const currentUserDueTaskCount = objects.filter((task) => {

View File

@ -4,11 +4,9 @@ import styled from '@emotion/styled';
import { ActivityCreateButton } from '@/activities/components/ActivityCreateButton';
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
import { Activity } from '@/activities/types/Activity';
import { ActivityForDrawer } from '@/activities/types/ActivityForDrawer';
import { ActivityTargetableEntity } from '@/activities/types/ActivityTargetableEntity';
import { useFindManyObjectRecords } from '@/object-record/hooks/useFindManyObjectRecords';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import { SortOrder } from '~/generated/graphql';
import { TimelineItemsContainer } from './TimelineItemsContainer';
@ -50,22 +48,29 @@ const StyledEmptyTimelineSubTitle = styled.div`
`;
export const Timeline = ({ entity }: { entity: ActivityTargetableEntity }) => {
const { objects, loading } = useFindManyObjectRecords({
const { objects: activityTargets, loading } = useFindManyObjectRecords({
objectNamePlural: 'activityTargetsV2',
filter: {
or: {
companyId: { eq: entity.id },
personId: { eq: entity.id },
},
},
});
const { objects: activities } = useFindManyObjectRecords({
skip: !activityTargets?.length,
objectNamePlural: 'activitiesV2',
filter: {
companyId: { eq: entity.id },
activityTargets: { in: activityTargets?.map((at) => at.id) },
},
orderBy: {
createdAt: 'AscNullsFirst',
},
orderBy: [
{
createdAt: SortOrder.Desc,
},
],
});
const openCreateActivity = useOpenCreateActivityDrawer();
const activities: ActivityForDrawer[] = (objects ?? []) as Activity[];
if (loading) {
return <></>;
}
@ -95,7 +100,7 @@ export const Timeline = ({ entity }: { entity: ActivityTargetableEntity }) => {
return (
<StyledMainContainer>
<TimelineItemsContainer activities={activities} />
<TimelineItemsContainer activities={activities as Activity[]} />
</StyledMainContainer>
);
};

View File

@ -1,32 +0,0 @@
import { v4 } from 'uuid';
import { ActivityTargetCreateManyActivityInput } from '~/generated/graphql';
import { ActivityTargetableEntity } from '../types/ActivityTargetableEntity';
export const getRelationData = (
entities: ActivityTargetableEntity[],
): ActivityTargetCreateManyActivityInput[] => {
const now = new Date().toISOString();
const relationData: ActivityTargetCreateManyActivityInput[] = [];
for (const entity of entities ?? []) {
relationData.push({
companyId: entity.type === 'Company' ? entity.id : null,
personId: entity.type === 'Person' ? entity.id : null,
id: v4(),
createdAt: now,
});
if (entity.relatedEntities) {
for (const relatedEntity of entity.relatedEntities ?? []) {
relationData.push({
companyId: relatedEntity.type === 'Company' ? relatedEntity.id : null,
personId: relatedEntity.type === 'Person' ? relatedEntity.id : null,
id: v4(),
createdAt: now,
});
}
}
}
return relationData;
};

View File

@ -0,0 +1,16 @@
import { ActivityTargetableEntity } from '../types/ActivityTargetableEntity';
export const getTargetableEntitiesWithParents = (
entities: ActivityTargetableEntity[],
): ActivityTargetableEntity[] => {
const entitiesWithRelations: ActivityTargetableEntity[] = [];
for (const entity of entities ?? []) {
entitiesWithRelations.push(entity);
if (entity.relatedEntities) {
for (const relatedEntity of entity.relatedEntities ?? []) {
entitiesWithRelations.push(relatedEntity);
}
}
}
return entitiesWithRelations;
};