diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
index 66e59e112..bdf8aafe0 100644
--- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/DefaultRecordActionsConfig.tsx
@@ -13,6 +13,7 @@ import { AddToFavoritesSingleRecordAction } from '@/action-menu/actions/record-a
import { DeleteSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/components/DeleteSingleRecordAction';
import { DestroySingleRecordAction } from '@/action-menu/actions/record-actions/single-record/components/DestroySingleRecordAction';
import { ExportNoteActionSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/components/ExportNoteActionSingleRecordAction';
+import { ExportSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/components/ExportSingleRecordAction';
import { NavigateToNextRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/components/NavigateToNextRecordSingleRecordAction';
import { NavigateToPreviousRecordSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/components/NavigateToPreviousRecordSingleRecordAction';
import { RemoveFromFavoritesSingleRecordAction } from '@/action-menu/actions/record-actions/single-record/components/RemoveFromFavoritesSingleRecordAction';
@@ -137,10 +138,10 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
],
component: ,
},
- [SingleRecordActionKeys.EXPORT]: {
+ [SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX]: {
type: ActionType.Standard,
scope: ActionScope.RecordSelection,
- key: SingleRecordActionKeys.EXPORT,
+ key: SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX,
label: msg`Export`,
shortLabel: msg`Export`,
position: 4,
@@ -149,12 +150,24 @@ export const DEFAULT_RECORD_ACTIONS_CONFIG: Record<
isPinned: false,
shouldBeRegistered: ({ selectedRecord }) =>
isDefined(selectedRecord) && !selectedRecord.isRemote,
- availableOn: [
- ActionViewType.SHOW_PAGE,
- ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
- ],
+ availableOn: [ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION],
component: ,
},
+ [SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW]: {
+ type: ActionType.Standard,
+ scope: ActionScope.RecordSelection,
+ key: SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW,
+ label: msg`Export`,
+ shortLabel: msg`Export`,
+ position: 4,
+ Icon: IconFileExport,
+ accent: 'default',
+ isPinned: false,
+ shouldBeRegistered: ({ selectedRecord }) =>
+ isDefined(selectedRecord) && !selectedRecord.isRemote,
+ availableOn: [ActionViewType.SHOW_PAGE],
+ component: ,
+ },
[MultipleRecordsActionKeys.EXPORT]: {
type: ActionType.Standard,
scope: ActionScope.RecordSelection,
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
index 10144c61a..847e9a1cf 100644
--- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowActionsConfig.tsx
@@ -222,7 +222,8 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
SingleRecordActionKeys.DELETE,
SingleRecordActionKeys.DESTROY,
SingleRecordActionKeys.RESTORE,
- SingleRecordActionKeys.EXPORT,
+ SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX,
+ SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW,
MultipleRecordsActionKeys.DELETE,
MultipleRecordsActionKeys.DESTROY,
MultipleRecordsActionKeys.RESTORE,
@@ -259,14 +260,18 @@ export const WORKFLOW_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
position: 12,
label: msg`Permanently destroy workflow`,
},
- [SingleRecordActionKeys.EXPORT]: {
+ [SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX]: {
position: 13,
label: msg`Export workflow`,
shouldBeRegistered: ({ selectedRecord }) =>
!isDefined(selectedRecord?.deletedAt),
},
- [MultipleRecordsActionKeys.EXPORT]: {
+ [SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW]: {
position: 14,
+ label: msg`Export workflow`,
+ },
+ [MultipleRecordsActionKeys.EXPORT]: {
+ position: 15,
label: msg`Export workflows`,
},
[NoSelectionRecordActionKeys.EXPORT_VIEW]: {
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowRunsActionsConfig.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowRunsActionsConfig.tsx
index a76ce0223..868a8adfb 100644
--- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowRunsActionsConfig.tsx
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowRunsActionsConfig.tsx
@@ -51,7 +51,8 @@ export const WORKFLOW_RUNS_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
SingleRecordActionKeys.REMOVE_FROM_FAVORITES,
SingleRecordActionKeys.NAVIGATE_TO_PREVIOUS_RECORD,
SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD,
- SingleRecordActionKeys.EXPORT,
+ SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX,
+ SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW,
MultipleRecordsActionKeys.EXPORT,
NoSelectionRecordActionKeys.EXPORT_VIEW,
NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
@@ -73,7 +74,11 @@ export const WORKFLOW_RUNS_ACTIONS_CONFIG = inheritActionsFromDefaultConfig({
isPinned: false,
position: 3,
},
- [SingleRecordActionKeys.EXPORT]: {
+ [SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX]: {
+ position: 4,
+ label: msg`Export run`,
+ },
+ [SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW]: {
position: 4,
label: msg`Export run`,
},
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowVersionsActionsConfig.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowVersionsActionsConfig.tsx
index 11dea90db..b05d292f5 100644
--- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowVersionsActionsConfig.tsx
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/constants/WorkflowVersionsActionsConfig.tsx
@@ -118,7 +118,8 @@ export const WORKFLOW_VERSIONS_ACTIONS_CONFIG = inheritActionsFromDefaultConfig(
SingleRecordActionKeys.NAVIGATE_TO_NEXT_RECORD,
SingleRecordActionKeys.ADD_TO_FAVORITES,
SingleRecordActionKeys.REMOVE_FROM_FAVORITES,
- SingleRecordActionKeys.EXPORT,
+ SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX,
+ SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW,
MultipleRecordsActionKeys.EXPORT,
NoSelectionRecordActionKeys.EXPORT_VIEW,
NoSelectionRecordActionKeys.SEE_DELETED_RECORDS,
@@ -140,7 +141,11 @@ export const WORKFLOW_VERSIONS_ACTIONS_CONFIG = inheritActionsFromDefaultConfig(
position: 6,
isPinned: false,
},
- [SingleRecordActionKeys.EXPORT]: {
+ [SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX]: {
+ position: 7,
+ label: msg`Export version`,
+ },
+ [SingleRecordActionKeys.EXPORT_FROM_RECORD_SHOW]: {
position: 7,
label: msg`Export version`,
},
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/ExportMultipleRecordsAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/ExportMultipleRecordsAction.tsx
index 294fa6dcc..89f505a6f 100644
--- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/ExportMultipleRecordsAction.tsx
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/multiple-records/components/ExportMultipleRecordsAction.tsx
@@ -1,7 +1,7 @@
import { Action } from '@/action-menu/actions/components/Action';
import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
-import { useExportRecords } from '@/object-record/record-index/export/hooks/useExportRecords';
+import { useRecordIndexExportRecords } from '@/object-record/record-index/export/hooks/useRecordIndexExportRecords';
import { getRecordIndexIdFromObjectNamePluralAndViewId } from '@/object-record/utils/getRecordIndexIdFromObjectNamePluralAndViewId';
import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
@@ -16,7 +16,7 @@ export const ExportMultipleRecordsAction = () => {
throw new Error('Current view ID is not defined');
}
- const { download } = useExportRecords({
+ const { download } = useRecordIndexExportRecords({
delayMs: 100,
objectMetadataItem,
recordIndexId: getRecordIndexIdFromObjectNamePluralAndViewId(
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/ExportSingleRecordAction.tsx b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/ExportSingleRecordAction.tsx
new file mode 100644
index 000000000..28a485829
--- /dev/null
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/components/ExportSingleRecordAction.tsx
@@ -0,0 +1,30 @@
+import { useSelectedRecordIdOrThrow } from '@/action-menu/actions/record-actions/single-record/hooks/useSelectedRecordIdOrThrow';
+import { useContextStoreObjectMetadataItemOrThrow } from '@/context-store/hooks/useContextStoreObjectMetadataItemOrThrow';
+import { contextStoreCurrentViewIdComponentState } from '@/context-store/states/contextStoreCurrentViewIdComponentState';
+import { useExportSingleRecord } from '@/object-record/record-show/hooks/useExportSingleRecord';
+import { useRecoilComponentValueV2 } from '@/ui/utilities/state/component-state/hooks/useRecoilComponentValueV2';
+
+import { Action } from '@/action-menu/actions/components/Action';
+
+export const ExportSingleRecordAction = () => {
+ const { objectMetadataItem } = useContextStoreObjectMetadataItemOrThrow();
+
+ const contextStoreCurrentViewId = useRecoilComponentValueV2(
+ contextStoreCurrentViewIdComponentState,
+ );
+
+ if (!contextStoreCurrentViewId) {
+ throw new Error('Current view ID is not defined');
+ }
+
+ const recordId = useSelectedRecordIdOrThrow();
+
+ const filename = `${objectMetadataItem.nameSingular}.csv`;
+ const { download } = useExportSingleRecord({
+ filename,
+ objectMetadataItem,
+ recordId,
+ });
+
+ return ;
+};
diff --git a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey.ts b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey.ts
index 019962423..229ca24fb 100644
--- a/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey.ts
+++ b/packages/twenty-front/src/modules/action-menu/actions/record-actions/single-record/types/SingleRecordActionsKey.ts
@@ -6,6 +6,7 @@ export enum SingleRecordActionKeys {
NAVIGATE_TO_NEXT_RECORD = 'navigate-to-next-record-single-record',
NAVIGATE_TO_PREVIOUS_RECORD = 'navigate-to-previous-record-single-record',
EXPORT_NOTE_TO_PDF = 'export-note-to-pdf-single-record',
- EXPORT = 'export-single-record',
+ EXPORT_FROM_RECORD_INDEX = 'export-from-record-index-single-record',
+ EXPORT_FROM_RECORD_SHOW = 'export-from-record-show-single-record',
RESTORE = 'restore-single-record',
}
diff --git a/packages/twenty-front/src/modules/action-menu/mock/action-menu-actions.mock.tsx b/packages/twenty-front/src/modules/action-menu/mock/action-menu-actions.mock.tsx
index 888d0c788..e3fa6a26e 100644
--- a/packages/twenty-front/src/modules/action-menu/mock/action-menu-actions.mock.tsx
+++ b/packages/twenty-front/src/modules/action-menu/mock/action-menu-actions.mock.tsx
@@ -45,7 +45,7 @@ export const createMockActionMenuActions = ({
{
type: ActionType.Standard,
scope: ActionScope.RecordSelection,
- key: SingleRecordActionKeys.EXPORT,
+ key: SingleRecordActionKeys.EXPORT_FROM_RECORD_INDEX,
label: msg`Export`,
shortLabel: msg`Export`,
position: 4,
@@ -53,10 +53,7 @@ export const createMockActionMenuActions = ({
accent: 'default',
isPinned: false,
shouldBeRegistered: () => true,
- availableOn: [
- ActionViewType.SHOW_PAGE,
- ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION,
- ],
+ availableOn: [ActionViewType.INDEX_PAGE_SINGLE_RECORD_SELECTION],
component: ,
},
{
diff --git a/packages/twenty-front/src/modules/context-store/utils/__tests__/computeContextStoreFilters.test.ts b/packages/twenty-front/src/modules/context-store/utils/__tests__/computeContextStoreFilters.test.ts
index 94a9a5efb..bf0f47e7c 100644
--- a/packages/twenty-front/src/modules/context-store/utils/__tests__/computeContextStoreFilters.test.ts
+++ b/packages/twenty-front/src/modules/context-store/utils/__tests__/computeContextStoreFilters.test.ts
@@ -29,9 +29,14 @@ describe('computeContextStoreFilters', () => {
);
expect(filters).toEqual({
- id: {
- in: ['1', '2', '3'],
- },
+ and: [
+ {
+ id: {
+ in: ['1', '2', '3'],
+ },
+ },
+ {},
+ ],
});
});
diff --git a/packages/twenty-front/src/modules/context-store/utils/computeContextStoreFilters.ts b/packages/twenty-front/src/modules/context-store/utils/computeContextStoreFilters.ts
index 73381a503..7842a1c8e 100644
--- a/packages/twenty-front/src/modules/context-store/utils/computeContextStoreFilters.ts
+++ b/packages/twenty-front/src/modules/context-store/utils/computeContextStoreFilters.ts
@@ -34,19 +34,21 @@ export const computeContextStoreFilters = (
]);
}
if (contextStoreTargetedRecordsRule.mode === 'selection') {
- queryFilter =
+ queryFilter = makeAndFilterVariables([
contextStoreTargetedRecordsRule.selectedRecordIds.length > 0
? {
id: {
in: contextStoreTargetedRecordsRule.selectedRecordIds,
},
}
- : computeRecordGqlOperationFilter({
- filterValueDependencies,
- fields: objectMetadataItem?.fields ?? [],
- recordFilters: contextStoreFilters,
- recordFilterGroups: [],
- });
+ : undefined,
+ computeRecordGqlOperationFilter({
+ filterValueDependencies,
+ fields: objectMetadataItem?.fields ?? [],
+ recordFilters: contextStoreFilters,
+ recordFilterGroups: [],
+ }),
+ ]);
}
return queryFilter;
diff --git a/packages/twenty-front/src/modules/object-record/record-index/export/hooks/__tests__/useExportRecords.test.ts b/packages/twenty-front/src/modules/object-record/record-index/export/hooks/__tests__/useRecordIndexExportRecords.test.ts
similarity index 96%
rename from packages/twenty-front/src/modules/object-record/record-index/export/hooks/__tests__/useExportRecords.test.ts
rename to packages/twenty-front/src/modules/object-record/record-index/export/hooks/__tests__/useRecordIndexExportRecords.test.ts
index 181990a42..c0f61ad1a 100644
--- a/packages/twenty-front/src/modules/object-record/record-index/export/hooks/__tests__/useExportRecords.test.ts
+++ b/packages/twenty-front/src/modules/object-record/record-index/export/hooks/__tests__/useRecordIndexExportRecords.test.ts
@@ -2,7 +2,10 @@ import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata'
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { FieldMetadataType, RelationType } from '~/generated-metadata/graphql';
-import { displayedExportProgress, generateCsv } from '../useExportRecords';
+import {
+ displayedExportProgress,
+ generateCsv,
+} from '../useRecordIndexExportRecords';
jest.useFakeTimers();
diff --git a/packages/twenty-front/src/modules/object-record/record-index/export/hooks/__tests__/useExportFetchRecords.test.ts b/packages/twenty-front/src/modules/object-record/record-index/export/hooks/__tests__/useRecordIndexLazyFetchRecords.test.ts
similarity index 97%
rename from packages/twenty-front/src/modules/object-record/record-index/export/hooks/__tests__/useExportFetchRecords.test.ts
rename to packages/twenty-front/src/modules/object-record/record-index/export/hooks/__tests__/useRecordIndexLazyFetchRecords.test.ts
index e91d76750..c75b40107 100644
--- a/packages/twenty-front/src/modules/object-record/record-index/export/hooks/__tests__/useExportFetchRecords.test.ts
+++ b/packages/twenty-front/src/modules/object-record/record-index/export/hooks/__tests__/useRecordIndexLazyFetchRecords.test.ts
@@ -3,8 +3,8 @@ import { act } from 'react';
import {
percentage,
sleep,
- useExportFetchRecords,
-} from '../useExportFetchRecords';
+ useRecordIndexLazyFetchRecords,
+} from '../useRecordIndexLazyFetchRecords';
import { useLazyFetchAllRecords } from '@/object-record/hooks/useLazyFetchAllRecords';
import { useObjectOptionsForBoard } from '@/object-record/object-options-dropdown/hooks/useObjectOptionsForBoard';
@@ -107,7 +107,7 @@ describe('useRecordData', () => {
const { result } = renderHook(
() =>
- useExportFetchRecords({
+ useRecordIndexLazyFetchRecords({
recordIndexId,
objectMetadataItem,
pageSize: 30,
@@ -134,7 +134,7 @@ describe('useRecordData', () => {
mockFetchAllRecords.mockReturnValue([mockPerson]);
const { result } = renderHook(
() =>
- useExportFetchRecords({
+ useRecordIndexLazyFetchRecords({
recordIndexId,
objectMetadataItem,
callback,
@@ -167,7 +167,7 @@ describe('useRecordData', () => {
);
return {
- tableData: useExportFetchRecords({
+ tableData: useRecordIndexLazyFetchRecords({
recordIndexId,
objectMetadataItem,
callback,
@@ -260,7 +260,7 @@ describe('useRecordData', () => {
);
return {
- tableData: useExportFetchRecords({
+ tableData: useRecordIndexLazyFetchRecords({
recordIndexId,
objectMetadataItem,
callback,
diff --git a/packages/twenty-front/src/modules/object-record/record-index/export/hooks/useExportRecords.ts b/packages/twenty-front/src/modules/object-record/record-index/export/hooks/useRecordIndexExportRecords.ts
similarity index 93%
rename from packages/twenty-front/src/modules/object-record/record-index/export/hooks/useExportRecords.ts
rename to packages/twenty-front/src/modules/object-record/record-index/export/hooks/useRecordIndexExportRecords.ts
index 890022662..81581a8a9 100644
--- a/packages/twenty-front/src/modules/object-record/record-index/export/hooks/useExportRecords.ts
+++ b/packages/twenty-front/src/modules/object-record/record-index/export/hooks/useRecordIndexExportRecords.ts
@@ -7,8 +7,8 @@ import { useExportProcessRecordsForCSV } from '@/object-record/object-options-dr
import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
import {
UseRecordDataOptions,
- useExportFetchRecords,
-} from '@/object-record/record-index/export/hooks/useExportFetchRecords';
+ useRecordIndexLazyFetchRecords,
+} from '@/object-record/record-index/export/hooks/useRecordIndexLazyFetchRecords';
import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
import { ObjectRecord } from '@/object-record/types/ObjectRecord';
import { COMPOSITE_FIELD_SUB_FIELD_LABELS } from '@/settings/data-model/constants/CompositeFieldSubFieldLabel';
@@ -20,7 +20,10 @@ import { FieldMetadataType, RelationType } from '~/generated-metadata/graphql';
import { isUndefinedOrNull } from '~/utils/isUndefinedOrNull';
type GenerateExportOptions = {
- columns: ColumnDefinition[];
+ columns: Pick<
+ ColumnDefinition,
+ 'size' | 'label' | 'type' | 'metadata'
+ >[];
rows: Record[];
};
@@ -121,7 +124,7 @@ type UseExportTableDataOptions = Omit & {
filename: string;
};
-export const useExportRecords = ({
+export const useRecordIndexExportRecords = ({
delayMs,
filename,
maximumRequests = 100,
@@ -144,7 +147,7 @@ export const useExportRecords = ({
[filename, processRecordsForCSVExport],
);
- const { getTableData: download, progress } = useExportFetchRecords({
+ const { getTableData: download, progress } = useRecordIndexLazyFetchRecords({
delayMs,
maximumRequests,
objectMetadataItem,
diff --git a/packages/twenty-front/src/modules/object-record/record-index/export/hooks/useExportFetchRecords.ts b/packages/twenty-front/src/modules/object-record/record-index/export/hooks/useRecordIndexLazyFetchRecords.ts
similarity index 98%
rename from packages/twenty-front/src/modules/object-record/record-index/export/hooks/useExportFetchRecords.ts
rename to packages/twenty-front/src/modules/object-record/record-index/export/hooks/useRecordIndexLazyFetchRecords.ts
index 2f8c0d90e..88d5b57d7 100644
--- a/packages/twenty-front/src/modules/object-record/record-index/export/hooks/useExportFetchRecords.ts
+++ b/packages/twenty-front/src/modules/object-record/record-index/export/hooks/useRecordIndexLazyFetchRecords.ts
@@ -36,7 +36,7 @@ export type UseRecordDataOptions = {
viewType?: ViewType;
};
-export const useExportFetchRecords = ({
+export const useRecordIndexLazyFetchRecords = ({
objectMetadataItem,
delayMs,
maximumRequests = 100,
@@ -74,6 +74,10 @@ export const useExportFetchRecords = ({
const { filterValueDependencies } = useFilterValueDependencies();
+ const findManyRecordsParams = useFindManyRecordIndexTableParams(
+ objectMetadataItem.nameSingular,
+ );
+
const queryFilter = computeContextStoreFilters(
contextStoreTargetedRecordsRule,
contextStoreFilters,
@@ -81,10 +85,6 @@ export const useExportFetchRecords = ({
filterValueDependencies,
);
- const findManyRecordsParams = useFindManyRecordIndexTableParams(
- objectMetadataItem.nameSingular,
- );
-
const finalColumns = [
...columns,
...(hiddenKanbanFieldColumn && viewType === ViewType.Kanban
diff --git a/packages/twenty-front/src/modules/object-record/record-show/hooks/useExportSingleRecord.ts b/packages/twenty-front/src/modules/object-record/record-show/hooks/useExportSingleRecord.ts
new file mode 100644
index 000000000..eaf36a0b3
--- /dev/null
+++ b/packages/twenty-front/src/modules/object-record/record-show/hooks/useExportSingleRecord.ts
@@ -0,0 +1,69 @@
+import { useMemo } from 'react';
+
+import { ObjectMetadataItem } from '@/object-metadata/types/ObjectMetadataItem';
+import { formatFieldMetadataItemAsColumnDefinition } from '@/object-metadata/utils/formatFieldMetadataItemAsColumnDefinition';
+import { useFindOneRecord } from '@/object-record/hooks/useFindOneRecord';
+import { useExportProcessRecordsForCSV } from '@/object-record/object-options-dropdown/hooks/useExportProcessRecordsForCSV';
+import { FieldMetadata } from '@/object-record/record-field/types/FieldMetadata';
+import { csvDownloader } from '@/object-record/record-index/export/hooks/useRecordIndexExportRecords';
+import { ColumnDefinition } from '@/object-record/record-table/types/ColumnDefinition';
+import { ObjectRecord } from '@/object-record/types/ObjectRecord';
+import { isDefined } from 'twenty-shared/utils';
+
+export type UseSingleExportTableDataOptions = {
+ filename: string;
+ objectMetadataItem: ObjectMetadataItem;
+ recordId: string;
+};
+export const useExportSingleRecord = ({
+ filename,
+ objectMetadataItem,
+ recordId,
+}: UseSingleExportTableDataOptions) => {
+ const { processRecordsForCSVExport } = useExportProcessRecordsForCSV(
+ objectMetadataItem.nameSingular,
+ );
+
+ const downloadCsv = useMemo(
+ () =>
+ (
+ record: ObjectRecord,
+ columns: Pick<
+ ColumnDefinition,
+ 'size' | 'label' | 'type' | 'metadata'
+ >[],
+ ) => {
+ const recordToArray = [record];
+ const recordsProcessedForExport =
+ processRecordsForCSVExport(recordToArray);
+
+ csvDownloader(filename, { rows: recordsProcessedForExport, columns });
+ },
+ [filename, processRecordsForCSVExport],
+ );
+
+ const columns: Pick<
+ ColumnDefinition,
+ 'size' | 'label' | 'type' | 'metadata'
+ >[] = objectMetadataItem.fields
+ .filter((field) => field.isActive)
+ .map((field, index) =>
+ formatFieldMetadataItemAsColumnDefinition({
+ field,
+ objectMetadataItem,
+ position: index,
+ }),
+ );
+ const { record, error } = useFindOneRecord({
+ objectNameSingular: objectMetadataItem.nameSingular,
+ objectRecordId: recordId,
+ withSoftDeleted: true,
+ });
+ const download = () => {
+ if (isDefined(error) || !isDefined(record)) {
+ return;
+ }
+ downloadCsv(record, columns);
+ };
+ return { download };
+};