Merge pull request #14614 from Budibase/view-filters-update

Update view handling of filters
This commit is contained in:
Andrew Kingston 2024-09-20 14:40:43 +01:00 committed by GitHub
commit 2a7686a11c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 69 additions and 55 deletions

View File

@ -97,9 +97,12 @@ export const initialise = context => {
order: get(initialSortOrder) || "ascending", 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( unsubscribers.push(
definition.subscribe($definition => { definition.subscribe($definition => {
if (!get(config).canSaveSchema) {
return
}
if ($definition?.id !== $datasource.id) { if ($definition?.id !== $datasource.id) {
return return
} }
@ -122,7 +125,6 @@ export const initialise = context => {
sort.subscribe(async $sort => { sort.subscribe(async $sort => {
// If we can mutate schema then update the view definition // If we can mutate schema then update the view definition
if (get(config).canSaveSchema) { if (get(config).canSaveSchema) {
// Ensure we're updating the correct view
const $view = get(definition) const $view = get(definition)
if ($view?.id !== $datasource.id) { if ($view?.id !== $datasource.id) {
return return
@ -144,7 +146,7 @@ export const initialise = context => {
// Also update the fetch to ensure the new sort is respected. // Also update the fetch to ensure the new sort is respected.
// Ensure we're updating the correct fetch. // Ensure we're updating the correct fetch.
const $fetch = get(fetch) const $fetch = get(fetch)
if ($fetch?.options?.datasource?.tableId !== $datasource.tableId) { if ($fetch?.options?.datasource?.id !== $datasource.id) {
return return
} }
$fetch.update({ $fetch.update({
@ -157,32 +159,49 @@ export const initialise = context => {
// When filters change, ensure view definition is kept up to date // When filters change, ensure view definition is kept up to date
unsubscribers?.push( unsubscribers?.push(
filter.subscribe(async $filter => { filter.subscribe(async $filter => {
// If we can mutate schema then update the view definition if (!get(config).canSaveSchema) {
if (get(config).canSaveSchema) { return
// Ensure we're updating the correct view }
const $view = get(definition) const $view = get(definition)
if ($view?.id !== $datasource.id) { if ($view?.id !== $datasource.id) {
return return
} }
if (JSON.stringify($filter) !== JSON.stringify($view.query)) { if (JSON.stringify($filter) !== JSON.stringify($view.query)) {
await datasource.actions.saveDefinition({ await datasource.actions.saveDefinition({
...$view, ...$view,
query: $filter, query: $filter,
}) })
}
// Refresh data since view definition changed
await rows.actions.refreshData()
} }
}) })
) )
// Keep fetch up to date with filters. // Keep fetch up to date with inline filters when in the data section
// If we're able to save filters against the view then we only need to apply unsubscribers.push(
// inline filters to the fetch, as saved filters are applied server side. inlineFilters.subscribe($inlineFilters => {
// If we can't save filters, then all filters must be applied to the fetch. 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( unsubscribers.push(
allFilters.subscribe($allFilters => { allFilters.subscribe($allFilters => {
// Ensure we're updating the correct fetch if (get(config).canSaveSchema) {
return
}
const $fetch = get(fetch) const $fetch = get(fetch)
if ($fetch?.options?.datasource?.tableId !== $datasource.tableId) { if ($fetch?.options?.datasource?.id !== $datasource.id) {
return return
} }
$fetch.update({ $fetch.update({

View File

@ -1,12 +1,13 @@
import { writable, get, derived } from "svelte/store" import { get, derived } from "svelte/store"
import { FieldType, FilterGroupLogicalOperator } from "@budibase/types" import { FieldType, FilterGroupLogicalOperator } from "@budibase/types"
import { memo } from "../../../utils/memo"
export const createStores = context => { export const createStores = context => {
const { props } = context const { props } = context
// Initialise to default props // Initialise to default props
const filter = writable(get(props).initialFilter) const filter = memo(get(props).initialFilter)
const inlineFilters = writable([]) const inlineFilters = memo([])
return { return {
filter, filter,
@ -19,19 +20,26 @@ export const deriveStores = context => {
const allFilters = derived( const allFilters = derived(
[filter, inlineFilters], [filter, inlineFilters],
([$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, logicalOperator: FilterGroupLogicalOperator.ALL,
filters: [...($inlineFilters || [])], filters: $inlineFilters,
} },
: null ],
}
return inlineFilterGroup // Just use inline if no filter
? { if (!$filter?.groups?.length) {
logicalOperator: FilterGroupLogicalOperator.ALL, return allFilters
groups: [...($filter?.groups || []), inlineFilterGroup], }
} // Join them together if both
: $filter allFilters.groups = [...allFilters.groups, ...$filter.groups]
return allFilters
} }
) )

View File

@ -178,7 +178,6 @@ export default class DataFetch {
// Build the query // Build the query
let query = this.options.query let query = this.options.query
if (!query && this.features.supportsSearch) { if (!query && this.features.supportsSearch) {
query = buildQuery(filter) query = buildQuery(filter)
} }
@ -365,7 +364,9 @@ export default class DataFetch {
let refresh = false let refresh = false
const entries = Object.entries(newOptions || {}) const entries = Object.entries(newOptions || {})
for (let [key, value] of entries) { 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 refresh = true
break break
} }

View File

@ -1,6 +1,5 @@
import DataFetch from "./DataFetch.js" import DataFetch from "./DataFetch.js"
import { get } from "svelte/store" import { get } from "svelte/store"
import { utils } from "@budibase/shared-core"
export default class ViewV2Fetch extends DataFetch { export default class ViewV2Fetch extends DataFetch {
determineFeatureFlags() { determineFeatureFlags() {
@ -36,15 +35,8 @@ export default class ViewV2Fetch extends DataFetch {
} }
async getData() { async getData() {
const { const { datasource, limit, sortColumn, sortOrder, sortType, paginate } =
datasource, this.options
limit,
sortColumn,
sortOrder,
sortType,
paginate,
filter,
} = this.options
const { cursor, query, definition } = get(this.store) const { cursor, query, definition } = get(this.store)
// If sort/filter params are not defined, update options to store the // 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 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 { try {
const res = await this.API.viewV2.fetch({ const res = await this.API.viewV2.fetch({
viewId: datasource.id, viewId: datasource.id,