From e5a79f9d9c811c8191368abae8b6673f31251f6f Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 24 Dec 2024 14:11:16 +0100 Subject: [PATCH 01/13] Initial conversion --- .../src/components/grid/stores/{filter.js => filter.ts} | 9 +++++---- .../frontend-core/src/components/grid/stores/index.ts | 1 + 2 files changed, 6 insertions(+), 4 deletions(-) rename packages/frontend-core/src/components/grid/stores/{filter.js => filter.ts} (89%) diff --git a/packages/frontend-core/src/components/grid/stores/filter.js b/packages/frontend-core/src/components/grid/stores/filter.ts similarity index 89% rename from packages/frontend-core/src/components/grid/stores/filter.js rename to packages/frontend-core/src/components/grid/stores/filter.ts index e7adc356ae6..5eb67b6e7e8 100644 --- a/packages/frontend-core/src/components/grid/stores/filter.js +++ b/packages/frontend-core/src/components/grid/stores/filter.ts @@ -1,8 +1,9 @@ import { get, derived } from "svelte/store" import { FieldType, UILogicalOperator } from "@budibase/types" +import { Store as StoreContext } from "." import { memo } from "../../../utils/memo" -export const createStores = context => { +export const createStores = (context: StoreContext) => { const { props } = context // Initialise to default props @@ -15,7 +16,7 @@ export const createStores = context => { } } -export const deriveStores = context => { +export const deriveStores = (context: StoreContext) => { const { filter, inlineFilters } = context const allFilters = derived( [filter, inlineFilters], @@ -48,7 +49,7 @@ export const deriveStores = context => { } } -export const createActions = context => { +export const createActions = (context: StoreContext) => { const { filter, inlineFilters } = context const addInlineFilter = (column, value) => { @@ -95,7 +96,7 @@ export const createActions = context => { } } -export const initialise = context => { +export const initialise = (context: StoreContext) => { const { filter, initialFilter } = context // Reset filter when initial filter prop changes diff --git a/packages/frontend-core/src/components/grid/stores/index.ts b/packages/frontend-core/src/components/grid/stores/index.ts index d0413cb80a5..59293f579bc 100644 --- a/packages/frontend-core/src/components/grid/stores/index.ts +++ b/packages/frontend-core/src/components/grid/stores/index.ts @@ -86,6 +86,7 @@ export type Store = BaseStore & selectedRowCount: Writable selectedCellMap: Writable selectedCellCount: Writable + props: Writable } export const attachStores = (context: Store): Store => { From c682a43d9ab09c25d95fd58f5cf879a005f69652 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 24 Dec 2024 14:13:41 +0100 Subject: [PATCH 02/13] Export stores --- .../src/components/grid/stores/filter.ts | 15 +++++++++++++-- .../src/components/grid/stores/index.ts | 6 ++---- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/packages/frontend-core/src/components/grid/stores/filter.ts b/packages/frontend-core/src/components/grid/stores/filter.ts index 5eb67b6e7e8..4061ee04d7e 100644 --- a/packages/frontend-core/src/components/grid/stores/filter.ts +++ b/packages/frontend-core/src/components/grid/stores/filter.ts @@ -1,9 +1,20 @@ -import { get, derived } from "svelte/store" +import { get, derived, Writable } from "svelte/store" import { FieldType, UILogicalOperator } from "@budibase/types" import { Store as StoreContext } from "." import { memo } from "../../../utils/memo" -export const createStores = (context: StoreContext) => { +export interface FilterStore { + filter: Writable + inlineFilters: Writable +} + +export interface FilterDerivedStore { + allFilters: Writable +} + +export type Store = FilterStore & FilterDerivedStore + +export const createStores = (context: StoreContext): FilterStore => { const { props } = context // Initialise to default props diff --git a/packages/frontend-core/src/components/grid/stores/index.ts b/packages/frontend-core/src/components/grid/stores/index.ts index 59293f579bc..659f45d56a6 100644 --- a/packages/frontend-core/src/components/grid/stores/index.ts +++ b/packages/frontend-core/src/components/grid/stores/index.ts @@ -63,12 +63,10 @@ export type Store = BaseStore & Datasource.Store & Validation.Store & Users.Store & - Menu.Store & { + Menu.Store & + Filter.Store & { // TODO while typing the rest of stores fetch: Writable - filter: Writable - inlineFilters: Writable - allFilters: Writable sort: Writable initialFilter: Writable initialSortColumn: Writable From dc0f16747e63d59d53a9121ff064cf608ac1d037 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 24 Dec 2024 14:17:42 +0100 Subject: [PATCH 03/13] Types --- .../src/components/grid/stores/filter.ts | 13 +++++++++---- packages/types/src/ui/stores/grid/columns.ts | 2 +- packages/types/src/ui/stores/grid/filters.ts | 10 ++++++++++ packages/types/src/ui/stores/grid/index.ts | 1 + 4 files changed, 21 insertions(+), 5 deletions(-) create mode 100644 packages/types/src/ui/stores/grid/filters.ts diff --git a/packages/frontend-core/src/components/grid/stores/filter.ts b/packages/frontend-core/src/components/grid/stores/filter.ts index 4061ee04d7e..b9f54fefb82 100644 --- a/packages/frontend-core/src/components/grid/stores/filter.ts +++ b/packages/frontend-core/src/components/grid/stores/filter.ts @@ -1,11 +1,16 @@ import { get, derived, Writable } from "svelte/store" -import { FieldType, UILogicalOperator } from "@budibase/types" +import { + FieldType, + UIColumn, + UIInlineFilter, + UILogicalOperator, +} from "@budibase/types" import { Store as StoreContext } from "." import { memo } from "../../../utils/memo" export interface FilterStore { filter: Writable - inlineFilters: Writable + inlineFilters: Writable } export interface FilterDerivedStore { @@ -63,10 +68,10 @@ export const deriveStores = (context: StoreContext) => { export const createActions = (context: StoreContext) => { const { filter, inlineFilters } = context - const addInlineFilter = (column, value) => { + const addInlineFilter = (column: UIColumn, value: string) => { const filterId = `inline-${column.name}` const type = column.schema.type - let inlineFilter = { + const inlineFilter: UIInlineFilter = { field: column.name, id: filterId, operator: "string", diff --git a/packages/types/src/ui/stores/grid/columns.ts b/packages/types/src/ui/stores/grid/columns.ts index d12739fffe2..a8be3b21b40 100644 --- a/packages/types/src/ui/stores/grid/columns.ts +++ b/packages/types/src/ui/stores/grid/columns.ts @@ -9,7 +9,7 @@ export type UIColumn = FieldSchema & { subField: string } primaryDisplay?: boolean - schema?: { + schema: { disabled: boolean type: FieldType readonly: boolean diff --git a/packages/types/src/ui/stores/grid/filters.ts b/packages/types/src/ui/stores/grid/filters.ts new file mode 100644 index 00000000000..3912a40f87e --- /dev/null +++ b/packages/types/src/ui/stores/grid/filters.ts @@ -0,0 +1,10 @@ +import { FieldType } from "@budibase/types" + +export interface UIInlineFilter { + field: string + type: FieldType + value: number | string + operator: string + id: string + valueType: string +} diff --git a/packages/types/src/ui/stores/grid/index.ts b/packages/types/src/ui/stores/grid/index.ts index b6a152ed737..aa68c3f2075 100644 --- a/packages/types/src/ui/stores/grid/index.ts +++ b/packages/types/src/ui/stores/grid/index.ts @@ -3,3 +3,4 @@ export * from "./datasource" export * from "./table" export * from "./view" export * from "./user" +export * from "./filters" From d176325179bea07d747dc7d2e057e766bf3fd8c5 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 24 Dec 2024 14:20:53 +0100 Subject: [PATCH 04/13] More typings --- .../frontend-core/src/components/grid/stores/filter.ts | 9 +++++---- packages/types/src/ui/stores/grid/filters.ts | 9 ++++++++- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/packages/frontend-core/src/components/grid/stores/filter.ts b/packages/frontend-core/src/components/grid/stores/filter.ts index b9f54fefb82..3df28d22e15 100644 --- a/packages/frontend-core/src/components/grid/stores/filter.ts +++ b/packages/frontend-core/src/components/grid/stores/filter.ts @@ -1,7 +1,8 @@ -import { get, derived, Writable } from "svelte/store" +import { get, derived, Writable, Readable } from "svelte/store" import { FieldType, UIColumn, + UIFilter, UIInlineFilter, UILogicalOperator, } from "@budibase/types" @@ -9,12 +10,12 @@ import { Store as StoreContext } from "." import { memo } from "../../../utils/memo" export interface FilterStore { - filter: Writable + filter: Writable inlineFilters: Writable } export interface FilterDerivedStore { - allFilters: Writable + allFilters: Readable } export type Store = FilterStore & FilterDerivedStore @@ -32,7 +33,7 @@ export const createStores = (context: StoreContext): FilterStore => { } } -export const deriveStores = (context: StoreContext) => { +export const deriveStores = (context: StoreContext): FilterDerivedStore => { const { filter, inlineFilters } = context const allFilters = derived( [filter, inlineFilters], diff --git a/packages/types/src/ui/stores/grid/filters.ts b/packages/types/src/ui/stores/grid/filters.ts index 3912a40f87e..cde922adc9c 100644 --- a/packages/types/src/ui/stores/grid/filters.ts +++ b/packages/types/src/ui/stores/grid/filters.ts @@ -1,4 +1,11 @@ -import { FieldType } from "@budibase/types" +import { FieldType, UILogicalOperator } from "@budibase/types" + +export interface UIFilter { + groups: { + logicalOperator: UILogicalOperator + filters: UIInlineFilter[] + }[] +} export interface UIInlineFilter { field: string From f6db307ebcff019c6b819919a01009494bbcac2d Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Tue, 24 Dec 2024 14:33:58 +0100 Subject: [PATCH 05/13] Use existing types --- .../src/components/grid/stores/filter.ts | 27 ++++++++++--------- packages/types/src/ui/stores/grid/filters.ts | 16 ++--------- 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/packages/frontend-core/src/components/grid/stores/filter.ts b/packages/frontend-core/src/components/grid/stores/filter.ts index 3df28d22e15..36f6cd9483b 100644 --- a/packages/frontend-core/src/components/grid/stores/filter.ts +++ b/packages/frontend-core/src/components/grid/stores/filter.ts @@ -1,21 +1,23 @@ import { get, derived, Writable, Readable } from "svelte/store" import { + ArrayOperator, + BasicOperator, FieldType, UIColumn, - UIFilter, - UIInlineFilter, + UILegacyFilter, UILogicalOperator, + UISearchFilter, } from "@budibase/types" import { Store as StoreContext } from "." import { memo } from "../../../utils/memo" export interface FilterStore { - filter: Writable - inlineFilters: Writable + filter: Writable + inlineFilters: Writable } export interface FilterDerivedStore { - allFilters: Readable + allFilters: Readable } export type Store = FilterStore & FilterDerivedStore @@ -42,7 +44,7 @@ export const deriveStores = (context: StoreContext): FilterDerivedStore => { if (!$inlineFilters?.length) { return $filter } - let allFilters = { + const allFilters: UISearchFilter = { logicalOperator: UILogicalOperator.ALL, groups: [ { @@ -51,12 +53,13 @@ export const deriveStores = (context: StoreContext): FilterDerivedStore => { }, ], } + // Just use inline if no filter if (!$filter?.groups?.length) { return allFilters } // Join them together if both - allFilters.groups = [...allFilters.groups, ...$filter.groups] + allFilters.groups = [...allFilters.groups!, ...$filter.groups] return allFilters } ) @@ -72,10 +75,10 @@ export const createActions = (context: StoreContext) => { const addInlineFilter = (column: UIColumn, value: string) => { const filterId = `inline-${column.name}` const type = column.schema.type - const inlineFilter: UIInlineFilter = { + const inlineFilter: UILegacyFilter = { field: column.name, id: filterId, - operator: "string", + operator: BasicOperator.STRING, valueType: "value", type, value, @@ -84,11 +87,11 @@ export const createActions = (context: StoreContext) => { // Add overrides specific so the certain column type if (type === FieldType.NUMBER) { inlineFilter.value = parseFloat(value) - inlineFilter.operator = "equal" + inlineFilter.operator = BasicOperator.EQUAL } else if (type === FieldType.BIGINT) { - inlineFilter.operator = "equal" + inlineFilter.operator = BasicOperator.EQUAL } else if (type === FieldType.ARRAY) { - inlineFilter.operator = "contains" + inlineFilter.operator = ArrayOperator.CONTAINS } inlineFilters.update($inlineFilters => { diff --git a/packages/types/src/ui/stores/grid/filters.ts b/packages/types/src/ui/stores/grid/filters.ts index cde922adc9c..d75f32370cf 100644 --- a/packages/types/src/ui/stores/grid/filters.ts +++ b/packages/types/src/ui/stores/grid/filters.ts @@ -1,17 +1,5 @@ -import { FieldType, UILogicalOperator } from "@budibase/types" +import { LegacyFilter } from "@budibase/types" -export interface UIFilter { - groups: { - logicalOperator: UILogicalOperator - filters: UIInlineFilter[] - }[] -} - -export interface UIInlineFilter { - field: string - type: FieldType - value: number | string - operator: string +export type UILegacyFilter = LegacyFilter & { id: string - valueType: string } From 1f957421d687f8d5d5ddf3ef12e6430f2c258ba1 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 27 Dec 2024 08:40:37 +0100 Subject: [PATCH 06/13] Initial ui conversion --- .../src/components/grid/stores/index.ts | 12 ++-- .../src/components/grid/stores/menu.ts | 13 +++- .../components/grid/stores/{ui.js => ui.ts} | 68 ++++++++++++++----- packages/types/src/ui/stores/grid/columns.ts | 2 + .../types/src/ui/stores/grid/datasource.ts | 1 + 5 files changed, 70 insertions(+), 26 deletions(-) rename packages/frontend-core/src/components/grid/stores/{ui.js => ui.ts} (85%) diff --git a/packages/frontend-core/src/components/grid/stores/index.ts b/packages/frontend-core/src/components/grid/stores/index.ts index 659f45d56a6..81e0e824b03 100644 --- a/packages/frontend-core/src/components/grid/stores/index.ts +++ b/packages/frontend-core/src/components/grid/stores/index.ts @@ -64,7 +64,8 @@ export type Store = BaseStore & Validation.Store & Users.Store & Menu.Store & - Filter.Store & { + Filter.Store & + UI.Store & { // TODO while typing the rest of stores fetch: Writable sort: Writable @@ -77,14 +78,11 @@ export type Store = BaseStore & dispatch: (event: string, data: any) => any notifications: Writable schemaOverrides: Writable - focusedCellId: Writable - previousFocusedRowId: Writable gridID: string - selectedRows: Writable - selectedRowCount: Writable - selectedCellMap: Writable - selectedCellCount: Writable props: Writable + rowLookupMap: Writable + width: Writable + fixedRowHeight: Writable } export const attachStores = (context: Store): Store => { diff --git a/packages/frontend-core/src/components/grid/stores/menu.ts b/packages/frontend-core/src/components/grid/stores/menu.ts index 27e41c412b6..77ce2c66673 100644 --- a/packages/frontend-core/src/components/grid/stores/menu.ts +++ b/packages/frontend-core/src/components/grid/stores/menu.ts @@ -15,7 +15,16 @@ interface MenuStore { menu: Writable } -export type Store = MenuStore +interface MenuActions { + menu: MenuStore["menu"] & { + actions: { + open: (cellId: string, e: MouseEvent) => void + close: () => void + } + } +} + +export type Store = MenuStore & MenuActions export const createStores = () => { const menu = writable({ @@ -30,7 +39,7 @@ export const createStores = () => { } } -export const createActions = (context: StoreContext) => { +export const createActions = (context: StoreContext): MenuActions => { const { menu, focusedCellId, diff --git a/packages/frontend-core/src/components/grid/stores/ui.js b/packages/frontend-core/src/components/grid/stores/ui.ts similarity index 85% rename from packages/frontend-core/src/components/grid/stores/ui.js rename to packages/frontend-core/src/components/grid/stores/ui.ts index 7f39116b05a..33bf8d40aa7 100644 --- a/packages/frontend-core/src/components/grid/stores/ui.js +++ b/packages/frontend-core/src/components/grid/stores/ui.ts @@ -1,4 +1,4 @@ -import { writable, get, derived } from "svelte/store" +import { writable, get, derived, Writable } from "svelte/store" import { tick } from "svelte" import { DefaultRowHeight, @@ -7,8 +7,42 @@ import { NewRowID, } from "../lib/constants" import { getCellID, parseCellID } from "../lib/utils" +import { Store as StoreContext } from "." + +export interface UIStore { + focusedCellId: Writable + focusedCellAPI: Writable + selectedRows: Writable + hoveredRowId: Writable + rowHeight: Writable + previousFocusedRowId: Writable + previousFocusedCellId: Writable + gridFocused: Writable + keyboardBlocked: Writable + isDragging: Writable + buttonColumnWidth: Writable + cellSelection: Writable<{ + active: boolean + sourceCellId: string | null + targetCellId: string | null + }> +} + +export interface UIDerivedStore { + focusedRowId: Writable + focusedRow: Writable + contentLines: Writable + compact: Writable + selectedRowCount: Writable + isSelectingCells: Writable + selectedCells: Writable & { actions: any } + selectedCellMap: Writable + selectedCellCount: Writable +} + +export type Store = UIStore & UIDerivedStore -export const createStores = context => { +export const createStores = (context: StoreContext): UIStore => { const { props } = context const focusedCellId = writable(null) const focusedCellAPI = writable(null) @@ -43,7 +77,7 @@ export const createStores = context => { } } -export const deriveStores = context => { +export const deriveStores = (context: StoreContext) => { const { focusedCellId, rows, @@ -128,8 +162,8 @@ export const deriveStores = context => { upperRowIndex = Math.min(upperRowIndex, lowerRowIndex + 49) // Column indices - const sourceColIndex = $columnLookupMap[sourceInfo.field].__idx - const targetColIndex = $columnLookupMap[targetInfo.field].__idx + const sourceColIndex = $columnLookupMap[sourceInfo.field].__idx || 0 + const targetColIndex = $columnLookupMap[targetInfo.field].__idx || 0 const lowerColIndex = Math.min(sourceColIndex, targetColIndex) const upperColIndex = Math.max(sourceColIndex, targetColIndex) @@ -151,7 +185,7 @@ export const deriveStores = context => { // Derive a quick lookup map of the selected cells const selectedCellMap = derived(selectedCells, $selectedCells => { - let map = {} + let map: Record = {} for (let row of $selectedCells) { for (let cell of row) { map[cell] = true @@ -178,7 +212,7 @@ export const deriveStores = context => { } } -export const createActions = context => { +export const createActions = (context: StoreContext) => { const { focusedCellId, hoveredRowId, @@ -190,7 +224,7 @@ export const createActions = context => { selectedCells, } = context // Keep the last selected index to use with bulk selection - let lastSelectedIndex = null + let lastSelectedIndex: number | null = null // Callback when leaving the grid, deselecting all focussed or selected items const blur = () => { @@ -200,7 +234,7 @@ export const createActions = context => { } // Toggles whether a certain row ID is selected or not - const toggleSelectedRow = id => { + const toggleSelectedRow = (id: string) => { selectedRows.update(state => { let newState = { ...state, @@ -215,7 +249,7 @@ export const createActions = context => { }) } - const bulkSelectRows = id => { + const bulkSelectRows = (id: string) => { if (!get(selectedRowCount)) { toggleSelectedRow(id) return @@ -241,7 +275,7 @@ export const createActions = context => { }) } - const startCellSelection = sourceCellId => { + const startCellSelection = (sourceCellId: string) => { cellSelection.set({ active: true, sourceCellId, @@ -249,7 +283,7 @@ export const createActions = context => { }) } - const updateCellSelection = targetCellId => { + const updateCellSelection = (targetCellId: string) => { cellSelection.update(state => ({ ...state, targetCellId, @@ -263,7 +297,7 @@ export const createActions = context => { })) } - const selectCellRange = (source, target) => { + const selectCellRange = (source: string, target: string) => { cellSelection.set({ active: false, sourceCellId: source, @@ -305,7 +339,7 @@ export const createActions = context => { } } -export const initialise = context => { +export const initialise = (context: StoreContext) => { const { focusedRowId, previousFocusedRowId, @@ -332,7 +366,7 @@ export const initialise = context => { const $focusedRowId = get(focusedRowId) const $selectedRows = get(selectedRows) const $hoveredRowId = get(hoveredRowId) - const hasRow = id => $rowLookupMap[id] != null + const hasRow = (id: string) => $rowLookupMap[id] != null // Check focused cell if ($focusedRowId && !hasRow($focusedRowId)) { @@ -362,13 +396,13 @@ export const initialise = context => { }) // Remember the last focused row ID so that we can store the previous one - let lastFocusedRowId = null + let lastFocusedRowId: string | null = null focusedRowId.subscribe(id => { previousFocusedRowId.set(lastFocusedRowId) lastFocusedRowId = id }) - let lastFocusedCellId = null + let lastFocusedCellId: string | null = null focusedCellId.subscribe(id => { // Remember the last focused cell ID so that we can store the previous one previousFocusedCellId.set(lastFocusedCellId) diff --git a/packages/types/src/ui/stores/grid/columns.ts b/packages/types/src/ui/stores/grid/columns.ts index a8be3b21b40..5f02efa8cb6 100644 --- a/packages/types/src/ui/stores/grid/columns.ts +++ b/packages/types/src/ui/stores/grid/columns.ts @@ -16,4 +16,6 @@ export type UIColumn = FieldSchema & { autocolumn: boolean } calculationType: CalculationType + __idx?: number + __left?: number } diff --git a/packages/types/src/ui/stores/grid/datasource.ts b/packages/types/src/ui/stores/grid/datasource.ts index 1d9b6740a47..b1231ab4b32 100644 --- a/packages/types/src/ui/stores/grid/datasource.ts +++ b/packages/types/src/ui/stores/grid/datasource.ts @@ -2,6 +2,7 @@ import { UITable, UIView } from "@budibase/types" export type UIDatasource = (UITable | UIView) & { type: string + rowHeight?: number } export interface UIFieldMutation { From 1b2059336bffdc893680c745d1da1364c2589292 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 27 Dec 2024 08:44:09 +0100 Subject: [PATCH 07/13] Type anys --- packages/frontend-core/src/components/grid/stores/ui.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/frontend-core/src/components/grid/stores/ui.ts b/packages/frontend-core/src/components/grid/stores/ui.ts index 33bf8d40aa7..1ef9c42a32f 100644 --- a/packages/frontend-core/src/components/grid/stores/ui.ts +++ b/packages/frontend-core/src/components/grid/stores/ui.ts @@ -11,7 +11,9 @@ import { Store as StoreContext } from "." export interface UIStore { focusedCellId: Writable - focusedCellAPI: Writable + focusedCellAPI: Writable<{ + isReadonly: () => boolean + } | null> selectedRows: Writable hoveredRowId: Writable rowHeight: Writable From de59cf9b6c9b161151e6c8ce14ba22dc66d68e79 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 27 Dec 2024 08:48:13 +0100 Subject: [PATCH 08/13] Type any --- packages/frontend-core/src/components/grid/stores/ui.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/frontend-core/src/components/grid/stores/ui.ts b/packages/frontend-core/src/components/grid/stores/ui.ts index 1ef9c42a32f..78a0b9c2b00 100644 --- a/packages/frontend-core/src/components/grid/stores/ui.ts +++ b/packages/frontend-core/src/components/grid/stores/ui.ts @@ -14,7 +14,7 @@ export interface UIStore { focusedCellAPI: Writable<{ isReadonly: () => boolean } | null> - selectedRows: Writable + selectedRows: Writable> hoveredRowId: Writable rowHeight: Writable previousFocusedRowId: Writable From b0e58587680343ea93b15f66307d69463dc9523f Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 27 Dec 2024 08:57:00 +0100 Subject: [PATCH 09/13] Type grid utils --- .../src/components/grid/lib/{utils.js => utils.ts} | 8 ++++---- .../frontend-core/src/components/grid/stores/menu.ts | 2 +- .../frontend-core/src/components/grid/stores/ui.ts | 12 ++++++++---- .../src/components/grid/stores/validation.ts | 8 +++++--- 4 files changed, 18 insertions(+), 12 deletions(-) rename packages/frontend-core/src/components/grid/lib/{utils.js => utils.ts} (71%) diff --git a/packages/frontend-core/src/components/grid/lib/utils.js b/packages/frontend-core/src/components/grid/lib/utils.ts similarity index 71% rename from packages/frontend-core/src/components/grid/lib/utils.js rename to packages/frontend-core/src/components/grid/lib/utils.ts index f1f33d9950e..14aee663b7c 100644 --- a/packages/frontend-core/src/components/grid/lib/utils.js +++ b/packages/frontend-core/src/components/grid/lib/utils.ts @@ -1,7 +1,7 @@ import { GeneratedIDPrefix, CellIDSeparator } from "./constants" import { Helpers } from "@budibase/bbui" -export const parseCellID = cellId => { +export const parseCellID = (cellId: string | null) => { if (!cellId) { return { rowId: undefined, field: undefined } } @@ -10,11 +10,11 @@ export const parseCellID = cellId => { return { rowId: parts.join(CellIDSeparator), field } } -export const getCellID = (rowId, fieldName) => { +export const getCellID = (rowId: string, fieldName: string) => { return `${rowId}${CellIDSeparator}${fieldName}` } -export const parseEventLocation = e => { +export const parseEventLocation = (e: MouseEvent & TouchEvent) => { return { x: e.clientX ?? e.touches?.[0]?.clientX, y: e.clientY ?? e.touches?.[0]?.clientY, @@ -25,6 +25,6 @@ export const generateRowID = () => { return `${GeneratedIDPrefix}${Helpers.uuid()}` } -export const isGeneratedRowID = id => { +export const isGeneratedRowID = (id: string) => { return id?.startsWith(GeneratedIDPrefix) } diff --git a/packages/frontend-core/src/components/grid/stores/menu.ts b/packages/frontend-core/src/components/grid/stores/menu.ts index 77ce2c66673..ae29ae1de36 100644 --- a/packages/frontend-core/src/components/grid/stores/menu.ts +++ b/packages/frontend-core/src/components/grid/stores/menu.ts @@ -69,7 +69,7 @@ export const createActions = (context: StoreContext): MenuActions => { let multiRowMode = false if (get(selectedRowCount) > 1) { const { rowId } = parseCellID(cellId) - if (get(selectedRows)[rowId]) { + if (rowId !== undefined && get(selectedRows)[rowId]) { multiRowMode = true } } diff --git a/packages/frontend-core/src/components/grid/stores/ui.ts b/packages/frontend-core/src/components/grid/stores/ui.ts index 78a0b9c2b00..3378d34c6ae 100644 --- a/packages/frontend-core/src/components/grid/stores/ui.ts +++ b/packages/frontend-core/src/components/grid/stores/ui.ts @@ -101,6 +101,10 @@ export const deriveStores = (context: StoreContext) => { const focusedRow = derived( [focusedRowId, rowLookupMap], ([$focusedRowId, $rowLookupMap]) => { + if ($focusedRowId === undefined) { + return + } + if ($focusedRowId === NewRowID) { return { _id: NewRowID } } @@ -152,8 +156,8 @@ export const deriveStores = (context: StoreContext) => { } // Row indices - const sourceRowIndex = $rowLookupMap[sourceInfo.rowId]?.__idx - const targetRowIndex = $rowLookupMap[targetInfo.rowId]?.__idx + const sourceRowIndex = $rowLookupMap[sourceInfo.rowId!]?.__idx + const targetRowIndex = $rowLookupMap[targetInfo.rowId!]?.__idx if (sourceRowIndex == null || targetRowIndex == null) { return [] } @@ -164,8 +168,8 @@ export const deriveStores = (context: StoreContext) => { upperRowIndex = Math.min(upperRowIndex, lowerRowIndex + 49) // Column indices - const sourceColIndex = $columnLookupMap[sourceInfo.field].__idx || 0 - const targetColIndex = $columnLookupMap[targetInfo.field].__idx || 0 + const sourceColIndex = $columnLookupMap[sourceInfo.field!].__idx || 0 + const targetColIndex = $columnLookupMap[targetInfo.field!].__idx || 0 const lowerColIndex = Math.min(sourceColIndex, targetColIndex) const upperColIndex = Math.max(sourceColIndex, targetColIndex) diff --git a/packages/frontend-core/src/components/grid/stores/validation.ts b/packages/frontend-core/src/components/grid/stores/validation.ts index 32bb1cf9781..f118020b16c 100644 --- a/packages/frontend-core/src/components/grid/stores/validation.ts +++ b/packages/frontend-core/src/components/grid/stores/validation.ts @@ -33,10 +33,12 @@ export const deriveStores = (context: StoreContext): DerivedValidationStore => { // Extract row ID from all errored cell IDs if (error) { const { rowId } = parseCellID(key) - if (!map[rowId]) { - map[rowId] = [] + if (rowId !== undefined) { + if (!map[rowId]) { + map[rowId] = [] + } + map[rowId].push(key) } - map[rowId].push(key) } }) return map From 5b2edc0630b381599adf6fa4ea32bd46aabedbeb Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 27 Dec 2024 09:01:42 +0100 Subject: [PATCH 10/13] Type derived store --- .../src/components/grid/stores/ui.ts | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/packages/frontend-core/src/components/grid/stores/ui.ts b/packages/frontend-core/src/components/grid/stores/ui.ts index 3378d34c6ae..23710668b71 100644 --- a/packages/frontend-core/src/components/grid/stores/ui.ts +++ b/packages/frontend-core/src/components/grid/stores/ui.ts @@ -1,4 +1,4 @@ -import { writable, get, derived, Writable } from "svelte/store" +import { writable, get, derived, Writable, Readable } from "svelte/store" import { tick } from "svelte" import { DefaultRowHeight, @@ -31,15 +31,15 @@ export interface UIStore { } export interface UIDerivedStore { - focusedRowId: Writable - focusedRow: Writable - contentLines: Writable - compact: Writable - selectedRowCount: Writable - isSelectingCells: Writable - selectedCells: Writable & { actions: any } - selectedCellMap: Writable - selectedCellCount: Writable + focusedRowId: Readable + focusedRow: Readable + contentLines: Readable<3 | 2 | 1> + compact: Readable + selectedRowCount: Readable + isSelectingCells: Readable + selectedCells: Readable & { actions: any } + selectedCellMap: Readable> + selectedCellCount: Readable } export type Store = UIStore & UIDerivedStore From d96b8c77fa5aa94ea0e937974534222820074584 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Fri, 27 Dec 2024 09:07:41 +0100 Subject: [PATCH 11/13] Add utils.js back --- .../src/components/grid/lib/utils.js | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) create mode 100644 packages/frontend-core/src/components/grid/lib/utils.js diff --git a/packages/frontend-core/src/components/grid/lib/utils.js b/packages/frontend-core/src/components/grid/lib/utils.js new file mode 100644 index 00000000000..ee74a14bf09 --- /dev/null +++ b/packages/frontend-core/src/components/grid/lib/utils.js @@ -0,0 +1,32 @@ +// TODO: remove when all stores are typed + +import { GeneratedIDPrefix, CellIDSeparator } from "./constants" +import { Helpers } from "@budibase/bbui" + +export const parseCellID = cellId => { + if (!cellId) { + return { rowId: undefined, field: undefined } + } + const parts = cellId.split(CellIDSeparator) + const field = parts.pop() + return { rowId: parts.join(CellIDSeparator), field } +} + +export const getCellID = (rowId, fieldName) => { + return `${rowId}${CellIDSeparator}${fieldName}` +} + +export const parseEventLocation = e => { + return { + x: e.clientX ?? e.touches?.[0]?.clientX, + y: e.clientY ?? e.touches?.[0]?.clientY, + } +} + +export const generateRowID = () => { + return `${GeneratedIDPrefix}${Helpers.uuid()}` +} + +export const isGeneratedRowID = id => { + return id?.startsWith(GeneratedIDPrefix) +} From 07416e3e4ab7c44edbb4515b88f5643811d209d3 Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 30 Dec 2024 21:50:31 +0100 Subject: [PATCH 12/13] Persist row height --- packages/server/src/api/controllers/view/viewsV2.ts | 2 ++ packages/types/src/documents/app/view.ts | 1 + packages/types/src/ui/stores/grid/datasource.ts | 1 - 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/server/src/api/controllers/view/viewsV2.ts b/packages/server/src/api/controllers/view/viewsV2.ts index da579efed72..5376ce49c3f 100644 --- a/packages/server/src/api/controllers/view/viewsV2.ts +++ b/packages/server/src/api/controllers/view/viewsV2.ts @@ -149,6 +149,7 @@ export async function create(ctx: Ctx) { sort: view.sort, schema, primaryDisplay: view.primaryDisplay, + rowHeight: view.rowHeight, } const result = await sdk.views.create(tableId, parsedView) @@ -229,6 +230,7 @@ export async function update(ctx: Ctx) { sort: view.sort, schema, primaryDisplay: view.primaryDisplay, + rowHeight: view.rowHeight, } const { view: result, existingView } = await sdk.views.update( diff --git a/packages/types/src/documents/app/view.ts b/packages/types/src/documents/app/view.ts index 1170284b159..fd97cee4099 100644 --- a/packages/types/src/documents/app/view.ts +++ b/packages/types/src/documents/app/view.ts @@ -99,6 +99,7 @@ export interface ViewV2 { type?: SortType } schema?: ViewV2Schema + rowHeight?: number } export interface PublicAPIView extends Omit { diff --git a/packages/types/src/ui/stores/grid/datasource.ts b/packages/types/src/ui/stores/grid/datasource.ts index b1231ab4b32..1d9b6740a47 100644 --- a/packages/types/src/ui/stores/grid/datasource.ts +++ b/packages/types/src/ui/stores/grid/datasource.ts @@ -2,7 +2,6 @@ import { UITable, UIView } from "@budibase/types" export type UIDatasource = (UITable | UIView) & { type: string - rowHeight?: number } export interface UIFieldMutation { From 066586e0a294a8459419e3952db10e72d450ac6a Mon Sep 17 00:00:00 2001 From: Adria Navarro Date: Mon, 30 Dec 2024 22:08:52 +0100 Subject: [PATCH 13/13] Fix test types --- packages/server/src/api/routes/tests/viewV2.spec.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/packages/server/src/api/routes/tests/viewV2.spec.ts b/packages/server/src/api/routes/tests/viewV2.spec.ts index ba2ad422eb2..6ace7e256b2 100644 --- a/packages/server/src/api/routes/tests/viewV2.spec.ts +++ b/packages/server/src/api/routes/tests/viewV2.spec.ts @@ -162,6 +162,7 @@ if (descriptions.length) { visible: true, }, }, + rowHeight: generator.integer(), } const res = await config.api.viewV2.create(newView) @@ -224,6 +225,7 @@ if (descriptions.length) { visible: true, }, }, + rowHeight: generator.integer(), } const res = await config.api.viewV2.create(newView) expect(events.view.created).toHaveBeenCalledTimes(1) @@ -1069,6 +1071,7 @@ if (descriptions.length) { readonly: true, }, }, + rowHeight: generator.integer(), } await config.api.viewV2.update(updatedData)