Merge pull request #10544 from Budibase/grid-id

Grid improvements and fixes
This commit is contained in:
Andrew Kingston 2023-05-11 17:23:35 +01:00 committed by GitHub
commit d52983839d
5 changed files with 79 additions and 13 deletions

View File

@ -18,10 +18,14 @@
export let ignoreTimezones = false export let ignoreTimezones = false
export let time24hr = false export let time24hr = false
export let range = false export let range = false
export let flatpickr
export let useKeyboardShortcuts = true
const dispatch = createEventDispatcher() const dispatch = createEventDispatcher()
const flatpickrId = `${uuid()}-wrapper` const flatpickrId = `${uuid()}-wrapper`
let open = false let open = false
let flatpickr, flatpickrOptions let flatpickrOptions
// Another classic flatpickr issue. Errors were randomly being thrown due to // Another classic flatpickr issue. Errors were randomly being thrown due to
// flatpickr internal code. Making sure that "destroy" is a valid function // flatpickr internal code. Making sure that "destroy" is a valid function
@ -59,6 +63,8 @@
dispatch("change", timestamp.toISOString()) dispatch("change", timestamp.toISOString())
} }
}, },
onOpen: () => dispatch("open"),
onClose: () => dispatch("close"),
} }
$: redrawOptions = { $: redrawOptions = {
@ -113,12 +119,16 @@
const onOpen = () => { const onOpen = () => {
open = true open = true
document.addEventListener("keyup", clearDateOnBackspace) if (useKeyboardShortcuts) {
document.addEventListener("keyup", clearDateOnBackspace)
}
} }
const onClose = () => { const onClose = () => {
open = false open = false
document.removeEventListener("keyup", clearDateOnBackspace) if (useKeyboardShortcuts) {
document.removeEventListener("keyup", clearDateOnBackspace)
}
// Manually blur all input fields since flatpickr creates a second // Manually blur all input fields since flatpickr creates a second
// duplicate input field. // duplicate input field.

View File

@ -32,6 +32,7 @@
$: readonly = $: readonly =
column.schema.autocolumn || column.schema.autocolumn ||
column.schema.disabled || column.schema.disabled ||
column.schema.type === "formula" ||
(!$config.allowEditRows && row._id) (!$config.allowEditRows && row._id)
// Register this cell API if the row is focused // Register this cell API if the row is focused

View File

@ -1,12 +1,17 @@
<script> <script>
import dayjs from "dayjs" import dayjs from "dayjs"
import { CoreDatePicker, Icon } from "@budibase/bbui" import { CoreDatePicker, Icon } from "@budibase/bbui"
import { onMount } from "svelte"
export let value export let value
export let schema export let schema
export let onChange export let onChange
export let focused = false export let focused = false
export let readonly = false export let readonly = false
export let api
let flatpickr
let isOpen
// adding the 0- will turn a string like 00:00:00 into a valid ISO // adding the 0- will turn a string like 00:00:00 into a valid ISO
// date, but will make actual ISO dates invalid // date, but will make actual ISO dates invalid
@ -19,6 +24,26 @@
? "MMM D YYYY" ? "MMM D YYYY"
: "MMM D YYYY, HH:mm" : "MMM D YYYY, HH:mm"
$: editable = focused && !readonly $: editable = focused && !readonly
// Ensure we close flatpickr when unselected
$: {
if (!focused) {
flatpickr?.close()
}
}
const onKeyDown = () => {
return isOpen
}
onMount(() => {
api = {
onKeyDown,
focus: () => flatpickr?.open(),
blur: () => flatpickr?.close(),
isActive: () => isOpen,
}
})
</script> </script>
<div class="container"> <div class="container">
@ -42,6 +67,10 @@
{timeOnly} {timeOnly}
time24hr time24hr
ignoreTimezones={schema.ignoreTimezones} ignoreTimezones={schema.ignoreTimezones}
bind:flatpickr
on:open={() => (isOpen = true)}
on:close={() => (isOpen = false)}
useKeyboardShortcuts={false}
/> />
</div> </div>
{/if} {/if}

View File

@ -1,6 +1,13 @@
<script> <script>
import { clickOutside, Menu, MenuItem, notifications } from "@budibase/bbui" import {
clickOutside,
Menu,
MenuItem,
Helpers,
notifications,
} from "@budibase/bbui"
import { getContext } from "svelte" import { getContext } from "svelte"
import { NewRowID } from "../lib/constants"
const { const {
focusedRow, focusedRow,
@ -14,9 +21,11 @@
clipboard, clipboard,
dispatch, dispatch,
focusedCellAPI, focusedCellAPI,
focusedRowId,
} = getContext("grid") } = getContext("grid")
$: style = makeStyle($menu) $: style = makeStyle($menu)
$: isNewRow = $focusedRowId === NewRowID
const makeStyle = menu => { const makeStyle = menu => {
return `left:${menu.left}px; top:${menu.top}px;` return `left:${menu.left}px; top:${menu.top}px;`
@ -36,6 +45,11 @@
$focusedCellId = `${newRow._id}-${column}` $focusedCellId = `${newRow._id}-${column}`
} }
} }
const copyToClipboard = async value => {
await Helpers.copyToClipboard(value)
notifications.success("Copied to clipboard")
}
</script> </script>
{#if $menu.visible} {#if $menu.visible}
@ -58,22 +72,38 @@
</MenuItem> </MenuItem>
<MenuItem <MenuItem
icon="Maximize" icon="Maximize"
disabled={!$config.allowEditRows} disabled={isNewRow || !$config.allowEditRows}
on:click={() => dispatch("edit-row", $focusedRow)} on:click={() => dispatch("edit-row", $focusedRow)}
on:click={menu.actions.close} on:click={menu.actions.close}
> >
Edit row in modal Edit row in modal
</MenuItem> </MenuItem>
<MenuItem
icon="Copy"
disabled={isNewRow || !$focusedRow?._id}
on:click={() => copyToClipboard($focusedRow?._id)}
on:click={menu.actions.close}
>
Copy row _id
</MenuItem>
<MenuItem
icon="Copy"
disabled={isNewRow || !$focusedRow?._rev}
on:click={() => copyToClipboard($focusedRow?._rev)}
on:click={menu.actions.close}
>
Copy row _rev
</MenuItem>
<MenuItem <MenuItem
icon="Duplicate" icon="Duplicate"
disabled={!$config.allowAddRows} disabled={isNewRow || !$config.allowAddRows}
on:click={duplicate} on:click={duplicate}
> >
Duplicate row Duplicate row
</MenuItem> </MenuItem>
<MenuItem <MenuItem
icon="Delete" icon="Delete"
disabled={!$config.allowDeleteRows} disabled={isNewRow || !$config.allowDeleteRows}
on:click={deleteRow} on:click={deleteRow}
> >
Delete row Delete row

View File

@ -338,15 +338,11 @@ export const deriveStores = context => {
...state, ...state,
[rowId]: true, [rowId]: true,
})) }))
const newRow = { ...row, ...get(rowChangeCache)[rowId] } const saved = await API.saveRow({ ...row, ...get(rowChangeCache)[rowId] })
const saved = await API.saveRow(newRow)
// Update state after a successful change // Update state after a successful change
rows.update(state => { rows.update(state => {
state[index] = { state[index] = saved
...newRow,
_rev: saved._rev,
}
return state.slice() return state.slice()
}) })
rowChangeCache.update(state => { rowChangeCache.update(state => {