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 5b3d1ec5a2f..46aea2a6c4f 100644 --- a/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/GridColumnConfiguration.svelte +++ b/packages/builder/src/components/design/settings/controls/GridColumnConfiguration/GridColumnConfiguration.svelte @@ -26,12 +26,14 @@ const getSchema = (asset, datasource) => { const schema = getSchemaForDatasource(asset, datasource).schema - // Don't show ID and rev in tables - if (schema) { - delete schema._id - delete schema._rev + if (!schema) { + return } + // Don't show ID and rev in tables + delete schema._id + delete schema._rev + const result = enrichSchemaWithRelColumns(schema) return result } diff --git a/packages/frontend-core/src/components/grid/layout/Grid.svelte b/packages/frontend-core/src/components/grid/layout/Grid.svelte index fcaf9724c3d..c0ad5810b75 100644 --- a/packages/frontend-core/src/components/grid/layout/Grid.svelte +++ b/packages/frontend-core/src/components/grid/layout/Grid.svelte @@ -47,7 +47,6 @@ export let buttonsCollapsedText = null export let darkMode = false export let isCloud = null - export let rowConditions = null export let aiEnabled = false // Unique identifier for DOM nodes inside this instance @@ -106,7 +105,6 @@ darkMode, isCloud, aiEnabled, - rowConditions, }) // Derive min height and make available in context diff --git a/packages/frontend-core/src/components/grid/stores/columns.ts b/packages/frontend-core/src/components/grid/stores/columns.ts index 80739883236..70b93d93e69 100644 --- a/packages/frontend-core/src/components/grid/stores/columns.ts +++ b/packages/frontend-core/src/components/grid/stores/columns.ts @@ -156,11 +156,11 @@ export const initialise = (context: StoreContext) => { // Merge new schema fields with existing schema in order to preserve widths const processColumns = ($enrichedSchema: any) => { - if (!$enrichedSchema) { + const $definition = get(definition) + if (!$enrichedSchema || !$definition) { columns.set([]) return } - const $definition = get(definition) const $columns = get(columns) const $displayColumn = get(displayColumn) diff --git a/packages/frontend-core/src/components/grid/stores/config.js b/packages/frontend-core/src/components/grid/stores/config.ts similarity index 77% rename from packages/frontend-core/src/components/grid/stores/config.js rename to packages/frontend-core/src/components/grid/stores/config.ts index 4a603706902..e334b58495e 100644 --- a/packages/frontend-core/src/components/grid/stores/config.js +++ b/packages/frontend-core/src/components/grid/stores/config.ts @@ -1,10 +1,22 @@ import { derivedMemo } from "../../../utils" -import { derived } from "svelte/store" +import { derived, Readable } from "svelte/store" import { ViewV2Type } from "@budibase/types" +import { BaseStoreProps, Store as StoreContext } from "." -export const createStores = context => { +type ConfigStore = { + [key in keyof BaseStoreProps]: Readable +} + +interface ConfigDerivedStore { + config: Readable +} + +export type Store = ConfigStore & ConfigDerivedStore + +export const createStores = (context: StoreContext): ConfigStore => { const { props } = context - const getProp = prop => derivedMemo(props, $props => $props[prop]) + const getProp = (prop: T) => + derivedMemo(props, $props => $props[prop]) // Derive and memoize some props so that we can react to them in isolation const datasource = getProp("datasource") @@ -15,7 +27,6 @@ export const createStores = context => { const schemaOverrides = getProp("schemaOverrides") const notifySuccess = getProp("notifySuccess") const notifyError = getProp("notifyError") - const rowConditions = getProp("rowConditions") return { datasource, @@ -26,11 +37,10 @@ export const createStores = context => { schemaOverrides, notifySuccess, notifyError, - rowConditions, } } -export const deriveStores = context => { +export const deriveStores = (context: StoreContext): ConfigDerivedStore => { const { props, definition, hasNonAutoColumn } = context // Derive features diff --git a/packages/frontend-core/src/components/grid/stores/datasource.ts b/packages/frontend-core/src/components/grid/stores/datasource.ts index 9e86cb53644..74101701edc 100644 --- a/packages/frontend-core/src/components/grid/stores/datasource.ts +++ b/packages/frontend-core/src/components/grid/stores/datasource.ts @@ -12,11 +12,11 @@ import { UpdateViewRequest, ViewV2Type, } from "@budibase/types" -import { Store as StoreContext } from "." +import { Store as StoreContext, BaseStoreProps } from "." import { DatasourceActions } from "./datasources" interface DatasourceStore { - definition: Writable + definition: Writable schemaMutations: Writable> subSchemaMutations: Writable>> } @@ -28,7 +28,7 @@ interface DerivedDatasourceStore { } interface ActionDatasourceStore { - datasource: DatasourceStore["definition"] & { + datasource: BaseStoreProps["datasource"] & { actions: DatasourceActions & { refreshDefinition: () => Promise changePrimaryDisplay: (column: string) => Promise @@ -218,7 +218,7 @@ export const createActions = (context: StoreContext): ActionDatasourceStore => { // Updates the datasources primary display column const changePrimaryDisplay = async (column: string) => { - let newDefinition = cloneDeep(get(definition)) + let newDefinition = cloneDeep(get(definition)!) // Update primary display newDefinition.primaryDisplay = column diff --git a/packages/frontend-core/src/components/grid/stores/datasources/nonPlus.ts b/packages/frontend-core/src/components/grid/stores/datasources/nonPlus.ts index 15bbc9b3960..ae8f1872784 100644 --- a/packages/frontend-core/src/components/grid/stores/datasources/nonPlus.ts +++ b/packages/frontend-core/src/components/grid/stores/datasources/nonPlus.ts @@ -91,7 +91,7 @@ export const initialise = (context: StoreContext) => { } // Wipe state - filter.set(get(initialFilter)) + filter.set(get(initialFilter) ?? undefined) inlineFilters.set([]) sort.set({ column: get(initialSortColumn), diff --git a/packages/frontend-core/src/components/grid/stores/datasources/table.ts b/packages/frontend-core/src/components/grid/stores/datasources/table.ts index 65d68a7d5d1..e52faef5cce 100644 --- a/packages/frontend-core/src/components/grid/stores/datasources/table.ts +++ b/packages/frontend-core/src/components/grid/stores/datasources/table.ts @@ -108,7 +108,7 @@ export const initialise = (context: StoreContext) => { } // Wipe state - filter.set(get(initialFilter)) + filter.set(get(initialFilter) ?? undefined) inlineFilters.set([]) sort.set({ column: get(initialSortColumn), diff --git a/packages/frontend-core/src/components/grid/stores/datasources/viewV2.ts b/packages/frontend-core/src/components/grid/stores/datasources/viewV2.ts index e18b9f71c08..71c22e68660 100644 --- a/packages/frontend-core/src/components/grid/stores/datasources/viewV2.ts +++ b/packages/frontend-core/src/components/grid/stores/datasources/viewV2.ts @@ -121,7 +121,7 @@ export const initialise = (context: StoreContext) => { } // Reset state for new view - filter.set(get(initialFilter)) + filter.set(get(initialFilter) ?? undefined) inlineFilters.set([]) sort.set({ column: get(initialSortColumn), diff --git a/packages/frontend-core/src/components/grid/stores/filter.ts b/packages/frontend-core/src/components/grid/stores/filter.ts index 36f6cd9483b..b0a204d42c8 100644 --- a/packages/frontend-core/src/components/grid/stores/filter.ts +++ b/packages/frontend-core/src/components/grid/stores/filter.ts @@ -26,7 +26,7 @@ export const createStores = (context: StoreContext): FilterStore => { const { props } = context // Initialise to default props - const filter = memo(get(props).initialFilter) + const filter = memo(get(props).initialFilter ?? undefined) const inlineFilters = memo([]) return { @@ -120,5 +120,7 @@ export const initialise = (context: StoreContext) => { const { filter, initialFilter } = context // Reset filter when initial filter prop changes - initialFilter.subscribe(filter.set) + initialFilter.subscribe($initialFilter => + filter.set($initialFilter ?? undefined) + ) } diff --git a/packages/frontend-core/src/components/grid/stores/index.ts b/packages/frontend-core/src/components/grid/stores/index.ts index 1706865981e..30a1a923f28 100644 --- a/packages/frontend-core/src/components/grid/stores/index.ts +++ b/packages/frontend-core/src/components/grid/stores/index.ts @@ -24,6 +24,7 @@ import * as ViewV2 from "./datasources/viewV2" import * as NonPlus from "./datasources/nonPlus" import * as Cache from "./cache" import * as Conditions from "./conditions" +import { SortOrder, UIDatasource, UISearchFilter } from "@budibase/types" const DependencyOrderedStores = [ Sort, @@ -51,8 +52,33 @@ const DependencyOrderedStores = [ Cache, ] +export interface BaseStoreProps { + datasource: UIDatasource + initialSortColumn: string | null + initialSortOrder: SortOrder | null + initialFilter: UISearchFilter | null + fixedRowHeight: number | null + schemaOverrides: Record< + string, + { + displayName?: string + disabled?: boolean + } + > | null + notifySuccess: (message: string) => void + notifyError: (message: string) => void + canAddRows?: boolean + canEditRows?: boolean + canDeleteRows?: boolean + canEditColumns?: boolean + canExpandRows?: boolean + canSaveSchema?: boolean +} + export interface BaseStore { API: APIClient + gridID: string + props: Writable } export type Store = BaseStore & @@ -70,23 +96,16 @@ export type Store = BaseStore & Scroll.Store & { // TODO while typing the rest of stores sort: Writable - initialFilter: Writable - initialSortColumn: Writable - initialSortOrder: Writable subscribe: any - config: Writable dispatch: (event: string, data: any) => any notifications: Writable - schemaOverrides: Writable - gridID: string - props: Writable width: Writable - fixedRowHeight: Writable bounds: Readable height: Readable } & Rows.Store & Reorder.Store & - Resize.Store + Resize.Store & + Config.Store export const attachStores = (context: Store): Store => { // Atomic store creation diff --git a/packages/frontend-core/src/utils/memo.d.ts b/packages/frontend-core/src/utils/memo.d.ts new file mode 100644 index 00000000000..04d3416e49a --- /dev/null +++ b/packages/frontend-core/src/utils/memo.d.ts @@ -0,0 +1,10 @@ +import { Readable, Writable } from "svelte/store" + +declare module "./memo" { + export function memo(value: T): Writable + + export function derivedMemo( + store: Readable, + derivation: (store: TStore) => TResult + ): Readable +} diff --git a/packages/frontend-core/src/utils/relatedColumns.ts b/packages/frontend-core/src/utils/relatedColumns.ts index e7bd3662d31..7bec5266051 100644 --- a/packages/frontend-core/src/utils/relatedColumns.ts +++ b/packages/frontend-core/src/utils/relatedColumns.ts @@ -46,10 +46,7 @@ const columnTypeManyParser = { export function enrichSchemaWithRelColumns( schema: Record -): Record | undefined { - if (!schema) { - return - } +): Record { const result = Object.keys(schema).reduce>( (result, fieldName) => { const field = schema[fieldName] diff --git a/packages/types/src/ui/stores/grid/table.ts b/packages/types/src/ui/stores/grid/table.ts index a5a13d5fa25..e69f9fd38f3 100644 --- a/packages/types/src/ui/stores/grid/table.ts +++ b/packages/types/src/ui/stores/grid/table.ts @@ -27,6 +27,7 @@ export type UIFieldSchema = FieldSchema & related?: { field: string; subField: string } columns?: Record cellRenderType?: string + disabled?: boolean } interface UIRelationSchemaField extends RelationSchemaField {