Improved activity editor re-renders (#4149)

* Refactor task count

* Fixed show page rerender

* Less rerenders and way better title and body UX

* Finished breaking down activity editor subscriptions

* Removed console.log

* Last console.log

* Fixed bugs and cleaned
This commit is contained in:
Lucas Bordeau
2024-02-23 17:54:27 +01:00
committed by GitHub
parent 5de1c2c31d
commit fb920a92e7
48 changed files with 1114 additions and 527 deletions

View File

@ -1,14 +1,14 @@
import { useLocation } from 'react-router-dom';
import styled from '@emotion/styled';
import { isNonEmptyArray } from '@sniptt/guards';
import { useRecoilState, useRecoilValue } from 'recoil';
import { useRecoilCallback, useRecoilState, useRecoilValue } from 'recoil';
import { useDeleteActivityFromCache } from '@/activities/hooks/useDeleteActivityFromCache';
import { useOpenCreateActivityDrawer } from '@/activities/hooks/useOpenCreateActivityDrawer';
import { useRemoveFromActivitiesQueries } from '@/activities/hooks/useRemoveFromActivitiesQueries';
import { useRemoveFromActivityTargetsQueries } from '@/activities/hooks/useRemoveFromActivityTargetsQueries';
import { currentNotesQueryVariablesState } from '@/activities/notes/states/currentNotesQueryVariablesState';
import { activityInDrawerState } from '@/activities/states/activityInDrawerState';
import { activityIdInDrawerState } from '@/activities/states/activityIdInDrawerState';
import { activityTargetableEntityArrayState } from '@/activities/states/activityTargetableEntityArrayState';
import { isActivityInCreateModeState } from '@/activities/states/isActivityInCreateModeState';
import { isUpsertingActivityInDBState } from '@/activities/states/isCreatingActivityInDBState';
@ -17,11 +17,13 @@ import { viewableActivityIdState } from '@/activities/states/viewableActivityIdS
import { currentCompletedTaskQueryVariablesState } from '@/activities/tasks/states/currentCompletedTaskQueryVariablesState';
import { currentIncompleteTaskQueryVariablesState } from '@/activities/tasks/states/currentIncompleteTaskQueryVariablesState';
import { FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY } from '@/activities/timeline/constants/FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY';
import { objectShowPageTargetableObjectState } from '@/activities/timeline/states/objectShowPageTargetableObjectState';
import { objectShowPageTargetableObjectState } from '@/activities/timeline/states/objectShowPageTargetableObjectIdState';
import { Activity } from '@/activities/types/Activity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { useDeleteManyRecords } from '@/object-record/hooks/useDeleteManyRecords';
import { useDeleteOneRecord } from '@/object-record/hooks/useDeleteOneRecord';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { getChildRelationArray } from '@/object-record/utils/getChildRelationArray';
import { mapToRecordId } from '@/object-record/utils/mapToObjectId';
import { IconPlus, IconTrash } from '@/ui/display/icon';
import { IconButton } from '@/ui/input/button/components/IconButton';
@ -35,7 +37,7 @@ const StyledButtonContainer = styled.div`
export const ActivityActionBar = () => {
const viewableActivityId = useRecoilValue(viewableActivityIdState);
const activityInDrawer = useRecoilValue(activityInDrawerState);
const activityIdInDrawer = useRecoilValue(activityIdInDrawerState);
const activityTargetableEntityArray = useRecoilValue(
activityTargetableEntityArrayState,
@ -60,9 +62,11 @@ export const ActivityActionBar = () => {
const [isUpsertingActivityInDB] = useRecoilState(
isUpsertingActivityInDBState,
);
const objectShowPageTargetableObject = useRecoilValue(
objectShowPageTargetableObjectState,
);
const openCreateActivity = useOpenCreateActivityDrawer();
const currentCompletedTaskQueryVariables = useRecoilValue(
@ -85,90 +89,130 @@ export const ActivityActionBar = () => {
const weAreOnObjectShowPage = pathname.startsWith('/object');
const weAreOnTaskPage = pathname.startsWith('/tasks');
const deleteActivity = async () => {
setIsRightDrawerOpen(false);
if (viewableActivityId) {
if (isActivityInCreateMode && isDefined(temporaryActivityForEditor)) {
deleteActivityFromCache(temporaryActivityForEditor);
setTemporaryActivityForEditor(null);
} else {
if (activityInDrawer) {
const activityTargetIdsToDelete =
activityInDrawer?.activityTargets.map(mapToRecordId) ?? [];
if (weAreOnTaskPage) {
removeFromActivitiesQueries({
activityIdToRemove: viewableActivityId,
targetableObjects: [],
activitiesFilters: currentCompletedTaskQueryVariables?.filter,
activitiesOrderByVariables:
currentCompletedTaskQueryVariables?.orderBy,
});
removeFromActivitiesQueries({
activityIdToRemove: viewableActivityId,
targetableObjects: [],
activitiesFilters: currentIncompleteTaskQueryVariables?.filter,
activitiesOrderByVariables:
currentIncompleteTaskQueryVariables?.orderBy,
});
} else if (
weAreOnObjectShowPage &&
isDefined(objectShowPageTargetableObject)
) {
removeFromActivitiesQueries({
activityIdToRemove: viewableActivityId,
targetableObjects: [objectShowPageTargetableObject],
activitiesFilters: {},
activitiesOrderByVariables:
FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY,
});
if (isDefined(currentCompletedTaskQueryVariables)) {
removeFromActivitiesQueries({
activityIdToRemove: viewableActivityId,
targetableObjects: [objectShowPageTargetableObject],
activitiesFilters: currentCompletedTaskQueryVariables?.filter,
activitiesOrderByVariables:
currentCompletedTaskQueryVariables?.orderBy,
});
}
if (isDefined(currentIncompleteTaskQueryVariables)) {
removeFromActivitiesQueries({
activityIdToRemove: viewableActivityId,
targetableObjects: [objectShowPageTargetableObject],
activitiesFilters: currentIncompleteTaskQueryVariables?.filter,
activitiesOrderByVariables:
currentIncompleteTaskQueryVariables?.orderBy,
});
}
if (isDefined(currentNotesQueryVariables)) {
removeFromActivitiesQueries({
activityIdToRemove: viewableActivityId,
targetableObjects: [objectShowPageTargetableObject],
activitiesFilters: currentNotesQueryVariables?.filter,
activitiesOrderByVariables: currentNotesQueryVariables?.orderBy,
});
}
removeFromActivityTargetsQueries({
activityTargetsToRemove: activityInDrawer?.activityTargets ?? [],
targetableObjects: [objectShowPageTargetableObject],
});
}
if (isNonEmptyArray(activityTargetIdsToDelete)) {
await deleteManyActivityTargets(activityTargetIdsToDelete);
}
await deleteOneActivity?.(viewableActivityId);
const deleteActivity = useRecoilCallback(
({ snapshot }) =>
async () => {
if (!activityIdInDrawer) {
throw new Error(
'activityIdInDrawer is not defined, this should not happen',
);
}
}
}
};
const activity = snapshot
.getLoadable(recordStoreFamilyState(activityIdInDrawer))
.getValue() as Activity;
const activityTargets = getChildRelationArray({
childRelation: activity.activityTargets,
});
setIsRightDrawerOpen(false);
if (viewableActivityId) {
if (isActivityInCreateMode && isDefined(temporaryActivityForEditor)) {
deleteActivityFromCache(temporaryActivityForEditor);
setTemporaryActivityForEditor(null);
} else {
if (activityIdInDrawer) {
const activityTargetIdsToDelete: string[] =
activityTargets.map(mapToRecordId) ?? [];
if (weAreOnTaskPage) {
removeFromActivitiesQueries({
activityIdToRemove: viewableActivityId,
targetableObjects: [],
activitiesFilters: currentCompletedTaskQueryVariables?.filter,
activitiesOrderByVariables:
currentCompletedTaskQueryVariables?.orderBy,
});
removeFromActivitiesQueries({
activityIdToRemove: viewableActivityId,
targetableObjects: [],
activitiesFilters:
currentIncompleteTaskQueryVariables?.filter,
activitiesOrderByVariables:
currentIncompleteTaskQueryVariables?.orderBy,
});
} else if (
weAreOnObjectShowPage &&
isDefined(objectShowPageTargetableObject)
) {
removeFromActivitiesQueries({
activityIdToRemove: viewableActivityId,
targetableObjects: [objectShowPageTargetableObject],
activitiesFilters: {},
activitiesOrderByVariables:
FIND_MANY_TIMELINE_ACTIVITIES_ORDER_BY,
});
if (isDefined(currentCompletedTaskQueryVariables)) {
removeFromActivitiesQueries({
activityIdToRemove: viewableActivityId,
targetableObjects: [objectShowPageTargetableObject],
activitiesFilters:
currentCompletedTaskQueryVariables?.filter,
activitiesOrderByVariables:
currentCompletedTaskQueryVariables?.orderBy,
});
}
if (isDefined(currentIncompleteTaskQueryVariables)) {
removeFromActivitiesQueries({
activityIdToRemove: viewableActivityId,
targetableObjects: [objectShowPageTargetableObject],
activitiesFilters:
currentIncompleteTaskQueryVariables?.filter,
activitiesOrderByVariables:
currentIncompleteTaskQueryVariables?.orderBy,
});
}
if (isDefined(currentNotesQueryVariables)) {
removeFromActivitiesQueries({
activityIdToRemove: viewableActivityId,
targetableObjects: [objectShowPageTargetableObject],
activitiesFilters: currentNotesQueryVariables?.filter,
activitiesOrderByVariables:
currentNotesQueryVariables?.orderBy,
});
}
removeFromActivityTargetsQueries({
activityTargetsToRemove: activity?.activityTargets ?? [],
targetableObjects: [objectShowPageTargetableObject],
});
}
if (isNonEmptyArray(activityTargetIdsToDelete)) {
await deleteManyActivityTargets(activityTargetIdsToDelete);
}
await deleteOneActivity?.(viewableActivityId);
}
}
}
},
[
activityIdInDrawer,
currentCompletedTaskQueryVariables,
currentIncompleteTaskQueryVariables,
currentNotesQueryVariables,
deleteActivityFromCache,
deleteManyActivityTargets,
deleteOneActivity,
isActivityInCreateMode,
objectShowPageTargetableObject,
removeFromActivitiesQueries,
removeFromActivityTargetsQueries,
setTemporaryActivityForEditor,
temporaryActivityForEditor,
viewableActivityId,
weAreOnObjectShowPage,
weAreOnTaskPage,
setIsRightDrawerOpen,
],
);
const record = useRecoilValue(
recordStoreFamilyState(viewableActivityId ?? ''),

View File

@ -1,7 +1,7 @@
import styled from '@emotion/styled';
import { ActivityEditor } from '@/activities/components/ActivityEditor';
import { useActivityById } from '@/activities/hooks/useActivityById';
import { ActivityEditorEffect } from '@/activities/components/ActivityEditorEffect';
const StyledContainer = styled.div`
box-sizing: border-box;
@ -24,18 +24,11 @@ export const RightDrawerActivity = ({
showComment = true,
fillTitleFromBody = false,
}: RightDrawerActivityProps) => {
const { activity, loading } = useActivityById({
activityId,
});
if (!activity || loading) {
return <></>;
}
return (
<StyledContainer>
<ActivityEditorEffect activityId={activityId} />
<ActivityEditor
activity={activity}
activityId={activityId}
showComment={showComment}
fillTitleFromBody={fillTitleFromBody}
/>