Fix activity (#11015)

Deprecating unused states and making sure that the ActivityRichText
editor loads when activity.bodyV2 is present
This commit is contained in:
Charles Bochet
2025-03-19 10:45:11 +01:00
committed by GitHub
parent 117a961622
commit ca9c070945
20 changed files with 46 additions and 69 deletions

View File

@ -1,6 +1,6 @@
{ {
"name": "twenty-e2e-testing", "name": "twenty-e2e-testing",
"version": "0.44.0-canary", "version": "0.50.0-canary",
"description": "", "description": "",
"author": "", "author": "",
"private": true, "private": true,

View File

@ -1,6 +1,6 @@
{ {
"name": "twenty-emails", "name": "twenty-emails",
"version": "0.44.0-canary", "version": "0.50.0-canary",
"description": "", "description": "",
"author": "", "author": "",
"private": true, "private": true,

View File

@ -1,6 +1,6 @@
{ {
"name": "twenty-front", "name": "twenty-front",
"version": "0.44.0-canary", "version": "0.50.0-canary",
"private": true, "private": true,
"type": "module", "type": "module",
"scripts": { "scripts": {

View File

@ -151,7 +151,10 @@ export const ActivityRichTextEditor = ({
return { return {
...oldActivity, ...oldActivity,
id: activityId, id: activityId,
body: newStringifiedBody, bodyV2: {
blocknote: newStringifiedBody,
markdown: null,
},
__typename: 'Activity', __typename: 'Activity',
}; };
}); });
@ -159,8 +162,11 @@ export const ActivityRichTextEditor = ({
modifyRecordFromCache({ modifyRecordFromCache({
recordId: activityId, recordId: activityId,
fieldModifiers: { fieldModifiers: {
body: () => { bodyV2: () => {
return newStringifiedBody; return {
blocknote: newStringifiedBody,
markdown: null,
};
}, },
}, },
cache, cache,

View File

@ -14,7 +14,6 @@ import { Task } from '@/activities/types/Task';
import { TaskTarget } from '@/activities/types/TaskTarget'; import { TaskTarget } from '@/activities/types/TaskTarget';
import { useOpenRecordInCommandMenu } from '@/command-menu/hooks/useOpenRecordInCommandMenu'; import { useOpenRecordInCommandMenu } from '@/command-menu/hooks/useOpenRecordInCommandMenu';
import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord'; import { useCreateOneRecord } from '@/object-record/hooks/useCreateOneRecord';
import { isNewViewableRecordLoadingState } from '@/object-record/record-right-drawer/states/isNewViewableRecordLoading';
export const useOpenCreateActivityDrawer = ({ export const useOpenCreateActivityDrawer = ({
activityObjectNameSingular, activityObjectNameSingular,
@ -46,9 +45,7 @@ export const useOpenCreateActivityDrawer = ({
const setViewableRecordNameSingular = useSetRecoilState( const setViewableRecordNameSingular = useSetRecoilState(
viewableRecordNameSingularState, viewableRecordNameSingularState,
); );
const setIsNewViewableRecordLoading = useSetRecoilState(
isNewViewableRecordLoadingState,
);
const setIsUpsertingActivityInDB = useSetRecoilState( const setIsUpsertingActivityInDB = useSetRecoilState(
isUpsertingActivityInDBState, isUpsertingActivityInDBState,
); );
@ -62,7 +59,6 @@ export const useOpenCreateActivityDrawer = ({
targetableObjects: ActivityTargetableObject[]; targetableObjects: ActivityTargetableObject[];
customAssignee?: WorkspaceMember; customAssignee?: WorkspaceMember;
}) => { }) => {
setIsNewViewableRecordLoading(true);
setViewableRecordId(null); setViewableRecordId(null);
setViewableRecordNameSingular(activityObjectNameSingular); setViewableRecordNameSingular(activityObjectNameSingular);
@ -113,7 +109,6 @@ export const useOpenCreateActivityDrawer = ({
setViewableRecordId(activity.id); setViewableRecordId(activity.id);
setIsUpsertingActivityInDB(false); setIsUpsertingActivityInDB(false);
setIsNewViewableRecordLoading(false);
}; };
return openCreateActivityDrawer; return openCreateActivityDrawer;

View File

@ -10,7 +10,6 @@ const task: Task = {
id: '123', id: '123',
status: 'DONE', status: 'DONE',
title: 'Test', title: 'Test',
body: 'Test',
bodyV2: { bodyV2: {
blocknote: 'Test', blocknote: 'Test',
markdown: 'Test', markdown: 'Test',

View File

@ -3,7 +3,6 @@ export type Activity = {
createdAt: string; createdAt: string;
updatedAt: string; updatedAt: string;
title: string; title: string;
body: string | null;
bodyV2?: { bodyV2?: {
blocknote: string | null; blocknote: string | null;
markdown: string | null; markdown: string | null;

View File

@ -1,6 +1,5 @@
import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext'; import { ActionMenuComponentInstanceContext } from '@/action-menu/states/contexts/ActionMenuComponentInstanceContext';
import { TimelineActivityContext } from '@/activities/timeline-activities/contexts/TimelineActivityContext'; import { TimelineActivityContext } from '@/activities/timeline-activities/contexts/TimelineActivityContext';
import { isNewViewableRecordLoadingComponentState } from '@/command-menu/pages/record-page/states/isNewViewableRecordLoadingComponentState';
import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page/states/viewableRecordIdComponentState'; import { viewableRecordIdComponentState } from '@/command-menu/pages/record-page/states/viewableRecordIdComponentState';
import { viewableRecordNameSingularComponentState } from '@/command-menu/pages/record-page/states/viewableRecordNameSingularComponentState'; import { viewableRecordNameSingularComponentState } from '@/command-menu/pages/record-page/states/viewableRecordNameSingularComponentState';
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext'; import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
@ -29,14 +28,12 @@ export const CommandMenuRecordPage = () => {
const viewableRecordNameSingular = useRecoilComponentValueV2( const viewableRecordNameSingular = useRecoilComponentValueV2(
viewableRecordNameSingularComponentState, viewableRecordNameSingularComponentState,
); );
const isNewViewableRecordLoading = useRecoilComponentValueV2(
isNewViewableRecordLoadingComponentState,
);
const viewableRecordId = useRecoilComponentValueV2( const viewableRecordId = useRecoilComponentValueV2(
viewableRecordIdComponentState, viewableRecordIdComponentState,
); );
if (!viewableRecordNameSingular && !isNewViewableRecordLoading) { if (!viewableRecordNameSingular) {
throw new Error(`Object name is not defined`); throw new Error(`Object name is not defined`);
} }
@ -73,9 +70,7 @@ export const CommandMenuRecordPage = () => {
> >
<StyledRightDrawerRecord isMobile={isMobile}> <StyledRightDrawerRecord isMobile={isMobile}>
<RecordFieldValueSelectorContextProvider> <RecordFieldValueSelectorContextProvider>
{!isNewViewableRecordLoading && ( <RecordValueSetterEffect recordId={objectRecordId} />
<RecordValueSetterEffect recordId={objectRecordId} />
)}
<TimelineActivityContext.Provider <TimelineActivityContext.Provider
value={{ value={{
recordId: objectRecordId, recordId: objectRecordId,
@ -90,7 +85,6 @@ export const CommandMenuRecordPage = () => {
objectRecordId={objectRecordId} objectRecordId={objectRecordId}
loading={false} loading={false}
isInRightDrawer={true} isInRightDrawer={true}
isNewRightDrawerItemLoading={isNewViewableRecordLoading}
/> />
</TimelineActivityContext.Provider> </TimelineActivityContext.Provider>
</RecordFieldValueSelectorContextProvider> </RecordFieldValueSelectorContextProvider>

View File

@ -1,9 +0,0 @@
import { CommandMenuPageComponentInstanceContext } from '@/command-menu/states/contexts/CommandMenuPageComponentInstanceContext';
import { createComponentStateV2 } from '@/ui/utilities/state/component-state/utils/createComponentStateV2';
export const isNewViewableRecordLoadingComponentState =
createComponentStateV2<boolean>({
key: 'command-menu/is-new-viewable-record-loading',
defaultValue: false,
componentInstanceContext: CommandMenuPageComponentInstanceContext,
});

View File

@ -1,6 +0,0 @@
import { createState } from '@ui/utilities/state/utils/createState';
export const isNewViewableRecordLoadingState = createState<boolean>({
key: 'activities/is-new-viewable-record-loading',
defaultValue: false,
});

View File

@ -24,7 +24,6 @@ export const RecordShowContainer = ({
objectRecordId, objectRecordId,
loading, loading,
isInRightDrawer = false, isInRightDrawer = false,
isNewRightDrawerItemLoading = false,
}: RecordShowContainerProps) => { }: RecordShowContainerProps) => {
const { objectMetadataItem } = useObjectMetadataItem({ const { objectMetadataItem } = useObjectMetadataItem({
objectNameSingular, objectNameSingular,
@ -70,7 +69,6 @@ export const RecordShowContainer = ({
}} }}
isInRightDrawer={isInRightDrawer} isInRightDrawer={isInRightDrawer}
loading={isPrefetchLoading || loading || recordLoading} loading={isPrefetchLoading || loading || recordLoading}
isNewRightDrawerItemLoading={isNewRightDrawerItemLoading}
/> />
</ShowPageContainer> </ShowPageContainer>
</> </>

View File

@ -17,7 +17,6 @@ import { FieldMetadataType } from '~/generated/graphql';
type SummaryCardProps = { type SummaryCardProps = {
objectNameSingular: string; objectNameSingular: string;
objectRecordId: string; objectRecordId: string;
isNewRightDrawerItemLoading: boolean;
isInRightDrawer: boolean; isInRightDrawer: boolean;
}; };
@ -25,7 +24,6 @@ type SummaryCardProps = {
export const SummaryCard = ({ export const SummaryCard = ({
objectNameSingular, objectNameSingular,
objectRecordId, objectRecordId,
isNewRightDrawerItemLoading,
isInRightDrawer, isInRightDrawer,
}: SummaryCardProps) => { }: SummaryCardProps) => {
const { recordLoading, labelIdentifierFieldMetadataItem, isPrefetchLoading } = const { recordLoading, labelIdentifierFieldMetadataItem, isPrefetchLoading } =
@ -57,7 +55,7 @@ export const SummaryCard = ({
}), }),
); );
if (isNewRightDrawerItemLoading || !isDefined(recordCreatedAt)) { if (!isDefined(recordCreatedAt)) {
return <ShowPageSummaryCardSkeletonLoader />; return <ShowPageSummaryCardSkeletonLoader />;
} }

View File

@ -1,12 +1,13 @@
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular'; import { CoreObjectNameSingular } from '@/object-metadata/types/CoreObjectNameSingular';
import { isNewViewableRecordLoadingState } from '@/object-record/record-right-drawer/states/isNewViewableRecordLoading'; import { recordStoreFamilySelector } from '@/object-record/record-store/states/selectors/recordStoreFamilySelector';
import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper'; import { ScrollWrapper } from '@/ui/utilities/scroll/components/ScrollWrapper';
import { useTheme } from '@emotion/react'; import { useTheme } from '@emotion/react';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { lazy, Suspense } from 'react'; import { lazy, Suspense } from 'react';
import Skeleton, { SkeletonTheme } from 'react-loading-skeleton'; import Skeleton, { SkeletonTheme } from 'react-loading-skeleton';
import { useRecoilValue } from 'recoil'; import { useRecoilValue } from 'recoil';
import { isDefined } from 'twenty-shared';
const ActivityRichTextEditor = lazy(() => const ActivityRichTextEditor = lazy(() =>
import('@/activities/components/ActivityRichTextEditor').then((module) => ({ import('@/activities/components/ActivityRichTextEditor').then((module) => ({
@ -20,7 +21,12 @@ const StyledShowPageActivityContainer = styled.div`
`; `;
const StyledSkeletonContainer = styled.div` const StyledSkeletonContainer = styled.div`
width: 100%; display: flex;
flex-direction: column;
gap: ${({ theme }) => theme.spacing(3)};
justify-content: center;
padding: ${({ theme }) => theme.spacing(4)};
`; `;
const LoadingSkeleton = () => { const LoadingSkeleton = () => {
@ -33,7 +39,9 @@ const LoadingSkeleton = () => {
highlightColor={theme.background.transparent.lighter} highlightColor={theme.background.transparent.lighter}
borderRadius={theme.border.radius.sm} borderRadius={theme.border.radius.sm}
> >
<Skeleton height={200} /> <Skeleton height={24} />
<Skeleton height={24} />
<Skeleton height={24} />
</SkeletonTheme> </SkeletonTheme>
</StyledSkeletonContainer> </StyledSkeletonContainer>
); );
@ -47,16 +55,23 @@ export const ShowPageActivityContainer = ({
'targetObjectNameSingular' | 'id' 'targetObjectNameSingular' | 'id'
>; >;
}) => { }) => {
const isNewViewableRecordLoading = useRecoilValue(
isNewViewableRecordLoadingState,
);
const activityObjectNameSingular = const activityObjectNameSingular =
targetableObject.targetObjectNameSingular as targetableObject.targetObjectNameSingular as
| CoreObjectNameSingular.Note | CoreObjectNameSingular.Note
| CoreObjectNameSingular.Task; | CoreObjectNameSingular.Task;
return !isNewViewableRecordLoading ? ( const activityBodyV2 = useRecoilValue(
recordStoreFamilySelector({
recordId: targetableObject.id,
fieldName: 'bodyV2',
}),
);
if (!isDefined(activityBodyV2)) {
return <LoadingSkeleton />;
}
return (
<ScrollWrapper <ScrollWrapper
contextProviderName="showPageActivityContainer" contextProviderName="showPageActivityContainer"
componentInstanceId={`scroll-wrapper-tab-list-${targetableObject.id}`} componentInstanceId={`scroll-wrapper-tab-list-${targetableObject.id}`}
@ -70,7 +85,5 @@ export const ShowPageActivityContainer = ({
</Suspense> </Suspense>
</StyledShowPageActivityContainer> </StyledShowPageActivityContainer>
</ScrollWrapper> </ScrollWrapper>
) : (
<></>
); );
}; };

View File

@ -1,7 +1,6 @@
import { RecordShowRightDrawerActionMenu } from '@/action-menu/components/RecordShowRightDrawerActionMenu'; import { RecordShowRightDrawerActionMenu } from '@/action-menu/components/RecordShowRightDrawerActionMenu';
import { RecordShowRightDrawerOpenRecordButton } from '@/action-menu/components/RecordShowRightDrawerOpenRecordButton'; import { RecordShowRightDrawerOpenRecordButton } from '@/action-menu/components/RecordShowRightDrawerOpenRecordButton';
import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity'; import { ActivityTargetableObject } from '@/activities/types/ActivityTargetableEntity';
import { isNewViewableRecordLoadingState } from '@/object-record/record-right-drawer/states/isNewViewableRecordLoading';
import { CardComponents } from '@/object-record/record-show/components/CardComponents'; import { CardComponents } from '@/object-record/record-show/components/CardComponents';
import { FieldsCard } from '@/object-record/record-show/components/FieldsCard'; import { FieldsCard } from '@/object-record/record-show/components/FieldsCard';
import { SummaryCard } from '@/object-record/record-show/components/SummaryCard'; import { SummaryCard } from '@/object-record/record-show/components/SummaryCard';
@ -14,7 +13,7 @@ import { SingleTabProps, TabList } from '@/ui/layout/tab/components/TabList';
import { useTabList } from '@/ui/layout/tab/hooks/useTabList'; import { useTabList } from '@/ui/layout/tab/hooks/useTabList';
import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile'; import { useIsMobile } from '@/ui/utilities/responsive/hooks/useIsMobile';
import styled from '@emotion/styled'; import styled from '@emotion/styled';
import { useRecoilState, useRecoilValue } from 'recoil'; import { useRecoilState } from 'recoil';
const StyledShowPageRightContainer = styled.div<{ isMobile: boolean }>` const StyledShowPageRightContainer = styled.div<{ isMobile: boolean }>`
display: flex; display: flex;
@ -62,7 +61,6 @@ export const ShowPageSubContainer = ({
targetableObject, targetableObject,
loading, loading,
isInRightDrawer = false, isInRightDrawer = false,
isNewRightDrawerItemLoading = false,
}: ShowPageSubContainerProps) => { }: ShowPageSubContainerProps) => {
const tabListComponentId = `${TAB_LIST_COMPONENT_ID}-${isInRightDrawer}-${targetableObject.id}`; const tabListComponentId = `${TAB_LIST_COMPONENT_ID}-${isInRightDrawer}-${targetableObject.id}`;
@ -70,15 +68,10 @@ export const ShowPageSubContainer = ({
const isMobile = useIsMobile(); const isMobile = useIsMobile();
const isNewViewableRecordLoading = useRecoilValue(
isNewViewableRecordLoadingState,
);
const summaryCard = ( const summaryCard = (
<SummaryCard <SummaryCard
objectNameSingular={targetableObject.targetObjectNameSingular} objectNameSingular={targetableObject.targetObjectNameSingular}
objectRecordId={targetableObject.id} objectRecordId={targetableObject.id}
isNewRightDrawerItemLoading={isNewRightDrawerItemLoading}
isInRightDrawer={isInRightDrawer} isInRightDrawer={isInRightDrawer}
/> />
); );
@ -127,7 +120,7 @@ export const ShowPageSubContainer = ({
<StyledTabListContainer shouldDisplay={visibleTabs.length > 1}> <StyledTabListContainer shouldDisplay={visibleTabs.length > 1}>
<StyledTabList <StyledTabList
behaveAsLinks={!isInRightDrawer} behaveAsLinks={!isInRightDrawer}
loading={loading || isNewViewableRecordLoading} loading={loading}
tabListInstanceId={tabListComponentId} tabListInstanceId={tabListComponentId}
tabs={tabs} tabs={tabs}
isInRightDrawer={isInRightDrawer} isInRightDrawer={isInRightDrawer}

View File

@ -9,7 +9,6 @@ export const mockedNotes: Array<MockedNote> = [
createdAt: '2023-04-26T10:12:42.33625+00:00', createdAt: '2023-04-26T10:12:42.33625+00:00',
updatedAt: '2023-04-26T10:23:42.33625+00:00', updatedAt: '2023-04-26T10:23:42.33625+00:00',
title: 'My very first note', title: 'My very first note',
body: null,
bodyV2: { bodyV2: {
blocknote: null, blocknote: null,
markdown: null, markdown: null,
@ -68,7 +67,6 @@ export const mockedNotes: Array<MockedNote> = [
createdAt: new Date().toISOString(), createdAt: new Date().toISOString(),
updatedAt: new Date().toISOString(), updatedAt: new Date().toISOString(),
title: 'Another note', title: 'Another note',
body: null,
bodyV2: { bodyV2: {
blocknote: null, blocknote: null,
markdown: null, markdown: null,

View File

@ -26,7 +26,6 @@ export const mockedTasks: Array<MockedTask> = [
createdAt: '2023-04-26T10:12:42.33625+00:00', createdAt: '2023-04-26T10:12:42.33625+00:00',
updatedAt: '2023-04-26T10:23:42.33625+00:00', updatedAt: '2023-04-26T10:23:42.33625+00:00',
title: 'My very first note', title: 'My very first note',
body: null,
bodyV2: { bodyV2: {
blocknote: null, blocknote: null,
markdown: null, markdown: null,

View File

@ -1,6 +1,6 @@
{ {
"name": "twenty-server", "name": "twenty-server",
"version": "0.44.0-canary", "version": "0.50.0-canary",
"description": "", "description": "",
"author": "", "author": "",
"private": true, "private": true,

View File

@ -1,6 +1,6 @@
{ {
"name": "twenty-shared", "name": "twenty-shared",
"version": "0.44.0-canary", "version": "0.50.0-canary",
"license": "AGPL-3.0", "license": "AGPL-3.0",
"main": "./dist/index.js", "main": "./dist/index.js",
"scripts": { "scripts": {

View File

@ -1,6 +1,6 @@
{ {
"name": "twenty-ui", "name": "twenty-ui",
"version": "0.44.0-canary", "version": "0.50.0-canary",
"type": "module", "type": "module",
"main": "./src/index.ts", "main": "./src/index.ts",
"exports": { "exports": {

View File

@ -1,6 +1,6 @@
{ {
"name": "twenty-website", "name": "twenty-website",
"version": "0.44.0-canary", "version": "0.50.0-canary",
"private": true, "private": true,
"scripts": { "scripts": {
"nx": "NX_DEFAULT_PROJECT=twenty-website node ../../node_modules/nx/bin/nx.js", "nx": "NX_DEFAULT_PROJECT=twenty-website node ../../node_modules/nx/bin/nx.js",