Merge pull request #14342 from Budibase/cheeks-fixes
Fixes + table native paste
This commit is contained in:
commit
37fe3b2af9
|
@ -1,4 +1,4 @@
|
||||||
import { getComponentContexts } from "dataBinding"
|
import { getAllComponentContexts } from "dataBinding"
|
||||||
import { capitalise } from "helpers"
|
import { capitalise } from "helpers"
|
||||||
|
|
||||||
// Generates bindings for all components that provider "datasource like"
|
// Generates bindings for all components that provider "datasource like"
|
||||||
|
@ -7,7 +7,7 @@ import { capitalise } from "helpers"
|
||||||
// Some examples are saving rows or duplicating rows.
|
// Some examples are saving rows or duplicating rows.
|
||||||
export const getDatasourceLikeProviders = ({ asset, componentId, nested }) => {
|
export const getDatasourceLikeProviders = ({ asset, componentId, nested }) => {
|
||||||
// Get all form context providers
|
// Get all form context providers
|
||||||
const formComponentContexts = getComponentContexts(
|
const formComponentContexts = getAllComponentContexts(
|
||||||
asset,
|
asset,
|
||||||
componentId,
|
componentId,
|
||||||
"form",
|
"form",
|
||||||
|
@ -16,7 +16,7 @@ export const getDatasourceLikeProviders = ({ asset, componentId, nested }) => {
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
// Get all schema context providers
|
// Get all schema context providers
|
||||||
const schemaComponentContexts = getComponentContexts(
|
const schemaComponentContexts = getAllComponentContexts(
|
||||||
asset,
|
asset,
|
||||||
componentId,
|
componentId,
|
||||||
"schema",
|
"schema",
|
||||||
|
|
|
@ -6,6 +6,7 @@ import {
|
||||||
findAllMatchingComponents,
|
findAllMatchingComponents,
|
||||||
findComponent,
|
findComponent,
|
||||||
findComponentPath,
|
findComponentPath,
|
||||||
|
getComponentContexts,
|
||||||
} from "helpers/components"
|
} from "helpers/components"
|
||||||
import {
|
import {
|
||||||
componentStore,
|
componentStore,
|
||||||
|
@ -213,7 +214,7 @@ export const getComponentBindableProperties = (asset, componentId) => {
|
||||||
* both global and local bindings, taking into account a component's position
|
* both global and local bindings, taking into account a component's position
|
||||||
* in the component tree.
|
* in the component tree.
|
||||||
*/
|
*/
|
||||||
export const getComponentContexts = (
|
export const getAllComponentContexts = (
|
||||||
asset,
|
asset,
|
||||||
componentId,
|
componentId,
|
||||||
type,
|
type,
|
||||||
|
@ -229,11 +230,6 @@ export const getComponentContexts = (
|
||||||
|
|
||||||
// Processes all contexts exposed by a component
|
// Processes all contexts exposed by a component
|
||||||
const processContexts = scope => component => {
|
const processContexts = scope => component => {
|
||||||
const def = componentStore.getDefinition(component._component)
|
|
||||||
if (!def?.context) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// Filter out global contexts not in the same branch.
|
// Filter out global contexts not in the same branch.
|
||||||
// Global contexts are only valid if their branch root is an ancestor of
|
// Global contexts are only valid if their branch root is an ancestor of
|
||||||
// this component.
|
// this component.
|
||||||
|
@ -242,8 +238,8 @@ export const getComponentContexts = (
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process all contexts provided by this component
|
const componentType = component._component
|
||||||
const contexts = Array.isArray(def.context) ? def.context : [def.context]
|
const contexts = getComponentContexts(componentType)
|
||||||
contexts.forEach(context => {
|
contexts.forEach(context => {
|
||||||
// Ensure type matches
|
// Ensure type matches
|
||||||
if (type && context.type !== type) {
|
if (type && context.type !== type) {
|
||||||
|
@ -261,7 +257,7 @@ export const getComponentContexts = (
|
||||||
if (!map[component._id]) {
|
if (!map[component._id]) {
|
||||||
map[component._id] = {
|
map[component._id] = {
|
||||||
component,
|
component,
|
||||||
definition: def,
|
definition: componentStore.getDefinition(componentType),
|
||||||
contexts: [],
|
contexts: [],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -286,7 +282,7 @@ 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 = (
|
export const getActionProviders = (
|
||||||
asset,
|
asset,
|
||||||
|
@ -294,36 +290,30 @@ export const getActionProviders = (
|
||||||
actionType,
|
actionType,
|
||||||
options = { includeSelf: false }
|
options = { includeSelf: false }
|
||||||
) => {
|
) => {
|
||||||
if (!asset) {
|
const contexts = getAllComponentContexts(asset, componentId, "action", {
|
||||||
return []
|
includeSelf: options?.includeSelf,
|
||||||
}
|
|
||||||
|
|
||||||
// Get all components
|
|
||||||
const components = findAllComponents(asset.props)
|
|
||||||
|
|
||||||
// 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,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
return providers
|
return (
|
||||||
|
contexts
|
||||||
|
// Find the definition of the action in question, if one is provided
|
||||||
|
.map(context => ({
|
||||||
|
...context,
|
||||||
|
action: context.contexts[0]?.actions?.find(x => x.type === actionType),
|
||||||
|
}))
|
||||||
|
// 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,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -371,7 +361,7 @@ export const getDatasourceForProvider = (asset, component) => {
|
||||||
*/
|
*/
|
||||||
const getContextBindings = (asset, componentId) => {
|
const getContextBindings = (asset, componentId) => {
|
||||||
// Get all available contexts for this component
|
// Get all available contexts for this component
|
||||||
const componentContexts = getComponentContexts(asset, componentId)
|
const componentContexts = getAllComponentContexts(asset, componentId)
|
||||||
|
|
||||||
// Generate bindings for each context
|
// Generate bindings for each context
|
||||||
return componentContexts
|
return componentContexts
|
||||||
|
|
|
@ -228,6 +228,25 @@ export const getComponentName = component => {
|
||||||
return componentDefinition.friendlyName || componentDefinition.name || ""
|
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
|
* Recurses through the component tree and builds a tree of contexts provided
|
||||||
* by components.
|
* by components.
|
||||||
|
@ -243,10 +262,9 @@ export const buildContextTree = (
|
||||||
}
|
}
|
||||||
|
|
||||||
// Process this component's contexts
|
// Process this component's contexts
|
||||||
const def = componentStore.getDefinition(rootComponent._component)
|
const contexts = getComponentContexts(rootComponent._component)
|
||||||
if (def?.context) {
|
if (contexts.length) {
|
||||||
tree[currentBranch].push(rootComponent._id)
|
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 we provide local context, start a new branch for our children
|
||||||
if (contexts.some(context => context.scope === ContextScopes.Local)) {
|
if (contexts.some(context => context.scope === ContextScopes.Local)) {
|
||||||
|
|
|
@ -147,6 +147,15 @@
|
||||||
onOperatorChange(condition, condition.operator)
|
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
|
||||||
|
} else {
|
||||||
|
delete condition.settingValue
|
||||||
|
}
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||||
|
@ -189,7 +198,7 @@
|
||||||
<Select
|
<Select
|
||||||
options={settingOptions}
|
options={settingOptions}
|
||||||
bind:value={condition.setting}
|
bind:value={condition.setting}
|
||||||
on:change={() => delete condition.settingValue}
|
on:change={e => onSettingChange(e, condition)}
|
||||||
/>
|
/>
|
||||||
<div>TO</div>
|
<div>TO</div>
|
||||||
{#if definition}
|
{#if definition}
|
||||||
|
|
|
@ -2,9 +2,16 @@
|
||||||
import { Modal, ModalContent, ProgressBar } from "@budibase/bbui"
|
import { Modal, ModalContent, ProgressBar } from "@budibase/bbui"
|
||||||
import { getContext, onMount } from "svelte"
|
import { getContext, onMount } from "svelte"
|
||||||
import { sleep } from "../../../utils/utils"
|
import { sleep } from "../../../utils/utils"
|
||||||
|
import { get } from "svelte/store"
|
||||||
|
|
||||||
const { clipboard, subscribe, copyAllowed, pasteAllowed, selectedCellCount } =
|
const {
|
||||||
getContext("grid")
|
clipboard,
|
||||||
|
subscribe,
|
||||||
|
copyAllowed,
|
||||||
|
pasteAllowed,
|
||||||
|
selectedCellCount,
|
||||||
|
focusedCellAPI,
|
||||||
|
} = getContext("grid")
|
||||||
const duration = 260
|
const duration = 260
|
||||||
|
|
||||||
let modal
|
let modal
|
||||||
|
@ -19,10 +26,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const handlePasteRequest = async () => {
|
const handlePasteRequest = async () => {
|
||||||
|
// If a cell is active then let the native paste action take over
|
||||||
|
if (get(focusedCellAPI)?.isActive()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
progressPercentage = 0
|
progressPercentage = 0
|
||||||
if (!$pasteAllowed) {
|
if (!$pasteAllowed) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prompt if paste will update multiple cells
|
// Prompt if paste will update multiple cells
|
||||||
const multiCellPaste = $selectedCellCount > 1
|
const multiCellPaste = $selectedCellCount > 1
|
||||||
const prompt = $clipboard.multiCellCopy || multiCellPaste
|
const prompt = $clipboard.multiCellCopy || multiCellPaste
|
||||||
|
|
|
@ -58,7 +58,7 @@
|
||||||
case "c":
|
case "c":
|
||||||
return handle(() => dispatch("copy"))
|
return handle(() => dispatch("copy"))
|
||||||
case "v":
|
case "v":
|
||||||
return handle(() => dispatch("paste"))
|
return dispatch("paste")
|
||||||
case "Enter":
|
case "Enter":
|
||||||
return handle(() => {
|
return handle(() => {
|
||||||
if ($config.canAddRows) {
|
if ($config.canAddRows) {
|
||||||
|
|
Loading…
Reference in New Issue