Broke out the hover tracking into its own store. Value check on the button group to mitigate excessive rendering. Fix for relationship field
This commit is contained in:
parent
164543acae
commit
361fea2a6b
|
@ -9,6 +9,7 @@ import { findComponent, findComponentPath } from "./componentUtils"
|
||||||
import { RoleUtils } from "@budibase/frontend-core"
|
import { RoleUtils } from "@budibase/frontend-core"
|
||||||
import { createHistoryStore } from "builderStore/store/history"
|
import { createHistoryStore } from "builderStore/store/history"
|
||||||
import { cloneDeep } from "lodash/fp"
|
import { cloneDeep } from "lodash/fp"
|
||||||
|
import { getHoverStore } from "./store/hover"
|
||||||
|
|
||||||
export const store = getFrontendStore()
|
export const store = getFrontendStore()
|
||||||
export const automationStore = getAutomationStore()
|
export const automationStore = getAutomationStore()
|
||||||
|
@ -16,6 +17,7 @@ export const themeStore = getThemeStore()
|
||||||
export const temporalStore = getTemporalStore()
|
export const temporalStore = getTemporalStore()
|
||||||
export const userStore = getUserStore()
|
export const userStore = getUserStore()
|
||||||
export const deploymentStore = getDeploymentStore()
|
export const deploymentStore = getDeploymentStore()
|
||||||
|
export const hoverStore = getHoverStore()
|
||||||
|
|
||||||
// Setup history for screens
|
// Setup history for screens
|
||||||
export const screenHistoryStore = createHistoryStore({
|
export const screenHistoryStore = createHistoryStore({
|
||||||
|
|
|
@ -92,9 +92,6 @@ const INITIAL_FRONTEND_STATE = {
|
||||||
// Onboarding
|
// Onboarding
|
||||||
onboarding: false,
|
onboarding: false,
|
||||||
tourNodes: null,
|
tourNodes: null,
|
||||||
|
|
||||||
// UI state
|
|
||||||
hoveredComponentId: null,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getFrontendStore = () => {
|
export const getFrontendStore = () => {
|
||||||
|
@ -1415,18 +1412,6 @@ export const getFrontendStore = () => {
|
||||||
return state
|
return state
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
hover: (componentId, notifyClient = true) => {
|
|
||||||
if (componentId === get(store).hoveredComponentId) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
store.update(state => {
|
|
||||||
state.hoveredComponentId = componentId
|
|
||||||
return state
|
|
||||||
})
|
|
||||||
if (notifyClient) {
|
|
||||||
store.actions.preview.sendEvent("hover-component", componentId)
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
links: {
|
links: {
|
||||||
save: async (url, title) => {
|
save: async (url, title) => {
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
import { get, writable } from "svelte/store"
|
||||||
|
import { store as builder } from "builderStore"
|
||||||
|
|
||||||
|
export const getHoverStore = () => {
|
||||||
|
const initialValue = {
|
||||||
|
componentId: null,
|
||||||
|
}
|
||||||
|
|
||||||
|
const store = writable(initialValue)
|
||||||
|
|
||||||
|
const update = (componentId, notifyClient = true) => {
|
||||||
|
if (componentId === get(store).componentId) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
store.update(state => {
|
||||||
|
state.componentId = componentId
|
||||||
|
return state
|
||||||
|
})
|
||||||
|
if (notifyClient) {
|
||||||
|
builder.actions.preview.sendEvent("hover-component", componentId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
subscribe: store.subscribe,
|
||||||
|
actions: { update },
|
||||||
|
}
|
||||||
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
import { store } from "builderStore"
|
import { store } from "builderStore"
|
||||||
import { Helpers } from "@budibase/bbui"
|
import { Helpers } from "@budibase/bbui"
|
||||||
import { getEventContextBindings } from "builderStore/dataBinding"
|
import { getEventContextBindings } from "builderStore/dataBinding"
|
||||||
|
import { cloneDeep, isEqual } from "lodash/fp"
|
||||||
|
|
||||||
export let componentInstance
|
export let componentInstance
|
||||||
export let componentBindings
|
export let componentBindings
|
||||||
|
@ -17,8 +18,13 @@
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
let focusItem
|
let focusItem
|
||||||
|
let cachedValue
|
||||||
|
|
||||||
$: buttonList = sanitizeValue(value) || []
|
$: if (!isEqual(value, cachedValue)) {
|
||||||
|
cachedValue = cloneDeep(value)
|
||||||
|
}
|
||||||
|
|
||||||
|
$: buttonList = sanitizeValue(cachedValue) || []
|
||||||
$: buttonCount = buttonList.length
|
$: buttonCount = buttonList.length
|
||||||
$: eventContextBindings = getEventContextBindings({
|
$: eventContextBindings = getEventContextBindings({
|
||||||
componentInstance,
|
componentInstance,
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<script>
|
<script>
|
||||||
import { get } from "svelte/store"
|
import { get } from "svelte/store"
|
||||||
import { onMount, onDestroy } from "svelte"
|
import { onMount, onDestroy } from "svelte"
|
||||||
import { store, selectedScreen, currentAsset } from "builderStore"
|
import { store, selectedScreen, currentAsset, hoverStore } from "builderStore"
|
||||||
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
import ConfirmDialog from "components/common/ConfirmDialog.svelte"
|
||||||
import {
|
import {
|
||||||
ProgressCircle,
|
ProgressCircle,
|
||||||
|
@ -118,7 +118,7 @@
|
||||||
} else if (type === "select-component" && data.id) {
|
} else if (type === "select-component" && data.id) {
|
||||||
$store.selectedComponentId = data.id
|
$store.selectedComponentId = data.id
|
||||||
} else if (type === "hover-component") {
|
} else if (type === "hover-component") {
|
||||||
store.actions.components.hover(data.id, false)
|
hoverStore.actions.update(data.id, false)
|
||||||
} else if (type === "update-prop") {
|
} else if (type === "update-prop") {
|
||||||
await store.actions.components.updateSetting(data.prop, data.value)
|
await store.actions.components.updateSetting(data.prop, data.value)
|
||||||
} else if (type === "update-styles") {
|
} else if (type === "update-styles") {
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
selectedComponentPath,
|
selectedComponentPath,
|
||||||
selectedComponent,
|
selectedComponent,
|
||||||
selectedScreen,
|
selectedScreen,
|
||||||
|
hoverStore,
|
||||||
} from "builderStore"
|
} from "builderStore"
|
||||||
import ComponentDropdownMenu from "./ComponentDropdownMenu.svelte"
|
import ComponentDropdownMenu from "./ComponentDropdownMenu.svelte"
|
||||||
import NavItem from "components/common/NavItem.svelte"
|
import NavItem from "components/common/NavItem.svelte"
|
||||||
|
@ -90,7 +91,7 @@
|
||||||
return findComponentPath($selectedComponent, component._id)?.length > 0
|
return findComponentPath($selectedComponent, component._id)?.length > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const hover = store.actions.components.hover
|
const hover = hoverStore.actions.update
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<ul>
|
<ul>
|
||||||
|
@ -111,7 +112,7 @@
|
||||||
on:dragover={dragover(component, index)}
|
on:dragover={dragover(component, index)}
|
||||||
on:iconClick={() => toggleNodeOpen(component._id)}
|
on:iconClick={() => toggleNodeOpen(component._id)}
|
||||||
on:drop={onDrop}
|
on:drop={onDrop}
|
||||||
hovering={$store.hoveredComponentId === component._id}
|
hovering={$hoverStore.componentId === component._id}
|
||||||
on:mouseenter={() => hover(component._id)}
|
on:mouseenter={() => hover(component._id)}
|
||||||
on:mouseleave={() => hover(null)}
|
on:mouseleave={() => hover(null)}
|
||||||
text={getComponentText(component)}
|
text={getComponentText(component)}
|
||||||
|
|
|
@ -1,7 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
import { notifications, Icon, Body } from "@budibase/bbui"
|
import { notifications, Icon, Body } from "@budibase/bbui"
|
||||||
import { isActive, goto } from "@roxi/routify"
|
import { isActive, goto } from "@roxi/routify"
|
||||||
import { store, selectedScreen, userSelectedResourceMap } from "builderStore"
|
import {
|
||||||
|
store,
|
||||||
|
selectedScreen,
|
||||||
|
userSelectedResourceMap,
|
||||||
|
hoverStore,
|
||||||
|
} from "builderStore"
|
||||||
import NavItem from "components/common/NavItem.svelte"
|
import NavItem from "components/common/NavItem.svelte"
|
||||||
import ComponentTree from "./ComponentTree.svelte"
|
import ComponentTree from "./ComponentTree.svelte"
|
||||||
import { dndStore, DropPosition } from "./dndStore.js"
|
import { dndStore, DropPosition } from "./dndStore.js"
|
||||||
|
@ -36,7 +41,7 @@
|
||||||
scrolling = e.target.scrollTop !== 0
|
scrolling = e.target.scrollTop !== 0
|
||||||
}
|
}
|
||||||
|
|
||||||
const hover = store.actions.components.hover
|
const hover = hoverStore.actions.update
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<div class="components">
|
<div class="components">
|
||||||
|
@ -60,7 +65,7 @@
|
||||||
icon="WebPage"
|
icon="WebPage"
|
||||||
on:drop={onDrop}
|
on:drop={onDrop}
|
||||||
on:click={() => ($store.selectedComponentId = screenComponentId)}
|
on:click={() => ($store.selectedComponentId = screenComponentId)}
|
||||||
hovering={$store.hoveredComponentId === screenComponentId}
|
hovering={$hoverStore.componentId === screenComponentId}
|
||||||
on:mouseenter={() => hover(screenComponentId)}
|
on:mouseenter={() => hover(screenComponentId)}
|
||||||
on:mouseleave={() => hover(null)}
|
on:mouseleave={() => hover(null)}
|
||||||
id="component-screen"
|
id="component-screen"
|
||||||
|
@ -79,7 +84,7 @@
|
||||||
: "VisibilityOff"}
|
: "VisibilityOff"}
|
||||||
on:drop={onDrop}
|
on:drop={onDrop}
|
||||||
on:click={() => ($store.selectedComponentId = navComponentId)}
|
on:click={() => ($store.selectedComponentId = navComponentId)}
|
||||||
hovering={$store.hoveredComponentId === navComponentId}
|
hovering={$hoverStore.componentId === navComponentId}
|
||||||
on:mouseenter={() => hover(navComponentId)}
|
on:mouseenter={() => hover(navComponentId)}
|
||||||
on:mouseleave={() => hover(null)}
|
on:mouseleave={() => hover(null)}
|
||||||
id="component-nav"
|
id="component-nav"
|
||||||
|
|
|
@ -108,10 +108,13 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$: forceFetchRows(filter)
|
$: forceFetchRows(filter, fieldApi)
|
||||||
$: debouncedFetchRows(searchTerm, primaryDisplay, defaultValue)
|
$: debouncedFetchRows(searchTerm, primaryDisplay, defaultValue)
|
||||||
|
|
||||||
const forceFetchRows = async () => {
|
const forceFetchRows = async () => {
|
||||||
|
if (!fieldApi) {
|
||||||
|
return
|
||||||
|
}
|
||||||
// if the filter has changed, then we need to reset the options, clear the selection, and re-fetch
|
// if the filter has changed, then we need to reset the options, clear the selection, and re-fetch
|
||||||
optionsObj = {}
|
optionsObj = {}
|
||||||
fieldApi.setValue([])
|
fieldApi.setValue([])
|
||||||
|
|
Loading…
Reference in New Issue