Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing issue with grid not allowing copying external ID #13650

Merged
merged 7 commits into from
May 13, 2024
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<script>
import { getContext } from "svelte"
import DataCell from "../cells/DataCell.svelte"
import { getCellID } from "../lib/utils"

export let row
export let top = false
Expand Down Expand Up @@ -38,7 +39,7 @@
on:click={() => dispatch("rowclick", rows.actions.cleanRow(row))}
>
{#each $visibleColumns as column, columnIdx}
{@const cellId = `${row._id}-${column.name}`}
{@const cellId = getCellID(row._id, column.name)}
<DataCell
{cellId}
{column}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import { GutterWidth, NewRowID } from "../lib/constants"
import GutterCell from "../cells/GutterCell.svelte"
import KeyboardShortcut from "./KeyboardShortcut.svelte"
import { getCellID } from "../lib/utils"

const {
hoveredRowId,
Expand Down Expand Up @@ -70,7 +71,7 @@

// Select the first cell if possible
if (firstColumn) {
$focusedCellId = `${savedRow._id}-${firstColumn.name}`
$focusedCellId = getCellID(savedRow._id, firstColumn.name)
}
}
isAdding = false
Expand Down Expand Up @@ -118,7 +119,7 @@
visible = true
$hoveredRowId = NewRowID
if (firstColumn) {
$focusedCellId = `${NewRowID}-${firstColumn.name}`
$focusedCellId = getCellID(NewRowID, firstColumn.name)
}

// Attach key listener
Expand Down Expand Up @@ -194,7 +195,7 @@
{/if}
</GutterCell>
{#if $stickyColumn}
{@const cellId = `${NewRowID}-${$stickyColumn.name}`}
{@const cellId = getCellID(NewRowID, $stickyColumn.name)}
<DataCell
{cellId}
rowFocused
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import { GutterWidth, BlankRowID } from "../lib/constants"
import GutterCell from "../cells/GutterCell.svelte"
import KeyboardShortcut from "./KeyboardShortcut.svelte"
import { getCellID } from "../lib/utils"

const {
rows,
Expand Down Expand Up @@ -71,7 +72,7 @@
{@const rowSelected = !!$selectedRows[row._id]}
{@const rowHovered = $hoveredRowId === row._id}
{@const rowFocused = $focusedRow?._id === row._id}
{@const cellId = `${row._id}-${$stickyColumn?.name}`}
{@const cellId = getCellID(row._id, $stickyColumn?.name)}
<div
class="row"
on:mouseenter={$isDragging ? null : () => ($hoveredRowId = row._id)}
Expand Down
17 changes: 17 additions & 0 deletions packages/frontend-core/src/components/grid/lib/utils.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,22 @@
import { TypeIconMap } from "../../../constants"

// we can't use "-" for joining the ID/field, as this can be present in the ID or column name
// using something very unusual to avoid this problem
const JOINING_CHARACTER = "‽‽"

export const parseCellID = rowId => {
if (!rowId) {
return undefined
}
const parts = rowId.split(JOINING_CHARACTER)
const field = parts.pop()
return { id: parts.join(JOINING_CHARACTER), field }
}

export const getCellID = (rowId, fieldName) => {
return `${rowId}${JOINING_CHARACTER}${fieldName}`
}

export const getColor = (idx, opacity = 0.3) => {
if (idx == null || idx === -1) {
idx = 0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
import { getContext, onMount } from "svelte"
import { debounce } from "../../../utils/utils"
import { NewRowID } from "../lib/constants"
import { getCellID, parseCellID } from "../lib/utils"

const {
rows,
Expand Down Expand Up @@ -154,7 +155,7 @@
if (!firstColumn) {
return
}
focusedCellId.set(`${firstRow._id}-${firstColumn.name}`)
focusedCellId.set(getCellID(firstRow._id, firstColumn.name))
}

// Changes the focused cell by moving it left or right to a different column
Expand All @@ -163,8 +164,7 @@
return
}
const cols = $visibleColumns
const split = $focusedCellId.split("-")
const columnName = split[1]
const { id, field: columnName } = parseCellID($focusedCellId)
let newColumnName
if (columnName === $stickyColumn?.name) {
const index = delta - 1
Expand All @@ -178,7 +178,7 @@
}
}
if (newColumnName) {
$focusedCellId = `${split[0]}-${newColumnName}`
$focusedCellId = getCellID(id, newColumnName)
}
}

Expand All @@ -189,8 +189,8 @@
}
const newRow = $rows[$focusedRow.__idx + delta]
if (newRow) {
const split = $focusedCellId.split("-")
$focusedCellId = `${newRow._id}-${split[1]}`
const { field } = parseCellID($focusedCellId)
$focusedCellId = getCellID(newRow._id, field)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { getContext } from "svelte"
import { NewRowID } from "../lib/constants"
import GridPopover from "./GridPopover.svelte"
import { getCellID } from "../lib/utils"

const {
focusedRow,
Expand Down Expand Up @@ -41,7 +42,7 @@
const newRow = await rows.actions.duplicateRow($focusedRow)
if (newRow) {
const column = $stickyColumn?.name || $columns[0].name
$focusedCellId = `${newRow._id}-${column}`
$focusedCellId = getCellID(newRow._id, column)
}
}

Expand Down
14 changes: 8 additions & 6 deletions packages/frontend-core/src/components/grid/stores/rows.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { writable, derived, get } from "svelte/store"
import { fetchData } from "../../../fetch"
import { NewRowID, RowPageSize } from "../lib/constants"
import { getCellID, parseCellID } from "../lib/utils"
import { tick } from "svelte"
import { Helpers } from "@budibase/bbui"

Expand Down Expand Up @@ -206,7 +207,7 @@ export const createActions = context => {
// If the server doesn't reply with a valid error, assume that the source
// of the error is the focused cell's column
if (!error?.json?.validationErrors && errorString) {
const focusedColumn = get(focusedCellId)?.split("-")[1]
const { field: focusedColumn } = parseCellID(get(focusedCellId))
if (focusedColumn) {
error = {
json: {
Expand Down Expand Up @@ -245,7 +246,7 @@ export const createActions = context => {
}
// Set error against the cell
validation.actions.setError(
`${rowId}-${column}`,
getCellID(rowId, column),
Helpers.capitalise(err)
)
// Ensure the column is visible
Expand All @@ -265,7 +266,7 @@ export const createActions = context => {

// Focus the first cell with an error
if (erroredColumns.length) {
focusedCellId.set(`${rowId}-${erroredColumns[0]}`)
focusedCellId.set(getCellID(rowId, erroredColumns[0]))
}
} else {
get(notifications).error(errorString || "An unknown error occurred")
Expand Down Expand Up @@ -571,9 +572,10 @@ export const initialise = context => {
return
}
// Stop if we changed row
const oldRowId = id.split("-")[0]
const oldColumn = id.split("-")[1]
const newRowId = get(focusedCellId)?.split("-")[0]
const split = parseCellID(id)
const oldRowId = split.id
const oldColumn = split.field
const { id: newRowId } = parseCellID(get(focusedCellId))
if (oldRowId !== newRowId) {
return
}
Expand Down
3 changes: 2 additions & 1 deletion packages/frontend-core/src/components/grid/stores/scroll.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { writable, derived, get } from "svelte/store"
import { tick } from "svelte"
import { Padding, GutterWidth, FocusedCellMinOffset } from "../lib/constants"
import { parseCellID } from "../lib/utils"

export const createStores = () => {
const scroll = writable({
Expand Down Expand Up @@ -176,7 +177,7 @@ export const initialise = context => {
// Ensure horizontal position is viewable
// Check horizontal position of columns next
const $visibleColumns = get(visibleColumns)
const columnName = $focusedCellId?.split("-")[1]
const { field: columnName } = parseCellID($focusedCellId)
const column = $visibleColumns.find(col => col.name === columnName)
if (!column) {
return
Expand Down
7 changes: 4 additions & 3 deletions packages/frontend-core/src/components/grid/stores/ui.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
MediumRowHeight,
NewRowID,
} from "../lib/constants"
import { parseCellID } from "../lib/utils"

export const createStores = context => {
const { props } = context
Expand All @@ -25,7 +26,7 @@ export const createStores = context => {
const focusedRowId = derived(
focusedCellId,
$focusedCellId => {
return $focusedCellId?.split("-")[0]
return parseCellID($focusedCellId)?.id
},
null
)
Expand Down Expand Up @@ -72,7 +73,7 @@ export const deriveStores = context => {
const focusedRow = derived(
[focusedCellId, rowLookupMap, rows],
([$focusedCellId, $rowLookupMap, $rows]) => {
const rowId = $focusedCellId?.split("-")[0]
const rowId = parseCellID($focusedCellId)?.id

// Edge case for new rows
if (rowId === NewRowID) {
Expand Down Expand Up @@ -152,7 +153,7 @@ export const initialise = context => {
const hasRow = rows.actions.hasRow

// Check selected cell
const selectedRowId = $focusedCellId?.split("-")[0]
const selectedRowId = parseCellID($focusedCellId)?.id
if (selectedRowId && !hasRow(selectedRowId)) {
focusedCellId.set(null)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { writable, get, derived } from "svelte/store"
import { getCellID, parseCellID } from "../lib/utils"

// Normally we would break out actions into the explicit "createActions"
// function, but for validation all these actions are pure so can go into
Expand All @@ -12,7 +13,7 @@ export const createStores = () => {
Object.entries($validation).forEach(([key, error]) => {
// Extract row ID from all errored cell IDs
if (error) {
map[key.split("-")[0]] = true
map[parseCellID(key).id] = true
}
})
return map
Expand Down Expand Up @@ -53,10 +54,10 @@ export const initialise = context => {
const $stickyColumn = get(stickyColumn)
validation.update(state => {
$columns.forEach(column => {
state[`${id}-${column.name}`] = null
state[getCellID(id, column.name)] = null
})
if ($stickyColumn) {
state[`${id}-${$stickyColumn.name}`] = null
state[getCellID(id, stickyColumn.name)] = null
}
return state
})
Expand Down