Update new row component to render inline where possible
This commit is contained in:
parent
98430138fe
commit
5cbaf2f58a
|
@ -27,12 +27,6 @@
|
|||
// Get the error for this cell if the row is focused
|
||||
$: error = getErrorStore(rowFocused, cellId)
|
||||
|
||||
$: {
|
||||
if ($error) {
|
||||
console.log(cellId, $error)
|
||||
}
|
||||
}
|
||||
|
||||
// Determine if the cell is editable
|
||||
$: readonly =
|
||||
column.schema.autocolumn ||
|
||||
|
|
|
@ -45,7 +45,7 @@
|
|||
style="width:{renderColumnsWidth}px"
|
||||
on:mouseenter={() => ($hoveredRowId = BlankRowID)}
|
||||
on:mouseleave={() => ($hoveredRowId = null)}
|
||||
on:click={() => dispatch("add-row-inline", true)}
|
||||
on:click={() => dispatch("add-row-inline")}
|
||||
/>
|
||||
{/if}
|
||||
</GridScrollWrapper>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
<script>
|
||||
import GridCell from "../cells/GridCell.svelte"
|
||||
import { getContext, onDestroy, onMount, tick } from "svelte"
|
||||
import { Icon, Button } from "@budibase/bbui"
|
||||
import GridScrollWrapper from "./GridScrollWrapper.svelte"
|
||||
|
@ -14,18 +13,23 @@
|
|||
focusedCellId,
|
||||
stickyColumn,
|
||||
scroll,
|
||||
config,
|
||||
dispatch,
|
||||
rows,
|
||||
focusedCellAPI,
|
||||
tableId,
|
||||
subscribe,
|
||||
renderedRows,
|
||||
renderedColumns,
|
||||
rowHeight,
|
||||
hasNextPage,
|
||||
maxScrollTop,
|
||||
} = getContext("grid")
|
||||
|
||||
let isAdding = false
|
||||
let newRow = {}
|
||||
let offset = 0
|
||||
|
||||
$: minimumDesiredRenderHeight = $rowHeight + 96
|
||||
$: firstColumn = $stickyColumn || $renderedColumns[0]
|
||||
$: width = GutterWidth + ($stickyColumn?.width || 0)
|
||||
$: $tableId, (isAdding = false)
|
||||
|
@ -36,13 +40,10 @@
|
|||
await tick()
|
||||
|
||||
// Create row
|
||||
const savedRow = await rows.actions.addRow(newRow, 0)
|
||||
const newRowIndex = offset ? undefined : 0
|
||||
const savedRow = await rows.actions.addRow(newRow, newRowIndex)
|
||||
if (savedRow) {
|
||||
// Reset state
|
||||
scroll.update(state => ({
|
||||
...state,
|
||||
top: 0,
|
||||
}))
|
||||
clear()
|
||||
|
||||
// Select the first cell if possible
|
||||
|
@ -63,6 +64,24 @@
|
|||
if (isAdding) {
|
||||
return
|
||||
}
|
||||
|
||||
// If we have a next page of data then we aren't truly at the bottom, so we
|
||||
// render the add row component at the top
|
||||
if ($hasNextPage) {
|
||||
offset = 0
|
||||
}
|
||||
|
||||
// If we don't have a next page then we're at the bottom and can scroll to
|
||||
// the max available offset
|
||||
else {
|
||||
scroll.update(state => ({
|
||||
...state,
|
||||
top: $maxScrollTop,
|
||||
}))
|
||||
offset =
|
||||
$renderedRows.length * $rowHeight - ($maxScrollTop % $rowHeight) - 1
|
||||
}
|
||||
|
||||
document.addEventListener("keydown", handleKeyPress)
|
||||
newRow = {}
|
||||
isAdding = true
|
||||
|
@ -105,7 +124,11 @@
|
|||
|
||||
<!-- Only show new row functionality if we have any columns -->
|
||||
{#if isAdding}
|
||||
<div class="container">
|
||||
<div
|
||||
class="container"
|
||||
class:floating={offset > 0}
|
||||
style="--offset:{offset}px"
|
||||
>
|
||||
<div
|
||||
class="underlay sticky"
|
||||
style="width:{width}px;"
|
||||
|
@ -134,25 +157,27 @@
|
|||
/>
|
||||
{/if}
|
||||
</div>
|
||||
<GridScrollWrapper scrollHorizontally wheelInteractive>
|
||||
<div class="row" transition:fade={{ duration: 130 }}>
|
||||
{#each $renderedColumns as column}
|
||||
{@const cellId = `new-${column.name}`}
|
||||
{#key cellId}
|
||||
<DataCell
|
||||
{cellId}
|
||||
{column}
|
||||
{updateValue}
|
||||
rowFocused
|
||||
row={newRow}
|
||||
focused={$focusedCellId === cellId}
|
||||
width={column.width}
|
||||
rowIdx={0}
|
||||
/>
|
||||
{/key}
|
||||
{/each}
|
||||
</div>
|
||||
</GridScrollWrapper>
|
||||
<div class="normal-columns">
|
||||
<GridScrollWrapper scrollHorizontally wheelInteractive>
|
||||
<div class="row" transition:fade={{ duration: 130 }}>
|
||||
{#each $renderedColumns as column}
|
||||
{@const cellId = `new-${column.name}`}
|
||||
{#key cellId}
|
||||
<DataCell
|
||||
{cellId}
|
||||
{column}
|
||||
{updateValue}
|
||||
rowFocused
|
||||
row={newRow}
|
||||
focused={$focusedCellId === cellId}
|
||||
width={column.width}
|
||||
rowIdx={0}
|
||||
/>
|
||||
{/key}
|
||||
{/each}
|
||||
</div>
|
||||
</GridScrollWrapper>
|
||||
</div>
|
||||
<div class="buttons" transition:fade={{ duration: 130 }}>
|
||||
<Button size="M" cta on:click={addRow}>Save</Button>
|
||||
<Button size="M" secondary newStyles on:click={clear}>Cancel</Button>
|
||||
|
@ -174,13 +199,17 @@
|
|||
.container :global(.cell) {
|
||||
--cell-background: var(--spectrum-global-color-gray-75) !important;
|
||||
}
|
||||
.container.floating :global(.cell) {
|
||||
height: calc(var(--row-height) + 1px);
|
||||
border-top: var(--cell-border);
|
||||
}
|
||||
|
||||
/* Underlay sits behind everything */
|
||||
.underlay {
|
||||
position: absolute;
|
||||
content: "";
|
||||
left: 0;
|
||||
top: var(--row-height);
|
||||
top: 0;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
background: var(--cell-background);
|
||||
|
@ -198,8 +227,8 @@
|
|||
pointer-events: all;
|
||||
z-index: 3;
|
||||
position: absolute;
|
||||
top: calc(var(--row-height) + 24px);
|
||||
left: 32px;
|
||||
top: calc(var(--row-height) + var(--offset) + 24px);
|
||||
left: var(--gutter-width);
|
||||
}
|
||||
|
||||
/* Sticky column styles */
|
||||
|
@ -212,20 +241,9 @@
|
|||
.sticky-column :global(.cell:not(:last-child)) {
|
||||
border-right: none;
|
||||
}
|
||||
.gutter {
|
||||
flex: 1 1 auto;
|
||||
display: grid;
|
||||
align-items: center;
|
||||
padding: var(--cell-padding);
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: var(--cell-spacing);
|
||||
}
|
||||
.number {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: var(--spectrum-global-color-gray-500);
|
||||
.sticky-column,
|
||||
.normal-columns {
|
||||
margin-top: var(--offset);
|
||||
}
|
||||
|
||||
/* Normal column styles */
|
||||
|
|
|
@ -91,7 +91,7 @@
|
|||
class="row new"
|
||||
on:mouseenter={() => ($hoveredRowId = BlankRowID)}
|
||||
on:mouseleave={() => ($hoveredRowId = null)}
|
||||
on:click={() => dispatch("add-row-inline", true)}
|
||||
on:click={() => dispatch("add-row-inline")}
|
||||
>
|
||||
<GutterCell disableExpand rowHovered={$hoveredRowId === BlankRowID}>
|
||||
<Icon name="Add" />
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export const Padding = 276
|
||||
export const Padding = 128
|
||||
export const MaxCellRenderHeight = 252
|
||||
export const MaxCellRenderWidthOverflow = 200
|
||||
export const ScrollBarSize = 8
|
||||
|
@ -11,3 +11,4 @@ export const LargeRowHeight = 92
|
|||
export const DefaultRowHeight = SmallRowHeight
|
||||
export const NewRowID = "new"
|
||||
export const BlankRowID = "blank"
|
||||
export const RowPageSize = 100
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
import { writable, derived, get } from "svelte/store"
|
||||
import { fetchData } from "../../../fetch/fetchData"
|
||||
import { notifications } from "@budibase/bbui"
|
||||
import { NewRowID } from "../lib/constants"
|
||||
import { NewRowID, RowPageSize } from "../lib/constants"
|
||||
|
||||
const initialSortState = {
|
||||
column: null,
|
||||
|
@ -17,6 +17,7 @@ export const createStores = () => {
|
|||
const sort = writable(initialSortState)
|
||||
const rowChangeCache = writable({})
|
||||
const inProgressChanges = writable({})
|
||||
const hasNextPage = writable(false)
|
||||
|
||||
// Generate a lookup map to quick find a row by ID
|
||||
const rowLookupMap = derived(
|
||||
|
@ -51,6 +52,7 @@ export const createStores = () => {
|
|||
sort,
|
||||
rowChangeCache,
|
||||
inProgressChanges,
|
||||
hasNextPage,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,6 +73,7 @@ export const deriveStores = context => {
|
|||
rowChangeCache,
|
||||
inProgressChanges,
|
||||
previousFocusedRowId,
|
||||
hasNextPage,
|
||||
} = context
|
||||
const instanceLoaded = writable(false)
|
||||
const fetch = writable(null)
|
||||
|
@ -115,7 +118,7 @@ export const deriveStores = context => {
|
|||
filter: [],
|
||||
sortColumn: initialSortState.column,
|
||||
sortOrder: initialSortState.order,
|
||||
limit: 100,
|
||||
limit: RowPageSize,
|
||||
paginate: true,
|
||||
},
|
||||
})
|
||||
|
@ -123,6 +126,7 @@ export const deriveStores = context => {
|
|||
// Subscribe to changes of this fetch model
|
||||
unsubscribe = newFetch.subscribe($fetch => {
|
||||
if ($fetch.loaded && !$fetch.loading) {
|
||||
hasNextPage.set($fetch.hasNextPage)
|
||||
const $instanceLoaded = get(instanceLoaded)
|
||||
const resetRows = $fetch.resetKey !== lastResetKey
|
||||
lastResetKey = $fetch.resetKey
|
||||
|
|
|
@ -29,7 +29,7 @@ export const deriveStores = context => {
|
|||
// Derive vertical limits
|
||||
const contentHeight = derived(
|
||||
[rows, rowHeight],
|
||||
([$rows, $rowHeight]) => $rows.length * $rowHeight + Padding,
|
||||
([$rows, $rowHeight]) => ($rows.length + 1) * $rowHeight + Padding,
|
||||
0
|
||||
)
|
||||
const maxScrollTop = derived(
|
||||
|
@ -138,7 +138,7 @@ export const initialise = context => {
|
|||
const $scroll = get(scroll)
|
||||
const $bounds = get(bounds)
|
||||
const $rowHeight = get(rowHeight)
|
||||
const verticalOffset = DefaultRowHeight * 1.5
|
||||
const verticalOffset = 60
|
||||
|
||||
// Ensure vertical position is viewable
|
||||
if ($focusedRow) {
|
||||
|
|
Loading…
Reference in New Issue