Skip to content

Commit

Permalink
fix(components): improved tree loading
Browse files Browse the repository at this point in the history
  • Loading branch information
Akryum committed Dec 20, 2021
1 parent 76981b5 commit 9e9e81c
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 66 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ export default defineComponent({
select,
isExpanded: expanded,
isExpandedUndefined,
checkIsExpanded,
isComponentOpen,
toggleExpand: toggle,
subscribeToComponentTree,
} = useComponent(instance)
Expand All @@ -50,7 +50,7 @@ export default defineComponent({
onMounted(() => {
if (isExpandedUndefined.value && props.depth < DEFAULT_EXPAND_DEPTH) {
toggle(false)
toggle()
}
})
Expand Down Expand Up @@ -129,7 +129,7 @@ export default defineComponent({
} else {
let child = sortedChildren.value[index - 1]
while (child) {
if (child.children.length && checkIsExpanded(child.id)) {
if (child.children.length && isComponentOpen(child.id)) {
const children = sortChildren(child.children)
child = children[children.length - 1]
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ export default defineComponent({
subscribeToSelectedData()
onMounted(() => {
requestComponentTree(null)
selectLastComponent()
})
Expand Down Expand Up @@ -90,12 +89,12 @@ export default defineComponent({
<template #left>
<div class="flex flex-col h-full">
<VueInput
ref="treeFilterInput"
v-model="treeFilter"
v-tooltip="{
content: $t('ComponentTree.filter.tooltip'),
html: true
}"
ref="treeFilterInput"
v-model="treeFilter"
icon-left="search"
placeholder="Find components..."
select-all
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ref, computed, watch, Ref } from '@vue/composition-api'
import { ref, computed, watch, Ref, onMounted } from '@vue/composition-api'
import { ComponentTreeNode, EditStatePayload, InspectedComponentData } from '@vue/devtools-api'
import Vue from 'vue'
import groupBy from 'lodash/groupBy'
Expand Down Expand Up @@ -26,7 +26,6 @@ export const selectedComponentPendingId = ref<ComponentTreeNode['id']>(null)
let lastSelectedApp: AppRecord = null
export const lastSelectedComponentId: Record<AppRecord['id'], ComponentTreeNode['id']> = {}
export const expandedMap = ref<Record<ComponentTreeNode['id'], boolean>>({})
export const resetComponentsQueued = ref(false)

export function useComponentRequests () {
const router = useRouter()
Expand Down Expand Up @@ -134,17 +133,13 @@ export function useComponent (instance: Ref<ComponentTreeNode>) {
const { selectComponent, requestComponentTree } = useComponentRequests()
const { subscribe } = useBridge()

function checkIsExpanded (id) {
return !!expandedMap.value[id]
}

const isExpanded = computed(() => checkIsExpanded(instance.value.id))
const isExpanded = computed(() => isComponentOpen(instance.value.id))
const isExpandedUndefined = computed(() => expandedMap.value[instance.value.id] == null)

function toggleExpand (load = true) {
function toggleExpand () {
if (!instance.value.hasChildren) return
setComponentOpen(instance.value.id, !isExpanded.value)
if (load) {
if (isComponentOpen(instance.value.id)) {
requestComponentTree(instance.value.id)
}
}
Expand Down Expand Up @@ -173,14 +168,16 @@ export function useComponent (instance: Ref<ComponentTreeNode>) {
})
}

if (isExpanded.value) {
requestComponentTree(instance.value.id)
}
onMounted(() => {
if (isExpanded.value) {
requestComponentTree(instance.value.id)
}
})

return {
isExpanded,
isExpandedUndefined,
checkIsExpanded,
isComponentOpen,
toggleExpand,
isSelected,
select,
Expand All @@ -192,6 +189,10 @@ export function setComponentOpen (id: ComponentTreeNode['id'], isOpen: boolean)
Vue.set(expandedMap.value, id, isOpen)
}

export function isComponentOpen (id) {
return !!expandedMap.value[id]
}

export function useSelectedComponent () {
const data = computed(() => selectedComponentData.value)
const state = computed(() => selectedComponentData.value
Expand Down Expand Up @@ -255,7 +256,6 @@ export function useSelectedComponent () {
}

export function resetComponents () {
resetComponentsQueued.value = false
rootInstances.value = []
componentsMap.value = {}
componentsParent = {}
Expand All @@ -273,9 +273,6 @@ export async function requestComponentTree (instanceId: ComponentTreeNode['id']
}
requestedComponentTree.add(instanceId)

if (instanceId === '_root') {
resetComponentsQueued.value = true
}
await waitForAppSelect()

getBridge().send(BridgeEvents.TO_BACK_COMPONENT_TREE, {
Expand All @@ -284,35 +281,45 @@ export async function requestComponentTree (instanceId: ComponentTreeNode['id']
})
}

export function restoreChildrenFromComponentsMap (data: ComponentTreeNode) {
const instance = componentsMap.value[data.id]
if (instance && data.hasChildren) {
if (!data.children.length && instance.children.length) {
data.children = instance.children
} else {
for (const child of data.children) {
restoreChildrenFromComponentsMap(child)
}
}
export function ensureComponentsMapData (data: ComponentTreeNode) {
let component = componentsMap.value[data.id]
if (!component) {
component = addToComponentsMap(data)
} else {
component = updateComponentsMapData(data)
}
return component
}

function ensureComponentsMapChildren (id: string, children: ComponentTreeNode[]) {
const result = children.map(child => ensureComponentsMapData(child))
for (const child of children) {
componentsParent[child.id] = id
}
return result
}

export function updateComponentsMapData (data: ComponentTreeNode) {
function updateComponentsMapData (data: ComponentTreeNode) {
const component = componentsMap.value[data.id]
for (const key in data) {
Vue.set(component, key, data[key])
if (key === 'children') {
if (!data.hasChildren || data.children.length) {
const children = ensureComponentsMapChildren(component.id, data.children)
Vue.set(component, key, children)
}
} else {
Vue.set(component, key, data[key])
}
}
return component
}

export function addToComponentsMap (instance: ComponentTreeNode) {
componentsMap.value[instance.id] = instance
if (instance.children) {
instance.children.forEach(c => {
componentsParent[c.id] = instance.id
addToComponentsMap(c)
})
function addToComponentsMap (data: ComponentTreeNode) {
if (!data.hasChildren || data.children.length) {
data.children = ensureComponentsMapChildren(data.id, data.children)
}
componentsMap.value[data.id] = data
return data
}

export async function loadComponent (id: ComponentTreeNode['id']) {
Expand Down
33 changes: 11 additions & 22 deletions packages/app-frontend/src/features/components/composable/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,12 @@ import { Bridge, BridgeEvents, parse, getStorage } from '@vue-devtools/shared-ut
import { putError } from '@front/features/error'
import {
selectedComponentPendingId,
resetComponentsQueued,
resetComponents,
componentsMap,
restoreChildrenFromComponentsMap,
updateComponentsMapData,
addToComponentsMap,
ensureComponentsMapData,
rootInstances,
selectedComponentId,
selectedComponentData,
loadComponent,
isComponentOpen,
setComponentOpen,
requestComponentTree,
requestedComponentTree,
Expand All @@ -27,11 +23,6 @@ export function setupComponentsBridgeEvents (bridge: Bridge) {

const isRoot = instanceId.endsWith('root')

// Reset
if (resetComponentsQueued.value) {
resetComponents()
}

// Not supported
if (!treeData) {
if (isRoot && !notFound) {
Expand All @@ -42,16 +33,12 @@ export function setupComponentsBridgeEvents (bridge: Bridge) {

// Handle tree data
const data = parse(treeData)
const instance = componentsMap.value[instanceId]
if (instance) {
for (const item of data) {
restoreChildrenFromComponentsMap(item)
const component = updateComponentsMapData(item)
addToComponentsMap(component)
if (isRoot) {
rootInstances.value = data.map(i => ensureComponentsMapData(i))
} else {
for (const child of data) {
ensureComponentsMapData(child)
}
} else if (Array.isArray(data)) {
rootInstances.value = data
data.forEach(i => addToComponentsMap(i))
}

// Try to load selected component again
Expand All @@ -72,8 +59,10 @@ export function setupComponentsBridgeEvents (bridge: Bridge) {
parentIds.reverse().forEach(id => {
// Ignore root
if (id.endsWith('root')) return
setComponentOpen(id, true)
requestComponentTree(id)
if (!isComponentOpen(id)) {
setComponentOpen(id, true)
requestComponentTree(id)
}
})
}
})
Expand Down
3 changes: 1 addition & 2 deletions packages/shell-host/src/DevIframe.vue
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,11 @@ export default defineComponent({
},
onReload (reloadFn) {
loadListener = reloadFn
iframe.value.addEventListener('load', reloadFn)
},
})
iframe.value.contentWindow.addEventListener('unload', () => {
if (loadListener) iframe.value.removeEventListener('load', loadListener)
if (loadListener) loadListener()
loading.value = true
})
} catch (e) {
Expand Down

0 comments on commit 9e9e81c

Please sign in to comment.