1
1
<script setup lang="ts">
2
2
import type { RouteMeta , RouteRecordNormalized } from ' vue-router'
3
+ import { tryGetAllMetaKeys } from ' ~/logic/routes'
3
4
4
5
const props = defineProps <{
5
6
pages: RouteRecordNormalized []
@@ -20,27 +21,85 @@ function metaToString(meta: RouteMeta, num: number = 0) {
20
21
const metaStr = JSON .stringify (meta , null , num )
21
22
return metaStr === ' {}' ? ' -' : metaStr
22
23
}
24
+
25
+ const allMetaKeys = computed (() => tryGetAllMetaKeys (props .pages ))
26
+
27
+ const activeMetaKeys = useStorage <string []>(' __vue-devtools-route-active-meta-keys__' , [],
28
+ localStorage ,
29
+ )
30
+
31
+ // ensure that activeMetaKeys is always a subset of allMetaKeys
32
+ watch (allMetaKeys , (v ) => {
33
+ activeMetaKeys .value = activeMetaKeys .value
34
+ .filter (key => v .includes (key ))
35
+ })
36
+
37
+ const dynamicTableColumns = computed (() => activeMetaKeys .value .map (key => ({
38
+ head: ` meta.${key } ` ,
39
+ key ,
40
+ })))
41
+
42
+ const tableHeadMeta = computed (() => {
43
+ return {
44
+ normal: activeMetaKeys .value ? 2 : 1 ,
45
+ dynamic: activeMetaKeys .value .length ,
46
+ }
47
+ })
48
+
49
+ const normalHead = [' ' , ' Route Path' , ' Name' ]
50
+
51
+ const showDynamicSelector = ref (false )
52
+ const dynamicSelectorEl = ref <HTMLElement >()
53
+ onClickOutside (dynamicSelectorEl , () => {
54
+ showDynamicSelector .value = false
55
+ })
23
56
</script >
24
57
25
58
<template >
26
59
<div >
27
60
<table w-full >
28
- <thead border =" b base" >
61
+ <thead border =" b base" text-left leading-8 >
29
62
<tr >
30
- <th text-left />
31
- <th text-left >
32
- Route Path
33
- </th >
34
- <th text-left >
35
- Name
63
+ <th v-for =" head of normalHead" :key =" head" :rowspan =" tableHeadMeta.normal" >
64
+ {{ head }}
36
65
</th >
37
- <th text-left >
38
- Route Meta
66
+ <template v-if =" allMetaKeys .length " >
67
+ <th :colspan =" tableHeadMeta.dynamic" >
68
+ <div flex items-center justify-between >
69
+ <span >Route Meta</span >
70
+ <div ref =" dynamicSelectorEl" relative >
71
+ <button text =" xs gray-400" relative @click =" () => showDynamicSelector = !showDynamicSelector" >
72
+ <i mingcute:filter-fill />
73
+ </button >
74
+ <VDDropdown v-model:show =" showDynamicSelector" top-40px w-200px :items =" allMetaKeys" position =" right" >
75
+ <template #item =" { item } " >
76
+ <div flex items-center gap2 truncate p5px font-normal leading-none >
77
+ <input
78
+ v-model =" activeMetaKeys"
79
+ cursor-pointer
80
+ type =" checkbox"
81
+ :value =" item"
82
+ >
83
+ <span >{{ item }}</span >
84
+ </div >
85
+ </template >
86
+ </VDDropdown >
87
+ </div >
88
+ </div >
89
+ </th >
90
+ </template >
91
+ </tr >
92
+ <tr b =" t-1px gray/20" >
93
+ <th v-for =" { head, key } of dynamicTableColumns" :key =" key" >
94
+ {{ head }}
39
95
</th >
40
96
</tr >
41
97
</thead >
42
98
<tbody >
43
- <tr v-for =" item of sorted" :key =" item.name" class =" group" h-7 border =" b dashed transparent hover:base" >
99
+ <tr
100
+ v-for =" item of sorted" :key =" item.name"
101
+ class =" group" h-7 border =" b dashed transparent hover:base" text-left text-sm font-mono
102
+ >
44
103
<td w-20 pr-1 >
45
104
<div flex items-center justify-end >
46
105
<VDBadge
@@ -57,7 +116,7 @@ function metaToString(meta: RouteMeta, num: number = 0) {
57
116
/>
58
117
</div >
59
118
</td >
60
- <td text-sm >
119
+ <td >
61
120
<div flex =" inline gap3" items-center >
62
121
<RoutePathItem
63
122
:route =" item"
@@ -67,10 +126,15 @@ function metaToString(meta: RouteMeta, num: number = 0) {
67
126
/>
68
127
</div >
69
128
</td >
70
- <td w-30 ws-nowrap pr-1 text-left text-sm font-mono op50 >
129
+ <td w-30 ws-nowrap pr-1 op50 >
71
130
{{ item.name ?? '-' }}
72
131
</td >
73
- <td w-50 ws-nowrap pr-1 text-left text-sm font-mono op50 hover =" text-primary op100" >
132
+ <template v-if =" dynamicTableColumns .length " >
133
+ <td v-for =" { key } in dynamicTableColumns " :key =" key" truncate ws-nowrap op50 >
134
+ {{ item.meta[key]?.toString() ?? '-' }}
135
+ </td >
136
+ </template >
137
+ <td v-else w-50 ws-nowrap pr-1 op50 hover =" text-primary op100" >
74
138
<span inline-block w-50 cursor-pointer overflow-hidden text-ellipsis :title =" metaToString(item.meta, 2)" @click =" () => $emit('selectMeta', item.meta)" >{{ metaToString(item.meta) }}</span >
75
139
</td >
76
140
</tr >
0 commit comments