Merge pull request #12094 from Budibase/refactor-grid-columns

Refactor grid column handling
This commit is contained in:
Andrew Kingston 2023-10-26 09:41:06 +01:00 committed by GitHub
commit dcc16cd4a2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 81 additions and 85 deletions

View File

@ -777,7 +777,8 @@
disabled={deleteColName !== originalName}
>
<p>
Are you sure you wish to delete the column <b>{originalName}?</b>
Are you sure you wish to delete the column
<b on:click={() => (deleteColName = originalName)}>{originalName}?</b>
Your data will be deleted and this action cannot be undone - enter the column
name to confirm.
</p>
@ -810,4 +811,11 @@
gap: 8px;
display: flex;
}
b {
transition: color 130ms ease-out;
}
b:hover {
cursor: pointer;
color: var(--spectrum-global-color-gray-900);
}
</style>

View File

@ -53,7 +53,8 @@
}
.alert-wrap {
display: flex;
width: 100%;
flex: 0 0 auto;
margin: -28px -40px 14px -40px;
}
.alert-wrap :global(> *) {
flex: 1;

View File

@ -21,6 +21,7 @@
export let invertX = false
export let invertY = false
export let contentLines = 1
export let hidden = false
const emptyError = writable(null)
@ -78,6 +79,7 @@
{focused}
{selectedUser}
{readonly}
{hidden}
error={$error}
on:click={() => focusedCellId.set(cellId)}
on:contextmenu={e => menu.actions.open(cellId, e)}

View File

@ -10,6 +10,7 @@
export let defaultHeight = false
export let center = false
export let readonly = false
export let hidden = false
$: style = getStyle(width, selectedUser)
@ -30,6 +31,7 @@
class:error
class:center
class:readonly
class:hidden
class:default-height={defaultHeight}
class:selected-other={selectedUser != null}
class:alt={rowIdx % 2 === 1}
@ -81,6 +83,9 @@
.cell.center {
align-items: center;
}
.cell.hidden {
content-visibility: hidden;
}
/* Cell border */
.cell.focused:after,

View File

@ -17,7 +17,7 @@
isResizing,
rand,
sort,
renderedColumns,
visibleColumns,
dispatch,
subscribe,
config,
@ -50,7 +50,7 @@
$: sortedBy = column.name === $sort.column
$: canMoveLeft = orderable && idx > 0
$: canMoveRight = orderable && idx < $renderedColumns.length - 1
$: canMoveRight = orderable && idx < $visibleColumns.length - 1
$: sortingLabels = getSortingLabels(column.schema?.type)
$: searchable = isColumnSearchable(column)
$: resetSearchValue(column.name)

View File

@ -7,7 +7,7 @@
const {
bounds,
renderedRows,
renderedColumns,
visibleColumns,
rowVerticalInversionIndex,
hoveredRowId,
dispatch,
@ -17,7 +17,7 @@
let body
$: renderColumnsWidth = $renderedColumns.reduce(
$: columnsWidth = $visibleColumns.reduce(
(total, col) => (total += col.width),
0
)
@ -47,7 +47,7 @@
<div
class="blank"
class:highlighted={$hoveredRowId === BlankRowID}
style="width:{renderColumnsWidth}px"
style="width:{columnsWidth}px"
on:mouseenter={$isDragging ? null : () => ($hoveredRowId = BlankRowID)}
on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
on:click={() => dispatch("add-row-inline")}

View File

@ -10,7 +10,7 @@
focusedCellId,
reorder,
selectedRows,
renderedColumns,
visibleColumns,
hoveredRowId,
selectedCellMap,
focusedRow,
@ -19,6 +19,7 @@
isDragging,
dispatch,
rows,
columnRenderMap,
} = getContext("grid")
$: rowSelected = !!$selectedRows[row._id]
@ -34,7 +35,7 @@
on:mouseleave={$isDragging ? null : () => ($hoveredRowId = null)}
on:click={() => dispatch("rowclick", rows.actions.cleanRow(row))}
>
{#each $renderedColumns as column, columnIdx (column.name)}
{#each $visibleColumns as column, columnIdx}
{@const cellId = `${row._id}-${column.name}`}
<DataCell
{cellId}
@ -51,6 +52,7 @@
selectedUser={$selectedCellMap[cellId]}
width={column.width}
contentLines={$contentLines}
hidden={!$columnRenderMap[column.name]}
/>
{/each}
</div>

View File

@ -11,7 +11,6 @@
maxScrollLeft,
bounds,
hoveredRowId,
hiddenColumnsWidth,
menu,
} = getContext("grid")
@ -23,10 +22,10 @@
let initialTouchX
let initialTouchY
$: style = generateStyle($scroll, $rowHeight, $hiddenColumnsWidth)
$: style = generateStyle($scroll, $rowHeight)
const generateStyle = (scroll, rowHeight, hiddenWidths) => {
const offsetX = scrollHorizontally ? -1 * scroll.left + hiddenWidths : 0
const generateStyle = (scroll, rowHeight) => {
const offsetX = scrollHorizontally ? -1 * scroll.left : 0
const offsetY = scrollVertically ? -1 * (scroll.top % rowHeight) : 0
return `transform: translate3d(${offsetX}px, ${offsetY}px, 0);`
}

View File

@ -5,14 +5,14 @@
import HeaderCell from "../cells/HeaderCell.svelte"
import { TempTooltip, TooltipType } from "@budibase/bbui"
const { renderedColumns, config, hasNonAutoColumn, datasource, loading } =
const { visibleColumns, config, hasNonAutoColumn, datasource, loading } =
getContext("grid")
</script>
<div class="header">
<GridScrollWrapper scrollHorizontally>
<div class="row">
{#each $renderedColumns as column, idx}
{#each $visibleColumns as column, idx}
<HeaderCell {column} {idx}>
<slot name="edit-column" />
</HeaderCell>

View File

@ -2,17 +2,16 @@
import { getContext, onMount } from "svelte"
import { Icon, Popover, clickOutside } from "@budibase/bbui"
const { renderedColumns, scroll, hiddenColumnsWidth, width, subscribe } =
getContext("grid")
const { visibleColumns, scroll, width, subscribe } = getContext("grid")
let anchor
let open = false
$: columnsWidth = $renderedColumns.reduce(
$: columnsWidth = $visibleColumns.reduce(
(total, col) => (total += col.width),
0
)
$: end = $hiddenColumnsWidth + columnsWidth - 1 - $scroll.left
$: end = columnsWidth - 1 - $scroll.left
$: left = Math.min($width - 40, end)
const close = () => {
@ -34,7 +33,7 @@
<Popover
bind:open
{anchor}
align={$renderedColumns.length ? "right" : "left"}
align={$visibleColumns.length ? "right" : "left"}
offset={0}
popoverTarget={document.getElementById(`add-column-button`)}
customZindex={100}

View File

@ -20,7 +20,7 @@
datasource,
subscribe,
renderedRows,
renderedColumns,
visibleColumns,
rowHeight,
hasNextPage,
maxScrollTop,
@ -31,6 +31,7 @@
refreshing,
config,
filter,
columnRenderMap,
} = getContext("grid")
let visible = false
@ -38,7 +39,7 @@
let newRow
let offset = 0
$: firstColumn = $stickyColumn || $renderedColumns[0]
$: firstColumn = $stickyColumn || $visibleColumns[0]
$: width = GutterWidth + ($stickyColumn?.width || 0)
$: $datasource, (visible = false)
$: invertY = shouldInvertY(offset, $rowVerticalInversionIndex, $renderedRows)
@ -211,9 +212,8 @@
<div class="normal-columns" transition:fade|local={{ duration: 130 }}>
<GridScrollWrapper scrollHorizontally attachHandlers>
<div class="row">
{#each $renderedColumns as column, columnIdx}
{#each $visibleColumns as column, columnIdx}
{@const cellId = `new-${column.name}`}
{#key cellId}
<DataCell
{cellId}
{column}
@ -225,6 +225,7 @@
topRow={offset === 0}
invertX={columnIdx >= $columnHorizontalInversionIndex}
{invertY}
hidden={!$columnRenderMap[column.name]}
>
{#if column?.schema?.autocolumn}
<div class="readonly-overlay">Can't edit auto column</div>
@ -233,7 +234,6 @@
<div in:fade={{ duration: 130 }} class="loading-overlay" />
{/if}
</DataCell>
{/key}
{/each}
</div>
</GridScrollWrapper>

View File

@ -2,7 +2,7 @@
import { getContext } from "svelte"
import { GutterWidth } from "../lib/constants"
const { resize, renderedColumns, stickyColumn, isReordering, scrollLeft } =
const { resize, visibleColumns, stickyColumn, isReordering, scrollLeft } =
getContext("grid")
$: offset = GutterWidth + ($stickyColumn?.width || 0)
@ -26,7 +26,7 @@
<div class="resize-indicator" />
</div>
{/if}
{#each $renderedColumns as column}
{#each $visibleColumns as column}
<div
class="resize-slider"
class:visible={activeColumn === column.name}

View File

@ -1,4 +1,4 @@
import { derived, get } from "svelte/store"
import { derived } from "svelte/store"
import {
MaxCellRenderHeight,
MaxCellRenderWidthOverflow,
@ -50,12 +50,11 @@ export const deriveStores = context => {
const interval = MinColumnWidth
return Math.round($scrollLeft / interval) * interval
})
const renderedColumns = derived(
const columnRenderMap = derived(
[visibleColumns, scrollLeftRounded, width],
([$visibleColumns, $scrollLeft, $width], set) => {
([$visibleColumns, $scrollLeft, $width]) => {
if (!$visibleColumns.length) {
set([])
return
return {}
}
let startColIdx = 0
let rightEdge = $visibleColumns[0].width
@ -75,34 +74,16 @@ export const deriveStores = context => {
leftEdge += $visibleColumns[endColIdx].width
endColIdx++
}
// Render an additional column on either side to account for
// debounce column updates based on scroll position
const next = $visibleColumns.slice(
Math.max(0, startColIdx - 1),
endColIdx + 1
)
const current = get(renderedColumns)
if (JSON.stringify(next) !== JSON.stringify(current)) {
set(next)
}
}
)
const hiddenColumnsWidth = derived(
[renderedColumns, visibleColumns],
([$renderedColumns, $visibleColumns]) => {
const idx = $visibleColumns.findIndex(
col => col.name === $renderedColumns[0]?.name
)
let width = 0
if (idx > 0) {
for (let i = 0; i < idx; i++) {
width += $visibleColumns[i].width
// Only update the store if different
let next = {}
$visibleColumns
.slice(Math.max(0, startColIdx), endColIdx)
.forEach(col => {
next[col.name] = true
})
return next
}
}
return width
},
0
)
// Determine the row index at which we should start vertically inverting cell
@ -130,12 +111,12 @@ export const deriveStores = context => {
// Determine the column index at which we should start horizontally inverting
// cell dropdowns
const columnHorizontalInversionIndex = derived(
[renderedColumns, scrollLeft, width],
([$renderedColumns, $scrollLeft, $width]) => {
[visibleColumns, scrollLeft, width],
([$visibleColumns, $scrollLeft, $width]) => {
const cutoff = $width + $scrollLeft - ScrollBarSize * 3
let inversionIdx = $renderedColumns.length
for (let i = $renderedColumns.length - 1; i >= 0; i--, inversionIdx--) {
const rightEdge = $renderedColumns[i].left + $renderedColumns[i].width
let inversionIdx = $visibleColumns.length
for (let i = $visibleColumns.length - 1; i >= 0; i--, inversionIdx--) {
const rightEdge = $visibleColumns[i].left + $visibleColumns[i].width
if (rightEdge + MaxCellRenderWidthOverflow <= cutoff) {
break
}
@ -148,8 +129,7 @@ export const deriveStores = context => {
scrolledRowCount,
visualRowCapacity,
renderedRows,
renderedColumns,
hiddenColumnsWidth,
columnRenderMap,
rowVerticalInversionIndex,
columnHorizontalInversionIndex,
}