Merge branch 'master' into new-datepicker
This commit is contained in:
commit
bc5922e2ed
|
@ -7,11 +7,11 @@
|
||||||
export let narrower = false
|
export let narrower = false
|
||||||
export let noPadding = false
|
export let noPadding = false
|
||||||
|
|
||||||
let sidePanelVisble = false
|
let sidePanelVisible = false
|
||||||
|
|
||||||
setContext("side-panel", {
|
setContext("side-panel", {
|
||||||
open: () => (sidePanelVisble = true),
|
open: () => (sidePanelVisible = true),
|
||||||
close: () => (sidePanelVisble = false),
|
close: () => (sidePanelVisible = false),
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@ -24,9 +24,9 @@
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
id="side-panel"
|
id="side-panel"
|
||||||
class:visible={sidePanelVisble}
|
class:visible={sidePanelVisible}
|
||||||
use:clickOutside={() => {
|
use:clickOutside={() => {
|
||||||
sidePanelVisble = false
|
sidePanelVisible = false
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<slot name="side-panel" />
|
<slot name="side-panel" />
|
||||||
|
|
|
@ -6723,7 +6723,21 @@
|
||||||
"illegalChildren": ["section", "sidepanel"],
|
"illegalChildren": ["section", "sidepanel"],
|
||||||
"showEmptyState": false,
|
"showEmptyState": false,
|
||||||
"draggable": false,
|
"draggable": false,
|
||||||
"info": "Side panels are hidden by default. They will only be revealed when triggered by the 'Open Side Panel' action."
|
"info": "Side panels are hidden by default. They will only be revealed when triggered by the 'Open Side Panel' action.",
|
||||||
|
"sendEvents": true,
|
||||||
|
"settings": [
|
||||||
|
{
|
||||||
|
"type": "boolean",
|
||||||
|
"key": "clickOutsideToClose",
|
||||||
|
"label": "Click outside to close",
|
||||||
|
"defaultValue": true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "event",
|
||||||
|
"key": "onSidePanelClose",
|
||||||
|
"label": "On side panel close"
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"rowexplorer": {
|
"rowexplorer": {
|
||||||
"block": true,
|
"block": true,
|
||||||
|
|
|
@ -73,7 +73,10 @@
|
||||||
$context.device.width,
|
$context.device.width,
|
||||||
$context.device.height
|
$context.device.height
|
||||||
)
|
)
|
||||||
$: autoCloseSidePanel = !$builderStore.inBuilder && $sidePanelStore.open
|
$: autoCloseSidePanel =
|
||||||
|
!$builderStore.inBuilder &&
|
||||||
|
$sidePanelStore.open &&
|
||||||
|
$sidePanelStore.clickOutsideToClose
|
||||||
$: screenId = $builderStore.inBuilder
|
$: screenId = $builderStore.inBuilder
|
||||||
? `${$builderStore.screen?._id}-screen`
|
? `${$builderStore.screen?._id}-screen`
|
||||||
: "screen"
|
: "screen"
|
||||||
|
|
|
@ -5,6 +5,9 @@
|
||||||
const { styleable, sidePanelStore, builderStore, dndIsDragging } =
|
const { styleable, sidePanelStore, builderStore, dndIsDragging } =
|
||||||
getContext("sdk")
|
getContext("sdk")
|
||||||
|
|
||||||
|
export let sidePanelClose
|
||||||
|
export let clickOutsideToClose
|
||||||
|
|
||||||
// Automatically show and hide the side panel when inside the builder.
|
// Automatically show and hide the side panel when inside the builder.
|
||||||
// For some unknown reason, svelte reactivity breaks if we reference the
|
// For some unknown reason, svelte reactivity breaks if we reference the
|
||||||
// reactive variable "open" inside the following expression, or if we define
|
// reactive variable "open" inside the following expression, or if we define
|
||||||
|
@ -26,6 +29,10 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$: {
|
||||||
|
sidePanelStore.actions.setSidepanelState(clickOutsideToClose)
|
||||||
|
}
|
||||||
|
|
||||||
// Derive visibility
|
// Derive visibility
|
||||||
$: open = $sidePanelStore.contentId === $component.id
|
$: open = $sidePanelStore.contentId === $component.id
|
||||||
|
|
||||||
|
@ -40,6 +47,12 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleSidePanelClose = async () => {
|
||||||
|
if (sidePanelClose) {
|
||||||
|
await sidePanelClose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const showInSidePanel = (el, visible) => {
|
const showInSidePanel = (el, visible) => {
|
||||||
const update = visible => {
|
const update = visible => {
|
||||||
const target = document.getElementById("side-panel-container")
|
const target = document.getElementById("side-panel-container")
|
||||||
|
@ -51,6 +64,7 @@
|
||||||
} else {
|
} else {
|
||||||
if (target.contains(node)) {
|
if (target.contains(node)) {
|
||||||
target.removeChild(node)
|
target.removeChild(node)
|
||||||
|
handleSidePanelClose()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ import { writable, derived } from "svelte/store"
|
||||||
export const createSidePanelStore = () => {
|
export const createSidePanelStore = () => {
|
||||||
const initialState = {
|
const initialState = {
|
||||||
contentId: null,
|
contentId: null,
|
||||||
|
clickOutsideToClose: true,
|
||||||
}
|
}
|
||||||
const store = writable(initialState)
|
const store = writable(initialState)
|
||||||
const derivedStore = derived(store, $store => {
|
const derivedStore = derived(store, $store => {
|
||||||
|
@ -32,11 +33,19 @@ export const createSidePanelStore = () => {
|
||||||
}, 50)
|
}, 50)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setSidepanelState = bool => {
|
||||||
|
clearTimeout(timeout)
|
||||||
|
store.update(state => {
|
||||||
|
state.clickOutsideToClose = bool
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
}
|
||||||
return {
|
return {
|
||||||
subscribe: derivedStore.subscribe,
|
subscribe: derivedStore.subscribe,
|
||||||
actions: {
|
actions: {
|
||||||
open,
|
open,
|
||||||
close,
|
close,
|
||||||
|
setSidepanelState,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,8 @@ import {
|
||||||
FieldType,
|
FieldType,
|
||||||
RowSearchParams,
|
RowSearchParams,
|
||||||
SearchFilters,
|
SearchFilters,
|
||||||
|
SortOrder,
|
||||||
|
SortType,
|
||||||
Table,
|
Table,
|
||||||
TableSchema,
|
TableSchema,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
|
@ -62,7 +64,32 @@ describe.each([
|
||||||
class SearchAssertion {
|
class SearchAssertion {
|
||||||
constructor(private readonly query: RowSearchParams) {}
|
constructor(private readonly query: RowSearchParams) {}
|
||||||
|
|
||||||
async toFind(expectedRows: any[]) {
|
// Asserts that the query returns rows matching exactly the set of rows
|
||||||
|
// passed in. The order of the rows matters. Rows returned in an order
|
||||||
|
// different to the one passed in will cause the assertion to fail. Extra
|
||||||
|
// rows returned by the query will also cause the assertion to fail.
|
||||||
|
async toMatchExactly(expectedRows: any[]) {
|
||||||
|
const { rows: foundRows } = await config.api.row.search(table._id!, {
|
||||||
|
...this.query,
|
||||||
|
tableId: table._id!,
|
||||||
|
})
|
||||||
|
|
||||||
|
// eslint-disable-next-line jest/no-standalone-expect
|
||||||
|
expect(foundRows).toHaveLength(expectedRows.length)
|
||||||
|
// eslint-disable-next-line jest/no-standalone-expect
|
||||||
|
expect(foundRows).toEqual(
|
||||||
|
expectedRows.map((expectedRow: any) =>
|
||||||
|
expect.objectContaining(
|
||||||
|
foundRows.find(foundRow => _.isMatch(foundRow, expectedRow))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Asserts that the query returns rows matching exactly the set of rows
|
||||||
|
// passed in. The order of the rows is not important, but extra rows will
|
||||||
|
// cause the assertion to fail.
|
||||||
|
async toContainExactly(expectedRows: any[]) {
|
||||||
const { rows: foundRows } = await config.api.row.search(table._id!, {
|
const { rows: foundRows } = await config.api.row.search(table._id!, {
|
||||||
...this.query,
|
...this.query,
|
||||||
tableId: table._id!,
|
tableId: table._id!,
|
||||||
|
@ -82,8 +109,39 @@ describe.each([
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Asserts that the query returns rows matching the set of rows passed in.
|
||||||
|
// The order of the rows is not important. Extra rows will not cause the
|
||||||
|
// assertion to fail.
|
||||||
|
async toContain(expectedRows: any[]) {
|
||||||
|
const { rows: foundRows } = await config.api.row.search(table._id!, {
|
||||||
|
...this.query,
|
||||||
|
tableId: table._id!,
|
||||||
|
})
|
||||||
|
|
||||||
|
// eslint-disable-next-line jest/no-standalone-expect
|
||||||
|
expect(foundRows).toEqual(
|
||||||
|
expect.arrayContaining(
|
||||||
|
expectedRows.map((expectedRow: any) =>
|
||||||
|
expect.objectContaining(
|
||||||
|
foundRows.find(foundRow => _.isMatch(foundRow, expectedRow))
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
async toFindNothing() {
|
async toFindNothing() {
|
||||||
await this.toFind([])
|
await this.toContainExactly([])
|
||||||
|
}
|
||||||
|
|
||||||
|
async toHaveLength(length: number) {
|
||||||
|
const { rows: foundRows } = await config.api.row.search(table._id!, {
|
||||||
|
...this.query,
|
||||||
|
tableId: table._id!,
|
||||||
|
})
|
||||||
|
|
||||||
|
// eslint-disable-next-line jest/no-standalone-expect
|
||||||
|
expect(foundRows).toHaveLength(length)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,28 +163,33 @@ describe.each([
|
||||||
|
|
||||||
describe("misc", () => {
|
describe("misc", () => {
|
||||||
it("should return all if no query is passed", () =>
|
it("should return all if no query is passed", () =>
|
||||||
expectSearch({} as RowSearchParams).toFind([
|
expectSearch({} as RowSearchParams).toContainExactly([
|
||||||
{ name: "foo" },
|
{ name: "foo" },
|
||||||
{ name: "bar" },
|
{ name: "bar" },
|
||||||
]))
|
]))
|
||||||
|
|
||||||
it("should return all if empty query is passed", () =>
|
it("should return all if empty query is passed", () =>
|
||||||
expectQuery({}).toFind([{ name: "foo" }, { name: "bar" }]))
|
expectQuery({}).toContainExactly([{ name: "foo" }, { name: "bar" }]))
|
||||||
|
|
||||||
it("should return all if onEmptyFilter is RETURN_ALL", () =>
|
it("should return all if onEmptyFilter is RETURN_ALL", () =>
|
||||||
expectQuery({
|
expectQuery({
|
||||||
onEmptyFilter: EmptyFilterOption.RETURN_ALL,
|
onEmptyFilter: EmptyFilterOption.RETURN_ALL,
|
||||||
}).toFind([{ name: "foo" }, { name: "bar" }]))
|
}).toContainExactly([{ name: "foo" }, { name: "bar" }]))
|
||||||
|
|
||||||
it("should return nothing if onEmptyFilter is RETURN_NONE", () =>
|
it("should return nothing if onEmptyFilter is RETURN_NONE", () =>
|
||||||
expectQuery({
|
expectQuery({
|
||||||
onEmptyFilter: EmptyFilterOption.RETURN_NONE,
|
onEmptyFilter: EmptyFilterOption.RETURN_NONE,
|
||||||
}).toFindNothing())
|
}).toFindNothing())
|
||||||
|
|
||||||
|
it("should respect limit", () =>
|
||||||
|
expectSearch({ limit: 1, paginate: true, query: {} }).toHaveLength(1))
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("equal", () => {
|
describe("equal", () => {
|
||||||
it("successfully finds a row", () =>
|
it("successfully finds a row", () =>
|
||||||
expectQuery({ equal: { name: "foo" } }).toFind([{ name: "foo" }]))
|
expectQuery({ equal: { name: "foo" } }).toContainExactly([
|
||||||
|
{ name: "foo" },
|
||||||
|
]))
|
||||||
|
|
||||||
it("fails to find nonexistent row", () =>
|
it("fails to find nonexistent row", () =>
|
||||||
expectQuery({ equal: { name: "none" } }).toFindNothing())
|
expectQuery({ equal: { name: "none" } }).toFindNothing())
|
||||||
|
@ -134,15 +197,21 @@ describe.each([
|
||||||
|
|
||||||
describe("notEqual", () => {
|
describe("notEqual", () => {
|
||||||
it("successfully finds a row", () =>
|
it("successfully finds a row", () =>
|
||||||
expectQuery({ notEqual: { name: "foo" } }).toFind([{ name: "bar" }]))
|
expectQuery({ notEqual: { name: "foo" } }).toContainExactly([
|
||||||
|
{ name: "bar" },
|
||||||
|
]))
|
||||||
|
|
||||||
it("fails to find nonexistent row", () =>
|
it("fails to find nonexistent row", () =>
|
||||||
expectQuery({ notEqual: { name: "bar" } }).toFind([{ name: "foo" }]))
|
expectQuery({ notEqual: { name: "bar" } }).toContainExactly([
|
||||||
|
{ name: "foo" },
|
||||||
|
]))
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("oneOf", () => {
|
describe("oneOf", () => {
|
||||||
it("successfully finds a row", () =>
|
it("successfully finds a row", () =>
|
||||||
expectQuery({ oneOf: { name: ["foo"] } }).toFind([{ name: "foo" }]))
|
expectQuery({ oneOf: { name: ["foo"] } }).toContainExactly([
|
||||||
|
{ name: "foo" },
|
||||||
|
]))
|
||||||
|
|
||||||
it("fails to find nonexistent row", () =>
|
it("fails to find nonexistent row", () =>
|
||||||
expectQuery({ oneOf: { name: ["none"] } }).toFindNothing())
|
expectQuery({ oneOf: { name: ["none"] } }).toFindNothing())
|
||||||
|
@ -150,11 +219,47 @@ describe.each([
|
||||||
|
|
||||||
describe("fuzzy", () => {
|
describe("fuzzy", () => {
|
||||||
it("successfully finds a row", () =>
|
it("successfully finds a row", () =>
|
||||||
expectQuery({ fuzzy: { name: "oo" } }).toFind([{ name: "foo" }]))
|
expectQuery({ fuzzy: { name: "oo" } }).toContainExactly([
|
||||||
|
{ name: "foo" },
|
||||||
|
]))
|
||||||
|
|
||||||
it("fails to find nonexistent row", () =>
|
it("fails to find nonexistent row", () =>
|
||||||
expectQuery({ fuzzy: { name: "none" } }).toFindNothing())
|
expectQuery({ fuzzy: { name: "none" } }).toFindNothing())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("sort", () => {
|
||||||
|
it("sorts ascending", () =>
|
||||||
|
expectSearch({
|
||||||
|
query: {},
|
||||||
|
sort: "name",
|
||||||
|
sortOrder: SortOrder.ASCENDING,
|
||||||
|
}).toMatchExactly([{ name: "bar" }, { name: "foo" }]))
|
||||||
|
|
||||||
|
it("sorts descending", () =>
|
||||||
|
expectSearch({
|
||||||
|
query: {},
|
||||||
|
sort: "name",
|
||||||
|
sortOrder: SortOrder.DESCENDING,
|
||||||
|
}).toMatchExactly([{ name: "foo" }, { name: "bar" }]))
|
||||||
|
|
||||||
|
describe("sortType STRING", () => {
|
||||||
|
it("sorts ascending", () =>
|
||||||
|
expectSearch({
|
||||||
|
query: {},
|
||||||
|
sort: "name",
|
||||||
|
sortType: SortType.STRING,
|
||||||
|
sortOrder: SortOrder.ASCENDING,
|
||||||
|
}).toMatchExactly([{ name: "bar" }, { name: "foo" }]))
|
||||||
|
|
||||||
|
it("sorts descending", () =>
|
||||||
|
expectSearch({
|
||||||
|
query: {},
|
||||||
|
sort: "name",
|
||||||
|
sortType: SortType.STRING,
|
||||||
|
sortOrder: SortOrder.DESCENDING,
|
||||||
|
}).toMatchExactly([{ name: "foo" }, { name: "bar" }]))
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("numbers", () => {
|
describe("numbers", () => {
|
||||||
|
@ -167,7 +272,7 @@ describe.each([
|
||||||
|
|
||||||
describe("equal", () => {
|
describe("equal", () => {
|
||||||
it("successfully finds a row", () =>
|
it("successfully finds a row", () =>
|
||||||
expectQuery({ equal: { age: 1 } }).toFind([{ age: 1 }]))
|
expectQuery({ equal: { age: 1 } }).toContainExactly([{ age: 1 }]))
|
||||||
|
|
||||||
it("fails to find nonexistent row", () =>
|
it("fails to find nonexistent row", () =>
|
||||||
expectQuery({ equal: { age: 2 } }).toFindNothing())
|
expectQuery({ equal: { age: 2 } }).toFindNothing())
|
||||||
|
@ -175,15 +280,15 @@ describe.each([
|
||||||
|
|
||||||
describe("notEqual", () => {
|
describe("notEqual", () => {
|
||||||
it("successfully finds a row", () =>
|
it("successfully finds a row", () =>
|
||||||
expectQuery({ notEqual: { age: 1 } }).toFind([{ age: 10 }]))
|
expectQuery({ notEqual: { age: 1 } }).toContainExactly([{ age: 10 }]))
|
||||||
|
|
||||||
it("fails to find nonexistent row", () =>
|
it("fails to find nonexistent row", () =>
|
||||||
expectQuery({ notEqual: { age: 10 } }).toFind([{ age: 1 }]))
|
expectQuery({ notEqual: { age: 10 } }).toContainExactly([{ age: 1 }]))
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("oneOf", () => {
|
describe("oneOf", () => {
|
||||||
it("successfully finds a row", () =>
|
it("successfully finds a row", () =>
|
||||||
expectQuery({ oneOf: { age: [1] } }).toFind([{ age: 1 }]))
|
expectQuery({ oneOf: { age: [1] } }).toContainExactly([{ age: 1 }]))
|
||||||
|
|
||||||
it("fails to find nonexistent row", () =>
|
it("fails to find nonexistent row", () =>
|
||||||
expectQuery({ oneOf: { age: [2] } }).toFindNothing())
|
expectQuery({ oneOf: { age: [2] } }).toFindNothing())
|
||||||
|
@ -193,17 +298,51 @@ describe.each([
|
||||||
it("successfully finds a row", () =>
|
it("successfully finds a row", () =>
|
||||||
expectQuery({
|
expectQuery({
|
||||||
range: { age: { low: 1, high: 5 } },
|
range: { age: { low: 1, high: 5 } },
|
||||||
}).toFind([{ age: 1 }]))
|
}).toContainExactly([{ age: 1 }]))
|
||||||
|
|
||||||
it("successfully finds multiple rows", () =>
|
it("successfully finds multiple rows", () =>
|
||||||
expectQuery({
|
expectQuery({
|
||||||
range: { age: { low: 1, high: 10 } },
|
range: { age: { low: 1, high: 10 } },
|
||||||
}).toFind([{ age: 1 }, { age: 10 }]))
|
}).toContainExactly([{ age: 1 }, { age: 10 }]))
|
||||||
|
|
||||||
it("successfully finds a row with a high bound", () =>
|
it("successfully finds a row with a high bound", () =>
|
||||||
expectQuery({
|
expectQuery({
|
||||||
range: { age: { low: 5, high: 10 } },
|
range: { age: { low: 5, high: 10 } },
|
||||||
}).toFind([{ age: 10 }]))
|
}).toContainExactly([{ age: 10 }]))
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("sort", () => {
|
||||||
|
it("sorts ascending", () =>
|
||||||
|
expectSearch({
|
||||||
|
query: {},
|
||||||
|
sort: "age",
|
||||||
|
sortOrder: SortOrder.ASCENDING,
|
||||||
|
}).toMatchExactly([{ age: 1 }, { age: 10 }]))
|
||||||
|
|
||||||
|
it("sorts descending", () =>
|
||||||
|
expectSearch({
|
||||||
|
query: {},
|
||||||
|
sort: "age",
|
||||||
|
sortOrder: SortOrder.DESCENDING,
|
||||||
|
}).toMatchExactly([{ age: 10 }, { age: 1 }]))
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("sortType NUMBER", () => {
|
||||||
|
it("sorts ascending", () =>
|
||||||
|
expectSearch({
|
||||||
|
query: {},
|
||||||
|
sort: "age",
|
||||||
|
sortType: SortType.NUMBER,
|
||||||
|
sortOrder: SortOrder.ASCENDING,
|
||||||
|
}).toMatchExactly([{ age: 1 }, { age: 10 }]))
|
||||||
|
|
||||||
|
it("sorts descending", () =>
|
||||||
|
expectSearch({
|
||||||
|
query: {},
|
||||||
|
sort: "age",
|
||||||
|
sortType: SortType.NUMBER,
|
||||||
|
sortOrder: SortOrder.DESCENDING,
|
||||||
|
}).toMatchExactly([{ age: 10 }, { age: 1 }]))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -223,7 +362,9 @@ describe.each([
|
||||||
|
|
||||||
describe("equal", () => {
|
describe("equal", () => {
|
||||||
it("successfully finds a row", () =>
|
it("successfully finds a row", () =>
|
||||||
expectQuery({ equal: { dob: JAN_1ST } }).toFind([{ dob: JAN_1ST }]))
|
expectQuery({ equal: { dob: JAN_1ST } }).toContainExactly([
|
||||||
|
{ dob: JAN_1ST },
|
||||||
|
]))
|
||||||
|
|
||||||
it("fails to find nonexistent row", () =>
|
it("fails to find nonexistent row", () =>
|
||||||
expectQuery({ equal: { dob: JAN_2ND } }).toFindNothing())
|
expectQuery({ equal: { dob: JAN_2ND } }).toFindNothing())
|
||||||
|
@ -231,15 +372,21 @@ describe.each([
|
||||||
|
|
||||||
describe("notEqual", () => {
|
describe("notEqual", () => {
|
||||||
it("successfully finds a row", () =>
|
it("successfully finds a row", () =>
|
||||||
expectQuery({ notEqual: { dob: JAN_1ST } }).toFind([{ dob: JAN_10TH }]))
|
expectQuery({ notEqual: { dob: JAN_1ST } }).toContainExactly([
|
||||||
|
{ dob: JAN_10TH },
|
||||||
|
]))
|
||||||
|
|
||||||
it("fails to find nonexistent row", () =>
|
it("fails to find nonexistent row", () =>
|
||||||
expectQuery({ notEqual: { dob: JAN_10TH } }).toFind([{ dob: JAN_1ST }]))
|
expectQuery({ notEqual: { dob: JAN_10TH } }).toContainExactly([
|
||||||
|
{ dob: JAN_1ST },
|
||||||
|
]))
|
||||||
})
|
})
|
||||||
|
|
||||||
describe("oneOf", () => {
|
describe("oneOf", () => {
|
||||||
it("successfully finds a row", () =>
|
it("successfully finds a row", () =>
|
||||||
expectQuery({ oneOf: { dob: [JAN_1ST] } }).toFind([{ dob: JAN_1ST }]))
|
expectQuery({ oneOf: { dob: [JAN_1ST] } }).toContainExactly([
|
||||||
|
{ dob: JAN_1ST },
|
||||||
|
]))
|
||||||
|
|
||||||
it("fails to find nonexistent row", () =>
|
it("fails to find nonexistent row", () =>
|
||||||
expectQuery({ oneOf: { dob: [JAN_2ND] } }).toFindNothing())
|
expectQuery({ oneOf: { dob: [JAN_2ND] } }).toFindNothing())
|
||||||
|
@ -249,17 +396,51 @@ describe.each([
|
||||||
it("successfully finds a row", () =>
|
it("successfully finds a row", () =>
|
||||||
expectQuery({
|
expectQuery({
|
||||||
range: { dob: { low: JAN_1ST, high: JAN_5TH } },
|
range: { dob: { low: JAN_1ST, high: JAN_5TH } },
|
||||||
}).toFind([{ dob: JAN_1ST }]))
|
}).toContainExactly([{ dob: JAN_1ST }]))
|
||||||
|
|
||||||
it("successfully finds multiple rows", () =>
|
it("successfully finds multiple rows", () =>
|
||||||
expectQuery({
|
expectQuery({
|
||||||
range: { dob: { low: JAN_1ST, high: JAN_10TH } },
|
range: { dob: { low: JAN_1ST, high: JAN_10TH } },
|
||||||
}).toFind([{ dob: JAN_1ST }, { dob: JAN_10TH }]))
|
}).toContainExactly([{ dob: JAN_1ST }, { dob: JAN_10TH }]))
|
||||||
|
|
||||||
it("successfully finds a row with a high bound", () =>
|
it("successfully finds a row with a high bound", () =>
|
||||||
expectQuery({
|
expectQuery({
|
||||||
range: { dob: { low: JAN_5TH, high: JAN_10TH } },
|
range: { dob: { low: JAN_5TH, high: JAN_10TH } },
|
||||||
}).toFind([{ dob: JAN_10TH }]))
|
}).toContainExactly([{ dob: JAN_10TH }]))
|
||||||
|
})
|
||||||
|
|
||||||
|
describe("sort", () => {
|
||||||
|
it("sorts ascending", () =>
|
||||||
|
expectSearch({
|
||||||
|
query: {},
|
||||||
|
sort: "dob",
|
||||||
|
sortOrder: SortOrder.ASCENDING,
|
||||||
|
}).toMatchExactly([{ dob: JAN_1ST }, { dob: JAN_10TH }]))
|
||||||
|
|
||||||
|
it("sorts descending", () =>
|
||||||
|
expectSearch({
|
||||||
|
query: {},
|
||||||
|
sort: "dob",
|
||||||
|
sortOrder: SortOrder.DESCENDING,
|
||||||
|
}).toMatchExactly([{ dob: JAN_10TH }, { dob: JAN_1ST }]))
|
||||||
|
|
||||||
|
describe("sortType STRING", () => {
|
||||||
|
it("sorts ascending", () =>
|
||||||
|
expectSearch({
|
||||||
|
query: {},
|
||||||
|
sort: "dob",
|
||||||
|
sortType: SortType.STRING,
|
||||||
|
sortOrder: SortOrder.ASCENDING,
|
||||||
|
}).toMatchExactly([{ dob: JAN_1ST }, { dob: JAN_10TH }]))
|
||||||
|
|
||||||
|
it("sorts descending", () =>
|
||||||
|
expectSearch({
|
||||||
|
query: {},
|
||||||
|
sort: "dob",
|
||||||
|
sortType: SortType.STRING,
|
||||||
|
sortOrder: SortOrder.DESCENDING,
|
||||||
|
}).toMatchExactly([{ dob: JAN_10TH }, { dob: JAN_1ST }]))
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
|
@ -132,7 +132,7 @@ export async function search(
|
||||||
type: "row",
|
type: "row",
|
||||||
}
|
}
|
||||||
|
|
||||||
if (params.sort && !params.sortType) {
|
if (params.sort) {
|
||||||
const sortField = table.schema[params.sort]
|
const sortField = table.schema[params.sort]
|
||||||
const sortType =
|
const sortType =
|
||||||
sortField.type === FieldType.NUMBER ? SortType.NUMBER : SortType.STRING
|
sortField.type === FieldType.NUMBER ? SortType.NUMBER : SortType.STRING
|
||||||
|
|
Loading…
Reference in New Issue