11<script setup lang="ts">
2- import type { ModuleGraphData } from ' vitest'
32import { client , current , currentLogs , isReport , browserState , config } from ' ~/composables/client'
43import type { Params } from ' ~/composables/params'
54import { viewMode } from ' ~/composables/params'
65import type { ModuleGraph } from ' ~/composables/module-graph'
76import { getModuleGraph } from ' ~/composables/module-graph'
8- import { getProjectNameColor } from ' ~/utils/task' ;
7+ import { getProjectNameColor } from ' ~/utils/task'
98
10- const data = ref <ModuleGraphData >({ externalized: [], graph: {}, inlined: [] })
119const graph = ref <ModuleGraph >({ nodes: [], links: [] })
1210const draft = ref (false )
1311const hasGraphBeenDisplayed = ref (false )
12+ const loadingModuleGraph = ref (false )
13+ const currentFilepath = ref <string | undefined >(undefined )
1414
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+ })
2625
2726function open() {
2827 const filePath = current .value ?.filepath
@@ -44,12 +43,42 @@ function onDraft(value: boolean) {
4443 draft .value = value
4544}
4645
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+ }
5272}
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+ )
5382 </script >
5483
5584<template >
@@ -61,7 +90,7 @@ function relativeToRoot(path?: string) {
6190 [{{ current?.file.projectName || '' }}]
6291 </div >
6392 <div flex-1 font-light op-50 ws-nowrap truncate text-sm >
64- {{ relativeToRoot( current?.filepath) }}
93+ {{ current?.name }}
6594 </div >
6695 <div class =" flex text-lg" >
6796 <IconButton
@@ -77,43 +106,52 @@ function relativeToRoot(path?: string) {
77106 <div flex =" ~" items-center bg-header border =" b-2 base" text-sm h-41px >
78107 <button
79108 tab-button
109+ class =" flex items-center gap-2"
80110 :class =" { 'tab-button-active': viewMode == null }"
81111 data-testid =" btn-report"
82112 @click =" changeViewMode(null)"
83113 >
114+ <span class =" block w-1.4em h-1.4em i-carbon:report" ></span >
84115 Report
85116 </button >
86117 <button
87118 tab-button
88119 data-testid =" btn-graph"
120+ class =" flex items-center gap-2"
89121 :class =" { 'tab-button-active': viewMode === 'graph' }"
90122 @click =" changeViewMode('graph')"
91123 >
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 >
92126 Module Graph
93127 </button >
94128 <button
95129 v-if =" !isReport"
96130 tab-button
97131 data-testid =" btn-code"
132+ class =" flex items-center gap-2"
98133 :class =" { 'tab-button-active': viewMode === 'editor' }"
99134 @click =" changeViewMode('editor')"
100135 >
136+ <span class =" block w-1.4em h-1.4em i-carbon:code" ></span >
101137 {{ draft ? '*  ; ' : '' }}Code
102138 </button >
103139 <button
104140 tab-button
105141 data-testid =" btn-console"
142+ class =" flex items-center gap-2"
106143 :class =" { 'tab-button-active': viewMode === 'console', 'op20': viewMode !== 'console' && consoleCount === 0 }"
107144 @click =" changeViewMode('console')"
108145 >
146+ <span class =" block w-1.4em h-1.4em i-carbon:terminal-3270" ></span >
109147 Console ({{ consoleCount }})
110148 </button >
111149 </div >
112150 </div >
113151
114152 <div flex flex-col flex-1 overflow =" hidden" >
115153 <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 || ''" />
117155 </div >
118156 <ViewEditor v-if =" viewMode === 'editor'" :key =" current.filepath" :file =" current" data-testid =" editor" @draft =" onDraft" />
119157 <ViewConsoleOutput v-else-if =" viewMode === 'console'" :file =" current" data-testid =" console" />
0 commit comments