Allow overriding default sort
This commit is contained in:
parent
4e646bb463
commit
1760980aad
|
@ -2,7 +2,13 @@ import { quotas } from "@budibase/pro"
|
||||||
import * as internal from "./internal"
|
import * as internal from "./internal"
|
||||||
import * as external from "./external"
|
import * as external from "./external"
|
||||||
import { isExternalTable } from "../../../integrations/utils"
|
import { isExternalTable } from "../../../integrations/utils"
|
||||||
import { Ctx, SearchResponse } from "@budibase/types"
|
import {
|
||||||
|
Ctx,
|
||||||
|
SearchResponse,
|
||||||
|
SortOrder,
|
||||||
|
SortType,
|
||||||
|
ViewV2,
|
||||||
|
} from "@budibase/types"
|
||||||
import * as utils from "./utils"
|
import * as utils from "./utils"
|
||||||
import { gridSocket } from "../../../websockets"
|
import { gridSocket } from "../../../websockets"
|
||||||
import sdk from "../../../sdk"
|
import sdk from "../../../sdk"
|
||||||
|
@ -146,6 +152,45 @@ export async function search(ctx: any) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getSortOptions(
|
||||||
|
ctx: Ctx,
|
||||||
|
view: ViewV2
|
||||||
|
):
|
||||||
|
| {
|
||||||
|
sort: string
|
||||||
|
sortOrder?: SortOrder
|
||||||
|
sortType?: SortType
|
||||||
|
}
|
||||||
|
| undefined {
|
||||||
|
const { sort_column, sort_order, sort_type } = ctx.query
|
||||||
|
if (Array.isArray(sort_column)) {
|
||||||
|
ctx.throw(404, "sort_column cannot be an array")
|
||||||
|
}
|
||||||
|
if (Array.isArray(sort_order)) {
|
||||||
|
ctx.throw(404, "sort_order cannot be an array")
|
||||||
|
}
|
||||||
|
if (Array.isArray(sort_type)) {
|
||||||
|
ctx.throw(404, "sort_type cannot be an array")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sort_column) {
|
||||||
|
return {
|
||||||
|
sort: sort_column,
|
||||||
|
sortOrder: sort_order as SortOrder,
|
||||||
|
sortType: sort_type as SortType,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (view.sort) {
|
||||||
|
return {
|
||||||
|
sort: view.sort.field,
|
||||||
|
sortOrder: view.sort.order,
|
||||||
|
sortType: view.sort.type,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
export async function searchView(ctx: Ctx<void, SearchResponse>) {
|
export async function searchView(ctx: Ctx<void, SearchResponse>) {
|
||||||
const { viewId } = ctx.params
|
const { viewId } = ctx.params
|
||||||
|
|
||||||
|
@ -160,9 +205,7 @@ export async function searchView(ctx: Ctx<void, SearchResponse>) {
|
||||||
sdk.rows.search({
|
sdk.rows.search({
|
||||||
tableId: view.tableId,
|
tableId: view.tableId,
|
||||||
query: view.query || {},
|
query: view.query || {},
|
||||||
sort: view.sort?.field,
|
...getSortOptions(ctx, view),
|
||||||
sortOrder: view.sort?.order,
|
|
||||||
sortType: view.sort?.type,
|
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
datasourceId: view.tableId,
|
datasourceId: view.tableId,
|
||||||
|
|
|
@ -755,7 +755,14 @@ describe("/rows", () => {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
it.each([
|
const sortTestOptions: [
|
||||||
|
{
|
||||||
|
field: string
|
||||||
|
order?: SortOrder
|
||||||
|
type?: SortType
|
||||||
|
},
|
||||||
|
string[]
|
||||||
|
][] = [
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
field: "name",
|
field: "name",
|
||||||
|
@ -815,31 +822,76 @@ describe("/rows", () => {
|
||||||
},
|
},
|
||||||
["Bob", "Charly", "Alice", "Danny"],
|
["Bob", "Charly", "Alice", "Danny"],
|
||||||
],
|
],
|
||||||
])("allow sorting (%s)", async (sortParams, expected) => {
|
]
|
||||||
await config.createTable(userTable())
|
|
||||||
const users = [
|
it.each(sortTestOptions)(
|
||||||
{ name: "Alice", age: 25 },
|
"allow sorting (%s)",
|
||||||
{ name: "Bob", age: 30 },
|
async (sortParams, expected) => {
|
||||||
{ name: "Charly", age: 27 },
|
await config.createTable(userTable())
|
||||||
{ name: "Danny", age: 15 },
|
const users = [
|
||||||
]
|
{ name: "Alice", age: 25 },
|
||||||
for (const user of users) {
|
{ name: "Bob", age: 30 },
|
||||||
await config.createRow({
|
{ name: "Charly", age: 27 },
|
||||||
tableId: config.table!._id,
|
{ name: "Danny", age: 15 },
|
||||||
...user,
|
]
|
||||||
|
for (const user of users) {
|
||||||
|
await config.createRow({
|
||||||
|
tableId: config.table!._id,
|
||||||
|
...user,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
const createViewResponse = await config.api.viewV2.create({
|
||||||
|
sort: sortParams,
|
||||||
|
})
|
||||||
|
|
||||||
|
const response = await config.api.viewV2.search(createViewResponse.id)
|
||||||
|
|
||||||
|
expect(response.body.rows).toHaveLength(4)
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
rows: expected.map(name => expect.objectContaining({ name })),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
)
|
||||||
|
|
||||||
const createViewResponse = await config.api.viewV2.create({
|
it.each(sortTestOptions)(
|
||||||
sort: sortParams,
|
"allow override the default view sorting (%s)",
|
||||||
})
|
async (sortParams, expected) => {
|
||||||
|
await config.createTable(userTable())
|
||||||
|
const users = [
|
||||||
|
{ name: "Alice", age: 25 },
|
||||||
|
{ name: "Bob", age: 30 },
|
||||||
|
{ name: "Charly", age: 27 },
|
||||||
|
{ name: "Danny", age: 15 },
|
||||||
|
]
|
||||||
|
for (const user of users) {
|
||||||
|
await config.createRow({
|
||||||
|
tableId: config.table!._id,
|
||||||
|
...user,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const response = await config.api.viewV2.search(createViewResponse.id)
|
const createViewResponse = await config.api.viewV2.create({
|
||||||
|
sort: {
|
||||||
|
field: "name",
|
||||||
|
order: SortOrder.ASCENDING,
|
||||||
|
type: SortType.STRING,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
expect(response.body.rows).toHaveLength(4)
|
const response = await config.api.viewV2.search(createViewResponse.id, {
|
||||||
expect(response.body).toEqual({
|
sort: {
|
||||||
rows: expected.map(name => expect.objectContaining({ name })),
|
column: sortParams.field,
|
||||||
})
|
order: sortParams.order,
|
||||||
})
|
type: sortParams.type,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
expect(response.body.rows).toHaveLength(4)
|
||||||
|
expect(response.body).toEqual({
|
||||||
|
rows: expected.map(name => expect.objectContaining({ name })),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { ViewV2 } from "@budibase/types"
|
import { SortOrder, SortType, ViewV2 } from "@budibase/types"
|
||||||
import TestConfiguration from "../TestConfiguration"
|
import TestConfiguration from "../TestConfiguration"
|
||||||
import { TestAPI } from "./base"
|
import { TestAPI } from "./base"
|
||||||
import { generator } from "@budibase/backend-core/tests"
|
import { generator } from "@budibase/backend-core/tests"
|
||||||
|
@ -38,9 +38,33 @@ export class ViewV2API extends TestAPI {
|
||||||
.expect(expectStatus)
|
.expect(expectStatus)
|
||||||
}
|
}
|
||||||
|
|
||||||
search = async (viewId: string, { expectStatus } = { expectStatus: 200 }) => {
|
search = async (
|
||||||
|
viewId: string,
|
||||||
|
options?: {
|
||||||
|
sort: {
|
||||||
|
column: string
|
||||||
|
order?: SortOrder
|
||||||
|
type?: SortType
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{ expectStatus } = { expectStatus: 200 }
|
||||||
|
) => {
|
||||||
|
const qs: [string, any][] = []
|
||||||
|
if (options?.sort.column) {
|
||||||
|
qs.push(["sort_column", options.sort.column])
|
||||||
|
}
|
||||||
|
if (options?.sort.order) {
|
||||||
|
qs.push(["sort_order", options.sort.order])
|
||||||
|
}
|
||||||
|
if (options?.sort.type) {
|
||||||
|
qs.push(["sort_type", options.sort.type])
|
||||||
|
}
|
||||||
|
let url = `/api/v2/views/${viewId}/search`
|
||||||
|
if (qs.length) {
|
||||||
|
url += "?" + qs.map(q => q.join("=")).join("&")
|
||||||
|
}
|
||||||
return this.request
|
return this.request
|
||||||
.get(`/api/v2/views/${viewId}/search`)
|
.get(url)
|
||||||
.set(this.config.defaultHeaders())
|
.set(this.config.defaultHeaders())
|
||||||
.expect("Content-Type", /json/)
|
.expect("Content-Type", /json/)
|
||||||
.expect(expectStatus)
|
.expect(expectStatus)
|
||||||
|
|
Loading…
Reference in New Issue