Refactor how relationship cells fetch and cache primary display columns to fix issues with store stale data
This commit is contained in:
parent
23cdac5906
commit
fd15f771ef
|
@ -1,27 +1,10 @@
|
|||
<script context="module">
|
||||
// We can create a module level cache for all relationship cells to avoid
|
||||
// having to fetch the table definition one time for each cell
|
||||
let primaryDisplayCache = {}
|
||||
|
||||
const getPrimaryDisplayForTableId = async (API, tableId) => {
|
||||
if (primaryDisplayCache[tableId]) {
|
||||
return primaryDisplayCache[tableId]
|
||||
}
|
||||
const definition = await API.fetchTableDefinition(tableId)
|
||||
const primaryDisplay =
|
||||
definition?.primaryDisplay || definition?.schema?.[0]?.name
|
||||
primaryDisplayCache[tableId] = primaryDisplay
|
||||
return primaryDisplay
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { getColor } from "../lib/utils"
|
||||
import { onMount, getContext } from "svelte"
|
||||
import { Icon, Input, ProgressCircle, clickOutside } from "@budibase/bbui"
|
||||
import { debounce } from "../../../utils/utils"
|
||||
|
||||
const { API, dispatch } = getContext("grid")
|
||||
const { API, dispatch, cache } = getContext("grid")
|
||||
|
||||
export let value
|
||||
export let api
|
||||
|
@ -147,7 +130,9 @@
|
|||
// Find the primary display for the related table
|
||||
if (!primaryDisplay) {
|
||||
searching = true
|
||||
primaryDisplay = await getPrimaryDisplayForTableId(API, schema.tableId)
|
||||
primaryDisplay = await cache.actions.getPrimaryDisplayForTableId(
|
||||
schema.tableId
|
||||
)
|
||||
}
|
||||
|
||||
// Show initial list of results
|
||||
|
@ -195,7 +180,7 @@
|
|||
const toggleRow = async row => {
|
||||
if (value?.some(x => x._id === row._id)) {
|
||||
// If the row is already included, remove it and update the candidate
|
||||
// row to be the the same position if possible
|
||||
// row to be the same position if possible
|
||||
if (oneRowOnly) {
|
||||
await onChange([])
|
||||
} else {
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
export const createActions = context => {
|
||||
const { API } = context
|
||||
|
||||
// Cache for the primary display columns of different tables.
|
||||
// If we ever need to cache table definitions for other purposes then we can
|
||||
// expand this to be a more generic cache.
|
||||
let primaryDisplayCache = {}
|
||||
|
||||
const resetPrimaryDisplayCache = () => {
|
||||
primaryDisplayCache = {}
|
||||
}
|
||||
|
||||
const getPrimaryDisplayForTableId = async tableId => {
|
||||
// If we've never encountered this tableId before then store a promise that
|
||||
// resolves to the primary display so that subsequent invocations before the
|
||||
// promise completes can reuse this promise
|
||||
if (!primaryDisplayCache[tableId]) {
|
||||
primaryDisplayCache[tableId] = new Promise(resolve => {
|
||||
API.fetchTableDefinition(tableId).then(def => {
|
||||
const display = def?.primaryDisplay || def?.schema?.[0]?.name
|
||||
primaryDisplayCache[tableId] = display
|
||||
resolve(display)
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
// We await the result so that we account for both promises and primitives
|
||||
return await primaryDisplayCache[tableId]
|
||||
}
|
||||
|
||||
return {
|
||||
cache: {
|
||||
actions: {
|
||||
getPrimaryDisplayForTableId,
|
||||
resetPrimaryDisplayCache,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
export const initialise = context => {
|
||||
const { datasource, cache } = context
|
||||
|
||||
// Wipe the caches whenever the datasource changes to ensure we aren't
|
||||
// storing any stale information
|
||||
datasource.subscribe(() => {
|
||||
cache.actions.resetPrimaryDisplayCache()
|
||||
})
|
||||
}
|
|
@ -19,6 +19,7 @@ import * as Datasource from "./datasource"
|
|||
import * as Table from "./datasources/table"
|
||||
import * as ViewV2 from "./datasources/viewV2"
|
||||
import * as NonPlus from "./datasources/nonPlus"
|
||||
import * as Cache from "./cache"
|
||||
|
||||
const DependencyOrderedStores = [
|
||||
Sort,
|
||||
|
@ -42,6 +43,7 @@ const DependencyOrderedStores = [
|
|||
Clipboard,
|
||||
Config,
|
||||
Notifications,
|
||||
Cache,
|
||||
]
|
||||
|
||||
export const attachStores = context => {
|
||||
|
|
Loading…
Reference in New Issue