Add support for tables updating server-side sorting

This commit is contained in:
Andrew Kingston 2021-11-03 15:26:15 +00:00
parent d054d496be
commit 512ed5aa2a
3 changed files with 69 additions and 15 deletions

View File

@ -35,28 +35,36 @@
let pageNumber = 0
let query = null
// Sorting can be overridden at run time, so we can't use the prop directly
let currentSortColumn = sortColumn
let currentSortOrder = sortOrder
$: query = buildLuceneQuery(filter)
$: internalTable = dataSource?.type === "table"
$: nestedProvider = dataSource?.type === "provider"
$: hasNextPage = bookmarks[pageNumber + 1] != null
$: hasPrevPage = pageNumber > 0
$: getSchema(dataSource)
$: sortType = getSortType(schema, sortColumn)
$: {
$: sortType = getSortType(schema, currentSortColumn)
// Wait until schema loads before loading data, so that we can determine
// the correct sort type first time
$: {
if (schemaLoaded) {
fetchData(
dataSource,
schema,
query,
limit,
sortColumn,
sortOrder,
currentSortColumn,
currentSortOrder,
sortType,
paginate
)
}
}
// Reactively filter and sort rows if required
$: {
if (internalTable) {
// Internal tables are already processed server-side
@ -65,10 +73,17 @@
// For anything else we use client-side implementations to filter, sort
// and limit
const filtered = luceneQuery(allRows, query)
const sorted = luceneSort(filtered, sortColumn, sortOrder, sortType)
const sorted = luceneSort(
filtered,
currentSortColumn,
currentSortOrder,
sortType
)
rows = luceneLimit(sorted, limit)
}
}
// Build our action context
$: actions = [
{
type: ActionTypes.RefreshDatasource,
@ -79,7 +94,20 @@
type: ActionTypes.SetDataProviderQuery,
callback: newQuery => (query = newQuery),
},
{
type: ActionTypes.SetDataProviderSorting,
callback: ({ column, order }) => {
if (column) {
currentSortColumn = column
}
if (order) {
currentSortOrder = order
}
},
},
]
// Build our data context
$: dataContext = {
rows,
schema,
@ -88,7 +116,11 @@
// Undocumented properties. These aren't supposed to be used in builder
// bindings, but are used internally by other components
id: $component?.id,
state: { query },
state: {
query,
sortColumn: currentSortColumn,
sortOrder: currentSortOrder,
},
loaded,
}
@ -104,10 +136,11 @@
if (schemaLoaded && !nestedProvider) {
fetchData(
dataSource,
schema,
query,
limit,
sortColumn,
sortOrder,
currentSortColumn,
currentSortOrder,
sortType,
paginate
)
@ -116,6 +149,7 @@
const fetchData = async (
dataSource,
schema,
query,
limit,
sortColumn,
@ -125,12 +159,16 @@
) => {
loading = true
if (dataSource?.type === "table") {
// Sanity check sort column, as using a non-existant column will prevent
// results coming back at all
const sort = schema?.[sortColumn] ? sortColumn : undefined
// For internal tables we use server-side processing
const res = await API.searchTable({
tableId: dataSource.tableId,
query,
limit,
sort: sortColumn,
sort,
sortOrder: sortOrder?.toLowerCase() ?? "ascending",
sortType,
paginate,
@ -181,13 +219,14 @@
if (!hasNextPage || !internalTable) {
return
}
const sort = schema?.[currentSortColumn] ? currentSortColumn : undefined
const res = await API.searchTable({
tableId: dataSource?.tableId,
query,
bookmark: bookmarks[pageNumber + 1],
limit,
sort: sortColumn,
sortOrder: sortOrder?.toLowerCase() ?? "ascending",
sort,
sortOrder: currentSortOrder?.toLowerCase() ?? "ascending",
sortType,
paginate: true,
})
@ -202,13 +241,14 @@
if (!hasPrevPage || !internalTable) {
return
}
const sort = schema?.[currentSortColumn] ? currentSortColumn : undefined
const res = await API.searchTable({
tableId: dataSource?.tableId,
query,
bookmark: bookmarks[pageNumber - 1],
limit,
sort: sortColumn,
sortOrder: sortOrder?.toLowerCase() ?? "ascending",
sort,
sortOrder: currentSortOrder?.toLowerCase() ?? "ascending",
sortType,
paginate: true,
})

View File

@ -11,7 +11,11 @@
export let size
const component = getContext("component")
const { styleable } = getContext("sdk")
const { styleable, getAction, ActionTypes } = getContext("sdk")
const setSorting = getAction(
dataProvider?.id,
ActionTypes.SetDataProviderSorting
)
const customColumnKey = `custom-${Math.random()}`
const customRenderers = [
{
@ -70,6 +74,13 @@
})
return newSchema
}
const onSort = e => {
setSorting({
column: e.detail.column,
order: e.detail.order,
})
}
</script>
<div use:styleable={$component.styles} class={size}>
@ -84,6 +95,8 @@
allowEditRows={false}
allowEditColumns={false}
showAutoColumns={true}
disableSorting
on:sort={onSort}
>
<slot />
</Table>

View File

@ -6,6 +6,7 @@ export const ActionTypes = {
ValidateForm: "ValidateForm",
RefreshDatasource: "RefreshDatasource",
SetDataProviderQuery: "SetDataProviderQuery",
SetDataProviderSorting: "SetDataProviderSorting",
ClearForm: "ClearForm",
ChangeFormStep: "ChangeFormStep",
}