Merge pull request #15442 from Budibase/budi-9006-allow-automation-test-data-modal-to-select-real-data-to-take-2

[BUDI-9006] Allow automation test data modal to select real data
This commit is contained in:
Sam Rose 2025-03-06 15:17:03 +00:00 committed by GitHub
commit d554796801
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 129 additions and 6 deletions

View File

@ -102,6 +102,10 @@
if (rowTriggers.includes(trigger?.event)) {
const tableId = trigger?.inputs?.tableId
if (!jsonUpdate.row) {
jsonUpdate.row = {}
}
// Reset the tableId as it must match the trigger
if (jsonUpdate?.row?.tableId !== tableId) {
jsonUpdate.row.tableId = tableId
@ -161,7 +165,7 @@
block={trigger}
on:update={e => {
const { testData: updatedTestData } = e.detail
testData = updatedTestData
testData = parseTestData(updatedTestData)
}}
/>
</div>

View File

@ -18,6 +18,7 @@
Toggle,
Divider,
Icon,
CoreSelect,
} from "@budibase/bbui"
import CreateWebhookModal from "@/components/automation/Shared/CreateWebhookModal.svelte"
@ -48,7 +49,13 @@
EditorModes,
} from "@/components/common/CodeEditor"
import FilterBuilder from "@/components/design/settings/controls/FilterEditor/FilterBuilder.svelte"
import { QueryUtils, Utils, search, memo } from "@budibase/frontend-core"
import {
QueryUtils,
Utils,
search,
memo,
fetchData,
} from "@budibase/frontend-core"
import { getSchemaForDatasourcePlus } from "@/dataBinding"
import { TriggerStepID, ActionStepID } from "@/constants/backend/automations"
import { onMount, createEventDispatcher } from "svelte"
@ -59,9 +66,12 @@
AutomationStepType,
AutomationActionStepId,
AutomationCustomIOType,
SortOrder,
} from "@budibase/types"
import PropField from "./PropField.svelte"
import { utils } from "@budibase/shared-core"
import { API } from "@/api"
import InfoDisplay from "@/pages/builder/app/[application]/design/[screenId]/[componentId]/_components/Component/InfoDisplay.svelte"
export let automation
export let block
@ -95,6 +105,8 @@
let inputData
let insertAtPos, getCaretPosition
let stepLayouts = {}
let rowSearchTerm = ""
let selectedRow
$: memoBlock.set(block)
@ -109,9 +121,13 @@
$: stepId = $memoBlock.stepId
$: getInputData(testData, $memoBlock.inputs)
$: tableId = inputData ? inputData.tableId : null
$: tableId =
inputData?.row?.tableId ||
testData?.row?.tableId ||
inputData?.tableId ||
null
$: table = tableId
? $tables.list.find(table => table._id === inputData.tableId)
? $tables.list.find(table => table._id === tableId)
: { schema: {} }
$: schema = getSchemaForDatasourcePlus(tableId, {
searchableSchema: true,
@ -140,6 +156,40 @@
? [hbAutocomplete([...bindingsToCompletions(bindings, codeMode)])]
: []
$: fetch = createFetch({ type: "table", tableId })
$: fetchedRows = $fetch?.rows
$: fetch?.update({
query: {
fuzzy: {
[primaryDisplay]: rowSearchTerm || "",
},
},
})
$: fetchLoading = $fetch?.loading
$: primaryDisplay = table?.primaryDisplay
const createFetch = datasource => {
if (!datasource) {
return
}
return fetchData({
API,
datasource,
options: {
sortColumn: primaryDisplay,
sortOrder: SortOrder.ASCENDING,
query: {
fuzzy: {
[primaryDisplay]: rowSearchTerm || "",
},
},
limit: 20,
},
})
}
const getInputData = (testData, blockInputs) => {
// Test data is not cloned for reactivity
let newInputData = testData || cloneDeep(blockInputs)
@ -167,7 +217,7 @@
const stepStore = writable({})
$: stepState = $stepStore?.[block.id]
$: customStepLayouts($memoBlock, schemaProperties, stepState)
$: customStepLayouts($memoBlock, schemaProperties, stepState, fetchedRows)
const customStepLayouts = block => {
if (
@ -362,6 +412,49 @@
disabled: isTestModal,
},
},
{
type: CoreSelect,
title: "Row",
props: {
disabled: !table,
placeholder: "Select a row",
options: fetchedRows,
loading: fetchLoading,
value: selectedRow,
autocomplete: true,
filter: false,
getOptionLabel: row => row?.[primaryDisplay] || "",
compare: (a, b) => a?.[primaryDisplay] === b?.[primaryDisplay],
onChange: e => {
if (isTestModal) {
onChange({
id: e.detail?._id,
revision: e.detail?._rev,
row: e.detail,
oldRow: e.detail,
meta: {
fields: inputData["meta"]?.fields || {},
oldFields: e.detail?.meta?.fields || {},
},
})
}
},
},
},
{
type: InfoDisplay,
props: {
warning: true,
icon: "AlertCircleFilled",
body: `Be careful when testing this automation because your data may be modified or deleted.`,
},
},
{
type: Divider,
props: {
noMargin: true,
},
},
...getIdConfig(),
...getRevConfig(),
...getRowTypeConfig(),
@ -556,6 +649,15 @@
...request,
}
if (
newTestData?.row == null ||
Object.keys(newTestData?.row).length === 0
) {
selectedRow = null
} else {
selectedRow = newTestData.row
}
const updatedAuto =
automationStore.actions.addTestDataToAutomation(newTestData)
@ -668,6 +770,7 @@
{...config.props}
{bindings}
on:change={config.props.onChange}
bind:searchTerm={rowSearchTerm}
/>
</PropField>
{:else}

View File

@ -303,13 +303,22 @@
>
<ActionButton
icon="Add"
fullWidth
on:click={() => {
customPopover.show()
}}
disabled={!schemaFields}
>Add fields
</ActionButton>
<ActionButton
icon="Remove"
on:click={() => {
dispatch("change", {
meta: { fields: {} },
row: {},
})
}}
>Clear
</ActionButton>
</div>
{/if}
@ -375,4 +384,11 @@
.prop-control-wrap :global(.icon.json-slot-icon) {
right: 1px !important;
}
.add-fields-btn {
display: flex;
flex-direction: row;
justify-content: center;
gap: var(--spacing-s);
}
</style>