Scroll to first invalid field (#11824)
* Final actions * Add vertical options to ScrollTo * Remove nearest option * Scroll to form field when invalid * Backwards compatibility for ScrollTo action * Revert "Final actions" This reverts commit 910e9e6d396aa8531c9662181ebccc77b90ed0ae. * Scroll to form field when invalid * Remove createAutomations function * Refactor * Refactor * lint --------- Co-authored-by: Michael Drury <me@michaeldrury.co.uk>
This commit is contained in:
parent
36f351e96d
commit
acb53c075a
|
@ -3,7 +3,6 @@
|
||||||
import { createEventDispatcher } from "svelte"
|
import { createEventDispatcher } from "svelte"
|
||||||
import { notifications } from "@budibase/bbui"
|
import { notifications } from "@budibase/bbui"
|
||||||
import ButtonActionDrawer from "./ButtonActionDrawer.svelte"
|
import ButtonActionDrawer from "./ButtonActionDrawer.svelte"
|
||||||
import { automationStore } from "builderStore"
|
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
@ -24,47 +23,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const saveEventData = async () => {
|
const saveEventData = async () => {
|
||||||
// any automations that need created from event triggers
|
|
||||||
const automationsToCreate = tmpValue.filter(
|
|
||||||
action => action["##eventHandlerType"] === "Trigger Automation"
|
|
||||||
)
|
|
||||||
for (let action of automationsToCreate) {
|
|
||||||
await createAutomation(action.parameters)
|
|
||||||
}
|
|
||||||
|
|
||||||
dispatch("change", tmpValue)
|
dispatch("change", tmpValue)
|
||||||
notifications.success("Component actions saved.")
|
notifications.success("Component actions saved.")
|
||||||
drawer.hide()
|
drawer.hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
// called by the parent modal when actions are saved
|
|
||||||
const createAutomation = async parameters => {
|
|
||||||
if (parameters.automationId || !parameters.newAutomationName) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
let trigger = automationStore.actions.constructBlock(
|
|
||||||
"TRIGGER",
|
|
||||||
"APP",
|
|
||||||
$automationStore.blockDefinitions.TRIGGER.APP
|
|
||||||
)
|
|
||||||
trigger.inputs = {
|
|
||||||
fields: Object.keys(parameters.fields ?? {}).reduce((fields, key) => {
|
|
||||||
fields[key] = "string"
|
|
||||||
return fields
|
|
||||||
}, {}),
|
|
||||||
}
|
|
||||||
const automation = await automationStore.actions.create(
|
|
||||||
parameters.newAutomationName,
|
|
||||||
trigger
|
|
||||||
)
|
|
||||||
parameters.automationId = automation._id
|
|
||||||
delete parameters.newAutomationName
|
|
||||||
} catch (error) {
|
|
||||||
notifications.error("Error creating automation")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$: actionCount = value?.length
|
$: actionCount = value?.length
|
||||||
$: actionText = `${actionCount || "No"} action${
|
$: actionText = `${actionCount || "No"} action${
|
||||||
actionCount !== 1 ? "s" : ""
|
actionCount !== 1 ? "s" : ""
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
<script>
|
<script>
|
||||||
import { currentAsset, store } from "builderStore"
|
import { currentAsset, store } from "builderStore"
|
||||||
import { onMount } from "svelte"
|
|
||||||
import { Label, Combobox, Select } from "@budibase/bbui"
|
import { Label, Combobox, Select } from "@budibase/bbui"
|
||||||
import {
|
import {
|
||||||
getActionProviderComponents,
|
getActionProviderComponents,
|
||||||
|
@ -10,12 +9,6 @@
|
||||||
|
|
||||||
export let parameters
|
export let parameters
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
if (!parameters.type) {
|
|
||||||
parameters.type = "top"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
$: formComponent = findComponent($currentAsset.props, parameters.componentId)
|
$: formComponent = findComponent($currentAsset.props, parameters.componentId)
|
||||||
$: formSchema = buildFormSchema(formComponent)
|
$: formSchema = buildFormSchema(formComponent)
|
||||||
$: fieldOptions = Object.keys(formSchema || {})
|
$: fieldOptions = Object.keys(formSchema || {})
|
||||||
|
|
|
@ -230,10 +230,16 @@
|
||||||
// We want to validate every field (even if validation fails early) to
|
// We want to validate every field (even if validation fails early) to
|
||||||
// ensure that all fields are populated with errors if invalid
|
// ensure that all fields are populated with errors if invalid
|
||||||
let valid = true
|
let valid = true
|
||||||
|
let hasScrolled = false
|
||||||
stepFields.forEach(field => {
|
stepFields.forEach(field => {
|
||||||
const fieldValid = get(field).fieldApi.validate()
|
const fieldValid = get(field).fieldApi.validate()
|
||||||
valid = valid && fieldValid
|
valid = valid && fieldValid
|
||||||
|
if (!valid && !hasScrolled) {
|
||||||
|
handleScrollToField({ field: get(field) })
|
||||||
|
hasScrolled = true
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
return valid
|
return valid
|
||||||
},
|
},
|
||||||
reset: () => {
|
reset: () => {
|
||||||
|
@ -409,10 +415,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleScrollToField = ({ field }) => {
|
const handleScrollToField = ({ field }) => {
|
||||||
const fieldId = get(getField(field)).fieldState.fieldId
|
if (!field.fieldState) {
|
||||||
|
field = get(getField(field))
|
||||||
|
}
|
||||||
|
const fieldId = field.fieldState.fieldId
|
||||||
|
const fieldElement = document.getElementById(fieldId)
|
||||||
|
fieldElement.focus({ preventScroll: true })
|
||||||
const label = document.querySelector(`label[for="${fieldId}"]`)
|
const label = document.querySelector(`label[for="${fieldId}"]`)
|
||||||
document.getElementById(fieldId).focus({ preventScroll: true })
|
label.style.scrollMargin = "100px"
|
||||||
label.scrollIntoView({ behavior: "smooth" })
|
label.scrollIntoView({ behavior: "smooth", block: "nearest" })
|
||||||
}
|
}
|
||||||
|
|
||||||
// Action context to pass to children
|
// Action context to pass to children
|
||||||
|
|
Loading…
Reference in New Issue