2
2
import type { CustomInspectorNode , CustomInspectorOptions , CustomInspectorState } from ' @vue/devtools-kit'
3
3
import { DevToolsMessagingEvents , onRpcConnected , rpc } from ' @vue/devtools-core'
4
4
import { parse } from ' @vue/devtools-kit'
5
- import { vTooltip , VueIcIcon } from ' @vue/devtools-ui'
5
+ import { vTooltip , VueIcIcon , VueInput } from ' @vue/devtools-ui'
6
6
import { until } from ' @vueuse/core'
7
7
import { Pane , Splitpanes } from ' splitpanes'
8
8
import { computed , onUnmounted , ref , watch } from ' vue'
@@ -13,6 +13,7 @@ import RootStateViewer from '~/components/state/RootStateViewer.vue'
13
13
import ComponentTree from ' ~/components/tree/TreeViewer.vue'
14
14
import { useCustomInspectorState } from ' ~/composables/custom-inspector-state'
15
15
import { createExpandedContext } from ' ~/composables/toggle-expanded'
16
+ import { filterInspectorState } from ' ~/utils'
16
17
17
18
const { expanded : expandedTreeNodes } = createExpandedContext ()
18
19
const { expanded : expandedStateNodes } = createExpandedContext (' custom-inspector-state' )
@@ -32,6 +33,24 @@ const selected = ref('')
32
33
const state = ref <Record <string , CustomInspectorState []>>({})
33
34
const emptyState = computed (() => ! Object .keys (state .value ).length )
34
35
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
+
35
54
// tree
36
55
function dfs(node : { id: string , children? : { id: string }[] }, path : string [] = [], linkedList : string [][] = []) {
37
56
path .push (node .id )
@@ -120,8 +139,8 @@ watch(selected, () => {
120
139
getInspectorState (selected .value )
121
140
})
122
141
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 ) => {
125
144
const data = parse (_data ! )
126
145
tree .value = data
127
146
if (! selected .value && data .length ) {
@@ -132,7 +151,7 @@ const getInspectorTree = () => {
132
151
})
133
152
}
134
153
135
- until (inspectorId ).toBeTruthy ().then (getInspectorTree )
154
+ until (inspectorId ).toBeTruthy ().then (() => getInspectorTree () )
136
155
137
156
function onInspectorTreeUpdated(_data : string ) {
138
157
const data = parse (_data ) as {
@@ -179,41 +198,46 @@ onUnmounted(() => {
179
198
<DevToolsHeader :doc-link =" customInspectState.homepage!" >
180
199
<Navbar />
181
200
</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 >
183
205
<Splitpanes class =" flex-1 overflow-auto" >
184
206
<Pane border =" r base" size =" 40" h-full >
185
207
<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" >
188
211
<div v-for =" (action, index) in actions" :key =" index" v-tooltip.bottom-end =" { content: action.tooltip }" class =" flex items-center gap1" @click =" callAction(index)" >
189
212
<VueIcIcon :name =" `baseline-${action.icon.replace(/\_/g, '-')}`" cursor-pointer op70 text-base hover:op100 />
190
213
</div >
191
214
</div >
192
215
</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" >
194
217
<ComponentTree v-model =" selected" :data =" tree" />
195
218
</div >
219
+ <Empty v-else >
220
+ No Data
221
+ </Empty >
196
222
</div >
197
223
</Pane >
198
224
<Pane size =" 60" >
199
225
<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" >
202
229
<div v-for =" (action, index) in nodeActions" :key =" index" v-tooltip.bottom-end =" { content: action.tooltip }" class =" flex items-center gap1" @click =" callNodeAction(index)" >
203
230
<VueIcIcon :name =" `baseline-${action.icon.replace(/\_/g, '-')}`" cursor-pointer op70 text-base hover:op100 />
204
231
</div >
205
232
</div >
206
233
</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" />
208
235
<Empty v-else >
209
236
No Data
210
237
</Empty >
211
238
</div >
212
239
</Pane >
213
240
</Splitpanes >
214
241
</template >
215
- <Empty v-else >
216
- No Data
217
- </Empty >
218
242
</div >
219
243
</template >
0 commit comments