diff --git a/packages/builder/src/builderStore/store/screenTemplates/rowListScreen.js b/packages/builder/src/builderStore/store/screenTemplates/rowListScreen.js
index 8d4dc48a94..603c730508 100644
--- a/packages/builder/src/builderStore/store/screenTemplates/rowListScreen.js
+++ b/packages/builder/src/builderStore/store/screenTemplates/rowListScreen.js
@@ -82,18 +82,45 @@ const createScreen = table => {
},
})
- const grid = new Component("@budibase/standard-components/datagrid")
+ const spectrumTable = new Component("@budibase/standard-components/table")
.customProps({
dataProvider: `{{ literal ${makePropSafe(provider._json._id)} }}`,
- editable: false,
- theme: "alpine",
- height: "540",
- pagination: true,
- detailUrl: `${rowListUrl(table)}/:id`,
+ theme: "spectrum--lightest",
+ showAutoColumns: false,
+ quiet: false,
+ size: "spectrum--medium",
+ rowCount: 8,
})
- .instanceName("Grid")
+ .instanceName(`${table.name} Table`)
- provider.addChild(grid)
+ const safeTableId = makePropSafe(spectrumTable._json._id)
+ const safeRowId = makePropSafe("_id")
+ const viewButton = new Component("@budibase/standard-components/button")
+ .customProps({
+ text: "View",
+ onClick: [
+ {
+ "##eventHandlerType": "Navigate To",
+ parameters: {
+ url: `${rowListUrl(table)}/{{ ${safeTableId}.${safeRowId} }}`,
+ },
+ },
+ ],
+ })
+ .instanceName("View Button")
+ .normalStyle({
+ background: "transparent",
+ "font-family": "Inter, sans-serif",
+ "font-weight": "500",
+ color: "#888",
+ "border-width": "0",
+ })
+ .hoverStyle({
+ color: "#4285f4",
+ })
+
+ spectrumTable.addChild(viewButton)
+ provider.addChild(spectrumTable)
const mainContainer = new Component("@budibase/standard-components/container")
.normalStyle({
diff --git a/packages/builder/src/components/design/AppPreview/componentStructure.json b/packages/builder/src/components/design/AppPreview/componentStructure.json
index 9dadf2aa25..267289a804 100644
--- a/packages/builder/src/components/design/AppPreview/componentStructure.json
+++ b/packages/builder/src/components/design/AppPreview/componentStructure.json
@@ -1,7 +1,6 @@
[
"container",
"dataprovider",
- "datagrid",
"table",
"repeater",
"button",
diff --git a/packages/standard-components/manifest.json b/packages/standard-components/manifest.json
index 36a4cbd1d5..9cd8999088 100644
--- a/packages/standard-components/manifest.json
+++ b/packages/standard-components/manifest.json
@@ -8,47 +8,6 @@
"transitionable": true,
"settings": []
},
- "datagrid": {
- "name": "Grid",
- "description": "A datagrid component with functionality to add, remove and edit rows.",
- "icon": "ri-grid-line",
- "styleable": true,
- "settings": [
- {
- "type": "dataProvider",
- "label": "Data",
- "key": "dataProvider"
- },
- {
- "type": "detailScreen",
- "label": "Detail URL",
- "key": "detailUrl"
- },
- {
- "type": "boolean",
- "label": "Editable",
- "key": "editable"
- },
- {
- "type": "select",
- "label": "Theme",
- "key": "theme",
- "options": ["alpine", "alpine-dark", "balham", "balham-dark", "material"],
- "defaultValue": "alpine"
- },
- {
- "type": "number",
- "label": "Height",
- "key": "height",
- "defaultValue": "500"
- },
- {
- "type": "boolean",
- "label": "Pagination",
- "key": "pagination"
- }
- ]
- },
"screenslot": {
"name": "Screenslot",
"icon": "ri-artboard-2-line",
diff --git a/packages/standard-components/package.json b/packages/standard-components/package.json
index 70e441b49a..492c6449c6 100644
--- a/packages/standard-components/package.json
+++ b/packages/standard-components/package.json
@@ -41,7 +41,6 @@
"dependencies": {
"@adobe/spectrum-css-workflow-icons": "^1.1.0",
"@budibase/bbui": "^1.58.13",
- "@budibase/svelte-ag-grid": "^1.0.4",
"@spectrum-css/actionbutton": "^1.0.1",
"@spectrum-css/button": "^3.0.1",
"@spectrum-css/checkbox": "^3.0.1",
diff --git a/packages/standard-components/src/grid/AttachmentCell/Button.svelte b/packages/standard-components/src/grid/AttachmentCell/Button.svelte
deleted file mode 100644
index 12f3cc8e9f..0000000000
--- a/packages/standard-components/src/grid/AttachmentCell/Button.svelte
+++ /dev/null
@@ -1,6 +0,0 @@
-
-
-
diff --git a/packages/standard-components/src/grid/AttachmentCell/Modal.svelte b/packages/standard-components/src/grid/AttachmentCell/Modal.svelte
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/packages/standard-components/src/grid/Component.svelte b/packages/standard-components/src/grid/Component.svelte
deleted file mode 100644
index c7e0f24d3c..0000000000
--- a/packages/standard-components/src/grid/Component.svelte
+++ /dev/null
@@ -1,180 +0,0 @@
-
-
-
- {#if dataLoaded}
- {#if canAddDelete}
-
- {#if selectedRows.length > 0}
-
-
- Delete
- {selectedRows.length}
- row(s)
-
- {/if}
-
- {/if}
-
(selectedRows = detail)} />
- {/if}
-
-
- Are you sure you want to delete {selectedRows.length} row(s)?
-
-
-
-
-
diff --git a/packages/standard-components/src/grid/CreateRow/Button.svelte b/packages/standard-components/src/grid/CreateRow/Button.svelte
deleted file mode 100644
index ab3513de91..0000000000
--- a/packages/standard-components/src/grid/CreateRow/Button.svelte
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
-
-
- Add New Row
- dispatch('newRow')} />
-
-
-
diff --git a/packages/standard-components/src/grid/CreateRow/Modal.svelte b/packages/standard-components/src/grid/CreateRow/Modal.svelte
deleted file mode 100644
index 1cb9aa923d..0000000000
--- a/packages/standard-components/src/grid/CreateRow/Modal.svelte
+++ /dev/null
@@ -1,144 +0,0 @@
-
-
-
- {#each errorMessages as error}
-
{error}
- {/each}
-
-
-
-
-
diff --git a/packages/standard-components/src/grid/DateTime/Wrapper.svelte b/packages/standard-components/src/grid/DateTime/Wrapper.svelte
deleted file mode 100644
index b493626d64..0000000000
--- a/packages/standard-components/src/grid/DateTime/Wrapper.svelte
+++ /dev/null
@@ -1,5 +0,0 @@
-
-
-
diff --git a/packages/standard-components/src/grid/Relationship/RelationshipDisplay.svelte b/packages/standard-components/src/grid/Relationship/RelationshipDisplay.svelte
deleted file mode 100644
index f269f8f2a8..0000000000
--- a/packages/standard-components/src/grid/Relationship/RelationshipDisplay.svelte
+++ /dev/null
@@ -1,75 +0,0 @@
-
-
-
- {#if linkedRows && linkedRows.length && displayColumn}
- {#each linkedRows as linkedRow}
- {#if linkedRow[displayColumn] != null && linkedRow[displayColumn] !== ''}
-
{linkedRow[displayColumn]}
- {/if}
- {/each}
- {:else}{count} related row(s){/if}
-
-
-
diff --git a/packages/standard-components/src/grid/Relationship/RelationshipLabel.svelte b/packages/standard-components/src/grid/Relationship/RelationshipLabel.svelte
deleted file mode 100644
index ec64255855..0000000000
--- a/packages/standard-components/src/grid/Relationship/RelationshipLabel.svelte
+++ /dev/null
@@ -1,32 +0,0 @@
-
-
-
- {#each items as item}
-
{item?.primaryDisplay ?? ''}
- {/each}
-
-
-
diff --git a/packages/standard-components/src/grid/Select/Wrapper.svelte b/packages/standard-components/src/grid/Select/Wrapper.svelte
deleted file mode 100644
index 4c4a8eaf21..0000000000
--- a/packages/standard-components/src/grid/Select/Wrapper.svelte
+++ /dev/null
@@ -1,17 +0,0 @@
-
-
-
diff --git a/packages/standard-components/src/grid/ViewDetails/Cell.svelte b/packages/standard-components/src/grid/ViewDetails/Cell.svelte
deleted file mode 100644
index f222429aa8..0000000000
--- a/packages/standard-components/src/grid/ViewDetails/Cell.svelte
+++ /dev/null
@@ -1,19 +0,0 @@
-
-
-
-
-
-
diff --git a/packages/standard-components/src/grid/customRenderer.js b/packages/standard-components/src/grid/customRenderer.js
deleted file mode 100644
index fd558baa98..0000000000
--- a/packages/standard-components/src/grid/customRenderer.js
+++ /dev/null
@@ -1,169 +0,0 @@
-// Custom renderers to handle special types
-// https://www.ag-grid.com/javascript-grid-cell-rendering-components/
-
-import AttachmentCell from "./AttachmentCell/Button.svelte"
-import ViewDetails from "./ViewDetails/Cell.svelte"
-import Select from "./Select/Wrapper.svelte"
-import DatePicker from "./DateTime/Wrapper.svelte"
-import RelationshipLabel from "./Relationship/RelationshipLabel.svelte"
-
-const renderers = new Map([
- ["boolean", booleanRenderer],
- ["attachment", attachmentRenderer],
- ["options", optionsRenderer],
- ["link", linkedRowRenderer],
- ["_id", viewDetailsRenderer],
-])
-
-export function getRenderer(schema, editable, SDK) {
- if (renderers.get(schema.type)) {
- return renderers.get(schema.type)(
- schema.options,
- schema.constraints,
- editable,
- SDK
- )
- } else {
- return false
- }
-}
-
-/* eslint-disable no-unused-vars */
-function booleanRenderer(options, constraints, editable, SDK) {
- return params => {
- const toggle = e => {
- params.value = !params.value
- params.setValue(e.currentTarget.checked)
- }
- let input = document.createElement("input")
- input.style.display = "grid"
- input.style.placeItems = "center"
- input.style.height = "100%"
- input.type = "checkbox"
- input.checked = params.value
- if (editable) {
- input.addEventListener("click", toggle)
- } else {
- input.disabled = true
- }
-
- return input
- }
-}
-/* eslint-disable no-unused-vars */
-function attachmentRenderer(options, constraints, editable, SDK) {
- return params => {
- const container = document.createElement("div")
-
- const attachmentInstance = new AttachmentCell({
- target: container,
- props: {
- files: params.value || [],
- SDK,
- },
- })
-
- const deleteFile = event => {
- const newFilesArray = params.value.filter(file => file !== event.detail)
- params.setValue(newFilesArray)
- }
-
- attachmentInstance.$on("delete", deleteFile)
-
- return container
- }
-}
-/* eslint-disable no-unused-vars */
-function dateRenderer(options, constraints, editable, SDK) {
- return function(params) {
- const container = document.createElement("div")
- const toggle = e => {
- params.setValue(e.detail[0][0])
- }
-
- // Options need to be passed in with minTime and maxTime! Needs bbui update.
- new DatePicker({
- target: container,
- props: {
- value: params.value,
- SDK,
- },
- })
-
- return container
- }
-}
-
-function optionsRenderer(options, constraints, editable, SDK) {
- return params => {
- if (!editable) return params.value
- const container = document.createElement("div")
- container.style.display = "grid"
- container.style.placeItems = "center"
- container.style.height = "100%"
- const change = e => {
- params.setValue(e.detail)
- }
-
- const selectInstance = new Select({
- target: container,
- props: {
- value: params.value,
- options: constraints.inclusion,
- SDK,
- },
- })
-
- selectInstance.$on("change", change)
-
- return container
- }
-}
-/* eslint-disable no-unused-vars */
-function linkedRowRenderer(options, constraints, editable, SDK) {
- return params => {
- let container = document.createElement("div")
- container.style.display = "grid"
- container.style.placeItems = "center"
- container.style.height = "100%"
-
- new RelationshipLabel({
- target: container,
- props: {
- row: params.data,
- columnName: params.column.colId,
- SDK,
- },
- })
-
- return container
- }
-}
-
-/* eslint-disable no-unused-vars */
-function viewDetailsRenderer(options, constraints, editable, SDK) {
- return params => {
- let container = document.createElement("div")
- container.style.display = "grid"
- container.style.alignItems = "center"
- container.style.height = "100%"
-
- let url = "/"
- if (options.detailUrl) {
- url = options.detailUrl.replace(":id", params.data._id)
- }
- if (!url.startsWith("/")) {
- url = `/${url}`
- }
-
- new ViewDetails({
- target: container,
- props: {
- url,
- SDK,
- },
- })
-
- return container
- }
-}
diff --git a/packages/standard-components/src/grid/valueSetters.js b/packages/standard-components/src/grid/valueSetters.js
deleted file mode 100644
index 2da8182092..0000000000
--- a/packages/standard-components/src/grid/valueSetters.js
+++ /dev/null
@@ -1,6 +0,0 @@
-// https://www.ag-grid.com/javascript-grid-value-setters/
-// These handles values and makes sure they adhere to the data type provided by the table
-export const number = params => {
- params.data[params.colDef.field] = parseFloat(params.newValue)
- return true
-}
diff --git a/packages/standard-components/src/index.js b/packages/standard-components/src/index.js
index 9280825ebf..d1ad792247 100644
--- a/packages/standard-components/src/index.js
+++ b/packages/standard-components/src/index.js
@@ -14,7 +14,6 @@ loadSpectrumIcons()
export { default as container } from "./Container.svelte"
export { default as dataprovider } from "./DataProvider.svelte"
-export { default as datagrid } from "./grid/Component.svelte"
export { default as screenslot } from "./ScreenSlot.svelte"
export { default as button } from "./Button.svelte"
export { default as repeater } from "./Repeater.svelte"
diff --git a/packages/standard-components/src/table/DateTimeRenderer.svelte b/packages/standard-components/src/table/DateTimeRenderer.svelte
index fbde2999e1..169adab163 100644
--- a/packages/standard-components/src/table/DateTimeRenderer.svelte
+++ b/packages/standard-components/src/table/DateTimeRenderer.svelte
@@ -4,4 +4,10 @@
export let value
-{dayjs(value).format('MMMM D YYYY, HH:mm')}
+{dayjs(value).format('MMMM D YYYY, HH:mm')}
+
+
diff --git a/packages/standard-components/src/table/StringRenderer.svelte b/packages/standard-components/src/table/StringRenderer.svelte
index 92f3c035c8..2756839616 100644
--- a/packages/standard-components/src/table/StringRenderer.svelte
+++ b/packages/standard-components/src/table/StringRenderer.svelte
@@ -8,6 +8,6 @@
div {
overflow: hidden;
text-overflow: ellipsis;
- max-width: 320px;
+ width: 150px;
}
diff --git a/packages/standard-components/src/table/Table.svelte b/packages/standard-components/src/table/Table.svelte
index b1f2a3ef2e..faa689aa97 100644
--- a/packages/standard-components/src/table/Table.svelte
+++ b/packages/standard-components/src/table/Table.svelte
@@ -14,22 +14,42 @@
const component = getContext("component")
const { styleable, Provider } = getContext("sdk")
+ // Config
+ const rowHeight = 55
+ const headerHeight = 36
+ const rowPreload = 5
+ const maxRows = 100
+
+ // Sorting state
let sortColumn
let sortOrder
- $: rows = dataProvider?.rows ?? []
- $: contentStyle = getContentStyle(rowCount, rows.length)
- $: sortedRows = sortRows(rows, sortColumn, sortOrder)
+ // Table state
$: loaded = dataProvider?.loaded ?? false
+ $: rows = dataProvider?.rows ?? []
+ $: visibleRowCount = Math.min(rows.length, rowCount || maxRows, maxRows)
+ $: scroll = rows.length > visibleRowCount
+ $: contentStyle = getContentStyle(visibleRowCount, scroll)
+ $: sortedRows = sortRows(rows, sortColumn, sortOrder)
$: schema = dataProvider?.schema ?? {}
$: fields = getFields(schema, columns, showAutoColumns)
- const getContentStyle = (rowCount, dataCount) => {
- if (!rowCount) {
+ // Scrolling state
+ let timeout
+ let nextScrollTop = 0
+ let scrollTop = 0
+ $: firstVisibleRow = calculateFirstVisibleRow(scrollTop)
+ $: lastVisibleRow = calculateLastVisibleRow(
+ firstVisibleRow,
+ visibleRowCount,
+ rows.length
+ )
+
+ const getContentStyle = (visibleRows, scroll) => {
+ if (!scroll) {
return ""
}
- const actualCount = Math.min(rowCount, dataCount)
- return `height: ${35 + actualCount * 56}px;`
+ return `height: ${headerHeight - 1 + visibleRows * (rowHeight + 1)}px;`
}
const sortRows = (rows, sortColumn, sortOrder) => {
@@ -71,69 +91,101 @@
})
return columns.concat(autoColumns)
}
+
+ const onScroll = event => {
+ nextScrollTop = event.target.scrollTop
+ if (timeout) {
+ return
+ }
+ timeout = setTimeout(() => {
+ scrollTop = nextScrollTop
+ timeout = null
+ }, 50)
+ }
+
+ const calculateFirstVisibleRow = scrollTop => {
+ return Math.max(Math.floor(scrollTop / (rowHeight + 1)) - rowPreload, 0)
+ }
+
+ const calculateLastVisibleRow = (firstRow, visibleRowCount, allRowCount) => {
+ return Math.min(firstRow + visibleRowCount + 2 * rowPreload, allRowCount)
+ }
-
-
-
-
-
-
- {#if $component.children}
-
-
- |
- {/if}
- {#each fields as field}
- sortBy(field)}>
-
- {schema[field]?.name}
-
-
- |
- {/each}
-
-
-
- {#each sortedRows as row}
-
+{#if loaded}
+
+
+
+
+
+
{#if $component.children}
-
-
- |
+
+
+ |
{/if}
{#each fields as field}
-
-
-
+ sortBy(field)}>
+
+ {schema[field]?.name}
+
- | |
+
{/each}
- {/each}
-
-
+
+
+ {#each sortedRows as row, idx}
+ lastVisibleRow}>
+ {#if idx < firstVisibleRow || idx > lastVisibleRow}
+
+ {:else}
+ {#if $component.children}
+
+
+ |
+ {/if}
+ {#each fields as field}
+
+
+
+
+ |
+ {/each}
+ {/if}
+
+ {/each}
+
+
+
-
+{/if}