@@ -16,12 +16,13 @@ import { InstanceDatabaseMap } from '@/integrations/api/api.patch';
1616import { useDeleteTableRecords } from '@/integrations/api/instance/database/deleteTableRecords' ;
1717import { getDescribeTableQueryOptions } from '@/integrations/api/instance/database/getDescribeTable' ;
1818import {
19+ getSearchByConditions ,
1920 getSearchByConditionsOptions ,
2021 SearchCondition ,
2122 translateColumnFilterToSearchConditions ,
2223} from '@/integrations/api/instance/database/getSearchByConditions' ;
2324import { getSearchByIdOptions } from '@/integrations/api/instance/database/getSearchById' ;
24- import { getSearchByValueOptions } from '@/integrations/api/instance/database/getSearchByValue' ;
25+ import { getSearchByValue , getSearchByValueOptions } from '@/integrations/api/instance/database/getSearchByValue' ;
2526import { useUpdateTableRecords } from '@/integrations/api/instance/database/updateTableRecords' ;
2627import { useSetWatchedValue } from '@/lib/events/watcher' ;
2728import { keyBy } from '@/lib/keyBy' ;
@@ -33,12 +34,13 @@ import { Row, VisibilityState } from '@tanstack/react-table';
3334import {
3435 CircleCheckBigIcon ,
3536 CircleIcon ,
37+ CloudDownloadIcon ,
38+ CloudUploadIcon ,
3639 EllipsisIcon ,
3740 ExternalLinkIcon ,
3841 FunnelIcon ,
3942 FunnelPlusIcon ,
4043 FunnelXIcon ,
41- ImportIcon ,
4244 PlusIcon ,
4345 RefreshCwIcon ,
4446 Trash2Icon ,
@@ -150,54 +152,46 @@ export function DatabaseTableView({ instanceDatabaseMap, databaseName, tableName
150152 const useFilteredList = filtersToggled && ! ! appliedSearchConditions ;
151153
152154 // Full list
153- const {
154- data : fullTableData ,
155- isFetching : tableDataFetching ,
156- } = useQuery (
157- getSearchByValueOptions ( {
158- ...instanceParams ,
159- enabled : ! useFilteredList && ! ! hashAttribute ,
160- databaseName,
161- tableName,
162- searchAttribute : hashAttribute ,
163- sort,
164- pageSize,
165- pageIndex,
166- onlyIfCached,
167- } ) ,
168- ) ;
155+ const searchByValueParams = {
156+ ...instanceParams ,
157+ enabled : ! useFilteredList && ! ! hashAttribute ,
158+ databaseName,
159+ tableName,
160+ searchAttribute : hashAttribute ,
161+ sort,
162+ pageSize,
163+ pageIndex,
164+ onlyIfCached,
165+ } ;
166+ const searchByValueOptions = getSearchByValueOptions ( searchByValueParams ) ;
167+ const { data : fullTableData , isFetching : tableDataFetching } = useQuery ( searchByValueOptions ) ;
169168
170169 // Filtered list
171- const {
172- data : filteredTableData ,
173- isFetching : tableConditionsDataFetching ,
174- } = useQuery (
175- getSearchByConditionsOptions ( {
176- ...instanceParams ,
177- enabled : useFilteredList && ! ! hashAttribute ,
178- databaseName,
179- tableName,
180- conditions : appliedSearchConditions ,
181- sort,
182- pageSize,
183- pageIndex,
184- onlyIfCached,
185- } ) ,
186- ) ;
170+ const searchByConditionsParams = {
171+ ...instanceParams ,
172+ enabled : useFilteredList && ! ! hashAttribute ,
173+ databaseName,
174+ tableName,
175+ conditions : appliedSearchConditions ,
176+ sort,
177+ pageSize,
178+ pageIndex,
179+ onlyIfCached,
180+ } ;
181+ const searchByConditionsOptions = getSearchByConditionsOptions ( searchByConditionsParams ) ;
182+ const { data : filteredTableData , isFetching : tableConditionsDataFetching } = useQuery ( searchByConditionsOptions ) ;
187183
188184 const tableData = useFilteredList ? filteredTableData : fullTableData ;
189185 const isFetching = tableDataFetching || tableConditionsDataFetching ;
190186
191187 // One by id
192- const { data : searchByIdData } = useQuery (
193- getSearchByIdOptions ( {
194- ...instanceParams ,
195- enabled : isEditModalOpen ,
196- databaseName : databaseName ,
197- tableName : tableName ,
198- ids : selectedIds ,
199- } ) ,
200- ) ;
188+ const { data : searchByIdData } = useQuery ( getSearchByIdOptions ( {
189+ ...instanceParams ,
190+ enabled : isEditModalOpen ,
191+ databaseName : databaseName ,
192+ tableName : tableName ,
193+ ids : selectedIds ,
194+ } ) ) ;
201195
202196 const { mutate : updateTableRecords , isPending : isUpdateTableRecordsPending } = useUpdateTableRecords ( ) ;
203197 const { mutate : deleteTableRecords , isPending : isDeleteTableRecordsPending } = useDeleteTableRecords ( ) ;
@@ -208,6 +202,37 @@ export function DatabaseTableView({ instanceDatabaseMap, databaseName, tableName
208202 [ queryClient , instanceParams . entityId , databaseName , tableName ] ,
209203 ) ;
210204
205+ const [ isExportingCSV , setisExportingCSV ] = useState ( false ) ;
206+ const onExportCSVClicked = useCallback ( async ( ) => {
207+ if ( ! hashAttribute ) {
208+ return ;
209+ }
210+ const id = toast . loading ( 'Loading CSV...' ) ;
211+ setisExportingCSV ( true ) ;
212+ const allResultsAsCSV = {
213+ pageIndex : 0 ,
214+ pageSize : 1_000_000 ,
215+ headers : {
216+ Accept : 'text/csv' ,
217+ } ,
218+ } ;
219+ const response = await (
220+ useFilteredList
221+ ? getSearchByConditions ( { ...searchByConditionsParams , ...allResultsAsCSV } )
222+ : getSearchByValue ( { ...searchByValueParams , ...allResultsAsCSV } )
223+ ) ;
224+ toast . loading ( 'Preparing CSV...' , { id } ) ;
225+ const content = response . data as unknown as string ;
226+ const blob = new Blob ( [ content ] , { type : 'text/csv' } ) ;
227+ const url = URL . createObjectURL ( blob ) ;
228+ const downloadLink = document . createElement ( 'a' ) ;
229+ downloadLink . href = url ;
230+ downloadLink . setAttribute ( 'download' , `${ databaseName } .${ tableName } .${ new Date ( ) . toISOString ( ) } .csv` ) ;
231+ downloadLink . click ( ) ;
232+ toast . success ( 'CSV Exported!' , { id } ) ;
233+ setisExportingCSV ( false ) ;
234+ } , [ databaseName , tableName , searchByValueOptions , searchByConditionsOptions ] ) ;
235+
211236 const onRecordUpdate = useCallback ( ( data : Record < string , unknown > [ ] ) => {
212237 updateTableRecords (
213238 {
@@ -307,12 +332,23 @@ export function DatabaseTableView({ instanceDatabaseMap, databaseName, tableName
307332 disabled = { isImportCSVModalOpen }
308333 accessKey = "c"
309334 >
310- < ImportIcon />
335+ < CloudUploadIcon />
311336 < span >
312337 Import < u > C</ u > SV
313338 </ span >
314339 </ Button >
315340 ) }
341+ < Button
342+ variant = "positiveOutline"
343+ onClick = { onExportCSVClicked }
344+ disabled = { isExportingCSV }
345+ accessKey = "e"
346+ >
347+ < CloudDownloadIcon />
348+ < span >
349+ < u > E</ u > xport CSV
350+ </ span >
351+ </ Button >
316352 </ div >
317353
318354 < div className = "flex space-x-2" >
0 commit comments