Skip to content

Commit

Permalink
Add export as csv
Browse files Browse the repository at this point in the history
Resolves 2183.
  • Loading branch information
tatethurston committed Feb 17, 2024
1 parent ba050cd commit 81753c7
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 1 deletion.
3 changes: 3 additions & 0 deletions packages/twenty-front/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,5 +59,8 @@
},
"msw": {
"workerDirectory": "public"
},
"dependencies": {
"json-2-csv": "^5.0.1"
}
}
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { useRef, useState } from 'react';
import { useRecoilValue } from 'recoil';
import { json2csv } from 'json-2-csv';
import pick from 'lodash.pick';
import { useRecoilCallback, useRecoilValue } from 'recoil';
import { Key } from 'ts-key-enum';

import { RECORD_INDEX_OPTIONS_DROPDOWN_ID } from '@/object-record/record-index/options/constants/RecordIndexOptionsDropdownId';
import { useRecordIndexOptionsForBoard } from '@/object-record/record-index/options/hooks/useRecordIndexOptionsForBoard';
import { useRecordIndexOptionsForTable } from '@/object-record/record-index/options/hooks/useRecordIndexOptionsForTable';
import { recordStoreFamilyState } from '@/object-record/record-store/states/recordStoreFamilyState';
import { useRecordTableStates } from '@/object-record/record-table/hooks/internal/useRecordTableStates';
import { TableOptionsHotkeyScope } from '@/object-record/record-table/types/TableOptionsHotkeyScope';
import { useSpreadsheetRecordImport } from '@/object-record/spreadsheet-import/useSpreadsheetRecordImport';
import {
IconBaselineDensitySmall,
IconChevronLeft,
IconFileExport,
IconFileImport,
IconTag,
} from '@/ui/display/icon';
Expand All @@ -21,6 +26,7 @@ import { useDropdown } from '@/ui/layout/dropdown/hooks/useDropdown';
import { MenuItem } from '@/ui/navigation/menu-item/components/MenuItem';
import { MenuItemToggle } from '@/ui/navigation/menu-item/components/MenuItemToggle';
import { useScopedHotkeys } from '@/ui/utilities/hotkey/hooks/useScopedHotkeys';
import { getSnapshotValue } from '@/ui/utilities/recoil-scope/utils/getSnapshotValue';
import { ViewFieldsVisibilityDropdownSection } from '@/views/components/ViewFieldsVisibilityDropdownSection';
import { useViewScopedStates } from '@/views/hooks/internal/useViewScopedStates';
import { useViewBar } from '@/views/hooks/useViewBar';
Expand Down Expand Up @@ -119,6 +125,63 @@ export const RecordIndexOptionsDropdownContent = ({
const { openRecordSpreadsheetImport } =
useSpreadsheetRecordImport(objectNameSingular);

const useExportTableData = (recordIndexId: string, filename: string) => {
const download = (blob: Blob, filename: string) => {
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.setAttribute('download', filename);
document.body.appendChild(link);
link.click();
link.parentNode?.removeChild(link);
};

const [progress, setProgress] = useState<number | undefined>(undefined);
const { getTableRowIdsState, getVisibleTableColumnsSelector } =
useRecordTableStates(recordIndexId);
const downloadCsv = useRecoilCallback(
({ snapshot }) =>
() => {
setProgress(1);

const columns = getSnapshotValue(
snapshot,
getVisibleTableColumnsSelector(),
);
const keys = columns.map((col) => ({
field: col.metadata.fieldName,
title: col.label,
}));
const fields = keys.map((k) => k.field);
const tableRowIds = getSnapshotValue(snapshot, getTableRowIdsState());
const rows = tableRowIds.map((id: string) =>
getSnapshotValue(snapshot, recordStoreFamilyState(id)),
);
const rowsWithOnlySelectedFields = rows.map((row) =>
pick(row, fields),
);

setProgress(90);

const csv = json2csv(rowsWithOnlySelectedFields, { keys });
const blob = new Blob([csv], { type: 'text/csv' });

setProgress(100);

download(blob, filename);

setProgress(undefined);
},
[filename],
);
return { progress, download: downloadCsv };
};

const { progress, download } = useExportTableData(
recordIndexId,
`${objectNameSingular}.csv`,
);

return (
<>
{!currentMenu && (
Expand Down Expand Up @@ -147,6 +210,11 @@ export const RecordIndexOptionsDropdownContent = ({
LeftIcon={IconFileImport}
text="Import"
/>
<MenuItem
onClick={download}
LeftIcon={IconFileExport}
text={progress === undefined ? `Export` : `Export (${progress}%)`}
/>
</DropdownMenuItemsContainer>
</>
)}
Expand Down
1 change: 1 addition & 0 deletions packages/twenty-front/src/modules/ui/display/icon/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ export {
IconEyeOff,
IconFile,
IconFileCheck,
IconFileExport,
IconFileImport,
IconFileText,
IconFileUpload,
Expand Down
26 changes: 26 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -22827,6 +22827,13 @@ __metadata:
languageName: node
linkType: hard

"deeks@npm:3.0.2":
version: 3.0.2
resolution: "deeks@npm:3.0.2"
checksum: 2d90a569f43a01e450e7693951ad4889475b68a3e95c09a8f04b47dd94cb64ba84f7d7e7fd5b3857461b5a38275be037242768e2686afe3e898c3c1ae65cb4de
languageName: node
linkType: hard

"deep-eql@npm:^4.1.3":
version: 4.1.3
resolution: "deep-eql@npm:4.1.3"
Expand Down Expand Up @@ -23284,6 +23291,13 @@ __metadata:
languageName: node
linkType: hard

"doc-path@npm:4.0.2":
version: 4.0.2
resolution: "doc-path@npm:4.0.2"
checksum: 4dde0c449b8bf7e4f1533510bb78a26f75aeec887917056eda19631ccfb966bb110c89d329f23cd19aaa0df97eced0d5cf9ea09178ce4b1bbe7b769a048da9a6
languageName: node
linkType: hard

"doctrine@npm:^2.1.0":
version: 2.1.0
resolution: "doctrine@npm:2.1.0"
Expand Down Expand Up @@ -31084,6 +31098,16 @@ __metadata:
languageName: node
linkType: hard

"json-2-csv@npm:^5.0.1":
version: 5.0.1
resolution: "json-2-csv@npm:5.0.1"
dependencies:
deeks: "npm:3.0.2"
doc-path: "npm:4.0.2"
checksum: b1aaf21e4f2c027b113e6832bce78af66b11683c8e88b53450d11e55591b714731f47839c9670a652309873f55e7ac97c45ea1ac649b5d952c4fb3d42dce0bf9
languageName: node
linkType: hard

"json-bigint@npm:^1.0.0":
version: 1.0.0
resolution: "json-bigint@npm:1.0.0"
Expand Down Expand Up @@ -44086,6 +44110,8 @@ __metadata:
"twenty-front@workspace:packages/twenty-front":
version: 0.0.0-use.local
resolution: "twenty-front@workspace:packages/twenty-front"
dependencies:
json-2-csv: "npm:^5.0.1"
languageName: unknown
linkType: soft

Expand Down

0 comments on commit 81753c7

Please sign in to comment.