Merge branch 'master' into execute-script-v2
This commit is contained in:
commit
f37ffb0930
|
@ -94,6 +94,15 @@ export default [
|
||||||
allowImportExportEverywhere: true,
|
allowImportExportEverywhere: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
plugins: {
|
||||||
|
...config.plugins,
|
||||||
|
"@typescript-eslint": tseslint.plugin,
|
||||||
|
},
|
||||||
|
rules: {
|
||||||
|
...config.rules,
|
||||||
|
"@typescript-eslint/consistent-type-imports": "error",
|
||||||
|
},
|
||||||
})),
|
})),
|
||||||
...tseslint.configs.strict.map(config => ({
|
...tseslint.configs.strict.map(config => ({
|
||||||
...config,
|
...config,
|
||||||
|
|
|
@ -27,7 +27,7 @@ export type UpdateHandler = (
|
||||||
|
|
||||||
interface Opts {
|
interface Opts {
|
||||||
anchor?: HTMLElement
|
anchor?: HTMLElement
|
||||||
align: PopoverAlignment
|
align: PopoverAlignment | `${PopoverAlignment}`
|
||||||
maxHeight?: number
|
maxHeight?: number
|
||||||
maxWidth?: number
|
maxWidth?: number
|
||||||
minWidth?: number
|
minWidth?: number
|
||||||
|
|
|
@ -19,7 +19,8 @@
|
||||||
import { PopoverAlignment } from "../constants"
|
import { PopoverAlignment } from "../constants"
|
||||||
|
|
||||||
export let anchor: HTMLElement
|
export let anchor: HTMLElement
|
||||||
export let align: PopoverAlignment = PopoverAlignment.Right
|
export let align: PopoverAlignment | `${PopoverAlignment}` =
|
||||||
|
PopoverAlignment.Right
|
||||||
export let portalTarget: string | undefined = undefined
|
export let portalTarget: string | undefined = undefined
|
||||||
export let minWidth: number | undefined = undefined
|
export let minWidth: number | undefined = undefined
|
||||||
export let maxWidth: number | undefined = undefined
|
export let maxWidth: number | undefined = undefined
|
||||||
|
|
|
@ -422,7 +422,7 @@
|
||||||
{context}
|
{context}
|
||||||
addHelper={onSelectHelper}
|
addHelper={onSelectHelper}
|
||||||
addBinding={onSelectBinding}
|
addBinding={onSelectBinding}
|
||||||
mode={editorMode}
|
{mode}
|
||||||
/>
|
/>
|
||||||
{:else if sidePanel === SidePanel.Evaluation}
|
{:else if sidePanel === SidePanel.Evaluation}
|
||||||
<EvaluationSidePanel
|
<EvaluationSidePanel
|
||||||
|
|
|
@ -1,32 +1,41 @@
|
||||||
<script>
|
<script lang="ts">
|
||||||
import groupBy from "lodash/fp/groupBy"
|
import groupBy from "lodash/fp/groupBy"
|
||||||
import { convertToJS } from "@budibase/string-templates"
|
import { convertToJS } from "@budibase/string-templates"
|
||||||
import { Input, Layout, Icon, Popover } from "@budibase/bbui"
|
import { Input, Layout, Icon, Popover } from "@budibase/bbui"
|
||||||
import { handlebarsCompletions } from "@/constants/completions"
|
import { handlebarsCompletions } from "@/constants/completions"
|
||||||
|
import type { EnrichedBinding, Helper } from "@budibase/types"
|
||||||
|
import { BindingMode } from "@budibase/types"
|
||||||
|
|
||||||
export let addHelper
|
export let addHelper: (_helper: Helper, _js?: boolean) => void
|
||||||
export let addBinding
|
export let addBinding: (_binding: EnrichedBinding) => void
|
||||||
export let bindings
|
export let bindings: EnrichedBinding[]
|
||||||
export let mode
|
export let mode: BindingMode
|
||||||
export let allowHelpers
|
export let allowHelpers: boolean
|
||||||
export let context = null
|
export let context = null
|
||||||
|
|
||||||
let search = ""
|
let search = ""
|
||||||
let searching = false
|
let searching = false
|
||||||
let popover
|
let popover: Popover
|
||||||
let popoverAnchor
|
let popoverAnchor: HTMLElement | null
|
||||||
let hoverTarget
|
let hoverTarget: {
|
||||||
|
helper: boolean
|
||||||
|
code: string
|
||||||
|
description?: string
|
||||||
|
} | null
|
||||||
let helpers = handlebarsCompletions()
|
let helpers = handlebarsCompletions()
|
||||||
let selectedCategory
|
let selectedCategory: string | null
|
||||||
let hideTimeout
|
let hideTimeout: ReturnType<typeof setTimeout> | null
|
||||||
|
|
||||||
$: bindingIcons = bindings?.reduce((acc, ele) => {
|
$: bindingIcons = bindings?.reduce<Record<string, string>>((acc, ele) => {
|
||||||
if (ele.icon) {
|
if (ele.icon) {
|
||||||
acc[ele.category] = acc[ele.category] || ele.icon
|
acc[ele.category] = acc[ele.category] || ele.icon
|
||||||
}
|
}
|
||||||
return acc
|
return acc
|
||||||
}, {})
|
}, {})
|
||||||
$: categoryIcons = { ...bindingIcons, Helpers: "MagicWand" }
|
$: categoryIcons = {
|
||||||
|
...bindingIcons,
|
||||||
|
Helpers: "MagicWand",
|
||||||
|
} as Record<string, string>
|
||||||
$: categories = Object.entries(groupBy("category", bindings))
|
$: categories = Object.entries(groupBy("category", bindings))
|
||||||
$: categoryNames = getCategoryNames(categories)
|
$: categoryNames = getCategoryNames(categories)
|
||||||
$: searchRgx = new RegExp(search, "ig")
|
$: searchRgx = new RegExp(search, "ig")
|
||||||
|
@ -48,11 +57,11 @@
|
||||||
(!search ||
|
(!search ||
|
||||||
helper.label.match(searchRgx) ||
|
helper.label.match(searchRgx) ||
|
||||||
helper.description.match(searchRgx)) &&
|
helper.description.match(searchRgx)) &&
|
||||||
(mode.name !== "javascript" || helper.allowsJs)
|
(mode !== BindingMode.JavaScript || helper.allowsJs)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
const getHelperExample = (helper, js) => {
|
const getHelperExample = (helper: Helper, js: boolean) => {
|
||||||
let example = helper.example || ""
|
let example = helper.example || ""
|
||||||
if (js) {
|
if (js) {
|
||||||
example = convertToJS(example).split("\n")[0].split("= ")[1]
|
example = convertToJS(example).split("\n")[0].split("= ")[1]
|
||||||
|
@ -63,15 +72,18 @@
|
||||||
return example || ""
|
return example || ""
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCategoryNames = categories => {
|
const getCategoryNames = (categories: [string, EnrichedBinding[]][]) => {
|
||||||
let names = [...categories.map(cat => cat[0])]
|
const names = [...categories.map(cat => cat[0])]
|
||||||
if (allowHelpers) {
|
if (allowHelpers) {
|
||||||
names.push("Helpers")
|
names.push("Helpers")
|
||||||
}
|
}
|
||||||
return names
|
return names
|
||||||
}
|
}
|
||||||
|
|
||||||
const showBindingPopover = (binding, target) => {
|
const showBindingPopover = (
|
||||||
|
binding: EnrichedBinding,
|
||||||
|
target: HTMLElement
|
||||||
|
) => {
|
||||||
if (!context || !binding.value || binding.value === "") {
|
if (!context || !binding.value || binding.value === "") {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -84,7 +96,7 @@
|
||||||
popover.show()
|
popover.show()
|
||||||
}
|
}
|
||||||
|
|
||||||
const showHelperPopover = (helper, target) => {
|
const showHelperPopover = (helper: any, target: HTMLElement) => {
|
||||||
stopHidingPopover()
|
stopHidingPopover()
|
||||||
if (!helper.displayText && helper.description) {
|
if (!helper.displayText && helper.description) {
|
||||||
return
|
return
|
||||||
|
@ -93,7 +105,7 @@
|
||||||
hoverTarget = {
|
hoverTarget = {
|
||||||
helper: true,
|
helper: true,
|
||||||
description: helper.description,
|
description: helper.description,
|
||||||
code: getHelperExample(helper, mode.name === "javascript"),
|
code: getHelperExample(helper, mode === BindingMode.JavaScript),
|
||||||
}
|
}
|
||||||
popover.show()
|
popover.show()
|
||||||
}
|
}
|
||||||
|
@ -119,37 +131,39 @@
|
||||||
search = ""
|
search = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
const stopSearching = e => {
|
const stopSearching = (e: Event) => {
|
||||||
e.stopPropagation()
|
e.stopPropagation()
|
||||||
searching = false
|
searching = false
|
||||||
search = ""
|
search = ""
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<Popover
|
{#if popoverAnchor && hoverTarget}
|
||||||
align="left-outside"
|
<Popover
|
||||||
bind:this={popover}
|
align="left-outside"
|
||||||
anchor={popoverAnchor}
|
bind:this={popover}
|
||||||
minWidth={0}
|
anchor={popoverAnchor}
|
||||||
maxWidth={480}
|
minWidth={0}
|
||||||
maxHeight={480}
|
maxWidth={480}
|
||||||
dismissible={false}
|
maxHeight={480}
|
||||||
on:mouseenter={stopHidingPopover}
|
dismissible={false}
|
||||||
on:mouseleave={hidePopover}
|
on:mouseenter={stopHidingPopover}
|
||||||
>
|
on:mouseleave={hidePopover}
|
||||||
<div class="binding-popover" class:helper={hoverTarget.helper}>
|
>
|
||||||
{#if hoverTarget.description}
|
<div class="binding-popover" class:helper={hoverTarget.helper}>
|
||||||
<div>
|
{#if hoverTarget.description}
|
||||||
|
<div>
|
||||||
|
<!-- eslint-disable-next-line svelte/no-at-html-tags-->
|
||||||
|
{@html hoverTarget.description}
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
|
{#if hoverTarget.code}
|
||||||
<!-- eslint-disable-next-line svelte/no-at-html-tags-->
|
<!-- eslint-disable-next-line svelte/no-at-html-tags-->
|
||||||
{@html hoverTarget.description}
|
<pre>{@html hoverTarget.code}</pre>
|
||||||
</div>
|
{/if}
|
||||||
{/if}
|
</div>
|
||||||
{#if hoverTarget.code}
|
</Popover>
|
||||||
<!-- eslint-disable-next-line svelte/no-at-html-tags-->
|
{/if}
|
||||||
<pre>{@html hoverTarget.code}</pre>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
</Popover>
|
|
||||||
|
|
||||||
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
<!-- svelte-ignore a11y-click-events-have-key-events -->
|
||||||
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
<!-- svelte-ignore a11y-no-noninteractive-element-interactions -->
|
||||||
|
@ -173,7 +187,7 @@
|
||||||
<div class="search-input">
|
<div class="search-input">
|
||||||
<Input
|
<Input
|
||||||
placeholder="Search for bindings"
|
placeholder="Search for bindings"
|
||||||
autocomplete="off"
|
autocomplete={false}
|
||||||
bind:value={search}
|
bind:value={search}
|
||||||
autofocus
|
autofocus
|
||||||
/>
|
/>
|
||||||
|
@ -230,7 +244,8 @@
|
||||||
{#each category.bindings as binding}
|
{#each category.bindings as binding}
|
||||||
<li
|
<li
|
||||||
class="binding"
|
class="binding"
|
||||||
on:mouseenter={e => showBindingPopover(binding, e.target)}
|
on:mouseenter={e =>
|
||||||
|
showBindingPopover(binding, e.currentTarget)}
|
||||||
on:mouseleave={hidePopover}
|
on:mouseleave={hidePopover}
|
||||||
on:click={() => addBinding(binding)}
|
on:click={() => addBinding(binding)}
|
||||||
>
|
>
|
||||||
|
@ -264,9 +279,11 @@
|
||||||
{#each filteredHelpers as helper}
|
{#each filteredHelpers as helper}
|
||||||
<li
|
<li
|
||||||
class="binding"
|
class="binding"
|
||||||
on:mouseenter={e => showHelperPopover(helper, e.target)}
|
on:mouseenter={e =>
|
||||||
|
showHelperPopover(helper, e.currentTarget)}
|
||||||
on:mouseleave={hidePopover}
|
on:mouseleave={hidePopover}
|
||||||
on:click={() => addHelper(helper, mode.name === "javascript")}
|
on:click={() =>
|
||||||
|
addHelper(helper, mode === BindingMode.JavaScript)}
|
||||||
>
|
>
|
||||||
<span class="binding__label">{helper.displayText}</span>
|
<span class="binding__label">{helper.displayText}</span>
|
||||||
<span class="binding__typeWrap">
|
<span class="binding__typeWrap">
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { getManifest, helpersToRemoveForJs } from "@budibase/string-templates"
|
import { getManifest, helpersToRemoveForJs } from "@budibase/string-templates"
|
||||||
|
import { Helper } from "@budibase/types"
|
||||||
|
|
||||||
export function handlebarsCompletions() {
|
export function handlebarsCompletions(): Helper[] {
|
||||||
const manifest = getManifest()
|
const manifest = getManifest()
|
||||||
|
return Object.values(manifest).flatMap(helpersObj =>
|
||||||
return Object.keys(manifest).flatMap(key =>
|
Object.entries(helpersObj).map<Helper>(([helperName, helperConfig]) => ({
|
||||||
Object.entries(manifest[key]).map(([helperName, helperConfig]) => ({
|
|
||||||
text: helperName,
|
text: helperName,
|
||||||
path: helperName,
|
path: helperName,
|
||||||
example: helperConfig.example,
|
example: helperConfig.example,
|
||||||
|
@ -14,6 +14,7 @@ export function handlebarsCompletions() {
|
||||||
allowsJs:
|
allowsJs:
|
||||||
!helperConfig.requiresBlock &&
|
!helperConfig.requiresBlock &&
|
||||||
!helpersToRemoveForJs.includes(helperName),
|
!helpersToRemoveForJs.includes(helperName),
|
||||||
|
args: helperConfig.args,
|
||||||
}))
|
}))
|
||||||
)
|
)
|
||||||
}
|
}
|
|
@ -2,9 +2,7 @@
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import { Pagination, ProgressCircle } from "@budibase/bbui"
|
import { Pagination, ProgressCircle } from "@budibase/bbui"
|
||||||
import { fetchData, QueryUtils } from "@budibase/frontend-core"
|
import { fetchData, QueryUtils } from "@budibase/frontend-core"
|
||||||
import {
|
import type {
|
||||||
LogicalOperator,
|
|
||||||
EmptyFilterOption,
|
|
||||||
TableSchema,
|
TableSchema,
|
||||||
SortOrder,
|
SortOrder,
|
||||||
SearchFilters,
|
SearchFilters,
|
||||||
|
@ -14,6 +12,7 @@
|
||||||
GroupUserDatasource,
|
GroupUserDatasource,
|
||||||
DataFetchOptions,
|
DataFetchOptions,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
import { LogicalOperator, EmptyFilterOption } from "@budibase/types"
|
||||||
|
|
||||||
type ProviderDatasource = Exclude<
|
type ProviderDatasource = Exclude<
|
||||||
DataFetchDatasource,
|
DataFetchDatasource,
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
import { Utils } from "@budibase/frontend-core"
|
import { Utils } from "@budibase/frontend-core"
|
||||||
import FormBlockWrapper from "./FormBlockWrapper.svelte"
|
import FormBlockWrapper from "./FormBlockWrapper.svelte"
|
||||||
import { get } from "svelte/store"
|
import { get } from "svelte/store"
|
||||||
import { TableSchema, UIDatasource } from "@budibase/types"
|
import type { TableSchema, UIDatasource } from "@budibase/types"
|
||||||
|
|
||||||
type Field = { name: string; active: boolean }
|
type Field = { name: string; active: boolean }
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import { Icon } from "@budibase/bbui"
|
import { Icon } from "@budibase/bbui"
|
||||||
import { UIComponentError } from "@budibase/types"
|
import type { UIComponentError } from "@budibase/types"
|
||||||
import ComponentErrorStateCta from "./ComponentErrorStateCTA.svelte"
|
import ComponentErrorStateCta from "./ComponentErrorStateCTA.svelte"
|
||||||
|
|
||||||
export let componentErrors: UIComponentError[] | undefined
|
export let componentErrors: UIComponentError[] | undefined
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { getContext } from "svelte"
|
import { getContext } from "svelte"
|
||||||
import { UIComponentError } from "@budibase/types"
|
import type { UIComponentError } from "@budibase/types"
|
||||||
|
|
||||||
export let error: UIComponentError | undefined
|
export let error: UIComponentError | undefined
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
import { findComponentById } from "@/utils/components.js"
|
import { findComponentById } from "@/utils/components.js"
|
||||||
import { isGridEvent } from "@/utils/grid"
|
import { isGridEvent } from "@/utils/grid"
|
||||||
import { DNDPlaceholderID } from "@/constants"
|
import { DNDPlaceholderID } from "@/constants"
|
||||||
import { Component } from "@budibase/types"
|
import type { Component } from "@budibase/types"
|
||||||
|
|
||||||
type ChildCoords = {
|
type ChildCoords = {
|
||||||
placeholder: boolean
|
placeholder: boolean
|
||||||
|
|
|
@ -1,7 +1,19 @@
|
||||||
export interface EnrichedBinding {
|
export interface EnrichedBinding {
|
||||||
|
value: string
|
||||||
|
valueHTML: string
|
||||||
runtimeBinding: string
|
runtimeBinding: string
|
||||||
readableBinding: string
|
readableBinding: string
|
||||||
type?: null | string
|
type?: null | string
|
||||||
|
icon?: string
|
||||||
|
category: string
|
||||||
|
display?: { name: string; type: string }
|
||||||
|
fieldSchema?: {
|
||||||
|
name: string
|
||||||
|
tableId: string
|
||||||
|
type: string
|
||||||
|
subtype?: string
|
||||||
|
prefixKeys?: string
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export enum BindingMode {
|
export enum BindingMode {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
export interface Helper {
|
export interface Helper {
|
||||||
|
label: string
|
||||||
|
displayText: string
|
||||||
example: string
|
example: string
|
||||||
description: string
|
description: string
|
||||||
args: any[]
|
args: any[]
|
||||||
requiresBlock?: boolean
|
requiresBlock?: boolean
|
||||||
|
allowsJs: boolean
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue