diff --git a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ExportData.svelte b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ExportData.svelte index 096341783d..6ed0135844 100644 --- a/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ExportData.svelte +++ b/packages/builder/src/components/design/settings/controls/ButtonActionEditor/actions/ExportData.svelte @@ -49,26 +49,34 @@ }, ] - $: tables = findAllMatchingComponents($selectedScreen?.props, component => - component._component.endsWith("table") - ) - $: tableBlocks = findAllMatchingComponents( + $: components = findAllMatchingComponents( $selectedScreen?.props, - component => component._component.endsWith("tableblock") + component => { + const type = component._component + return ( + type.endsWith("/table") || + type.endsWith("/tableblock") || + type.endsWith("/gridblock") + ) + } ) - $: components = tables.concat(tableBlocks) - $: componentOptions = components.map(table => ({ - label: table._instanceName, - value: table._component.includes("tableblock") - ? `${table._id}-table` - : table._id, - })) + $: componentOptions = components.map(component => { + let value = component._id + if (component._component.endsWith("/tableblock")) { + value = `${component._id}-table` + } + return { + label: component._instanceName, + value, + } + }) $: selectedTableId = parameters.tableComponentId?.includes("-") ? parameters.tableComponentId.split("-")[0] : parameters.tableComponentId $: selectedTable = components.find( component => component._id === selectedTableId ) + $: parameters.rows = `{{ literal [${parameters.tableComponentId}].[selectedRows] }}` onMount(() => { if (!parameters.type) { diff --git a/packages/client/src/components/app/GridBlock.svelte b/packages/client/src/components/app/GridBlock.svelte index 52a8e963c7..e2d901cdb5 100644 --- a/packages/client/src/components/app/GridBlock.svelte +++ b/packages/client/src/components/app/GridBlock.svelte @@ -36,12 +36,10 @@ let grid let gridContext - $: columnWhitelist = parsedColumns - ?.filter(col => col.active) - ?.map(col => col.field) + $: parsedColumns = getParsedColumns(columns) + $: columnWhitelist = parsedColumns.filter(x => x.active).map(x => x.field) $: schemaOverrides = getSchemaOverrides(parsedColumns) $: enrichedButtons = enrichButtons(buttons) - $: parsedColumns = getParsedColumns(columns) $: selectedRows = deriveSelectedRows(gridContext) $: data = { selectedRows: $selectedRows } $: actions = [ @@ -67,12 +65,14 @@ // Parses columns to fix older formats const getParsedColumns = columns => { + if (!columns?.length) { + return [] + } // If the first element has an active key all elements should be in the new format - if (columns?.length && columns[0]?.active !== undefined) { + if (columns[0].active !== undefined) { return columns } - - return columns?.map(column => ({ + return columns.map(column => ({ label: column.displayName || column.name, field: column.name, active: true, @@ -81,7 +81,7 @@ const getSchemaOverrides = columns => { let overrides = {} - columns?.forEach(column => { + columns.forEach(column => { overrides[column.field] = { displayName: column.label, } @@ -115,13 +115,12 @@ return derived( [gridContext.selectedRows, gridContext.rowLookupMap, gridContext.rows], ([$selectedRows, $rowLookupMap, $rows]) => { - const rowIds = Object.entries($selectedRows || {}) + return Object.entries($selectedRows || {}) .filter(([_, selected]) => selected) - .map(([rowId]) => rowId) - return rowIds.map(id => { - const idx = $rowLookupMap[id] - return gridContext.rows.actions.cleanRow($rows[idx]) - }) + .map(([rowId]) => { + const idx = $rowLookupMap[rowId] + return gridContext.rows.actions.cleanRow($rows[idx]) + }) } ) } diff --git a/packages/client/src/stores/rowSelection.js b/packages/client/src/stores/rowSelection.js index 4c0a196678..554c3645f0 100644 --- a/packages/client/src/stores/rowSelection.js +++ b/packages/client/src/stores/rowSelection.js @@ -15,7 +15,7 @@ const createRowSelectionStore = () => { const componentId = Object.keys(selection).find( componentId => componentId === tableComponentId ) - return selection[componentId] || {} + return selection[componentId] } return { diff --git a/packages/client/src/utils/buttonActions.js b/packages/client/src/utils/buttonActions.js index 710fac085d..1532a9c85b 100644 --- a/packages/client/src/utils/buttonActions.js +++ b/packages/client/src/utils/buttonActions.js @@ -332,31 +332,49 @@ const s3UploadHandler = async action => { } const exportDataHandler = async action => { - let selection = rowSelectionStore.actions.getSelection( - action.parameters.tableComponentId - ) - console.log(selection) - if (selection.selectedRows && selection.selectedRows.length > 0) { + let { tableComponentId, rows, type, columns, delimiter, customHeaders } = + action.parameters + + // Handle legacy configs using the row selection store + if (!rows?.length) { + const selection = rowSelectionStore.actions.getSelection(tableComponentId) + if (selection?.rows?.length) { + rows = selection.selectedRows + } + } + + // Get table ID from first row + const tableId = rows?.[0]?.tableId + + // Handle no rows selected + if (!rows?.length) { + notificationStore.actions.error("Please select at least one row") + } + // Handle case where we're not using a DS+ + else if (!tableId) { + notificationStore.actions.error( + "Exporting data only works for tables and views" + ) + } + // Happy path when we have both rows and table ID + else { try { + // Flatten rows if required + if (typeof rows[0] !== "string") { + rows = rows.map(row => row._id) + } const data = await API.exportRows({ - tableId: selection.tableId, - rows: selection.selectedRows, - format: action.parameters.type, - columns: action.parameters.columns?.map( - column => column.name || column - ), - delimiter: action.parameters.delimiter, - customHeaders: action.parameters.customHeaders, + tableId, + rows, + format: type, + columns: columns?.map(column => column.name || column), + delimiter, + customHeaders, }) - download( - new Blob([data], { type: "text/plain" }), - `${selection.tableId}.${action.parameters.type}` - ) + download(new Blob([data], { type: "text/plain" }), `${tableId}.${type}`) } catch (error) { notificationStore.actions.error("There was an error exporting the data") } - } else { - notificationStore.actions.error("Please select at least one row") } } diff --git a/packages/frontend-core/src/components/grid/stores/ui.js b/packages/frontend-core/src/components/grid/stores/ui.js index da0558bb5b..656db3627e 100644 --- a/packages/frontend-core/src/components/grid/stores/ui.js +++ b/packages/frontend-core/src/components/grid/stores/ui.js @@ -113,9 +113,9 @@ export const createActions = context => { // Callback when leaving the grid, deselecting all focussed or selected items const blur = () => { - focusedCellId.set(null) - selectedRows.set({}) - hoveredRowId.set(null) + // focusedCellId.set(null) + // selectedRows.set({}) + // hoveredRowId.set(null) } return {