More fixes (#9387)
* Mark filters as nested settings to support persisting bindings post block ejection * Add support for searching on linked fields in blocks * Fix multi-select pickers closing on every click * Target spectrum root element by default when rendering popovers, and allow customisation via context for client library * Don't send up invalid HBS expressions when filtering on dates in blocks with empty date value * Move profile above theme in user dropdown
This commit is contained in:
parent
d5aebb3db4
commit
2a2466fbda
|
@ -45,7 +45,9 @@
|
|||
getOptionLabel
|
||||
)
|
||||
|
||||
const onClick = () => {
|
||||
const onClick = e => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
dispatch("click")
|
||||
if (readonly) {
|
||||
return
|
||||
|
@ -88,7 +90,6 @@
|
|||
class:is-open={open}
|
||||
aria-haspopup="listbox"
|
||||
on:click={onClick}
|
||||
use:clickOutside={() => (open = false)}
|
||||
bind:this={button}
|
||||
>
|
||||
{#if fieldIcon}
|
||||
|
@ -130,14 +131,17 @@
|
|||
<Popover
|
||||
anchor={button}
|
||||
align="left"
|
||||
portalTarget={document.documentElement}
|
||||
bind:this={popover}
|
||||
{open}
|
||||
on:close={() => (open = false)}
|
||||
useAnchorWidth={!autoWidth}
|
||||
maxWidth={autoWidth ? 400 : null}
|
||||
>
|
||||
<div class="popover-content" class:auto-width={autoWidth}>
|
||||
<div
|
||||
class="popover-content"
|
||||
class:auto-width={autoWidth}
|
||||
use:clickOutside={() => (open = false)}
|
||||
>
|
||||
{#if autocomplete}
|
||||
<Search
|
||||
value={searchTerm}
|
||||
|
|
|
@ -5,6 +5,8 @@
|
|||
import positionDropdown from "../Actions/position_dropdown"
|
||||
import clickOutside from "../Actions/click_outside"
|
||||
import { fly } from "svelte/transition"
|
||||
import { getContext } from "svelte"
|
||||
import Context from "../context"
|
||||
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
|
@ -24,6 +26,7 @@
|
|||
$: tooltipClasses = showTip
|
||||
? `spectrum-Popover--withTip spectrum-Popover--${direction}`
|
||||
: ""
|
||||
$: target = portalTarget || getContext(Context.PopoverRoot) || ".spectrum"
|
||||
|
||||
export const show = () => {
|
||||
dispatch("open")
|
||||
|
@ -61,7 +64,7 @@
|
|||
</script>
|
||||
|
||||
{#if open}
|
||||
<Portal target={portalTarget}>
|
||||
<Portal {target}>
|
||||
<div
|
||||
tabindex="0"
|
||||
use:positionDropdown={{ anchor, align, maxWidth, useAnchorWidth }}
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
export default {
|
||||
Modal: "bbui-modal",
|
||||
PopoverRoot: "bbui-popover-root",
|
||||
}
|
||||
|
|
|
@ -26,9 +26,6 @@
|
|||
<Avatar size="M" initials={$auth.initials} url={$auth.user.pictureUrl} />
|
||||
<Icon size="XL" name="ChevronDown" />
|
||||
</div>
|
||||
<MenuItem icon="Moon" on:click={() => themeModal.show()} dataCy="theme">
|
||||
Theme
|
||||
</MenuItem>
|
||||
<MenuItem
|
||||
icon="UserEdit"
|
||||
on:click={() => profileModal.show()}
|
||||
|
@ -36,6 +33,9 @@
|
|||
>
|
||||
My profile
|
||||
</MenuItem>
|
||||
<MenuItem icon="Moon" on:click={() => themeModal.show()} dataCy="theme">
|
||||
Theme
|
||||
</MenuItem>
|
||||
<MenuItem icon="LockClosed" on:click={() => updatePasswordModal.show()}>
|
||||
Update password
|
||||
</MenuItem>
|
||||
|
|
|
@ -4019,7 +4019,8 @@
|
|||
{
|
||||
"type": "filter",
|
||||
"label": "Filtering",
|
||||
"key": "filter"
|
||||
"key": "filter",
|
||||
"nested": true
|
||||
},
|
||||
{
|
||||
"type": "field",
|
||||
|
@ -4535,7 +4536,8 @@
|
|||
{
|
||||
"type": "filter",
|
||||
"label": "Filtering",
|
||||
"key": "filter"
|
||||
"key": "filter",
|
||||
"nested": true
|
||||
},
|
||||
{
|
||||
"type": "searchfield",
|
||||
|
@ -4665,7 +4667,8 @@
|
|||
{
|
||||
"type": "filter",
|
||||
"label": "Filtering",
|
||||
"key": "filter"
|
||||
"key": "filter",
|
||||
"nested": true
|
||||
},
|
||||
{
|
||||
"type": "field/sortable",
|
||||
|
@ -4831,7 +4834,8 @@
|
|||
{
|
||||
"type": "filter",
|
||||
"label": "Filtering",
|
||||
"key": "filter"
|
||||
"key": "filter",
|
||||
"nested": true
|
||||
},
|
||||
{
|
||||
"type": "field/sortable",
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
<script>
|
||||
import { themeStore } from "stores"
|
||||
import { setContext } from "svelte"
|
||||
import { Context } from "@budibase/bbui"
|
||||
|
||||
setContext(Context.PopoverRoot, "#theme-root")
|
||||
</script>
|
||||
|
||||
<div style={$themeStore.customThemeCss} id="theme-root">
|
||||
|
|
|
@ -36,9 +36,12 @@
|
|||
let dataProviderId
|
||||
let repeaterId
|
||||
let schema
|
||||
let enrichedSearchColumns
|
||||
|
||||
$: fetchSchema(dataSource)
|
||||
$: enrichedSearchColumns = enrichSearchColumns(searchColumns, schema)
|
||||
$: enrichSearchColumns(searchColumns, schema).then(
|
||||
val => (enrichedSearchColumns = val)
|
||||
)
|
||||
$: enrichedFilter = enrichFilter(filter, enrichedSearchColumns, formId)
|
||||
$: cardWidth = cardHorizontal ? 420 : 300
|
||||
$: fullCardURL = buildFullCardUrl(
|
||||
|
|
|
@ -36,9 +36,12 @@
|
|||
let newRowSidePanelId
|
||||
let schema
|
||||
let primaryDisplay
|
||||
let enrichedSearchColumns
|
||||
|
||||
$: fetchSchema(dataSource)
|
||||
$: enrichedSearchColumns = enrichSearchColumns(searchColumns, schema)
|
||||
$: enrichSearchColumns(searchColumns, schema).then(
|
||||
val => (enrichedSearchColumns = val)
|
||||
)
|
||||
$: enrichedFilter = enrichFilter(filter, enrichedSearchColumns, formId)
|
||||
$: editTitle = getEditTitle(detailsFormBlockId, primaryDisplay)
|
||||
$: normalFields = getNormalFields(schema)
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
import { makePropSafe as safe } from "@budibase/string-templates"
|
||||
import { API } from "../api/index.js"
|
||||
|
||||
// Map of data types to component types for search fields inside blocks
|
||||
const schemaComponentMap = {
|
||||
|
@ -15,10 +16,28 @@ const schemaComponentMap = {
|
|||
* @param searchColumns the search columns to use
|
||||
* @param schema the datasource schema
|
||||
*/
|
||||
export const enrichSearchColumns = (searchColumns, schema) => {
|
||||
export const enrichSearchColumns = async (searchColumns, schema) => {
|
||||
if (!searchColumns?.length || !schema) {
|
||||
return []
|
||||
}
|
||||
let enrichedColumns = []
|
||||
searchColumns?.forEach(column => {
|
||||
const schemaType = schema?.[column]?.type
|
||||
for (let column of searchColumns) {
|
||||
let schemaType = schema[column]?.type
|
||||
|
||||
// Check if this is a field in another related table. The only way we can
|
||||
// check this is checking for a "." inside the column, then checking if we
|
||||
// have a link field named the same as that field prefix.
|
||||
if (column.includes(".")) {
|
||||
const split = column.split(".")
|
||||
const sourceField = split[0]
|
||||
const linkField = split.slice(1).join(".")
|
||||
const linkSchema = schema[sourceField]
|
||||
if (linkSchema?.type === "link") {
|
||||
const linkedDef = await API.fetchTableDefinition(linkSchema.tableId)
|
||||
schemaType = linkedDef?.schema?.[linkField]?.type
|
||||
}
|
||||
}
|
||||
|
||||
const componentType = schemaComponentMap[schemaType]
|
||||
if (componentType) {
|
||||
enrichedColumns.push({
|
||||
|
@ -27,7 +46,7 @@ export const enrichSearchColumns = (searchColumns, schema) => {
|
|||
type: schemaType,
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
return enrichedColumns.slice(0, 5)
|
||||
}
|
||||
|
||||
|
@ -57,12 +76,14 @@ export const enrichFilter = (filter, columns, formId) => {
|
|||
value: `{{ ${binding} }}`,
|
||||
})
|
||||
const format = "YYYY-MM-DDTHH:mm:ss.SSSZ"
|
||||
let hbs = `{{ date (add (date ${binding} "x") 86399999) "${format}" }}`
|
||||
hbs = `{{#if ${binding} }}${hbs}{{/if}}`
|
||||
enrichedFilter.push({
|
||||
field: column.name,
|
||||
type: column.type,
|
||||
operator: "rangeHigh",
|
||||
valueType: "Binding",
|
||||
value: `{{ date (add (date ${binding} "x") 86399999) "${format}" }}`,
|
||||
value: hbs,
|
||||
})
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue