diff --git a/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/GridColumnConfiguration.svelte b/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/GridColumnConfiguration.svelte index 439bf5e261..19d61e1f2a 100644 --- a/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/GridColumnConfiguration.svelte +++ b/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/GridColumnConfiguration.svelte @@ -34,7 +34,7 @@ $selectedScreen, datasource )?.table?.primaryDisplay - $: schema = getSchema(selectedScreen, datasource) + $: schema = getSchema($selectedScreen, datasource) $: columns = getColumns({ columns: value, schema, diff --git a/packages/builder/src/constants/backend/index.js b/packages/builder/src/constants/backend/index.js index e3888a52e0..ffa6ef36c6 100644 --- a/packages/builder/src/constants/backend/index.js +++ b/packages/builder/src/constants/backend/index.js @@ -5,6 +5,9 @@ import { AutoFieldSubType, Hosting, } from "@budibase/types" +import { Constants } from "@budibase/frontend-core" + +const { TypeIconMap } = Constants export { RelationshipType } from "@budibase/types" @@ -22,7 +25,7 @@ export const FIELDS = { STRING: { name: "Text", type: FieldType.STRING, - icon: "Text", + icon: TypeIconMap[FieldType.STRING], constraints: { type: "string", length: {}, @@ -32,7 +35,7 @@ export const FIELDS = { BARCODEQR: { name: "Barcode/QR", type: FieldType.BARCODEQR, - icon: "Camera", + icon: TypeIconMap[FieldType.BARCODEQR], constraints: { type: "string", length: {}, @@ -42,7 +45,7 @@ export const FIELDS = { LONGFORM: { name: "Long Form Text", type: FieldType.LONGFORM, - icon: "TextAlignLeft", + icon: TypeIconMap[FieldType.LONGFORM], constraints: { type: "string", length: {}, @@ -52,7 +55,7 @@ export const FIELDS = { OPTIONS: { name: "Options", type: FieldType.OPTIONS, - icon: "Dropdown", + icon: TypeIconMap[FieldType.OPTIONS], constraints: { type: "string", presence: false, @@ -62,7 +65,7 @@ export const FIELDS = { ARRAY: { name: "Multi-select", type: FieldType.ARRAY, - icon: "Duplicate", + icon: TypeIconMap[FieldType.ARRAY], constraints: { type: "array", presence: false, @@ -72,7 +75,7 @@ export const FIELDS = { NUMBER: { name: "Number", type: FieldType.NUMBER, - icon: "123", + icon: TypeIconMap[FieldType.NUMBER], constraints: { type: "number", presence: false, @@ -82,12 +85,12 @@ export const FIELDS = { BIGINT: { name: "BigInt", type: FieldType.BIGINT, - icon: "TagBold", + icon: TypeIconMap[FieldType.BIGINT], }, BOOLEAN: { name: "Boolean", type: FieldType.BOOLEAN, - icon: "Boolean", + icon: TypeIconMap[FieldType.BOOLEAN], constraints: { type: "boolean", presence: false, @@ -96,7 +99,7 @@ export const FIELDS = { DATETIME: { name: "Date/Time", type: FieldType.DATETIME, - icon: "Calendar", + icon: TypeIconMap[FieldType.DATETIME], constraints: { type: "string", length: {}, @@ -110,7 +113,7 @@ export const FIELDS = { ATTACHMENT_SINGLE: { name: "Attachment", type: FieldType.ATTACHMENT_SINGLE, - icon: "Document", + icon: TypeIconMap[FieldType.ATTACHMENT_SINGLE], constraints: { presence: false, }, @@ -118,7 +121,7 @@ export const FIELDS = { ATTACHMENTS: { name: "Attachment List", type: FieldType.ATTACHMENTS, - icon: "AppleFiles", + icon: TypeIconMap[FieldType.ATTACHMENTS], constraints: { type: "array", presence: false, @@ -127,7 +130,7 @@ export const FIELDS = { LINK: { name: "Relationship", type: FieldType.LINK, - icon: "Link", + icon: TypeIconMap[FieldType.LINK], constraints: { type: "array", presence: false, @@ -136,19 +139,19 @@ export const FIELDS = { AUTO: { name: "Auto Column", type: FieldType.AUTO, - icon: "MagicWand", + icon: TypeIconMap[FieldType.AUTO], constraints: {}, }, FORMULA: { name: "Formula", type: FieldType.FORMULA, - icon: "Calculator", + icon: TypeIconMap[FieldType.FORMULA], constraints: {}, }, JSON: { name: "JSON", type: FieldType.JSON, - icon: "Brackets", + icon: TypeIconMap[FieldType.JSON], constraints: { type: "object", presence: false, @@ -158,13 +161,13 @@ export const FIELDS = { name: "User", type: FieldType.BB_REFERENCE, subtype: FieldSubtype.USER, - icon: "User", + icon: TypeIconMap[FieldType.USER], }, USERS: { name: "Users", type: FieldType.BB_REFERENCE, subtype: FieldSubtype.USERS, - icon: "User", + icon: TypeIconMap[FieldType.USERS], constraints: { type: "array", }, diff --git a/packages/builder/src/stores/builder/tests/sortedIntegrations.test.js b/packages/builder/src/stores/builder/tests/sortedIntegrations.test.js index 9b430b1621..d57aa19148 100644 --- a/packages/builder/src/stores/builder/tests/sortedIntegrations.test.js +++ b/packages/builder/src/stores/builder/tests/sortedIntegrations.test.js @@ -6,7 +6,10 @@ import { derived } from "svelte/store" import { integrations } from "stores/builder/integrations" vi.mock("svelte/store", () => ({ - derived: vi.fn(() => {}), + derived: vi.fn(), + writable: vi.fn(() => ({ + subscribe: vi.fn(), + })), })) vi.mock("stores/builder/integrations", () => ({ integrations: vi.fn() })) diff --git a/packages/client/manifest.json b/packages/client/manifest.json index 46df1fcad2..7689907e3c 100644 --- a/packages/client/manifest.json +++ b/packages/client/manifest.json @@ -6102,7 +6102,7 @@ "block": true, "name": "Repeater Block", "icon": "ViewList", - "illegalChildren": ["section"], + "illegalChildren": ["section", "rowexplorer"], "hasChildren": true, "size": { "width": 400, diff --git a/packages/client/src/components/app/GridBlock.svelte b/packages/client/src/components/app/GridBlock.svelte index 085449a5b0..0ee2cf1487 100644 --- a/packages/client/src/components/app/GridBlock.svelte +++ b/packages/client/src/components/app/GridBlock.svelte @@ -147,7 +147,8 @@ border: 1px solid var(--spectrum-global-color-gray-300); border-radius: 4px; overflow: hidden; - min-height: 410px; + min-height: 230px; + height: 410px; } div.in-builder :global(*) { pointer-events: none; diff --git a/packages/frontend-core/src/components/grid/lib/utils.js b/packages/frontend-core/src/components/grid/lib/utils.js index 49d6b0a439..c7c618e6f8 100644 --- a/packages/frontend-core/src/components/grid/lib/utils.js +++ b/packages/frontend-core/src/components/grid/lib/utils.js @@ -1,4 +1,4 @@ -import { FieldType, FieldTypeSubtypes } from "@budibase/types" +import { TypeIconMap } from "../../../constants" export const getColor = (idx, opacity = 0.3) => { if (idx == null || idx === -1) { @@ -7,27 +7,6 @@ export const getColor = (idx, opacity = 0.3) => { return `hsla(${((idx + 1) * 222) % 360}, 90%, 75%, ${opacity})` } -const TypeIconMap = { - [FieldType.STRING]: "Text", - [FieldType.OPTIONS]: "Dropdown", - [FieldType.DATETIME]: "Date", - [FieldType.BARCODEQR]: "Camera", - [FieldType.LONGFORM]: "TextAlignLeft", - [FieldType.ARRAY]: "Dropdown", - [FieldType.NUMBER]: "123", - [FieldType.BOOLEAN]: "Boolean", - [FieldType.ATTACHMENTS]: "AppleFiles", - [FieldType.ATTACHMENT_SINGLE]: "Document", - [FieldType.LINK]: "DataCorrelated", - [FieldType.FORMULA]: "Calculator", - [FieldType.JSON]: "Brackets", - [FieldType.BIGINT]: "TagBold", - [FieldType.BB_REFERENCE]: { - [FieldTypeSubtypes.BB_REFERENCE.USER]: "User", - [FieldTypeSubtypes.BB_REFERENCE.USERS]: "UserGroup", - }, -} - export const getColumnIcon = column => { if (column.schema.autocolumn) { return "MagicWand" diff --git a/packages/frontend-core/src/constants.js b/packages/frontend-core/src/constants.js index 68da439195..e6860da52d 100644 --- a/packages/frontend-core/src/constants.js +++ b/packages/frontend-core/src/constants.js @@ -4,6 +4,7 @@ export { OperatorOptions, SqlNumberTypeRangeMap } from "@budibase/shared-core" export { Feature as Features } from "@budibase/types" import { BpmCorrelationKey } from "@budibase/shared-core" +import { FieldType, FieldTypeSubtypes } from "@budibase/types" // Cookie names export const Cookies = { @@ -113,3 +114,27 @@ export const ContextScopes = { Local: "local", Global: "global", } + +export const TypeIconMap = { + [FieldType.STRING]: "Text", + [FieldType.OPTIONS]: "Dropdown", + [FieldType.DATETIME]: "Calendar", + [FieldType.BARCODEQR]: "Camera", + [FieldType.LONGFORM]: "TextAlignLeft", + [FieldType.ARRAY]: "Duplicate", + [FieldType.NUMBER]: "123", + [FieldType.BOOLEAN]: "Boolean", + [FieldType.ATTACHMENTS]: "AppleFiles", + [FieldType.ATTACHMENT_SINGLE]: "Document", + [FieldType.LINK]: "DataCorrelated", + [FieldType.FORMULA]: "Calculator", + [FieldType.JSON]: "Brackets", + [FieldType.BIGINT]: "TagBold", + [FieldType.AUTO]: "MagicWand", + [FieldType.USER]: "User", + [FieldType.USERS]: "UserGroup", + [FieldType.BB_REFERENCE]: { + [FieldTypeSubtypes.BB_REFERENCE.USER]: "User", + [FieldTypeSubtypes.BB_REFERENCE.USERS]: "UserGroup", + }, +} diff --git a/packages/server/src/api/routes/tests/search.spec.ts b/packages/server/src/api/routes/tests/search.spec.ts index a281d624dc..2b08f9afc1 100644 --- a/packages/server/src/api/routes/tests/search.spec.ts +++ b/packages/server/src/api/routes/tests/search.spec.ts @@ -2,7 +2,7 @@ import { tableForDatasource } from "../../../tests/utilities/structures" import { DatabaseName, getDatasource } from "../../../integrations/tests/utils" import * as setup from "./utilities" -import { Datasource, FieldType, Table } from "@budibase/types" +import { Datasource, FieldType, SearchFilters, Table } from "@budibase/types" jest.unmock("mssql") @@ -53,22 +53,38 @@ describe.each([ ) }) - it("should return rows", async () => { - const rows = await Promise.all([ - config.api.row.save(table._id!, { name: "foo" }), - config.api.row.save(table._id!, { name: "bar" }), - ]) + describe("strings", () => { + const rows = [{ name: "foo" }, { name: "bar" }] - const result = await config.api.row.search(table._id!, { - tableId: table._id!, - query: {}, - }) + interface StringSearchTest { + query: SearchFilters + expected: (typeof rows)[number][] + } - expect(result.rows).toEqual( - expect.arrayContaining([ - expect.objectContaining({ _id: rows[0]._id }), - expect.objectContaining({ _id: rows[1]._id }), - ]) + const stringSearchTests: StringSearchTest[] = [ + { query: {}, expected: rows }, + { query: { string: { name: "foo" } }, expected: [rows[0]] }, + { query: { fuzzy: { name: "oo" } }, expected: [rows[0]] }, + { query: { equal: { name: "foo" } }, expected: [rows[0]] }, + { query: { notEqual: { name: "foo" } }, expected: [rows[1]] }, + { query: { oneOf: { name: ["foo"] } }, expected: [rows[0]] }, + // { query: { contains: { name: "f" } }, expected: [0] }, + // { query: { notContains: { name: ["f"] } }, expected: [1] }, + // { query: { containsAny: { name: ["f"] } }, expected: [0] }, + ] + + it.each(stringSearchTests)( + `should be able to run query: $query`, + async ({ query, expected }) => { + await Promise.all(rows.map(r => config.api.row.save(table._id!, r))) + const { rows: foundRows } = await config.api.row.search(table._id!, { + tableId: table._id!, + query, + }) + expect(foundRows).toEqual( + expect.arrayContaining(expected.map(r => expect.objectContaining(r))) + ) + } ) }) })