diff --git a/packages/frontend-core/src/components/grid/stores/datasources/viewV2.js b/packages/frontend-core/src/components/grid/stores/datasources/viewV2.js index 425519d97e..2ee2039e4c 100644 --- a/packages/frontend-core/src/components/grid/stores/datasources/viewV2.js +++ b/packages/frontend-core/src/components/grid/stores/datasources/viewV2.js @@ -97,9 +97,12 @@ export const initialise = context => { order: get(initialSortOrder) || "ascending", }) - // Keep sort and filter state in line with the view definition + // Keep sort and filter state in line with the view definition when in builder unsubscribers.push( definition.subscribe($definition => { + if (!get(config).canSaveSchema) { + return + } if ($definition?.id !== $datasource.id) { return } @@ -122,7 +125,6 @@ export const initialise = context => { sort.subscribe(async $sort => { // If we can mutate schema then update the view definition if (get(config).canSaveSchema) { - // Ensure we're updating the correct view const $view = get(definition) if ($view?.id !== $datasource.id) { return @@ -144,7 +146,7 @@ export const initialise = context => { // Also update the fetch to ensure the new sort is respected. // Ensure we're updating the correct fetch. const $fetch = get(fetch) - if ($fetch?.options?.datasource?.tableId !== $datasource.tableId) { + if ($fetch?.options?.datasource?.id !== $datasource.id) { return } $fetch.update({ @@ -157,32 +159,49 @@ export const initialise = context => { // When filters change, ensure view definition is kept up to date unsubscribers?.push( filter.subscribe(async $filter => { - // If we can mutate schema then update the view definition - if (get(config).canSaveSchema) { - // Ensure we're updating the correct view - const $view = get(definition) - if ($view?.id !== $datasource.id) { - return - } - if (JSON.stringify($filter) !== JSON.stringify($view.query)) { - await datasource.actions.saveDefinition({ - ...$view, - query: $filter, - }) - } + if (!get(config).canSaveSchema) { + return + } + const $view = get(definition) + if ($view?.id !== $datasource.id) { + return + } + if (JSON.stringify($filter) !== JSON.stringify($view.query)) { + await datasource.actions.saveDefinition({ + ...$view, + query: $filter, + }) + + // Refresh data since view definition changed + await rows.actions.refreshData() } }) ) - // Keep fetch up to date with filters. - // If we're able to save filters against the view then we only need to apply - // inline filters to the fetch, as saved filters are applied server side. - // If we can't save filters, then all filters must be applied to the fetch. + // Keep fetch up to date with inline filters when in the data section + unsubscribers.push( + inlineFilters.subscribe($inlineFilters => { + if (!get(config).canSaveSchema) { + return + } + const $fetch = get(fetch) + if ($fetch?.options?.datasource?.id !== $datasource.id) { + return + } + $fetch.update({ + filter: $inlineFilters, + }) + }) + ) + + // Keep fetch up to date with all filters when not in the data section unsubscribers.push( allFilters.subscribe($allFilters => { - // Ensure we're updating the correct fetch + if (get(config).canSaveSchema) { + return + } const $fetch = get(fetch) - if ($fetch?.options?.datasource?.tableId !== $datasource.tableId) { + if ($fetch?.options?.datasource?.id !== $datasource.id) { return } $fetch.update({ diff --git a/packages/frontend-core/src/components/grid/stores/filter.js b/packages/frontend-core/src/components/grid/stores/filter.js index f5feee9c35..6e6c37da87 100644 --- a/packages/frontend-core/src/components/grid/stores/filter.js +++ b/packages/frontend-core/src/components/grid/stores/filter.js @@ -1,12 +1,13 @@ -import { writable, get, derived } from "svelte/store" +import { get, derived } from "svelte/store" import { FieldType, FilterGroupLogicalOperator } from "@budibase/types" +import { memo } from "../../../utils/memo" export const createStores = context => { const { props } = context // Initialise to default props - const filter = writable(get(props).initialFilter) - const inlineFilters = writable([]) + const filter = memo(get(props).initialFilter) + const inlineFilters = memo([]) return { filter, @@ -19,19 +20,26 @@ export const deriveStores = context => { const allFilters = derived( [filter, inlineFilters], ([$filter, $inlineFilters]) => { - const inlineFilterGroup = $inlineFilters?.length - ? { + // Just use filter prop if no inline filters + if (!$inlineFilters?.length) { + return $filter + } + let allFilters = { + logicalOperator: FilterGroupLogicalOperator.ALL, + groups: [ + { logicalOperator: FilterGroupLogicalOperator.ALL, - filters: [...($inlineFilters || [])], - } - : null - - return inlineFilterGroup - ? { - logicalOperator: FilterGroupLogicalOperator.ALL, - groups: [...($filter?.groups || []), inlineFilterGroup], - } - : $filter + filters: $inlineFilters, + }, + ], + } + // Just use inline if no filter + if (!$filter?.groups?.length) { + return allFilters + } + // Join them together if both + allFilters.groups = [...allFilters.groups, ...$filter.groups] + return allFilters } ) diff --git a/packages/frontend-core/src/fetch/DataFetch.js b/packages/frontend-core/src/fetch/DataFetch.js index 246cc4f804..a056cdff5d 100644 --- a/packages/frontend-core/src/fetch/DataFetch.js +++ b/packages/frontend-core/src/fetch/DataFetch.js @@ -178,7 +178,6 @@ export default class DataFetch { // Build the query let query = this.options.query - if (!query && this.features.supportsSearch) { query = buildQuery(filter) } @@ -365,7 +364,9 @@ export default class DataFetch { let refresh = false const entries = Object.entries(newOptions || {}) for (let [key, value] of entries) { - if (JSON.stringify(value) !== JSON.stringify(this.options[key])) { + const oldVal = this.options[key] == null ? null : this.options[key] + const newVal = value == null ? null : value + if (JSON.stringify(newVal) !== JSON.stringify(oldVal)) { refresh = true break } diff --git a/packages/frontend-core/src/fetch/ViewV2Fetch.js b/packages/frontend-core/src/fetch/ViewV2Fetch.js index 46343492b4..40135746df 100644 --- a/packages/frontend-core/src/fetch/ViewV2Fetch.js +++ b/packages/frontend-core/src/fetch/ViewV2Fetch.js @@ -1,6 +1,5 @@ import DataFetch from "./DataFetch.js" import { get } from "svelte/store" -import { utils } from "@budibase/shared-core" export default class ViewV2Fetch extends DataFetch { determineFeatureFlags() { @@ -36,15 +35,8 @@ export default class ViewV2Fetch extends DataFetch { } async getData() { - const { - datasource, - limit, - sortColumn, - sortOrder, - sortType, - paginate, - filter, - } = this.options + const { datasource, limit, sortColumn, sortOrder, sortType, paginate } = + this.options const { cursor, query, definition } = get(this.store) // If sort/filter params are not defined, update options to store the @@ -55,12 +47,6 @@ export default class ViewV2Fetch extends DataFetch { this.options.sortOrder = definition.sort.order } - const parsed = utils.processSearchFilters(filter) - - if (!parsed?.groups?.length && definition.query?.groups?.length) { - this.options.filter = definition.query - } - try { const res = await this.API.viewV2.fetch({ viewId: datasource.id,