22import type { CustomInspectorNode , CustomInspectorOptions , CustomInspectorState } from ' @vue/devtools-kit'
33import { DevToolsMessagingEvents , onRpcConnected , rpc } from ' @vue/devtools-core'
44import { parse } from ' @vue/devtools-kit'
5- import { vTooltip , VueIcIcon } from ' @vue/devtools-ui'
5+ import { vTooltip , VueIcIcon , VueInput } from ' @vue/devtools-ui'
66import { until } from ' @vueuse/core'
77import { Pane , Splitpanes } from ' splitpanes'
88import { computed , onUnmounted , ref , watch } from ' vue'
@@ -13,6 +13,7 @@ import RootStateViewer from '~/components/state/RootStateViewer.vue'
1313import ComponentTree from ' ~/components/tree/TreeViewer.vue'
1414import { useCustomInspectorState } from ' ~/composables/custom-inspector-state'
1515import { createExpandedContext } from ' ~/composables/toggle-expanded'
16+ import { filterInspectorState } from ' ~/utils'
1617
1718const { expanded : expandedTreeNodes } = createExpandedContext ()
1819const { expanded : expandedStateNodes } = createExpandedContext (' custom-inspector-state' )
@@ -32,6 +33,24 @@ const selected = ref('')
3233const state = ref <Record <string , CustomInspectorState []>>({})
3334const emptyState = computed (() => ! Object .keys (state .value ).length )
3435
36+ const inspectorState = useCustomInspectorState ()
37+
38+ const filterTreeKey = ref (' ' )
39+ const filterStateKey = ref (' ' )
40+
41+ watch (filterTreeKey , (value , oldValue ) => {
42+ if (! value .trim ().length && ! oldValue .trim ().length )
43+ return
44+ getInspectorTree (value )
45+ })
46+
47+ const displayState = computed (() => {
48+ return filterInspectorState ({
49+ state: state .value ,
50+ filterKey: filterStateKey .value ,
51+ })
52+ })
53+
3554// tree
3655function dfs(node : { id: string , children? : { id: string }[] }, path : string [] = [], linkedList : string [][] = []) {
3756 path .push (node .id )
@@ -120,8 +139,8 @@ watch(selected, () => {
120139 getInspectorState (selected .value )
121140})
122141
123- const getInspectorTree = () => {
124- rpc .value .getInspectorTree ({ inspectorId: inspectorId .value , filter: ' ' }).then ((_data ) => {
142+ function getInspectorTree( filter = ' ' ) {
143+ rpc .value .getInspectorTree ({ inspectorId: inspectorId .value , filter }).then ((_data ) => {
125144 const data = parse (_data ! )
126145 tree .value = data
127146 if (! selected .value && data .length ) {
@@ -132,7 +151,7 @@ const getInspectorTree = () => {
132151 })
133152}
134153
135- until (inspectorId ).toBeTruthy ().then (getInspectorTree )
154+ until (inspectorId ).toBeTruthy ().then (() => getInspectorTree () )
136155
137156function onInspectorTreeUpdated(_data : string ) {
138157 const data = parse (_data ) as {
@@ -179,41 +198,46 @@ onUnmounted(() => {
179198 <DevToolsHeader :doc-link =" customInspectState.homepage!" >
180199 <Navbar />
181200 </DevToolsHeader >
182- <template v-if =" tree .length " >
201+ <Empty v-if =" !tree.length && !filterTreeKey.trim().length" >
202+ No Data
203+ </Empty >
204+ <template v-else >
183205 <Splitpanes class =" flex-1 overflow-auto" >
184206 <Pane border =" r base" size =" 40" h-full >
185207 <div class =" h-full flex flex-col p2" >
186- <div v-if =" actions?.length" class =" mb-1 flex justify-end pb-1" border =" b dashed base" >
187- <div class =" flex items-center gap-2 px-1" >
208+ <div class =" grid grid-cols-[1fr_auto] mb1 items-center gap2 pb1" border =" b dashed base" >
209+ <VueInput v-model =" filterTreeKey" :placeholder =" inspectorState.treeFilterPlaceholder" />
210+ <div v-if =" actions?.length" class =" flex items-center gap-2 px-1" >
188211 <div v-for =" (action, index) in actions" :key =" index" v-tooltip.bottom-end =" { content: action.tooltip }" class =" flex items-center gap1" @click =" callAction(index)" >
189212 <VueIcIcon :name =" `baseline-${action.icon.replace(/\_/g, '-')}`" cursor-pointer op70 text-base hover:op100 />
190213 </div >
191214 </div >
192215 </div >
193- <div class =" no-scrollbar flex-1 select-none overflow-scroll" >
216+ <div v-if = " tree.length " class =" no-scrollbar flex-1 select-none overflow-scroll" >
194217 <ComponentTree v-model =" selected" :data =" tree" />
195218 </div >
219+ <Empty v-else >
220+ No Data
221+ </Empty >
196222 </div >
197223 </Pane >
198224 <Pane size =" 60" >
199225 <div class =" h-full flex flex-col p2" >
200- <div v-if =" nodeActions?.length" class =" mb-1 flex justify-end pb-1" border =" b dashed base" >
201- <div class =" flex items-center gap-2 px-1" >
226+ <div class =" grid grid-cols-[1fr_auto] mb1 items-center gap2 pb1" border =" b dashed base" >
227+ <VueInput v-model =" filterStateKey" :placeholder =" inspectorState.stateFilterPlaceholder" />
228+ <div v-if =" nodeActions?.length" class =" flex items-center gap-2 px-1" >
202229 <div v-for =" (action, index) in nodeActions" :key =" index" v-tooltip.bottom-end =" { content: action.tooltip }" class =" flex items-center gap1" @click =" callNodeAction(index)" >
203230 <VueIcIcon :name =" `baseline-${action.icon.replace(/\_/g, '-')}`" cursor-pointer op70 text-base hover:op100 />
204231 </div >
205232 </div >
206233 </div >
207- <RootStateViewer v-if =" selected && !emptyState" :data =" state " :node-id =" selected" :inspector-id =" inspectorId" expanded-state-id =" custom-inspector-state" class =" no-scrollbar flex-1 select-none overflow-scroll" />
234+ <RootStateViewer v-if =" selected && !emptyState" :data =" displayState " :node-id =" selected" :inspector-id =" inspectorId" expanded-state-id =" custom-inspector-state" class =" no-scrollbar flex-1 select-none overflow-scroll" />
208235 <Empty v-else >
209236 No Data
210237 </Empty >
211238 </div >
212239 </Pane >
213240 </Splitpanes >
214241 </template >
215- <Empty v-else >
216- No Data
217- </Empty >
218242 </div >
219243</template >
0 commit comments