diff --git a/apps/studio/components/grid/components/header/ExportDialog.tsx b/apps/studio/components/grid/components/header/ExportDialog.tsx index 59ffe39bd9a..93aa9ef8ecc 100644 --- a/apps/studio/components/grid/components/header/ExportDialog.tsx +++ b/apps/studio/components/grid/components/header/ExportDialog.tsx @@ -1,8 +1,13 @@ +import { useState } from 'react' + import { useParams } from 'common' +import { Filter, Sort, SupaTable } from 'components/grid/types' import { getConnectionStrings } from 'components/interfaces/Connect/DatabaseSettings.utils' import { useReadReplicasQuery } from 'data/read-replicas/replicas-query' +import { getAllTableRowsSql } from 'data/table-rows/table-rows-query' import { pluckObjectFields } from 'lib/helpers' -import { useState } from 'react' +import { RoleImpersonationState, wrapWithRoleImpersonation } from 'lib/role-impersonation' +import { useRoleImpersonationStateSnapshot } from 'state/role-impersonation-state' import { Button, cn, @@ -22,13 +27,25 @@ import { import { Admonition } from 'ui-patterns' interface ExportDialogProps { - table?: { name: string; schema: string } + table?: SupaTable + filters?: Filter[] + sorts?: Sort[] + ignoreRoleImpersonation?: boolean + open: boolean onOpenChange: (open: boolean) => void } -export const ExportDialog = ({ table, open, onOpenChange }: ExportDialogProps) => { +export const ExportDialog = ({ + table, + filters = [], + sorts = [], + ignoreRoleImpersonation = false, + open, + onOpenChange, +}: ExportDialogProps) => { const { ref: projectRef } = useParams() + const roleImpersonationState = useRoleImpersonationStateSnapshot() const [selectedTab, setSelectedTab] = useState('csv') @@ -48,10 +65,18 @@ export const ExportDialog = ({ table, open, onOpenChange }: ExportDialogProps) = }) const outputName = `${table?.name}_rows` + const queryChains = !table ? undefined : getAllTableRowsSql({ table, sorts, filters }) + const query = !!queryChains + ? ignoreRoleImpersonation + ? queryChains.toSql() + : wrapWithRoleImpersonation( + queryChains.toSql(), + roleImpersonationState as RoleImpersonationState + ) + : '' const csvExportCommand = ` -${connectionStrings.direct.psql} -c "COPY (SELECT * FROM "${table?.schema}"."${table?.name}") TO STDOUT WITH CSV HEADER DELIMITER ',';" > ${outputName}.csv -`.trim() +${connectionStrings.direct.psql} -c "COPY (${query}) TO STDOUT WITH CSV HEADER DELIMITER ',';" > ${outputName}.csv`.trim() const sqlExportCommand = ` pg_dump -h ${db_host} -p ${db_port} -d ${db_name} -U ${db_user} --table="${table?.schema}.${table?.name}" --data-only --column-inserts > ${outputName}.sql @@ -95,6 +120,12 @@ pg_dump -h ${db_host} -p ${db_port} -d ${db_name} -U ${db_user} --table="${table value={sqlExportCommand} className="[&_code]:text-[12px] [&_code]:text-foreground" /> + @@ -107,15 +138,11 @@ pg_dump -h ${db_host} -p ${db_port} -d ${db_name} -U ${db_user} --table="${table

{selectedTab === 'sql' && ( - -

- If you run into a server version mismatch error, you will need to update{' '} - pg_dump before running the command. -

-
+

+ Note: pg_dump needs to match your project's Postgres version. If you run + into a server version mismatch error, you will need to update pg_dump{' '} + before running the command. +

)} diff --git a/apps/studio/components/grid/components/header/Header.tsx b/apps/studio/components/grid/components/header/Header.tsx index baeeecc662f..bb401db90e8 100644 --- a/apps/studio/components/grid/components/header/Header.tsx +++ b/apps/studio/components/grid/components/header/Header.tsx @@ -504,11 +504,9 @@ const RowHeader = () => { Export - + Export as CSV Export as SQL - {/* [Joshen] Should make this available for all cases, but that'll involve updating - the Dialog's SQL output to be dynamic based on any filters applied */} {snap.allRowsSelected ? ( setShowExportModal(true)}>
@@ -535,7 +533,9 @@ const RowHeader = () => {
setShowExportModal(false)} /> diff --git a/apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx b/apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx index e693516ccb8..c8ee912c07f 100644 --- a/apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx +++ b/apps/studio/components/layouts/TableEditorLayout/EntityListItem.tsx @@ -1,5 +1,5 @@ import saveAs from 'file-saver' -import { Clipboard, Copy, Download, Edit, Lock, MoreHorizontal, Trash } from 'lucide-react' +import { Clipboard, Copy, Download, Edit, Lock, MoreVertical, Trash } from 'lucide-react' import Link from 'next/link' import Papa from 'papaparse' import { toast } from 'sonner' @@ -30,6 +30,7 @@ import { useTableEditorStateSnapshot } from 'state/table-editor' import { createTabId, useTabsStateSnapshot } from 'state/tabs' import { Badge, + Button, cn, copyToClipboard, DropdownMenu, @@ -242,7 +243,7 @@ const EntityListItem: ItemRenderer = ({ isOpened: isOpened && !isPreview, isPreview, }), - 'px-4' + 'pl-4 pr-1' )} onDoubleClick={(e) => { e.preventDefault() @@ -285,8 +286,16 @@ const EntityListItem: ItemRenderer = ({ {canEdit && ( - - + +