diff --git a/packages/builder/src/components/backend/DataTable/DataTable.svelte b/packages/builder/src/components/backend/DataTable/DataTable.svelte index acb3dacf93..dfe30a3711 100644 --- a/packages/builder/src/components/backend/DataTable/DataTable.svelte +++ b/packages/builder/src/components/backend/DataTable/DataTable.svelte @@ -42,13 +42,14 @@ {/if} - {#if isUsersTable} - - {/if} {#if !isInternal} {/if} - + {#if isUsersTable} + + {:else} + + {/if} diff --git a/packages/builder/src/components/backend/DataTable/buttons/ManageAccessButton.svelte b/packages/builder/src/components/backend/DataTable/buttons/ManageAccessButton.svelte index 4d5faca4c6..bc8e0c5318 100644 --- a/packages/builder/src/components/backend/DataTable/buttons/ManageAccessButton.svelte +++ b/packages/builder/src/components/backend/DataTable/buttons/ManageAccessButton.svelte @@ -16,7 +16,7 @@ - Manage access + Access - Create view + Add view diff --git a/packages/frontend-core/src/components/grid/cells/AttachmentCell.svelte b/packages/frontend-core/src/components/grid/cells/AttachmentCell.svelte index 2eb191e113..4d830723c2 100644 --- a/packages/frontend-core/src/components/grid/cells/AttachmentCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/AttachmentCell.svelte @@ -72,6 +72,7 @@ api = { focus: () => open(), blur: () => close(), + isActive: () => isOpen, onKeyDown, } }) diff --git a/packages/frontend-core/src/components/grid/cells/DataCell.svelte b/packages/frontend-core/src/components/grid/cells/DataCell.svelte index d97edabc01..f205c0a74a 100644 --- a/packages/frontend-core/src/components/grid/cells/DataCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/DataCell.svelte @@ -50,6 +50,7 @@ const cellAPI = { focus: () => api?.focus(), blur: () => api?.blur(), + isActive: () => api?.isActive?.() ?? false, onKeyDown: (...params) => api?.onKeyDown(...params), isReadonly: () => readonly, getType: () => column.schema.type, @@ -67,6 +68,7 @@ {rowIdx} {focused} {selectedUser} + {readonly} error={$error} on:click={() => focusedCellId.set(cellId)} on:contextmenu={e => menu.actions.open(cellId, e)} diff --git a/packages/frontend-core/src/components/grid/cells/GridCell.svelte b/packages/frontend-core/src/components/grid/cells/GridCell.svelte index 52dbed641c..dfc53f6f0c 100644 --- a/packages/frontend-core/src/components/grid/cells/GridCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/GridCell.svelte @@ -8,6 +8,7 @@ export let rowIdx export let defaultHeight = false export let center = false + export let readonly = false $: style = getStyle(width, selectedUser) @@ -27,6 +28,7 @@ class:focused class:error class:center + class:readonly class:default-height={defaultHeight} class:selected-other={selectedUser != null} on:focus @@ -121,7 +123,8 @@ .cell:hover { cursor: default; } - .cell.highlighted:not(.focused) { + .cell.highlighted:not(.focused), + .cell.focused.readonly { --cell-background: var(--cell-background-hover); } .cell.selected:not(.focused) { diff --git a/packages/frontend-core/src/components/grid/cells/GutterCell.svelte b/packages/frontend-core/src/components/grid/cells/GutterCell.svelte new file mode 100644 index 0000000000..d7d197758d --- /dev/null +++ b/packages/frontend-core/src/components/grid/cells/GutterCell.svelte @@ -0,0 +1,123 @@ + + + +
+ {#if $$slots.default} + + {:else} +
+ +
+ {#if !disableNumber} +
+ {row.__idx + 1} +
+ {/if} + {/if} + {#if $config.allowExpandRows} +
+ +
+ {/if} +
+
+ + diff --git a/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte b/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte index 890f314e2e..ae3794e1bd 100644 --- a/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/HeaderCell.svelte @@ -20,6 +20,7 @@ ui, columns, } = getContext("grid") + const bannedDisplayColumnTypes = [ "link", "array", @@ -100,7 +101,7 @@ style="flex: 0 0 {column.width}px;" bind:this={anchor} class:disabled={$isReordering || $isResizing} - class:sorted={sortedBy} + class:sticky={idx === "sticky"} > 100) { + textarea.setSelectionRange(0, 0) + } } const close = () => { @@ -43,6 +45,7 @@ api = { focus: () => open(), blur: () => close(), + isActive: () => isOpen, onKeyDown, } }) diff --git a/packages/frontend-core/src/components/grid/cells/OptionsCell.svelte b/packages/frontend-core/src/components/grid/cells/OptionsCell.svelte index 37c37fcd70..f3b6b9b59d 100644 --- a/packages/frontend-core/src/components/grid/cells/OptionsCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/OptionsCell.svelte @@ -73,6 +73,7 @@ api = { focus: open, blur: close, + isActive: () => isOpen, onKeyDown, } }) diff --git a/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte b/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte index 08dabe0fec..90182e9983 100644 --- a/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/RelationshipCell.svelte @@ -235,6 +235,7 @@ api = { focus: open, blur: close, + isActive: () => isOpen, onKeyDown, } }) diff --git a/packages/frontend-core/src/components/grid/cells/TextCell.svelte b/packages/frontend-core/src/components/grid/cells/TextCell.svelte index 73fb83dfbf..533b030b5c 100644 --- a/packages/frontend-core/src/components/grid/cells/TextCell.svelte +++ b/packages/frontend-core/src/components/grid/cells/TextCell.svelte @@ -33,6 +33,7 @@ api = { focus: () => input?.focus(), blur: () => input?.blur(), + isActive: () => active, onKeyDown, } }) diff --git a/packages/frontend-core/src/components/grid/controls/AddColumnButton.svelte b/packages/frontend-core/src/components/grid/controls/AddColumnButton.svelte index e04c1ee627..6ad241eb65 100644 --- a/packages/frontend-core/src/components/grid/controls/AddColumnButton.svelte +++ b/packages/frontend-core/src/components/grid/controls/AddColumnButton.svelte @@ -12,5 +12,5 @@ on:click={() => dispatch("add-column")} disabled={!$config.allowAddColumns} > - Create column + Add column diff --git a/packages/frontend-core/src/components/grid/controls/AddRowButton.svelte b/packages/frontend-core/src/components/grid/controls/AddRowButton.svelte index 6b8e259999..71062d6a1a 100644 --- a/packages/frontend-core/src/components/grid/controls/AddRowButton.svelte +++ b/packages/frontend-core/src/components/grid/controls/AddRowButton.svelte @@ -9,10 +9,10 @@ icon="TableRowAddBottom" quiet size="M" - on:click={() => dispatch("add-row")} + on:click={() => dispatch("add-row-inline")} disabled={!loaded || !$config.allowAddRows || (!$columns.length && !$stickyColumn)} > - Create row + Add row diff --git a/packages/frontend-core/src/components/grid/controls/ColumnWidthButton.svelte b/packages/frontend-core/src/components/grid/controls/ColumnWidthButton.svelte new file mode 100644 index 0000000000..754aebbb51 --- /dev/null +++ b/packages/frontend-core/src/components/grid/controls/ColumnWidthButton.svelte @@ -0,0 +1,91 @@ + + +
+ (open = !open)} + selected={open} + disabled={!allCols.length} + > + Width + +
+ + +
+ {#each sizeOptions as option} + changeColumnWidth(option.size)} + selected={option.selected} + > + {option.label} + + {/each} + {#if custom} + Custom + {/if} +
+
+ + diff --git a/packages/frontend-core/src/components/grid/controls/DeleteButton.svelte b/packages/frontend-core/src/components/grid/controls/DeleteButton.svelte index 9380228f2c..8ca5f0920d 100644 --- a/packages/frontend-core/src/components/grid/controls/DeleteButton.svelte +++ b/packages/frontend-core/src/components/grid/controls/DeleteButton.svelte @@ -1,13 +1,8 @@ {#if selectedRowCount}
- Delete {selectedRowCount} row{selectedRowCount === 1 ? "" : "s"} - +
{/if} @@ -57,16 +55,12 @@
diff --git a/packages/frontend-core/src/components/grid/controls/HideColumnsButton.svelte b/packages/frontend-core/src/components/grid/controls/HideColumnsButton.svelte index 6c9d1be8ac..7d7c4664b6 100644 --- a/packages/frontend-core/src/components/grid/controls/HideColumnsButton.svelte +++ b/packages/frontend-core/src/components/grid/controls/HideColumnsButton.svelte @@ -48,7 +48,7 @@ selected={open || anyHidden} disabled={!$columns.length} > - Hide columns + Columns diff --git a/packages/frontend-core/src/components/grid/controls/RowHeightButton.svelte b/packages/frontend-core/src/components/grid/controls/RowHeightButton.svelte index 0fcbbed089..e9045ac5c7 100644 --- a/packages/frontend-core/src/components/grid/controls/RowHeightButton.svelte +++ b/packages/frontend-core/src/components/grid/controls/RowHeightButton.svelte @@ -36,13 +36,13 @@
(open = !open)} selected={open} > - Row height + Height
diff --git a/packages/frontend-core/src/components/grid/controls/SortButton.svelte b/packages/frontend-core/src/components/grid/controls/SortButton.svelte index 471e28a2ab..26eba050bf 100644 --- a/packages/frontend-core/src/components/grid/controls/SortButton.svelte +++ b/packages/frontend-core/src/components/grid/controls/SortButton.svelte @@ -2,7 +2,7 @@ import { getContext } from "svelte" import { ActionButton, Popover, Select } from "@budibase/bbui" - const { sort, visibleColumns, stickyColumn } = getContext("grid") + const { sort, columns, stickyColumn } = getContext("grid") const orderOptions = [ { label: "A-Z", value: "ascending" }, { label: "Z-A", value: "descending" }, @@ -11,15 +11,24 @@ let open = false let anchor - $: columnOptions = getColumnOptions($stickyColumn, $visibleColumns) - $: checkValidSortColumn($sort.column, $stickyColumn, $visibleColumns) + $: columnOptions = getColumnOptions($stickyColumn, $columns) + $: checkValidSortColumn($sort.column, $stickyColumn, $columns) const getColumnOptions = (stickyColumn, columns) => { let options = [] if (stickyColumn) { - options.push(stickyColumn.name) + options.push({ + label: stickyColumn.label || stickyColumn.name, + value: stickyColumn.name, + }) } - return [...options, ...columns.map(col => col.name)] + return [ + ...options, + ...columns.map(col => ({ + label: col.label || col.name, + value: col.name, + })), + ] } const updateSortColumn = e => { @@ -37,13 +46,13 @@ } // Ensure we never have a sort column selected that is not visible - const checkValidSortColumn = (sortColumn, stickyColumn, visibleColumns) => { + const checkValidSortColumn = (sortColumn, stickyColumn, columns) => { if (!sortColumn) { return } if ( sortColumn !== stickyColumn?.name && - !visibleColumns.some(col => col.name === sortColumn) + !columns.some(col => col.name === sortColumn) ) { if (stickyColumn) { sort.update(state => ({ @@ -53,7 +62,7 @@ } else { sort.update(state => ({ ...state, - column: visibleColumns[0]?.name, + column: columns[0]?.name, })) } } @@ -66,7 +75,7 @@ quiet size="M" on:click={() => (open = !open)} - selected={open || $sort.column} + selected={open} disabled={!columnOptions.length} > Sort diff --git a/packages/frontend-core/src/components/grid/layout/Grid.svelte b/packages/frontend-core/src/components/grid/layout/Grid.svelte index e6bc3e05e4..36a3802164 100644 --- a/packages/frontend-core/src/components/grid/layout/Grid.svelte +++ b/packages/frontend-core/src/components/grid/layout/Grid.svelte @@ -22,6 +22,8 @@ import HideColumnsButton from "../controls/HideColumnsButton.svelte" import AddRowButton from "../controls/AddRowButton.svelte" import RowHeightButton from "../controls/RowHeightButton.svelte" + import ColumnWidthButton from "../controls/ColumnWidthButton.svelte" + import NewRow from "./NewRow.svelte" import { MaxCellRenderHeight, MaxCellRenderWidthOverflow, @@ -110,6 +112,7 @@ + @@ -127,10 +130,11 @@ + +
-
diff --git a/packages/frontend-core/src/components/grid/layout/GridBody.svelte b/packages/frontend-core/src/components/grid/layout/GridBody.svelte index 5c61fde3ef..67f5f03898 100644 --- a/packages/frontend-core/src/components/grid/layout/GridBody.svelte +++ b/packages/frontend-core/src/components/grid/layout/GridBody.svelte @@ -2,11 +2,25 @@ import { getContext, onMount } from "svelte" import GridScrollWrapper from "./GridScrollWrapper.svelte" import GridRow from "./GridRow.svelte" + import { BlankRowID } from "../lib/constants" - const { bounds, renderedRows, rowVerticalInversionIndex } = getContext("grid") + const { + bounds, + renderedRows, + renderedColumns, + rowVerticalInversionIndex, + config, + hoveredRowId, + dispatch, + } = getContext("grid") let body + $: renderColumnsWidth = $renderedColumns.reduce( + (total, col) => (total += col.width), + 0 + ) + onMount(() => { // Observe and record the height of the body const observer = new ResizeObserver(() => { @@ -24,6 +38,16 @@ {#each $renderedRows as row, idx} = $rowVerticalInversionIndex} /> {/each} + {#if $config.allowAddRows && $renderedColumns.length} +
($hoveredRowId = BlankRowID)} + on:mouseleave={() => ($hoveredRowId = null)} + on:click={() => dispatch("add-row-inline")} + /> + {/if}
@@ -35,4 +59,15 @@ overflow: hidden; flex: 1 1 auto; } + .blank { + height: var(--row-height); + background: var(--cell-background); + border-bottom: var(--cell-border); + border-right: var(--cell-border); + position: absolute; + } + .blank.highlighted { + background: var(--cell-background-hover); + cursor: pointer; + } diff --git a/packages/frontend-core/src/components/grid/layout/GridScrollWrapper.svelte b/packages/frontend-core/src/components/grid/layout/GridScrollWrapper.svelte index 0d241147a6..04f0960057 100644 --- a/packages/frontend-core/src/components/grid/layout/GridScrollWrapper.svelte +++ b/packages/frontend-core/src/components/grid/layout/GridScrollWrapper.svelte @@ -29,10 +29,7 @@ // Handles a wheel even and updates the scroll offsets const handleWheel = e => { e.preventDefault() - const modifier = e.ctrlKey || e.metaKey - let x = modifier ? e.deltaY : e.deltaX - let y = modifier ? e.deltaX : e.deltaY - debouncedHandleWheel(x, y, e.clientY) + debouncedHandleWheel(e.deltaX, e.deltaY, e.clientY) } const debouncedHandleWheel = domDebounce((deltaX, deltaY, clientY) => { const { top, left } = $scroll diff --git a/packages/frontend-core/src/components/grid/layout/HeaderRow.svelte b/packages/frontend-core/src/components/grid/layout/HeaderRow.svelte index caf8ac280b..2ec186a4d6 100644 --- a/packages/frontend-core/src/components/grid/layout/HeaderRow.svelte +++ b/packages/frontend-core/src/components/grid/layout/HeaderRow.svelte @@ -2,8 +2,17 @@ import { getContext } from "svelte" import GridScrollWrapper from "./GridScrollWrapper.svelte" import HeaderCell from "../cells/HeaderCell.svelte" + import { Icon } from "@budibase/bbui" - const { renderedColumns } = getContext("grid") + const { renderedColumns, dispatch, scroll, hiddenColumnsWidth, width } = + getContext("grid") + + $: columnsWidth = $renderedColumns.reduce( + (total, col) => (total += col.width), + 0 + ) + $: end = $hiddenColumnsWidth + columnsWidth - 1 - $scroll.left + $: left = Math.min($width - 40, end)
@@ -14,6 +23,13 @@ {/each}
+
dispatch("add-column")} + > + +
diff --git a/packages/frontend-core/src/components/grid/layout/NewRow.svelte b/packages/frontend-core/src/components/grid/layout/NewRow.svelte new file mode 100644 index 0000000000..54fef78301 --- /dev/null +++ b/packages/frontend-core/src/components/grid/layout/NewRow.svelte @@ -0,0 +1,265 @@ + + + +{#if isAdding} +
0} + style="--offset:{offset}px; --sticky-width:{width}px;" + > +
+
+
+ + + + {#if $stickyColumn} + {@const cellId = `${NewRowID}-${$stickyColumn.name}`} + + {/if} +
+
+ +
+ {#each $renderedColumns as column, columnIdx} + {@const cellId = `new-${column.name}`} + {#key cellId} + = $columnHorizontalInversionIndex} + {invertY} + /> + {/key} + {/each} +
+
+
+
+ + +
+
+{/if} + + diff --git a/packages/frontend-core/src/components/grid/layout/NewRowTop.svelte b/packages/frontend-core/src/components/grid/layout/NewRowTop.svelte deleted file mode 100644 index 5b92bc30fc..0000000000 --- a/packages/frontend-core/src/components/grid/layout/NewRowTop.svelte +++ /dev/null @@ -1,247 +0,0 @@ - - - -{#if isAdding} -
-
-
($hoveredRowId = "new")} - on:mouseleave={() => ($hoveredRowId = null)} - > -
0} - > - -
-
1
- {#if $config.allowExpandRows} - - {/if} -
-
- {#if $stickyColumn} - {@const cellId = `new-${$stickyColumn.name}`} - - {/if} -
- - -
- {#each $visibleColumns as column} - {@const cellId = `new-${column.name}`} - {#key cellId} - - {/key} - {/each} -
-
-
-
-
- - -
-
-{/if} - - diff --git a/packages/frontend-core/src/components/grid/layout/StickyColumn.svelte b/packages/frontend-core/src/components/grid/layout/StickyColumn.svelte index cbf74a0d22..6f10c30695 100644 --- a/packages/frontend-core/src/components/grid/layout/StickyColumn.svelte +++ b/packages/frontend-core/src/components/grid/layout/StickyColumn.svelte @@ -1,24 +1,26 @@
0} >
- -
-
- {#if $config.allowDeleteRows} -
- -
- {/if} -
- {#if $config.allowExpandRows} -
- -
- {/if} -
-
- + {#if $stickyColumn} {/if} @@ -95,41 +72,7 @@ on:mouseenter={() => ($hoveredRowId = row._id)} on:mouseleave={() => ($hoveredRowId = null)} > - -
-
selectRow(row._id)} - class="checkbox" - class:visible={$config.allowDeleteRows && - (rowSelected || rowHovered || rowFocused)} - > - -
-
- {row.__idx + 1} -
- {#if $config.allowExpandRows} -
- { - dispatch("edit-row", row) - }} - /> -
- {/if} -
-
+ {#if $stickyColumn} {/each} + {#if $config.allowAddRows && ($renderedColumns.length || $stickyColumn)} +
($hoveredRowId = BlankRowID)} + on:mouseleave={() => ($hoveredRowId = null)} + on:click={() => dispatch("add-row-inline")} + > + + + + {#if $stickyColumn} + + {/if} +
+ {/if}
@@ -156,6 +117,7 @@ flex-direction: column; position: relative; z-index: 2; + background: var(--cell-background); } /* Add right border */ @@ -203,43 +165,7 @@ position: relative; flex: 1 1 auto; } - - /* Styles for gutter */ - .gutter { - flex: 1 1 auto; - display: grid; - align-items: center; - padding: var(--cell-padding); - grid-template-columns: 1fr auto; - gap: var(--cell-spacing); - } - .checkbox, - .number { - display: none; - flex-direction: row; - justify-content: center; - align-items: center; - } - .checkbox :global(.spectrum-Checkbox) { - min-height: 0; - height: 20px; - } - .checkbox :global(.spectrum-Checkbox-box) { - margin: 3px 0 0 0; - } - .number { - color: var(--spectrum-global-color-gray-500); - } - .checkbox.visible, - .number.visible { - display: flex; - } - .expand { - opacity: 0; - pointer-events: none; - } - .expand.visible { - opacity: 1; - pointer-events: all; + .row.new :global(*:hover) { + cursor: pointer; } diff --git a/packages/frontend-core/src/components/grid/lib/constants.js b/packages/frontend-core/src/components/grid/lib/constants.js index e5427106a7..a7209d6ea4 100644 --- a/packages/frontend-core/src/components/grid/lib/constants.js +++ b/packages/frontend-core/src/components/grid/lib/constants.js @@ -1,11 +1,14 @@ -export const Padding = 276 +export const Padding = 128 export const MaxCellRenderHeight = 252 export const MaxCellRenderWidthOverflow = 200 export const ScrollBarSize = 8 export const GutterWidth = 72 export const DefaultColumnWidth = 200 -export const MinColumnWidth = 100 +export const MinColumnWidth = 80 export const SmallRowHeight = 36 export const MediumRowHeight = 64 export const LargeRowHeight = 92 export const DefaultRowHeight = SmallRowHeight +export const NewRowID = "new" +export const BlankRowID = "blank" +export const RowPageSize = 100 diff --git a/packages/frontend-core/src/components/grid/lib/utils.js b/packages/frontend-core/src/components/grid/lib/utils.js index 5b1d01ee36..d830d96dba 100644 --- a/packages/frontend-core/src/components/grid/lib/utils.js +++ b/packages/frontend-core/src/components/grid/lib/utils.js @@ -15,7 +15,7 @@ const TypeIconMap = { number: "123", boolean: "Boolean", attachment: "AppleFiles", - link: "Link", + link: "DataCorrelated", formula: "Calculator", json: "Brackets", } diff --git a/packages/frontend-core/src/components/grid/overlays/KeyboardManager.svelte b/packages/frontend-core/src/components/grid/overlays/KeyboardManager.svelte index c3ca6103c7..4b6d611757 100644 --- a/packages/frontend-core/src/components/grid/overlays/KeyboardManager.svelte +++ b/packages/frontend-core/src/components/grid/overlays/KeyboardManager.svelte @@ -1,6 +1,7 @@