budibase/packages/client/src/components/app/table/Table.svelte

139 lines
3.3 KiB
Svelte

<script>
import { getContext } from "svelte"
import { Table } from "@budibase/bbui"
import SlotRenderer from "./SlotRenderer.svelte"
import { UnsortableTypes } from "../../../constants"
export let dataProvider
export let columns
export let showAutoColumns
export let rowCount
export let quiet
export let size
export let linkRows
export let linkURL
export let linkColumn
export let linkPeek
export let allowSelectRows
const component = getContext("component")
const { styleable, getAction, ActionTypes, routeStore, rowSelectionStore } =
getContext("sdk")
const customColumnKey = `custom-${Math.random()}`
const customRenderers = [
{
column: customColumnKey,
component: SlotRenderer,
},
]
let selectedRows = []
$: hasChildren = $component.children
$: loading = dataProvider?.loading ?? false
$: data = dataProvider?.rows || []
$: fullSchema = dataProvider?.schema ?? {}
$: fields = getFields(fullSchema, columns, showAutoColumns)
$: schema = getFilteredSchema(fullSchema, fields, hasChildren)
$: setSorting = getAction(
dataProvider?.id,
ActionTypes.SetDataProviderSorting
)
$: {
rowSelectionStore.actions.update(selectedRows)
}
const getFields = (schema, customColumns, showAutoColumns) => {
// Check for an invalid column selection
let invalid = false
customColumns?.forEach(column => {
if (schema[column] == null) {
invalid = true
}
})
// Use column selection if it exists
if (!invalid && customColumns?.length) {
return customColumns
}
// Otherwise generate columns
let columns = []
let autoColumns = []
Object.entries(schema).forEach(([field, fieldSchema]) => {
if (!fieldSchema?.autocolumn) {
columns.push(field)
} else if (showAutoColumns) {
autoColumns.push(field)
}
})
return columns.concat(autoColumns)
}
const getFilteredSchema = (schema, fields, hasChildren) => {
let newSchema = {}
if (hasChildren) {
newSchema[customColumnKey] = {
displayName: null,
order: 0,
sortable: false,
divider: true,
}
}
fields.forEach(field => {
newSchema[field] = schema[field]
if (schema[field] && UnsortableTypes.indexOf(schema[field].type) !== -1) {
newSchema[field].sortable = false
}
})
return newSchema
}
const onSort = e => {
setSorting({
column: e.detail.column,
order: e.detail.order,
})
}
const onClick = e => {
if (!linkRows || !linkURL) {
return
}
const col = linkColumn || "_id"
const id = e.detail?.[col]
if (!id) {
return
}
const split = linkURL.split("/:")
routeStore.actions.navigate(`${split[0]}/${id}`, linkPeek)
}
</script>
<div use:styleable={$component.styles} class={size}>
<Table
{data}
{schema}
{loading}
{rowCount}
{quiet}
{customRenderers}
{allowSelectRows}
bind:selectedRows
allowSelectAllRows={true}
allowEditRows={false}
allowEditColumns={false}
showAutoColumns={true}
disableSorting
on:sort={onSort}
on:click={onClick}
>
<slot />
</Table>
</div>
<style>
div {
background-color: var(--spectrum-alias-background-color-secondary);
}
</style>