Binding selection fixes, delete controller refactor and some fixes

This commit is contained in:
Dean 2023-07-14 09:11:34 +01:00
parent ccb82e5575
commit a481eee39e
7 changed files with 117 additions and 41 deletions

View File

@ -491,6 +491,7 @@ const getSelectedRowsBindings = asset => {
readableBinding: `${table._instanceName}.Selected rows`, readableBinding: `${table._instanceName}.Selected rows`,
category: "Selected rows", category: "Selected rows",
icon: "ViewRow", icon: "ViewRow",
display: { name: table._instanceName },
})) }))
) )
@ -506,6 +507,7 @@ const getSelectedRowsBindings = asset => {
)}.${makePropSafe("selectedRows")}`, )}.${makePropSafe("selectedRows")}`,
readableBinding: `${block._instanceName}.Selected rows`, readableBinding: `${block._instanceName}.Selected rows`,
category: "Selected rows", category: "Selected rows",
display: { name: block._instanceName },
})) }))
) )
} }

View File

@ -1,5 +1,5 @@
<script> <script>
import { Select, Label, Checkbox, Input } from "@budibase/bbui" import { Select, Label, Checkbox, Input, Body } from "@budibase/bbui"
import { tables } from "stores/backend" import { tables } from "stores/backend"
import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte" import DrawerBindableInput from "components/common/bindings/DrawerBindableInput.svelte"
@ -10,6 +10,8 @@
</script> </script>
<div class="root"> <div class="root">
<Body size="small">Please specify one or more rows to delete.</Body>
<div class="params">
<Label>Table</Label> <Label>Table</Label>
<Select <Select
bind:value={parameters.tableId} bind:value={parameters.tableId}
@ -18,10 +20,10 @@
getOptionValue={table => table._id} getOptionValue={table => table._id}
/> />
<Label small>Row ID</Label> <Label small>Row IDs</Label>
<DrawerBindableInput <DrawerBindableInput
{bindings} {bindings}
title="Row ID to delete" title="Rows to delete"
value={parameters.rowId} value={parameters.rowId}
on:change={value => (parameters.rowId = value.detail)} on:change={value => (parameters.rowId = value.detail)}
/> />
@ -37,20 +39,30 @@
{#if parameters.confirm} {#if parameters.confirm}
<Label small>Confirm text</Label> <Label small>Confirm text</Label>
<Input <Input
placeholder="Are you sure you want to delete this row?" placeholder="Are you sure you want to delete?"
bind:value={parameters.confirmText} bind:value={parameters.confirmText}
/> />
{/if} {/if}
</div>
</div> </div>
<style> <style>
.root { .root {
width: 100%;
max-width: 800px;
margin: 0 auto;
display: flex;
flex-direction: column;
justify-content: flex-start;
align-items: stretch;
gap: var(--spacing-xl);
}
.params {
display: grid; display: grid;
column-gap: var(--spacing-l); column-gap: var(--spacing-l);
row-gap: var(--spacing-s); row-gap: var(--spacing-s);
grid-template-columns: 60px 1fr; grid-template-columns: 60px 1fr;
align-items: center; align-items: center;
max-width: 800px;
margin: 0 auto;
} }
</style> </style>

View File

@ -24,6 +24,7 @@
}, },
{ {
"name": "Delete Row", "name": "Delete Row",
"displayName": "Delete Rows",
"type": "data", "type": "data",
"component": "DeleteRow" "component": "DeleteRow"
}, },

View File

@ -47,6 +47,14 @@
) )
} }
// If the data changes, double check that the selected elements are still present.
$: if (data) {
let rowIds = data.map(row => row._id)
if (rowIds.length) {
selectedRows = selectedRows.filter(row => rowIds.includes(row._id))
}
}
const getFields = (schema, customColumns, showAutoColumns) => { const getFields = (schema, customColumns, showAutoColumns) => {
// Check for an invalid column selection // Check for an invalid column selection
let invalid = false let invalid = false

View File

@ -101,13 +101,47 @@ const fetchRowHandler = async action => {
} }
} }
const deleteRowHandler = async action => { const deleteRowHandler = async (action, context) => {
const { tableId, revId, rowId, notificationOverride } = action.parameters const { tableId, rowId: rowConfig, notificationOverride } = action.parameters
if (tableId && rowId) {
if (tableId && rowConfig) {
try { try {
await API.deleteRow({ tableId, rowId, revId }) let requestConfig
let parsedRowConfig = []
if (typeof rowConfig === "string") {
try {
parsedRowConfig = JSON.parse(rowConfig)
} catch (e) {
parsedRowConfig = rowConfig
.split(",")
.map(id => id.trim())
.filter(id => id)
}
} else {
parsedRowConfig = rowConfig
}
if (
typeof parsedRowConfig === "object" &&
parsedRowConfig.constructor === Object
) {
requestConfig = [parsedRowConfig]
} else if (Array.isArray(parsedRowConfig)) {
requestConfig = parsedRowConfig
}
if (!requestConfig.length) {
notificationStore.actions.warning("No valid rows were supplied")
return false
}
const resp = await API.deleteRows({ tableId, rows: requestConfig })
if (!notificationOverride) { if (!notificationOverride) {
notificationStore.actions.success("Row deleted") notificationStore.actions.success(
resp?.length == 1 ? "Row deleted" : `${resp.length} Rows deleted`
)
} }
// Refresh related datasources // Refresh related datasources
@ -115,8 +149,10 @@ const deleteRowHandler = async action => {
invalidateRelationships: true, invalidateRelationships: true,
}) })
} catch (error) { } catch (error) {
// Abort next actions console.error(error)
return false notificationStore.actions.error(
"An error occurred while executing the query"
)
} }
} }
} }

View File

@ -5,7 +5,7 @@ import { convertBookmark } from "../../../utilities"
// makes sure that the user doesn't need to pass in the type, tableId or _id params for // makes sure that the user doesn't need to pass in the type, tableId or _id params for
// the call to be correct // the call to be correct
function fixRow(row: Row, params: any) { export function fixRow(row: Row, params: any) {
if (!params || !row) { if (!params || !row) {
return row return row
} }

View File

@ -5,6 +5,8 @@ import { isExternalTable } from "../../../integrations/utils"
import { Ctx } from "@budibase/types" import { Ctx } from "@budibase/types"
import * as utils from "./utils" import * as utils from "./utils"
import { gridSocket } from "../../../websockets" import { gridSocket } from "../../../websockets"
import { addRev } from "../public/utils"
import { fixRow } from "../public/rows"
function pickApi(tableId: any) { function pickApi(tableId: any) {
if (isExternalTable(tableId)) { if (isExternalTable(tableId)) {
@ -88,7 +90,22 @@ export async function destroy(ctx: any) {
const inputs = ctx.request.body const inputs = ctx.request.body
const tableId = utils.getTableId(ctx) const tableId = utils.getTableId(ctx)
let response, row let response, row
if (inputs.rows) { if (inputs.rows) {
const targetRows = inputs.rows.map(
(row: { [key: string]: string | string }) => {
let processedRow = typeof row == "string" ? { _id: row } : row
return !processedRow._rev
? addRev(fixRow(processedRow, ctx.params), tableId)
: fixRow(processedRow, ctx.params)
}
)
const rowDeletes = await Promise.all(targetRows)
if (rowDeletes) {
ctx.request.body.rows = rowDeletes
}
let { rows } = await quotas.addQuery( let { rows } = await quotas.addQuery(
() => pickApi(tableId).bulkDestroy(ctx), () => pickApi(tableId).bulkDestroy(ctx),
{ {