1
1
<script setup lang="ts">
2
- import type { ModuleGraphData } from ' vitest'
3
2
import { client , current , currentLogs , isReport , browserState , config } from ' ~/composables/client'
4
3
import type { Params } from ' ~/composables/params'
5
4
import { viewMode } from ' ~/composables/params'
6
5
import type { ModuleGraph } from ' ~/composables/module-graph'
7
6
import { getModuleGraph } from ' ~/composables/module-graph'
8
- import { getProjectNameColor } from ' ~/utils/task' ;
7
+ import { getProjectNameColor } from ' ~/utils/task'
9
8
10
- const data = ref <ModuleGraphData >({ externalized: [], graph: {}, inlined: [] })
11
9
const graph = ref <ModuleGraph >({ nodes: [], links: [] })
12
10
const draft = ref (false )
13
11
const hasGraphBeenDisplayed = ref (false )
12
+ const loadingModuleGraph = ref (false )
13
+ const currentFilepath = ref <string | undefined >(undefined )
14
14
15
- debouncedWatch (
16
- current ,
17
- async (c , o ) => {
18
- if (c && c .filepath !== o ?.filepath ) {
19
- const project = c .file .projectName || ' '
20
- data .value = await client .rpc .getModuleGraph (project , c .filepath , !! browserState )
21
- graph .value = getModuleGraph (data .value , c .filepath )
22
- }
23
- },
24
- { debounce: 100 , immediate: true },
25
- )
15
+ const graphData = computed (() => {
16
+ const c = current .value
17
+ if (! c || ! c .filepath )
18
+ return
19
+
20
+ return {
21
+ filepath: c .filepath ,
22
+ projectName: c .file .projectName || ' ' ,
23
+ }
24
+ })
26
25
27
26
function open() {
28
27
const filePath = current .value ?.filepath
@@ -44,12 +43,42 @@ function onDraft(value: boolean) {
44
43
draft .value = value
45
44
}
46
45
47
- function relativeToRoot(path ? : string ) {
48
- if (! path ) return ' '
49
- if (path .startsWith (config .root ))
50
- return path .slice (config .root .length )
51
- return path
46
+ async function loadModuleGraph() {
47
+ if (loadingModuleGraph .value || graphData .value ?.filepath === currentFilepath .value )
48
+ return
49
+
50
+ loadingModuleGraph .value = true
51
+
52
+ await nextTick ()
53
+
54
+ try {
55
+ const gd = graphData .value
56
+ if (! gd )
57
+ return
58
+
59
+ if (! currentFilepath .value || gd .filepath !== currentFilepath .value || (! graph .value .nodes .length && ! graph .value .links .length )) {
60
+ graph .value = getModuleGraph (
61
+ await client .rpc .getModuleGraph (gd .projectName , gd .filepath , !! browserState ),
62
+ gd .filepath ,
63
+ )
64
+ currentFilepath .value = gd .filepath
65
+ }
66
+ changeViewMode (' graph' )
67
+ }
68
+ finally {
69
+ await new Promise (resolve => setTimeout (resolve , 100 ))
70
+ loadingModuleGraph .value = false
71
+ }
52
72
}
73
+
74
+ debouncedWatch (
75
+ () => [graphData .value , viewMode .value ] as const ,
76
+ ([, vm ]) => {
77
+ if (vm === ' graph' )
78
+ loadModuleGraph ()
79
+ },
80
+ { debounce: 100 , immediate: true },
81
+ )
53
82
</script >
54
83
55
84
<template >
@@ -61,7 +90,7 @@ function relativeToRoot(path?: string) {
61
90
[{{ current?.file.projectName || '' }}]
62
91
</div >
63
92
<div flex-1 font-light op-50 ws-nowrap truncate text-sm >
64
- {{ relativeToRoot( current?.filepath) }}
93
+ {{ current?.name }}
65
94
</div >
66
95
<div class =" flex text-lg" >
67
96
<IconButton
@@ -77,43 +106,52 @@ function relativeToRoot(path?: string) {
77
106
<div flex =" ~" items-center bg-header border =" b-2 base" text-sm h-41px >
78
107
<button
79
108
tab-button
109
+ class =" flex items-center gap-2"
80
110
:class =" { 'tab-button-active': viewMode == null }"
81
111
data-testid =" btn-report"
82
112
@click =" changeViewMode(null)"
83
113
>
114
+ <span class =" block w-1.4em h-1.4em i-carbon:report" ></span >
84
115
Report
85
116
</button >
86
117
<button
87
118
tab-button
88
119
data-testid =" btn-graph"
120
+ class =" flex items-center gap-2"
89
121
:class =" { 'tab-button-active': viewMode === 'graph' }"
90
122
@click =" changeViewMode('graph')"
91
123
>
124
+ <span v-if =" loadingModuleGraph" class =" block w-1.4em h-1.4em i-carbon:circle-dash animate-spin animate-2s" ></span >
125
+ <span v-else class =" block w-1.4em h-1.4em i-carbon:chart-relationship" ></span >
92
126
Module Graph
93
127
</button >
94
128
<button
95
129
v-if =" !isReport"
96
130
tab-button
97
131
data-testid =" btn-code"
132
+ class =" flex items-center gap-2"
98
133
:class =" { 'tab-button-active': viewMode === 'editor' }"
99
134
@click =" changeViewMode('editor')"
100
135
>
136
+ <span class =" block w-1.4em h-1.4em i-carbon:code" ></span >
101
137
{{ draft ? '*  ; ' : '' }}Code
102
138
</button >
103
139
<button
104
140
tab-button
105
141
data-testid =" btn-console"
142
+ class =" flex items-center gap-2"
106
143
:class =" { 'tab-button-active': viewMode === 'console', 'op20': viewMode !== 'console' && consoleCount === 0 }"
107
144
@click =" changeViewMode('console')"
108
145
>
146
+ <span class =" block w-1.4em h-1.4em i-carbon:terminal-3270" ></span >
109
147
Console ({{ consoleCount }})
110
148
</button >
111
149
</div >
112
150
</div >
113
151
114
152
<div flex flex-col flex-1 overflow =" hidden" >
115
153
<div v-if =" hasGraphBeenDisplayed" :flex-1 =" viewMode === 'graph' && ''" >
116
- <ViewModuleGraph v-show =" viewMode === 'graph'" :graph =" graph" data-testid =" graph" :project-name =" current.file.projectName || ''" />
154
+ <ViewModuleGraph v-show =" viewMode === 'graph' && !loadingModuleGraph " :graph =" graph" data-testid =" graph" :project-name =" current.file.projectName || ''" />
117
155
</div >
118
156
<ViewEditor v-if =" viewMode === 'editor'" :key =" current.filepath" :file =" current" data-testid =" editor" @draft =" onDraft" />
119
157
<ViewConsoleOutput v-else-if =" viewMode === 'console'" :file =" current" data-testid =" console" />
0 commit comments