diff --git a/packages/frontend-core/src/components/sheet/HeaderRow.svelte b/packages/frontend-core/src/components/sheet/HeaderRow.svelte
index 61152f35e8..71fd1237cc 100644
--- a/packages/frontend-core/src/components/sheet/HeaderRow.svelte
+++ b/packages/frontend-core/src/components/sheet/HeaderRow.svelte
@@ -2,65 +2,37 @@
import SheetCell from "./SheetCell.svelte"
import { getContext } from "svelte"
import { Icon } from "@budibase/bbui"
- import { Checkbox } from "@budibase/bbui"
+ import { getIconForField } from "./utils"
+ import SheetScrollWrapper from "./SheetScrollWrapper.svelte"
const { visibleColumns, reorder, selectedRows, rows } =
getContext("spreadsheet")
-
- $: rowCount = $rows.length
- $: selectedRowCount = Object.values($selectedRows).filter(x => !!x).length
-
- const getIconForField = field => {
- const type = field.schema.type
- if (type === "options") {
- return "ChevronDown"
- } else if (type === "datetime") {
- return "Date"
- }
- return "Text"
- }
-
- const selectAll = () => {
- const allSelected = selectedRowCount === rowCount
- if (allSelected) {
- $selectedRows = {}
- } else {
- let allRows = {}
- $rows.forEach(row => {
- allRows[row._id] = true
- })
- $selectedRows = allRows
- }
- }
-
-
-
-
-
- {#each $visibleColumns as column}
-
reorder.actions.startReordering(column.idx, e)}
- width={column.width}
- left={column.left}
- >
-
-
- {column.name}
-
-
- {/each}
+
+
+
+ {#each $visibleColumns as column}
+ reorder.actions.startReordering(column.idx, e)}
+ width={column.width}
+ left={column.left}
+ >
+
+
+ {column.name}
+
+
+ {/each}
+
+
diff --git a/packages/frontend-core/src/components/sheet/ResizeOverlay.svelte b/packages/frontend-core/src/components/sheet/ResizeOverlay.svelte
index 32edc77016..a51d0b11f4 100644
--- a/packages/frontend-core/src/components/sheet/ResizeOverlay.svelte
+++ b/packages/frontend-core/src/components/sheet/ResizeOverlay.svelte
@@ -1,8 +1,15 @@
+{#if $stickyColumn}
+
startResizing("sticky", e)}
+ style="--left:{40 +
+ $stickyColumn.width}px; --content-height:{contentHeight}px;"
+ >
+
+
+{/if}
{#each $visibleColumns as col}
- {#if col.idx === 0 || col.left + col.width > cutoff}
-
startResizing(col.idx, e)}
- style={getStyle(col, scrollLeft, rowCount)}
- >
-
-
- {/if}
+
startResizing(col.idx, e)}
+ style={getStyle(col, offset, scrollLeft, contentHeight)}
+ >
+
+
{/each}
diff --git a/packages/frontend-core/src/components/sheet/SheetBody.svelte b/packages/frontend-core/src/components/sheet/SheetBody.svelte
index 6a5bfe68d5..49c0ca3a16 100644
--- a/packages/frontend-core/src/components/sheet/SheetBody.svelte
+++ b/packages/frontend-core/src/components/sheet/SheetBody.svelte
@@ -1,7 +1,7 @@
@@ -39,7 +38,7 @@
border-color: var(--spectrum-global-color-gray-200);
border-width: 0;
border-bottom-width: 1px;
- border-left-width: 1px;
+ border-right-width: 1px;
display: flex;
flex-direction: row;
justify-content: flex-start;
@@ -48,10 +47,11 @@
font-size: var(--cell-font-size);
gap: var(--cell-spacing);
background: var(--cell-background);
- position: absolute;
transition: border-color 130ms ease-out;
- width: var(--width);
+ flex: 0 0 var(--width);
+ position: absolute;
left: var(--left);
+ width: var(--width);
}
.cell.selected {
box-shadow: inset 0 0 0 2px var(--spectrum-global-color-blue-400);
@@ -91,18 +91,6 @@
z-index: 11;
}
- /* Sticky styles */
- .cell.sticky {
- position: sticky;
- border-left-width: 0;
- transform: none;
- left: 40px;
- z-index: 5;
- }
- .cell.selected.sticky {
- z-index: 6;
- }
-
/* Reorder styles */
.cell.reorder-source {
background: var(--spectrum-global-color-gray-100);
@@ -122,8 +110,8 @@
/* Label cells */
.cell.label {
padding: var(--cell-padding);
- width: 40px;
- border-left-width: 0;
+ flex: 0 0 40px;
+ border-right-width: 0;
position: sticky;
left: 0;
z-index: 5;
diff --git a/packages/frontend-core/src/components/sheet/SheetHeader.svelte b/packages/frontend-core/src/components/sheet/SheetControls.svelte
similarity index 100%
rename from packages/frontend-core/src/components/sheet/SheetHeader.svelte
rename to packages/frontend-core/src/components/sheet/SheetControls.svelte
diff --git a/packages/frontend-core/src/components/sheet/SheetRow.svelte b/packages/frontend-core/src/components/sheet/SheetRow.svelte
index 5129ec0b98..ff1940abcb 100644
--- a/packages/frontend-core/src/components/sheet/SheetRow.svelte
+++ b/packages/frontend-core/src/components/sheet/SheetRow.svelte
@@ -2,14 +2,8 @@
-
selectRow(row._id)}>
-
-
-
-
- {row.__idx + 1}
-
-
{#each $visibleColumns as column (column.name)}
{@const cellIdx = `${row._id}-${column.name}`}
-
($selectedCellId = cellIdx)}
width={column.width}
left={column.left}
- column={column.idx}
>
rows.actions.updateRow(row._id, column, val)}
readonly={column.schema.autocolumn}
/>
-
+
{/each}
@@ -80,32 +50,9 @@
display: flex;
position: relative;
width: inherit;
+ height: var(--cell-height);
}
:global(.sheet:not(.is-resizing):not(.is-reordering) .row:hover .cell) {
background: var(--cell-background-hover);
}
-
- /* Styles for label cell */
- .checkbox {
- display: none;
- }
- .number {
- display: none;
- color: var(--spectrum-global-color-gray-500);
- }
- .row:hover .checkbox,
- .checkbox.visible {
- display: flex;
- }
- .number.visible {
- display: block;
- }
- .row:hover .number {
- display: none;
- }
-
- /* Add right border to last cell */
- .row :global(> :last-child) {
- border-right-width: 1px;
- }
diff --git a/packages/frontend-core/src/components/sheet/SheetScrollWrapper.svelte b/packages/frontend-core/src/components/sheet/SheetScrollWrapper.svelte
new file mode 100644
index 0000000000..c6f5798246
--- /dev/null
+++ b/packages/frontend-core/src/components/sheet/SheetScrollWrapper.svelte
@@ -0,0 +1,82 @@
+
+
+
+
+
+
+
diff --git a/packages/frontend-core/src/components/sheet/StickyColumn.svelte b/packages/frontend-core/src/components/sheet/StickyColumn.svelte
new file mode 100644
index 0000000000..1669460e53
--- /dev/null
+++ b/packages/frontend-core/src/components/sheet/StickyColumn.svelte
@@ -0,0 +1,153 @@
+
+
+
+
+
+
+
+
+
+ {#if $stickyColumn}
+
+
+
+ {$stickyColumn.name}
+
+
+ {/if}
+
+
+
+ {#each $visibleRows as row}
+ {@const rowSelected = !!$selectedRows[row._id]}
+
+
selectRow(row._id)}
+ width="40"
+ >
+
+
+
+
+ {row.__idx + 1}
+
+
+
+ {#if $stickyColumn}
+ {@const cellIdx = `${row._id}-${$stickyColumn.name}`}
+
($selectedCellId = cellIdx)}
+ width={$stickyColumn.width}
+ left="40"
+ >
+
+ rows.actions.updateRow(row._id, $stickyColumn, val)}
+ readonly={$stickyColumn.schema.autocolumn}
+ />
+
+ {/if}
+
+ {/each}
+
+
+
+
+
+ {#if $stickyColumn}
+
+ {/if}
+
+
+
+
+
diff --git a/packages/frontend-core/src/components/sheet/stores/columns.js b/packages/frontend-core/src/components/sheet/stores/columns.js
new file mode 100644
index 0000000000..a5728f639d
--- /dev/null
+++ b/packages/frontend-core/src/components/sheet/stores/columns.js
@@ -0,0 +1,64 @@
+import { get, writable } from "svelte/store"
+
+export const createColumnsStores = context => {
+ const { schema } = context
+ const defaultWidth = 200
+ const columns = writable([])
+ const stickyColumn = writable(null)
+
+ schema.subscribe($schema => {
+ const currentColumns = get(columns)
+ if (!$schema) {
+ columns.set([])
+ return
+ }
+
+ // Get field list
+ let fields = []
+ Object.entries($schema || {}).forEach(([field, fieldSchema]) => {
+ if (!fieldSchema.primaryDisplay) {
+ fields.push(field)
+ }
+ })
+
+ // Update columns, removing extraneous columns and adding missing ones
+ let offset = 0
+ columns.set(
+ fields.map((field, idx) => {
+ const existing = currentColumns.find(x => x.name === field)
+ const newCol = {
+ idx,
+ name: field,
+ width: existing?.width || defaultWidth,
+ left: offset,
+ schema: $schema[field],
+ }
+ offset += newCol.width
+ return newCol
+ })
+ )
+ })
+
+ schema.subscribe($schema => {
+ const primaryDisplay = Object.entries($schema).find(entry => {
+ return entry[1].primaryDisplay
+ })
+ if (!primaryDisplay) {
+ stickyColumn.set(null)
+ return
+ }
+ const existingWidth = get(stickyColumn)?.width
+ const same = primaryDisplay[0] === get(stickyColumn)?.name
+ stickyColumn.set({
+ name: primaryDisplay[0],
+ width: same ? existingWidth : defaultWidth,
+ left: 40,
+ schema: primaryDisplay[1],
+ })
+ })
+
+ return {
+ columns,
+ stickyColumn,
+ }
+}
diff --git a/packages/frontend-core/src/components/sheet/stores/reorder.js b/packages/frontend-core/src/components/sheet/stores/reorder.js
index f327a5ef2d..4d4659fe8d 100644
--- a/packages/frontend-core/src/components/sheet/stores/reorder.js
+++ b/packages/frontend-core/src/components/sheet/stores/reorder.js
@@ -76,7 +76,7 @@ export const createReorderStores = context => {
swapColumnIdx++
}
state.splice(swapColumnIdx, 0, removed[0])
- let offset = 40
+ let offset = 0
return state.map((col, idx) => {
const newCol = {
...col,
diff --git a/packages/frontend-core/src/components/sheet/stores/rows.js b/packages/frontend-core/src/components/sheet/stores/rows.js
index 2fa58f4c76..840798f1e2 100644
--- a/packages/frontend-core/src/components/sheet/stores/rows.js
+++ b/packages/frontend-core/src/components/sheet/stores/rows.js
@@ -15,7 +15,6 @@ export const createRowsStore = context => {
// Exported stores
const rows = writable([])
const schema = writable({})
- const primaryDisplay = writable(null)
// Local stores for managing fetching data
const query = derived(filter, $filter => buildLuceneQuery($filter))
@@ -62,8 +61,12 @@ export const createRowsStore = context => {
loaded = true
rowCacheMap = {}
rows.set([])
- schema.set($$fetch.schema)
- primaryDisplay.set($$fetch.definition?.primaryDisplay)
+ let newSchema = $$fetch.schema
+ const primaryDisplay = $$fetch.definition?.primaryDisplay
+ if (primaryDisplay && newSchema[primaryDisplay]) {
+ newSchema[primaryDisplay].primaryDisplay = true
+ }
+ schema.set(newSchema)
}
// Process new rows
@@ -220,6 +223,5 @@ export const createRowsStore = context => {
},
},
schema,
- primaryDisplay,
}
}
diff --git a/packages/frontend-core/src/components/sheet/stores/viewport.js b/packages/frontend-core/src/components/sheet/stores/viewport.js
index 82df7739e7..56987006a7 100644
--- a/packages/frontend-core/src/components/sheet/stores/viewport.js
+++ b/packages/frontend-core/src/components/sheet/stores/viewport.js
@@ -39,25 +39,26 @@ export const createViewportStores = context => {
if (!$columns.length) {
return []
}
- let startColIdx = 1
- let rightEdge = $columns[1].width
+ let startColIdx = 0
+ let rightEdge = $columns[0].width
while (rightEdge < $scrollLeft) {
startColIdx++
rightEdge += $columns[startColIdx].width
}
let endColIdx = startColIdx + 1
- let leftEdge = $columns[0].width + 40 + rightEdge
+ let leftEdge = rightEdge
while (leftEdge < $width + $scrollLeft) {
leftEdge += $columns[endColIdx]?.width
endColIdx++
}
- return [
- $columns[0],
- ...$columns.slice(Math.max(1, startColIdx - 2), endColIdx + 2),
- ]
+ return $columns.slice(Math.max(0, startColIdx - 1), endColIdx + 1)
}
)
+ // visibleColumns.subscribe(state => {
+ // console.log(state)
+ // })
+
// Fetch next page when approaching end of data
visibleRows.subscribe($visibleRows => {
const lastVisible = $visibleRows[$visibleRows.length - 1]
diff --git a/packages/frontend-core/src/components/sheet/utils.js b/packages/frontend-core/src/components/sheet/utils.js
index 9c708c3237..895dd99cfc 100644
--- a/packages/frontend-core/src/components/sheet/utils.js
+++ b/packages/frontend-core/src/components/sheet/utils.js
@@ -1,6 +1,34 @@
+import OptionsCell from "./cells/OptionsCell.svelte"
+import DateCell from "./cells/DateCell.svelte"
+import MultiSelectCell from "./cells/MultiSelectCell.svelte"
+import NumberCell from "./cells/NumberCell.svelte"
+import RelationshipCell from "./cells/RelationshipCell.svelte"
+import TextCell from "./cells/TextCell.svelte"
+
export const getColor = idx => {
if (idx == null || idx === -1) {
return null
}
return `hsla(${((idx + 1) * 222) % 360}, 90%, 75%, 0.3)`
}
+
+export const getIconForField = field => {
+ const type = field.schema.type
+ if (type === "options") {
+ return "ChevronDown"
+ } else if (type === "datetime") {
+ return "Date"
+ }
+ return "Text"
+}
+
+const TypeComponentMap = {
+ options: OptionsCell,
+ datetime: DateCell,
+ array: MultiSelectCell,
+ number: NumberCell,
+ link: RelationshipCell,
+}
+export const getCellComponent = column => {
+ return TypeComponentMap[column?.schema?.type] || TextCell
+}