Update attachment cells to use popovers

This commit is contained in:
Andrew Kingston 2024-04-24 17:35:23 +01:00
parent 443be4cdab
commit 377cd97f4b
9 changed files with 39 additions and 46 deletions

View File

@ -1,6 +1,7 @@
<script> <script>
import { onMount, getContext } from "svelte" import { onMount, getContext } from "svelte"
import { Dropzone } from "@budibase/bbui" import { Dropzone } from "@budibase/bbui"
import GridPopover from "../overlays/GridPopover.svelte"
export let value export let value
export let focused = false export let focused = false
@ -8,14 +9,15 @@
export let readonly = false export let readonly = false
export let api export let api
export let invertX = false export let invertX = false
export let invertY = false
export let schema export let schema
export let maximum export let maximum
export let gridID
const { API, notifications } = getContext("grid") const { API, notifications } = getContext("grid")
const imageExtensions = ["png", "tiff", "gif", "raw", "jpg", "jpeg"] const imageExtensions = ["png", "tiff", "gif", "raw", "jpg", "jpeg"]
let isOpen = false let isOpen = false
let anchor
$: editable = focused && !readonly $: editable = focused && !readonly
$: { $: {
@ -73,7 +75,12 @@
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<!-- svelte-ignore a11y-click-events-have-key-events --> <!-- svelte-ignore a11y-click-events-have-key-events -->
<div class="attachment-cell" class:editable on:click={editable ? open : null}> <div
class="attachment-cell"
class:editable
on:click={editable ? open : null}
bind:this={anchor}
>
{#each value || [] as attachment} {#each value || [] as attachment}
{#if isImage(attachment.extension)} {#if isImage(attachment.extension)}
<img src={attachment.url} alt={attachment.extension} /> <img src={attachment.url} alt={attachment.extension} />
@ -86,16 +93,18 @@
</div> </div>
{#if isOpen} {#if isOpen}
<div class="dropzone" class:invertX class:invertY> <GridPopover open={isOpen} {anchor} {gridID} {invertX} on:close={close}>
<Dropzone <div class="dropzone">
{value} <Dropzone
compact {value}
on:change={e => onChange(e.detail)} compact
maximum={maximum || schema.constraints?.length?.maximum} on:change={e => onChange(e.detail)}
{processFiles} maximum={maximum || schema.constraints?.length?.maximum}
{handleFileTooLarge} {processFiles}
/> {handleFileTooLarge}
</div> />
</div>
</GridPopover>
{/if} {/if}
<style> <style>
@ -129,23 +138,7 @@
user-select: none; user-select: none;
} }
.dropzone { .dropzone {
position: absolute;
top: 100%;
left: 0;
width: 320px; width: 320px;
background: var(--grid-background-alt);
border: var(--cell-border);
padding: var(--cell-padding); padding: var(--cell-padding);
box-shadow: 0 0 20px -4px rgba(0, 0, 0, 0.15);
border-bottom-left-radius: 2px;
border-bottom-right-radius: 2px;
}
.dropzone.invertX {
left: auto;
right: 0;
}
.dropzone.invertY {
transform: translateY(-100%);
top: 0;
} }
</style> </style>

View File

@ -22,7 +22,7 @@
export let invertY = false export let invertY = false
export let contentLines = 1 export let contentLines = 1
export let hidden = false export let hidden = false
export let rand export let gridID
const emptyError = writable(null) const emptyError = writable(null)
@ -97,7 +97,7 @@
{invertY} {invertY}
{invertX} {invertX}
{contentLines} {contentLines}
{rand} {gridID}
/> />
<slot /> <slot />
</GridCell> </GridCell>

View File

@ -11,7 +11,7 @@
export let readonly = false export let readonly = false
export let api export let api
export let invertX = false export let invertX = false
export let rand export let gridID
let isOpen let isOpen
let anchor let anchor
@ -112,7 +112,7 @@
</div> </div>
{#if isOpen} {#if isOpen}
<GridPopover open={isOpen} {anchor} {invertX} {rand} on:close={close}> <GridPopover open={isOpen} {anchor} {invertX} {gridID} on:close={close}>
<CoreDatePickerPopoverContents <CoreDatePickerPopoverContents
value={parsedValue} value={parsedValue}
useKeyboardShortcuts={false} useKeyboardShortcuts={false}

View File

@ -24,7 +24,7 @@
reorder, reorder,
isReordering, isReordering,
isResizing, isResizing,
rand, gridID,
sort, sort,
visibleColumns, visibleColumns,
dispatch, dispatch,
@ -316,7 +316,7 @@
{anchor} {anchor}
align="right" align="right"
offset={0} offset={0}
popoverTarget={document.getElementById(`grid-${rand}`)} popoverTarget={document.getElementById(gridID)}
customZindex={50} customZindex={50}
> >
{#if editIsOpen} {#if editIsOpen}

View File

@ -13,7 +13,7 @@
export let api export let api
export let invertX export let invertX
export let contentLines = 1 export let contentLines = 1
export let rand export let gridID
let isOpen = false let isOpen = false
let focusedOptionIdx = null let focusedOptionIdx = null
@ -121,7 +121,7 @@
</div> </div>
{#if isOpen} {#if isOpen}
<GridPopover open={isOpen} {anchor} {rand} {invertX} on:close={close}> <GridPopover open={isOpen} {anchor} {gridID} {invertX} on:close={close}>
<div class="options" on:wheel={e => e.stopPropagation()}> <div class="options" on:wheel={e => e.stopPropagation()}>
{#each options as option, idx} {#each options as option, idx}
{@const color = optionColors[option] || getOptionColor(option)} {@const color = optionColors[option] || getOptionColor(option)}

View File

@ -52,7 +52,7 @@
export let buttons = null export let buttons = null
// Unique identifier for DOM nodes inside this instance // Unique identifier for DOM nodes inside this instance
const rand = Math.random().toString().slice(2) const gridID = `grid-${Math.random().toString().slice(2)}`
// Store props in a store for reference in other stores // Store props in a store for reference in other stores
const props = writable($$props) const props = writable($$props)
@ -60,7 +60,7 @@
// Build up context // Build up context
let context = { let context = {
API: API || createAPIClient(), API: API || createAPIClient(),
rand, gridID,
props, props,
} }
context = { ...context, ...createEventManagers() } context = { ...context, ...createEventManagers() }
@ -122,7 +122,7 @@
<!-- svelte-ignore a11y-no-static-element-interactions --> <!-- svelte-ignore a11y-no-static-element-interactions -->
<div <div
class="grid" class="grid"
id="grid-{rand}" id={gridID}
class:is-resizing={$isResizing} class:is-resizing={$isResizing}
class:is-reordering={$isReordering} class:is-reordering={$isReordering}
class:stripe={stripeRows} class:stripe={stripeRows}

View File

@ -20,7 +20,7 @@
dispatch, dispatch,
rows, rows,
columnRenderMap, columnRenderMap,
rand, gridID,
} = getContext("grid") } = getContext("grid")
$: rowSelected = !!$selectedRows[row._id] $: rowSelected = !!$selectedRows[row._id]
@ -46,7 +46,7 @@
{row} {row}
{invertY} {invertY}
{rowFocused} {rowFocused}
{rand} {gridID}
invertX={columnIdx >= $columnHorizontalInversionIndex} invertX={columnIdx >= $columnHorizontalInversionIndex}
highlighted={rowHovered || rowFocused || reorderSource === column.name} highlighted={rowHovered || rowFocused || reorderSource === column.name}
selected={rowSelected} selected={rowSelected}

View File

@ -2,10 +2,10 @@
import { Popover, clickOutside } from "@budibase/bbui" import { Popover, clickOutside } from "@budibase/bbui"
import { createEventDispatcher } from "svelte" import { createEventDispatcher } from "svelte"
export let rand
export let invertX
export let open export let open
export let anchor export let anchor
export let invertX
export let gridID
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
</script> </script>
@ -14,7 +14,7 @@
bind:open bind:open
{anchor} {anchor}
align={invertX ? "right" : "left"} align={invertX ? "right" : "left"}
portalTarget="#grid-{rand} .grid-popover-container" portalTarget="#{gridID} .grid-popover-container"
offset={1} offset={1}
> >
<div use:clickOutside={() => dispatch("close")}> <div use:clickOutside={() => dispatch("close")}>

View File

@ -13,13 +13,13 @@ export const createStores = () => {
} }
export const createActions = context => { export const createActions = context => {
const { menu, focusedCellId, rand } = context const { menu, focusedCellId, gridID } = context
const open = (cellId, e) => { const open = (cellId, e) => {
e.preventDefault() e.preventDefault()
// Get DOM node for grid data wrapper to compute relative position to // Get DOM node for grid data wrapper to compute relative position to
const gridNode = document.getElementById(`grid-${rand}`) const gridNode = document.getElementById(gridID)
const dataNode = gridNode?.getElementsByClassName("grid-data-outer")?.[0] const dataNode = gridNode?.getElementsByClassName("grid-data-outer")?.[0]
if (!dataNode) { if (!dataNode) {
return return