Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes + table native paste #14342

Merged
merged 8 commits into from
Aug 13, 2024
Merged
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getComponentContexts } from "dataBinding"
import { getAllComponentContexts } from "dataBinding"
import { capitalise } from "helpers"

// Generates bindings for all components that provider "datasource like"
Expand All @@ -7,7 +7,7 @@ import { capitalise } from "helpers"
// Some examples are saving rows or duplicating rows.
export const getDatasourceLikeProviders = ({ asset, componentId, nested }) => {
// Get all form context providers
const formComponentContexts = getComponentContexts(
const formComponentContexts = getAllComponentContexts(
asset,
componentId,
"form",
Expand All @@ -16,7 +16,7 @@ export const getDatasourceLikeProviders = ({ asset, componentId, nested }) => {
}
)
// Get all schema context providers
const schemaComponentContexts = getComponentContexts(
const schemaComponentContexts = getAllComponentContexts(
asset,
componentId,
"schema",
Expand Down
69 changes: 30 additions & 39 deletions packages/builder/src/dataBinding.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
findAllMatchingComponents,
findComponent,
findComponentPath,
getComponentContexts,
} from "helpers/components"
import {
componentStore,
Expand Down Expand Up @@ -213,7 +214,7 @@ export const getComponentBindableProperties = (asset, componentId) => {
* both global and local bindings, taking into account a component's position
* in the component tree.
*/
export const getComponentContexts = (
export const getAllComponentContexts = (
asset,
componentId,
type,
Expand All @@ -229,11 +230,6 @@ export const getComponentContexts = (

// Processes all contexts exposed by a component
const processContexts = scope => component => {
const def = componentStore.getDefinition(component._component)
if (!def?.context) {
return
}

// Filter out global contexts not in the same branch.
// Global contexts are only valid if their branch root is an ancestor of
// this component.
Expand All @@ -242,8 +238,8 @@ export const getComponentContexts = (
return
}

// Process all contexts provided by this component
const contexts = Array.isArray(def.context) ? def.context : [def.context]
const componentType = component._component
const contexts = getComponentContexts(componentType)
contexts.forEach(context => {
// Ensure type matches
if (type && context.type !== type) {
Expand All @@ -261,7 +257,7 @@ export const getComponentContexts = (
if (!map[component._id]) {
map[component._id] = {
component,
definition: def,
definition: componentStore.getDefinition(componentType),
contexts: [],
}
}
Expand All @@ -286,44 +282,39 @@ export const getComponentContexts = (
}

/**
* Gets all data provider components above a component.
* Gets all components available to this component that expose a certain action
*/
export const getActionProviders = (
asset,
componentId,
actionType,
options = { includeSelf: false }
) => {
if (!asset) {
return []
}

// Get all components
const components = findAllComponents(asset.props)
const contexts = getAllComponentContexts(asset, componentId, "action", {
includeSelf: options?.includeSelf,
})
return (
contexts
// Find the definition of the action in question, if one is provided
.map(context => ({
...context,

// Find matching contexts and generate bindings
let providers = []
components.forEach(component => {
if (!options?.includeSelf && component._id === componentId) {
return
}
const def = componentStore.getDefinition(component._component)
const actions = (def?.actions || []).map(action => {
return typeof action === "string" ? { type: action } : action
})
const action = actions.find(x => x.type === actionType)
if (action) {
let runtimeBinding = component._id
if (action.suffix) {
runtimeBinding += `-${action.suffix}`
}
providers.push({
readableBinding: component._instanceName,
runtimeBinding,
action: context.contexts[0].actions.find(x => x.type === actionType),
aptkingston marked this conversation as resolved.
Show resolved Hide resolved
}))
// Filter out contexts which don't have this action
.filter(({ action }) => action != null)
// Generate bindings for this component and action
.map(({ component, action }) => {
let runtimeBinding = component._id
if (action.suffix) {
runtimeBinding += `-${action.suffix}`
}
return {
readableBinding: component._instanceName,
runtimeBinding,
}
})
}
})
return providers
)
}

/**
Expand Down Expand Up @@ -371,7 +362,7 @@ export const getDatasourceForProvider = (asset, component) => {
*/
const getContextBindings = (asset, componentId) => {
// Get all available contexts for this component
const componentContexts = getComponentContexts(asset, componentId)
const componentContexts = getAllComponentContexts(asset, componentId)

// Generate bindings for each context
return componentContexts
Expand Down
24 changes: 21 additions & 3 deletions packages/builder/src/helpers/components.js
Original file line number Diff line number Diff line change
Expand Up @@ -228,6 +228,25 @@ export const getComponentName = component => {
return componentDefinition.friendlyName || componentDefinition.name || ""
}

// Gets all contexts exposed by a certain component type, including actions
export const getComponentContexts = component => {
const def = componentStore.getDefinition(component)
let contexts = []
if (def?.context) {
contexts = Array.isArray(def.context) ? [...def.context] : [def.context]
}
if (def?.actions) {
contexts.push({
type: "action",
scope: ContextScopes.Global,

// Ensure all actions are their verbose object versions
actions: def.actions.map(x => (typeof x === "string" ? { type: x } : x)),
})
}
return contexts
}

/**
* Recurses through the component tree and builds a tree of contexts provided
* by components.
Expand All @@ -243,10 +262,9 @@ export const buildContextTree = (
}

// Process this component's contexts
const def = componentStore.getDefinition(rootComponent._component)
if (def?.context) {
const contexts = getComponentContexts(rootComponent._component)
if (contexts.length) {
tree[currentBranch].push(rootComponent._id)
const contexts = Array.isArray(def.context) ? def.context : [def.context]

// If we provide local context, start a new branch for our children
if (contexts.some(context => context.scope === ContextScopes.Local)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,15 @@
onOperatorChange(condition, condition.operator)
}
}

const onSettingChange = (e, condition) => {
const setting = settings.find(x => x.key === e.detail)
if (setting?.defaultValue != null) {
condition.settingValue = setting?.defaultValue
aptkingston marked this conversation as resolved.
Show resolved Hide resolved
} else {
delete condition.settingValue
}
}
</script>

<!-- svelte-ignore a11y-no-static-element-interactions -->
Expand Down Expand Up @@ -189,7 +198,7 @@
<Select
options={settingOptions}
bind:value={condition.setting}
on:change={() => delete condition.settingValue}
on:change={e => onSettingChange(e, condition)}
/>
<div>TO</div>
{#if definition}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@
import { Modal, ModalContent, ProgressBar } from "@budibase/bbui"
import { getContext, onMount } from "svelte"
import { sleep } from "../../../utils/utils"
import { get } from "svelte/store"

const { clipboard, subscribe, copyAllowed, pasteAllowed, selectedCellCount } =
getContext("grid")
const {
clipboard,
subscribe,
copyAllowed,
pasteAllowed,
selectedCellCount,
focusedCellAPI,
} = getContext("grid")
const duration = 260

let modal
Expand All @@ -19,10 +26,15 @@
}

const handlePasteRequest = async () => {
// If a cell is active then let the native paste action take over
if (get(focusedCellAPI)?.isActive()) {
return
}
progressPercentage = 0
if (!$pasteAllowed) {
return
}

// Prompt if paste will update multiple cells
const multiCellPaste = $selectedCellCount > 1
const prompt = $clipboard.multiCellCopy || multiCellPaste
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
case "c":
return handle(() => dispatch("copy"))
case "v":
return handle(() => dispatch("paste"))
return dispatch("paste")
melohagan marked this conversation as resolved.
Show resolved Hide resolved
case "Enter":
return handle(() => {
if ($config.canAddRows) {
Expand Down
Loading