Update relationship cells to use popovers
This commit is contained in:
parent
377cd97f4b
commit
23bd635a8b
|
@ -93,7 +93,14 @@
|
|||
</div>
|
||||
|
||||
{#if isOpen}
|
||||
<GridPopover open={isOpen} {anchor} {gridID} {invertX} on:close={close}>
|
||||
<GridPopover
|
||||
open={isOpen}
|
||||
{anchor}
|
||||
{gridID}
|
||||
{invertX}
|
||||
maxHeight={null}
|
||||
on:close={close}
|
||||
>
|
||||
<div class="dropzone">
|
||||
<Dropzone
|
||||
{value}
|
||||
|
|
|
@ -112,7 +112,7 @@
|
|||
</div>
|
||||
|
||||
{#if isOpen}
|
||||
<GridPopover open={isOpen} {anchor} {invertX} {gridID} on:close={close}>
|
||||
<GridPopover {anchor} {invertX} maxHeight={null} on:close={close}>
|
||||
<CoreDatePickerPopoverContents
|
||||
value={parsedValue}
|
||||
useKeyboardShortcuts={false}
|
||||
|
|
|
@ -121,8 +121,8 @@
|
|||
</div>
|
||||
|
||||
{#if isOpen}
|
||||
<GridPopover open={isOpen} {anchor} {gridID} {invertX} on:close={close}>
|
||||
<div class="options" on:wheel={e => e.stopPropagation()}>
|
||||
<GridPopover {anchor} {invertX} on:close={close}>
|
||||
<div class="options">
|
||||
{#each options as option, idx}
|
||||
{@const color = optionColors[option] || getOptionColor(option)}
|
||||
<!-- svelte-ignore a11y-no-static-element-interactions -->
|
||||
|
@ -219,10 +219,6 @@
|
|||
flex-direction: column;
|
||||
justify-content: flex-start;
|
||||
align-items: stretch;
|
||||
max-height: var(--max-cell-render-overflow);
|
||||
overflow-y: auto;
|
||||
min-width: 200px;
|
||||
max-width: 400px;
|
||||
}
|
||||
.option {
|
||||
flex: 0 0 var(--default-row-height);
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
<script>
|
||||
import { getColor } from "../lib/utils"
|
||||
import { onMount, getContext } from "svelte"
|
||||
import { Icon, Input, ProgressCircle, clickOutside } from "@budibase/bbui"
|
||||
import { Icon, Input, ProgressCircle } from "@budibase/bbui"
|
||||
import { debounce } from "../../../utils/utils"
|
||||
import GridPopover from "../overlays/GridPopover.svelte"
|
||||
|
||||
const { API, dispatch, cache } = getContext("grid")
|
||||
|
||||
|
@ -17,6 +18,7 @@
|
|||
export let contentLines = 1
|
||||
export let searchFunction = API.searchTable
|
||||
export let primaryDisplay
|
||||
export let gridID
|
||||
|
||||
const color = getColor(0)
|
||||
|
||||
|
@ -27,8 +29,8 @@
|
|||
let candidateIndex
|
||||
let lastSearchId
|
||||
let searching = false
|
||||
let valuesHeight = 0
|
||||
let container
|
||||
let anchor
|
||||
|
||||
$: oneRowOnly = schema?.relationshipType === "one-to-many"
|
||||
$: editable = focused && !readonly
|
||||
|
@ -125,7 +127,6 @@
|
|||
|
||||
const open = async () => {
|
||||
isOpen = true
|
||||
valuesHeight = container.getBoundingClientRect().height
|
||||
|
||||
// Find the primary display for the related table
|
||||
if (!primaryDisplay) {
|
||||
|
@ -240,6 +241,7 @@
|
|||
class:focused
|
||||
class:invertY
|
||||
style="--color:{color};"
|
||||
bind:this={anchor}
|
||||
>
|
||||
<div class="container" bind:this={container}>
|
||||
<div
|
||||
|
@ -250,11 +252,7 @@
|
|||
{#each value || [] as relationship}
|
||||
{#if relationship[primaryDisplay] || relationship.primaryDisplay}
|
||||
<div class="badge">
|
||||
<span
|
||||
on:click={editable
|
||||
? () => showRelationship(relationship._id)
|
||||
: null}
|
||||
>
|
||||
<span>
|
||||
{readable(
|
||||
relationship[primaryDisplay] || relationship.primaryDisplay
|
||||
)}
|
||||
|
@ -282,16 +280,11 @@
|
|||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{#if isOpen}
|
||||
<div
|
||||
class="dropdown"
|
||||
class:invertX
|
||||
class:invertY
|
||||
on:wheel|stopPropagation
|
||||
use:clickOutside={close}
|
||||
style="--values-height:{valuesHeight}px;"
|
||||
>
|
||||
{#if isOpen}
|
||||
<GridPopover open={isOpen} {anchor} {gridID} {invertX} on:close={close}>
|
||||
<div class="dropdown" on:wheel|stopPropagation>
|
||||
<div class="search">
|
||||
<Input
|
||||
autofocus
|
||||
|
@ -327,8 +320,8 @@
|
|||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
</GridPopover>
|
||||
{/if}
|
||||
|
||||
<style>
|
||||
.wrapper {
|
||||
|
@ -426,10 +419,6 @@
|
|||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
.editable .values .badge span:hover {
|
||||
cursor: pointer;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.add {
|
||||
background: var(--spectrum-global-color-gray-200);
|
||||
|
@ -446,30 +435,9 @@
|
|||
}
|
||||
|
||||
.dropdown {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
max-height: calc(
|
||||
var(--max-cell-render-overflow) + var(--row-height) - var(--values-height)
|
||||
);
|
||||
background: var(--grid-background-alt);
|
||||
border: var(--cell-border);
|
||||
box-shadow: 0 0 20px -4px rgba(0, 0, 0, 0.15);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
padding: 0 0 8px 0;
|
||||
border-bottom-left-radius: 2px;
|
||||
border-bottom-right-radius: 2px;
|
||||
}
|
||||
.dropdown.invertY {
|
||||
transform: translateY(-100%);
|
||||
top: -1px;
|
||||
}
|
||||
.dropdown.invertX {
|
||||
left: auto;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.searching {
|
||||
|
@ -497,7 +465,8 @@
|
|||
cursor: pointer;
|
||||
}
|
||||
.result .badge {
|
||||
max-width: calc(100% - 30px);
|
||||
flex: 1 1 auto;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.search {
|
||||
|
@ -505,7 +474,6 @@
|
|||
display: flex;
|
||||
align-items: center;
|
||||
margin: 4px var(--cell-padding);
|
||||
width: calc(100% - 2 * var(--cell-padding));
|
||||
}
|
||||
.search :global(.spectrum-Textfield) {
|
||||
min-width: 0;
|
||||
|
|
|
@ -11,4 +11,9 @@ export const NewRowID = "new"
|
|||
export const BlankRowID = "blank"
|
||||
export const RowPageSize = 100
|
||||
export const FocusedCellMinOffset = 48
|
||||
|
||||
// Popovers
|
||||
export const PopoverMinWidth = 200
|
||||
export const PopoverMaxWidth = 400
|
||||
export const PopoverMaxHeight = 236
|
||||
export const MaxCellRenderOverflow = 222
|
||||
|
|
|
@ -1,23 +1,51 @@
|
|||
<script>
|
||||
import { Popover, clickOutside } from "@budibase/bbui"
|
||||
import { createEventDispatcher } from "svelte"
|
||||
import { createEventDispatcher, getContext } from "svelte"
|
||||
import {
|
||||
PopoverMinWidth,
|
||||
PopoverMaxWidth,
|
||||
PopoverMaxHeight,
|
||||
} from "../lib/constants"
|
||||
|
||||
export let open
|
||||
export let anchor
|
||||
export let invertX
|
||||
export let gridID
|
||||
export let minWidth = PopoverMinWidth
|
||||
export let maxWidth = PopoverMaxWidth
|
||||
export let maxHeight = PopoverMaxHeight
|
||||
|
||||
const { gridID } = getContext("grid")
|
||||
const dispatch = createEventDispatcher()
|
||||
|
||||
$: style = buildStyles(minWidth, maxWidth, maxHeight)
|
||||
|
||||
const buildStyles = (minWidth, maxWidth, maxHeight) => {
|
||||
let style = ""
|
||||
if (minWidth != null) {
|
||||
style += `min-width: ${minWidth}px;`
|
||||
}
|
||||
if (maxWidth != null) {
|
||||
style += `max-width: ${maxWidth}px;`
|
||||
}
|
||||
if (maxHeight != null) {
|
||||
style += `max-height: ${maxHeight}px;`
|
||||
}
|
||||
return style
|
||||
}
|
||||
</script>
|
||||
|
||||
<Popover
|
||||
bind:open
|
||||
open
|
||||
{anchor}
|
||||
align={invertX ? "right" : "left"}
|
||||
portalTarget="#{gridID} .grid-popover-container"
|
||||
offset={1}
|
||||
>
|
||||
<div use:clickOutside={() => dispatch("close")}>
|
||||
<div
|
||||
class="grid-popover-contents"
|
||||
{style}
|
||||
use:clickOutside={() => dispatch("close")}
|
||||
on:wheel={e => e.stopPropagation()}
|
||||
>
|
||||
<slot />
|
||||
</div>
|
||||
</Popover>
|
||||
|
@ -26,5 +54,12 @@
|
|||
:global(.grid-popover-container .spectrum-Popover) {
|
||||
background: var(--grid-background-alt);
|
||||
border: var(--cell-border);
|
||||
min-width: none;
|
||||
max-width: none;
|
||||
overflow: hidden;
|
||||
}
|
||||
.grid-popover-contents {
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue