Skip to content
Merged
14 changes: 12 additions & 2 deletions packages/twenty-front/src/generated-metadata/graphql.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,15 @@ export type FilesConfiguration = {
configurationType: WidgetConfigurationType;
};

export type FilesFieldFile = {
__typename?: 'FilesFieldFile';
createdAt: Scalars['DateTime'];
id: Scalars['UUID'];
path: Scalars['String'];
size: Scalars['Float'];
url: Scalars['String'];
};

export type FindAvailableSsoidpOutput = {
__typename?: 'FindAvailableSSOIDPOutput';
id: Scalars['UUID'];
Expand Down Expand Up @@ -2212,7 +2221,7 @@ export type Mutation = {
uploadApplicationFile: File;
/** @deprecated Use uploadFilesFieldFile instead */
uploadFile: SignedFile;
uploadFilesFieldFile: File;
uploadFilesFieldFile: FilesFieldFile;
uploadImage: SignedFile;
uploadWorkspaceLogo: SignedFile;
uploadWorkspaceMemberProfilePicture: SignedFile;
Expand Down Expand Up @@ -5612,7 +5621,7 @@ export type UploadFilesFieldFileMutationVariables = Exact<{
}>;


export type UploadFilesFieldFileMutation = { __typename?: 'Mutation', uploadFilesFieldFile: { __typename?: 'File', id: string, path: string, size: number, createdAt: string } };
export type UploadFilesFieldFileMutation = { __typename?: 'Mutation', uploadFilesFieldFile: { __typename?: 'FilesFieldFile', id: string, path: string, size: number, createdAt: string, url: string } };

export type LogicFunctionFieldsFragment = { __typename?: 'LogicFunction', id: string, name: string, description?: string | null, runtime: string, timeoutSeconds: number, sourceHandlerPath: string, handlerName: string, toolInputSchema?: any | null, isTool: boolean, applicationId?: string | null, createdAt: string, updatedAt: string };

Expand Down Expand Up @@ -10159,6 +10168,7 @@ export const UploadFilesFieldFileDocument = gql`
path
size
createdAt
url
}
}
`;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,11 +71,9 @@ export const FileBlock = createReactBlockSpec(
editor.updateBlock(block.id, {
props: {
...block.props,
...{
url: fileUrl,
fileCategory: getFileType(file.name),
name: file.name,
},
url: fileUrl,
fileCategory: getFileType(file.name),
name: file.name,
},
});
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,9 @@ export const ActivityRichTextEditor = ({
if (!canCreateActivity) {
setCanCreateActivity(true);
}

persistBodyDebounced(prepareBodyWithSignedUrls(activityBody));
},
[persistBodyDebounced, setCanCreateActivity, canCreateActivity],
[canCreateActivity, persistBodyDebounced, setCanCreateActivity],
);

const handleBodyChange = useRecoilCallback(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,10 @@ import { useIsFeatureEnabled } from '@/workspace/hooks/useIsFeatureEnabled';
import { useTheme } from '@emotion/react';
import styled from '@emotion/styled';
import { useState } from 'react';
import { assertIsDefinedOrThrow, isDefined } from 'twenty-shared/utils';
import { isDefined } from 'twenty-shared/utils';

import { FileIcon } from '@/file/components/FileIcon';
import { useHasPermissionFlag } from '@/settings/roles/hooks/useHasPermissionFlag';
import { t } from '@lingui/core/macro';
import { IconCalendar, OverflowingTextWithTooltip } from 'twenty-ui/display';
import { isNavigationModifierPressed } from 'twenty-ui/utilities';
import {
Expand Down Expand Up @@ -107,11 +106,9 @@ export const AttachmentRow = ({
: attachment.fileCategory;

const fileUrl = isFilesFieldMigrated
? attachment.file?.[0]?.url
? (attachment.file?.[0]?.url as string) // TODO : fix attachment.file type after Files field migration
: attachment.fullPath;

assertIsDefinedOrThrow(fileUrl, new Error(t`File URL is not defined`));

const { destroyOneRecord: destroyOneAttachment } = useDestroyOneRecord({
objectNameSingular: CoreObjectNameSingular.Attachment,
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ export const useUploadAttachmentFile = () => {
) => {
let attachmentPath: string;
let fileId: string | undefined;
let fileUrl: string | undefined;

if (isFilesFieldMigrated) {
assertIsDefinedOrThrow(
Expand All @@ -69,6 +70,7 @@ export const useUploadAttachmentFile = () => {

attachmentPath = uploadedFile.path;
fileId = uploadedFile.id;
fileUrl = uploadedFile.url;
} else {
const result = await uploadFile({
variables: {
Expand All @@ -93,7 +95,7 @@ export const useUploadAttachmentFile = () => {

const attachmentToCreate = {
name: file.name,
fullPath: attachmentPath,
fullPath: isFilesFieldMigrated ? null : attachmentPath,
fileCategory: getFileType(file.name),
[targetableObjectFieldIdName]: targetableObject.id,
...(isFilesFieldMigrated && isDefined(fileId)
Expand All @@ -110,7 +112,12 @@ export const useUploadAttachmentFile = () => {

const createdAttachment = await createOneAttachment(attachmentToCreate);

return { attachmentAbsoluteURL: createdAttachment.fullPath };
return {
attachmentAbsoluteURL: isFilesFieldMigrated
? fileUrl
: createdAttachment.fullPath,
attachmentFileId: fileId,
};
};

return { uploadAttachmentFile };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,22 @@ describe('filterAttachmentsToRestore', () => {
fullPath: 'https://exemple.com/test.txt',
},
] as Attachment[];
const attachmentIdsToRestore = filterAttachmentsToRestore(
[],
const attachmentIdsToRestore = filterAttachmentsToRestore({
attachmentPathsToRestore: [],
softDeletedAttachments,
);
isFilesFieldMigrated: false,
});
expect(attachmentIdsToRestore).toEqual([]);
});

it('should not return any ids if there are no soft deleted attachments', () => {
const attachmentIdsToRestore = filterAttachmentsToRestore(
['https://exemple.com/files/attachment/test.txt'],
[],
);
const attachmentIdsToRestore = filterAttachmentsToRestore({
attachmentPathsToRestore: [
'https://exemple.com/files/attachment/test.txt',
],
softDeletedAttachments: [],
isFilesFieldMigrated: false,
});
expect(attachmentIdsToRestore).toEqual([]);
});

Expand All @@ -35,10 +39,11 @@ describe('filterAttachmentsToRestore', () => {
fullPath: 'https://exemple.com/files/images/test2.txt',
},
] as Attachment[];
const attachmentIdsToRestore = filterAttachmentsToRestore(
['https://exemple.com/files/images/test.txt'],
const attachmentIdsToRestore = filterAttachmentsToRestore({
attachmentPathsToRestore: ['https://exemple.com/files/images/test.txt'],
softDeletedAttachments,
);
isFilesFieldMigrated: false,
});
expect(attachmentIdsToRestore).toEqual(['1']);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ describe('getActivityAttachmentIdsAndNameToUpdate', () => {
},
]);
const attachmentIdsAndNameToUpdate =
getActivityAttachmentIdsAndNameToUpdate(activityBody, attachments);
getActivityAttachmentIdsAndNameToUpdate(activityBody, attachments, false);
expect(attachmentIdsAndNameToUpdate).toEqual([]);
});

Expand Down Expand Up @@ -68,7 +68,7 @@ describe('getActivityAttachmentIdsAndNameToUpdate', () => {
},
]);
const attachmentIdsAndNameToUpdate =
getActivityAttachmentIdsAndNameToUpdate(activityBody, attachments);
getActivityAttachmentIdsAndNameToUpdate(activityBody, attachments, false);
expect(attachmentIdsAndNameToUpdate).toEqual([{ id: '2', name: 'image4' }]);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ describe('getActivityAttachmentIdsToDelete', () => {
newActivityBody,
attachments,
oldActivityBody,
false,
);
expect(attachmentIdsToDelete).toEqual([]);
});
Expand Down Expand Up @@ -72,6 +73,7 @@ describe('getActivityAttachmentIdsToDelete', () => {
newActivityBody,
attachments,
oldActivityBody,
false,
);
expect(attachmentIdsToDelete).toEqual(['2']);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ describe('getActivityAttachmentPathsToRestore', () => {
const attachmentPathsToRestore = getActivityAttachmentPathsToRestore(
newActivityBody,
oldActivityAttachments,
false,
);
expect(attachmentPathsToRestore).toEqual([]);
});
Expand All @@ -43,6 +44,7 @@ describe('getActivityAttachmentPathsToRestore', () => {
const attachmentPathsToRestore = getActivityAttachmentPathsToRestore(
newActivityBody,
oldActivityAttachments,
false,
);
expect(attachmentPathsToRestore).toEqual([
'https://example.com/files/images/test2.txt',
Expand Down

This file was deleted.

18 changes: 11 additions & 7 deletions packages/twenty-front/src/modules/activities/utils/compareUrls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,15 @@ export const compareUrls = (
firstAttachmentUrl: string,
secondAttachmentUrl: string,
): boolean => {
const urlA = new URL(firstAttachmentUrl);
const urlB = new URL(secondAttachmentUrl);
if (urlA.hostname !== urlB.hostname) return false;
return (
getAttachmentPath(firstAttachmentUrl) ===
getAttachmentPath(secondAttachmentUrl)
);
try {
const urlA = new URL(firstAttachmentUrl);
const urlB = new URL(secondAttachmentUrl);
if (urlA.hostname !== urlB.hostname) return false;
return (
getAttachmentPath(firstAttachmentUrl) ===
getAttachmentPath(secondAttachmentUrl)
);
} catch {
return firstAttachmentUrl === secondAttachmentUrl;
}
};
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import { type Attachment } from '@/activities/files/types/Attachment';
import { compareUrls } from '@/activities/utils/compareUrls';
import { getAttachmentUrl } from '@/activities/utils/getAttachmentUrl';

export const filterAttachmentsToRestore = (
attachmentPathsToRestore: string[],
softDeletedAttachments: Attachment[],
) => {
export const filterAttachmentsToRestore = ({
attachmentPathsToRestore,
softDeletedAttachments,
isFilesFieldMigrated,
}: {
attachmentPathsToRestore: string[];
softDeletedAttachments: Attachment[];
isFilesFieldMigrated: boolean;
}) => {
return softDeletedAttachments
.filter((attachment) =>
attachmentPathsToRestore.some((path) =>
compareUrls(attachment.fullPath, path),
compareUrls(
getAttachmentUrl({ attachment, isFilesFieldMigrated }),
path,
),
),
)
.map((attachment) => attachment.id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,13 @@ import {
type AttachmentInfo,
getActivityAttachmentPathsAndName,
} from '@/activities/utils/getActivityAttachmentPathsAndName';
import { getAttachmentUrl } from '@/activities/utils/getAttachmentUrl';
import { isDefined } from 'twenty-shared/utils';

export const getActivityAttachmentIdsAndNameToUpdate = (
newActivityBody: string,
oldActivityAttachments: Attachment[] = [],
isFilesFieldMigrated: boolean,
) => {
const activityAttachmentsNameAndPaths =
getActivityAttachmentPathsAndName(newActivityBody);
Expand All @@ -17,7 +19,10 @@ export const getActivityAttachmentIdsAndNameToUpdate = (
return activityAttachmentsNameAndPaths.reduce(
(acc: Partial<Attachment>[], activity: AttachmentInfo) => {
const foundActivity = oldActivityAttachments.find((attachment) =>
compareUrls(attachment.fullPath, activity.path),
compareUrls(
getAttachmentUrl({ attachment, isFilesFieldMigrated }),
activity.path,
),
);
if (isDefined(foundActivity) && foundActivity.name !== activity.name) {
acc.push({ id: foundActivity.id, name: activity.name });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { type Attachment } from '@/activities/files/types/Attachment';
import { compareUrls } from '@/activities/utils/compareUrls';
import { getActivityAttachmentPathsAndName } from '@/activities/utils/getActivityAttachmentPathsAndName';
import { getAttachmentUrl } from '@/activities/utils/getAttachmentUrl';

export const getActivityAttachmentIdsToDelete = (
newActivityBody: string,
oldActivityAttachments: Attachment[] = [],
oldActivityBody: string,
isFilesFieldMigrated: boolean,
) => {
if (oldActivityAttachments.length === 0) return [];

Expand All @@ -27,7 +29,10 @@ export const getActivityAttachmentIdsToDelete = (
return oldActivityAttachments
.filter((attachment) =>
pathsToDelete.some((pathToDelete) =>
compareUrls(attachment.fullPath, pathToDelete),
compareUrls(
getAttachmentUrl({ attachment, isFilesFieldMigrated }),
pathToDelete,
),
),
)
.map((attachment) => attachment.id);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { type Attachment } from '@/activities/files/types/Attachment';
import { compareUrls } from '@/activities/utils/compareUrls';
import { getActivityAttachmentPathsAndName } from '@/activities/utils/getActivityAttachmentPathsAndName';
import { getAttachmentUrl } from '@/activities/utils/getAttachmentUrl';

export const getActivityAttachmentPathsToRestore = (
newActivityBody: string,
oldActivityAttachments: Attachment[],
isFilesFieldMigrated: boolean,
) => {
const newActivityAttachmentPaths =
getActivityAttachmentPathsAndName(newActivityBody);
Expand All @@ -13,7 +15,10 @@ export const getActivityAttachmentPathsToRestore = (
.filter(
(newActivity) =>
!oldActivityAttachments.some((attachment) =>
compareUrls(newActivity.path, attachment.fullPath),
compareUrls(
newActivity.path,
getAttachmentUrl({ attachment, isFilesFieldMigrated }),
),
),
)
.map((activity) => activity.path);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
export const getAttachmentPath = (attachmentFullPath: string) => {
if (attachmentFullPath.includes('/files-field/')) {
return attachmentFullPath?.split('?')[0];
}

if (!attachmentFullPath.includes('/files/')) {
return attachmentFullPath?.split('?')[0];
}
Expand Down
Loading
Loading