Merge pull request #10544 from Budibase/grid-id
Grid improvements and fixes
This commit is contained in:
commit
d52983839d
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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}
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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 => {
|
||||||
|
|
Loading…
Reference in New Issue