diff --git a/packages/applet/src/modules/components/index.vue b/packages/applet/src/modules/components/index.vue index 3e2b57149..5ce172c0a 100644 --- a/packages/applet/src/modules/components/index.vue +++ b/packages/applet/src/modules/components/index.vue @@ -16,9 +16,12 @@ import ComponentTree from '~/components/tree/TreeViewer.vue' import { createExpandedContext } from '~/composables/toggle-expanded' import { createSelectedContext } from '~/composables/select' import RootStateViewer from '~/components/state/RootStateViewer.vue' -import { searchDeepInObject } from '~/utils' +import { getValidNodeId, searchDeepInObject } from '~/utils' -const emit = defineEmits(['openInEditor', 'onInspectComponentStart', 'onInspectComponentEnd']) +const props = defineProps<{ + savedSelectedId?: string +}>() +const emit = defineEmits(['openInEditor', 'onInspectComponentStart', 'onInspectComponentEnd', 'onSelectId']) // responsive layout const splitpanesRef = ref() const splitpanesReady = ref(false) @@ -133,7 +136,7 @@ async function getComponentsInspectorTree(filter = '') { return rpc.value.getInspectorTree({ inspectorId, filter }).then((data) => { const res = parse(data) tree.value = res - activeComponentId.value = tree.value?.[0]?.id + activeComponentId.value = getValidNodeId(tree.value, props.savedSelectedId) || tree.value?.[0]?.id expandedTreeNodes.value = getNodesByDepth(treeNodeLinkedList.value, 1) componentTreeLoaded.value = true }) @@ -163,6 +166,7 @@ function getComponentState(id: string) { watch(activeComponentId, (id) => { getComponentState(id) + emit('onSelectId', id) if (componentRenderCodeVisible.value) { getComponentRenderCode() } diff --git a/packages/applet/src/modules/custom-inspector/components/state/Index.vue b/packages/applet/src/modules/custom-inspector/components/state/Index.vue index 133e4ef63..c46cf2135 100644 --- a/packages/applet/src/modules/custom-inspector/components/state/Index.vue +++ b/packages/applet/src/modules/custom-inspector/components/state/Index.vue @@ -11,9 +11,17 @@ import DevToolsHeader from '~/components/basic/DevToolsHeader.vue' import Empty from '~/components/basic/Empty.vue' import RootStateViewer from '~/components/state/RootStateViewer.vue' import { createExpandedContext } from '~/composables/toggle-expanded' +import { getValidNodeId } from '~/utils' import { useCustomInspectorState } from '~/composables/custom-inspector-state' import ComponentTree from '~/components/tree/TreeViewer.vue' +const props = defineProps<{ + savedSelectedId?: string +}>() +const emit = defineEmits<{ + (e: 'onSelectId', id: string): void +}>() + const { expanded: expandedTreeNodes } = createExpandedContext() const { expanded: expandedStateNodes } = createExpandedContext('custom-inspector-state') @@ -118,6 +126,7 @@ function clearInspectorState() { watch(selected, () => { clearInspectorState() getInspectorState(selected.value) + emit('onSelectId', selected.value) }) const getInspectorTree = () => { @@ -125,9 +134,9 @@ const getInspectorTree = () => { const data = parse(_data!) tree.value = data if (!selected.value && data.length) { - selected.value = data[0].id + selected.value = getValidNodeId(tree.value, props.savedSelectedId) || data[0].id expandedTreeNodes.value = getNodesByDepth(treeNodeLinkedList.value, 1) - getInspectorState(data[0].id) + getInspectorState(selected.value) } }) } diff --git a/packages/applet/src/modules/custom-inspector/index.vue b/packages/applet/src/modules/custom-inspector/index.vue index 4f3fe4c9e..af885de46 100644 --- a/packages/applet/src/modules/custom-inspector/index.vue +++ b/packages/applet/src/modules/custom-inspector/index.vue @@ -11,9 +11,10 @@ import { createCustomInspectorStateContext } from '~/composables/custom-inspecto const props = defineProps<{ id: string + savedSelectedId?: string }>() +const emit = defineEmits(['loadError', 'onSelectId']) -const emit = defineEmits(['loadError']) const inspectorState = createCustomInspectorStateContext() const loading = ref(false) @@ -74,6 +75,10 @@ watch(() => props.id, () => { onUnmounted(() => { rpc.value.unhighlight() }) + +function handleSelectId(id: string) { + emit('onSelectId', id) +} diff --git a/packages/applet/src/modules/pinia/components/store/Index.vue b/packages/applet/src/modules/pinia/components/store/Index.vue index e3b764446..1513fbe92 100644 --- a/packages/applet/src/modules/pinia/components/store/Index.vue +++ b/packages/applet/src/modules/pinia/components/store/Index.vue @@ -10,9 +10,16 @@ import DevToolsHeader from '~/components/basic/DevToolsHeader.vue' import Empty from '~/components/basic/Empty.vue' import RootStateViewer from '~/components/state/RootStateViewer.vue' import ComponentTree from '~/components/tree/TreeViewer.vue' - +import { getValidNodeId } from '~/utils' import { createExpandedContext } from '~/composables/toggle-expanded' +const props = defineProps<{ + savedSelectedId?: string +}>() +const emit = defineEmits<{ + (e: 'onSelectId', id: string): void +}>() + const { expanded: expandedTreeNodes } = createExpandedContext() const { expanded: expandedStateNodes } = createExpandedContext('pinia-store-state') @@ -116,6 +123,7 @@ function clearPiniaState() { watch(selected, () => { clearPiniaState() getPiniaState(selected.value) + emit('onSelectId', selected.value) }) const getPiniaInspectorTree = () => { @@ -123,8 +131,8 @@ const getPiniaInspectorTree = () => { const data = parse(_data!) tree.value = data if (!selected.value && data.length) { - selected.value = data[0].id - getPiniaState(data[0].id) + selected.value = getValidNodeId(tree.value, props.savedSelectedId) || data[0].id + getPiniaState(selected.value) expandedTreeNodes.value = getNodesByDepth(treeNodeLinkedList.value, 1) } }) diff --git a/packages/applet/src/modules/pinia/index.vue b/packages/applet/src/modules/pinia/index.vue index 595bd6d68..8a085f40c 100644 --- a/packages/applet/src/modules/pinia/index.vue +++ b/packages/applet/src/modules/pinia/index.vue @@ -4,6 +4,13 @@ import Store from './components/store/Index.vue' import Timeline from './components/timeline/Index.vue' import { registerVirtualRouter } from '~/composables/virtual-router' +const props = defineProps<{ + savedSelectedId?: string +}>() +const emit = defineEmits<{ + (e: 'onSelectId', id: string): void +}>() + const { VirtualRouterView } = registerVirtualRouter([ { path: '/store', @@ -26,10 +33,14 @@ const { VirtualRouterView } = registerVirtualRouter([ ], { defaultRoutePath: '/store', }) + +const handleSelectId = (id: string) => { + emit('onSelectId', id) +} diff --git a/packages/applet/src/modules/router/components/routes/Index.vue b/packages/applet/src/modules/router/components/routes/Index.vue index 448399673..53b9d2ba3 100644 --- a/packages/applet/src/modules/router/components/routes/Index.vue +++ b/packages/applet/src/modules/router/components/routes/Index.vue @@ -11,8 +11,16 @@ import Empty from '~/components/basic/Empty.vue' import RootStateViewer from '~/components/state/RootStateViewer.vue' import { createExpandedContext } from '~/composables/toggle-expanded' import { useCustomInspectorState } from '~/composables/custom-inspector-state' +import { getValidNodeId } from '~/utils' import ComponentTree from '~/components/tree/TreeViewer.vue' +const props = defineProps<{ + savedSelectedId?: string +}>() +const emit = defineEmits<{ + (e: 'onSelectId', id: string): void +}>() + const { expanded: expandedTreeNodes } = createExpandedContext() const { expanded: expandedStateNodes } = createExpandedContext('routes-state') @@ -90,6 +98,7 @@ function clearRoutesState() { watch(selected, () => { clearRoutesState() getRoutesState(selected.value) + emit('onSelectId', selected.value) }) const getRoutesInspectorTree = () => { @@ -97,8 +106,8 @@ const getRoutesInspectorTree = () => { const data = parse(_data!) tree.value = data if (!selected.value && data.length) { - selected.value = data[0].id - getRoutesState(data[0].id) + selected.value = getValidNodeId(data, props.savedSelectedId) || data[0].id + getRoutesState(selected.value) expandedTreeNodes.value = getNodesByDepth(treeNodeLinkedList.value, 1) } }) diff --git a/packages/applet/src/modules/router/index.vue b/packages/applet/src/modules/router/index.vue index b134b5883..97bf8ee62 100644 --- a/packages/applet/src/modules/router/index.vue +++ b/packages/applet/src/modules/router/index.vue @@ -9,7 +9,12 @@ import { createCustomInspectorStateContext } from '~/composables/custom-inspecto const props = defineProps<{ id: string + savedSelectedId?: string }>() +const emit = defineEmits<{ + (e: 'onSelectId', id: string): void +}>() + const inspectorState = createCustomInspectorStateContext() const loading = ref(false) const { VirtualRouterView, restoreRouter } = registerVirtualRouter([ @@ -61,10 +66,14 @@ watch(() => props.id, (v) => { getInspectorInfo() } }) + +const handleSelectId = (id: string) => { + emit('onSelectId', id) +} diff --git a/packages/applet/src/utils/search.ts b/packages/applet/src/utils/search.ts index 3ba452a6a..08a330835 100644 --- a/packages/applet/src/utils/search.ts +++ b/packages/applet/src/utils/search.ts @@ -1,4 +1,5 @@ import { INFINITY, NAN, NEGATIVE_INFINITY, UNDEFINED, isPlainObject } from '@vue/devtools-kit' +import type { CustomInspectorNode } from '@vue/devtools-kit' /** * Searches a key or value in the object, with a maximum deepness @@ -132,3 +133,10 @@ function internalSearchArray(array, searchTerm, seen, depth) { } return match } + +/** + * Recursively search for target tree Id in nodes and there children + */ +export function getValidNodeId(treeNode: CustomInspectorNode[], targetId?: string) { + return treeNode.some(({ id: treeNodeId, children }) => (children && getValidNodeId(children, targetId)) || treeNodeId === targetId) && (targetId as string) +} diff --git a/packages/client/src/composables/select.ts b/packages/client/src/composables/select.ts index df68e63b7..b9f487b46 100644 --- a/packages/client/src/composables/select.ts +++ b/packages/client/src/composables/select.ts @@ -44,3 +44,21 @@ export function useSelectWithContext(groupId: string, id: string, onSelect?: (id toggleSelected, } } + +export function useDefaultSelect() { + const router = useRouter() + const route = useRoute() + + function saveSelectedId(id: string) { + router.push({ + params: { + id, + }, + }) + } + + return { + saveSelectedId, + savedSelectedId: route.params.id as string, + } +} diff --git a/packages/client/src/main.ts b/packages/client/src/main.ts index 0bc02ca97..f0285ba6c 100644 --- a/packages/client/src/main.ts +++ b/packages/client/src/main.ts @@ -28,15 +28,15 @@ import '~/assets/styles/main.css' const routes = [ { path: '/', component: Index }, { path: '/overview', component: Overview }, - { path: '/components', component: Components }, - { path: '/pinia', component: PiniaPage }, - { path: '/router', component: RouterPage }, + { path: '/components/:id?', component: Components }, + { path: '/pinia/:id?', component: PiniaPage }, + { path: '/router/:id?', component: RouterPage }, { path: '/pages', component: Pages }, { path: '/assets', component: Assets }, { path: '/graph', component: Graph }, { path: '/settings', component: Settings }, { path: `/${CUSTOM_TAB_VIEW}/:name`, component: CustomTabView }, - { path: `/${CUSTOM_INSPECTOR_TAB_VIEW}/:name`, component: CustomInspectorTabView }, + { path: `/${CUSTOM_INSPECTOR_TAB_VIEW}/:name/:id?`, component: CustomInspectorTabView }, ] const router = createRouter({ diff --git a/packages/client/src/pages/components.vue b/packages/client/src/pages/components.vue index c042e417a..03cb42e27 100644 --- a/packages/client/src/pages/components.vue +++ b/packages/client/src/pages/components.vue @@ -3,6 +3,7 @@ import { Components as ComponentsPanel } from '@vue/devtools-applet' import '@vue/devtools-applet/style.css' import { rpc } from '@vue/devtools-core' import { openInEditor } from '../composables/open-in-editor' +import { useDefaultSelect } from '../composables/select' function onInspectComponentStart() { rpc.value.emit('toggle-panel', false) @@ -11,12 +12,16 @@ function onInspectComponentStart() { function onInspectComponentEnd() { rpc.value.emit('toggle-panel', true) } + +const { saveSelectedId, savedSelectedId } = useDefaultSelect() diff --git a/packages/client/src/pages/custom-inspector-tab-view.vue b/packages/client/src/pages/custom-inspector-tab-view.vue index 47238e392..1ddf33475 100644 --- a/packages/client/src/pages/custom-inspector-tab-view.vue +++ b/packages/client/src/pages/custom-inspector-tab-view.vue @@ -1,5 +1,6 @@ diff --git a/packages/client/src/pages/pinia.vue b/packages/client/src/pages/pinia.vue index 11d7d1c9c..86e224edc 100644 --- a/packages/client/src/pages/pinia.vue +++ b/packages/client/src/pages/pinia.vue @@ -1,8 +1,14 @@ diff --git a/packages/client/src/pages/router.vue b/packages/client/src/pages/router.vue index a53e3402d..3a0a5525f 100644 --- a/packages/client/src/pages/router.vue +++ b/packages/client/src/pages/router.vue @@ -1,8 +1,11 @@