Skip to content

Commit b117e87

Browse files
authored
feat(ui): load module graph on tab selection (#5844)
1 parent 4700367 commit b117e87

File tree

10 files changed

+82
-42
lines changed

10 files changed

+82
-42
lines changed

packages/ui/client/components/FileDetails.vue

Lines changed: 59 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
<script setup lang="ts">
2-
import type { ModuleGraphData } from 'vitest'
32
import { client, current, currentLogs, isReport, browserState, config } from '~/composables/client'
43
import type { Params } from '~/composables/params'
54
import { viewMode } from '~/composables/params'
65
import type { ModuleGraph } from '~/composables/module-graph'
76
import { 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: [] })
119
const graph = ref<ModuleGraph>({ nodes: [], links: [] })
1210
const draft = ref(false)
1311
const 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
2726
function 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 ? '*&#160;' : '' }}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" />

packages/ui/client/components/Navigation.vue

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ import {
1111
disableCoverage,
1212
showCoverage,
1313
showDashboard,
14-
} from '../composables/navigation'
15-
import { client, findById } from '../composables/client'
14+
} from '~/composables/navigation'
15+
import { client, findById } from '~/composables/client'
1616
import { isDark, toggleDark } from '~/composables'
1717
import { files, isReport, runAll } from '~/composables/client'
1818
import { activeFileId } from '~/composables/params'
@@ -63,18 +63,18 @@ function expandTests() {
6363
<img w-6 h-6 src="/favicon.svg" alt="Vitest logo">
6464
<span font-light text-sm flex-1>Vitest</span>
6565
<div class="flex text-lg">
66-
<IconButton
66+
<IconButton
6767
v-show="openedTreeItems.length > 0"
6868
v-tooltip.bottom="'Collapse tests'"
6969
title="Collapse tests"
70-
icon="i-carbon:collapse-all"
70+
icon="i-carbon:collapse-all"
7171
@click="collapseTests()"
7272
/>
73-
<IconButton
73+
<IconButton
7474
v-show="openedTreeItems.length === 0"
7575
v-tooltip.bottom="'Expand tests'"
7676
title="Expand tests"
77-
icon="i-carbon:expand-all"
77+
icon="i-carbon:expand-all"
7878
@click="expandTests()"
7979
/>
8080
<IconButton

packages/ui/client/components/ProgressBar.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
2-
import { files } from '../composables/client'
3-
import { filesFailed, filesSuccess, finished } from '../composables/summary'
2+
import { files } from '~/composables/client'
3+
import { filesFailed, filesSuccess, finished } from '~/composables/summary'
44
55
const { width } = useWindowSize()
66
const classes = computed(() => {

packages/ui/client/components/dashboard/DashboardEntry.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
withDefaults(defineProps<{ tail?: boolean }>(), { tail: false })
2+
// const { tail = false } = defineProps<{ tail?: boolean }>()
33
</script>
44

55
<template>

packages/ui/client/components/dashboard/ErrorEntry.vue

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
<script setup lang="ts">
2-
const props = defineProps<{
3-
error: ErrorWithDiff
4-
}>()
2+
import type { ErrorWithDiff } from '@vitest/utils'
3+
4+
defineProps<{
5+
error: ErrorWithDiff
6+
}>()
57
</script>
68

79
<template>

packages/ui/client/components/dashboard/TestFilesEntry.vue

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<script setup lang="ts">
2-
import { files, unhandledErrors } from '../../composables/client'
3-
import { filesFailed, filesSnapshotFailed, filesSuccess, time } from '../../composables/summary'
2+
import { files, unhandledErrors } from '~/composables/client'
3+
import { filesFailed, filesSnapshotFailed, filesSuccess, time } from '~/composables/summary'
44
</script>
55

66
<template>

packages/ui/client/components/dashboard/TestsEntry.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<script setup lang="ts">
2-
import { tests, testsFailed, testsSkipped, testsSuccess, testsTodo } from '../../composables/summary'
2+
import { tests, testsFailed, testsSkipped, testsSuccess, testsTodo } from '~/composables/summary'
33
44
const total = computed(() => tests.value.length)
55
const pass = computed(() => testsSuccess.value.length)

packages/ui/client/components/views/ViewEditor.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import type CodeMirror from 'codemirror'
44
import type { ErrorWithDiff, File } from 'vitest'
55
import { createTooltip, destroyTooltip } from 'floating-vue'
6-
import { openInEditor } from '../../composables/error'
6+
import { openInEditor } from '~/composables/error'
77
import { client } from '~/composables/client'
88
99
const props = defineProps<{

packages/ui/client/components/views/ViewReportError.vue

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<script setup lang="ts">
22
import type { ErrorWithDiff } from 'vitest'
33
import { openInEditor, shouldOpenInEditor } from '~/composables/error'
4-
import { escapeHtml } from '~/utils/escape';
4+
import { escapeHtml } from '~/utils/escape'
55
66
const props = defineProps<{
77
root: string

packages/ui/client/pages/index.vue

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,19 +39,19 @@ function resizeMain() {
3939
<Navigation />
4040
</Pane>
4141
<Pane :size="mainSizes[1]">
42-
<transition v-if="!browserState">
42+
<transition v-if="!browserState" key="ui-detail">
4343
<Dashboard v-if="dashboardVisible" key="summary" />
4444
<Coverage v-else-if="coverageVisible" key="coverage" :src="coverageUrl" />
45-
<FileDetails v-else />
45+
<FileDetails v-else key="details" />
4646
</transition>
47-
<Splitpanes v-else key="detail" id="details-splitpanes" @resize="onBrowserPanelResizing(true)" @resized="onModuleResized">
47+
<Splitpanes v-else key="browser-detail" id="details-splitpanes" @resize="onBrowserPanelResizing(true)" @resized="onModuleResized">
4848
<Pane :size="detailSizes[0]" min-size="10">
4949
<BrowserIframe v-once />
5050
</Pane>
5151
<Pane :size="detailSizes[1]" min-size="5">
5252
<Dashboard v-if="dashboardVisible" key="summary" />
5353
<Coverage v-else-if="coverageVisible" key="coverage" :src="coverageUrl" />
54-
<FileDetails v-else />
54+
<FileDetails v-else key="details" />
5555
</Pane>
5656
</Splitpanes>
5757
</Pane>

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy