Skip to content

Commit

Permalink
feat(ui): load module graph on tab selection (#5844)
Browse files Browse the repository at this point in the history
  • Loading branch information
userquin authored Jun 6, 2024
1 parent 4700367 commit b117e87
Show file tree
Hide file tree
Showing 10 changed files with 82 additions and 42 deletions.
80 changes: 59 additions & 21 deletions packages/ui/client/components/FileDetails.vue
Original file line number Diff line number Diff line change
@@ -1,28 +1,27 @@
<script setup lang="ts">
import type { ModuleGraphData } from 'vitest'
import { client, current, currentLogs, isReport, browserState, config } from '~/composables/client'
import type { Params } from '~/composables/params'
import { viewMode } from '~/composables/params'
import type { ModuleGraph } from '~/composables/module-graph'
import { getModuleGraph } from '~/composables/module-graph'
import { getProjectNameColor } from '~/utils/task';
import { getProjectNameColor } from '~/utils/task'
const data = ref<ModuleGraphData>({ externalized: [], graph: {}, inlined: [] })
const graph = ref<ModuleGraph>({ nodes: [], links: [] })
const draft = ref(false)
const hasGraphBeenDisplayed = ref(false)
const loadingModuleGraph = ref(false)
const currentFilepath = ref<string | undefined>(undefined)
debouncedWatch(
current,
async (c, o) => {
if (c && c.filepath !== o?.filepath) {
const project = c.file.projectName || ''
data.value = await client.rpc.getModuleGraph(project, c.filepath, !!browserState)
graph.value = getModuleGraph(data.value, c.filepath)
}
},
{ debounce: 100, immediate: true },
)
const graphData = computed(() => {
const c = current.value
if (!c || !c.filepath)
return
return {
filepath: c.filepath,
projectName: c.file.projectName || '',
}
})
function open() {
const filePath = current.value?.filepath
Expand All @@ -44,12 +43,42 @@ function onDraft(value: boolean) {
draft.value = value
}
function relativeToRoot(path?: string) {
if (!path) return ''
if (path.startsWith(config.root))
return path.slice(config.root.length)
return path
async function loadModuleGraph() {
if (loadingModuleGraph.value || graphData.value?.filepath === currentFilepath.value)
return
loadingModuleGraph.value = true
await nextTick()
try {
const gd = graphData.value
if (!gd)
return
if (!currentFilepath.value || gd.filepath !== currentFilepath.value || (!graph.value.nodes.length && !graph.value.links.length)) {
graph.value = getModuleGraph(
await client.rpc.getModuleGraph(gd.projectName, gd.filepath, !!browserState),
gd.filepath,
)
currentFilepath.value = gd.filepath
}
changeViewMode('graph')
}
finally {
await new Promise(resolve => setTimeout(resolve, 100))
loadingModuleGraph.value = false
}
}
debouncedWatch(
() => [graphData.value, viewMode.value] as const,
([, vm]) => {
if (vm === 'graph')
loadModuleGraph()
},
{ debounce: 100, immediate: true },
)
</script>

<template>
Expand All @@ -61,7 +90,7 @@ function relativeToRoot(path?: string) {
[{{ current?.file.projectName || '' }}]
</div>
<div flex-1 font-light op-50 ws-nowrap truncate text-sm>
{{ relativeToRoot(current?.filepath) }}
{{ current?.name }}
</div>
<div class="flex text-lg">
<IconButton
Expand All @@ -77,43 +106,52 @@ function relativeToRoot(path?: string) {
<div flex="~" items-center bg-header border="b-2 base" text-sm h-41px>
<button
tab-button
class="flex items-center gap-2"
:class="{ 'tab-button-active': viewMode == null }"
data-testid="btn-report"
@click="changeViewMode(null)"
>
<span class="block w-1.4em h-1.4em i-carbon:report"></span>
Report
</button>
<button
tab-button
data-testid="btn-graph"
class="flex items-center gap-2"
:class="{ 'tab-button-active': viewMode === 'graph' }"
@click="changeViewMode('graph')"
>
<span v-if="loadingModuleGraph" class="block w-1.4em h-1.4em i-carbon:circle-dash animate-spin animate-2s"></span>
<span v-else class="block w-1.4em h-1.4em i-carbon:chart-relationship"></span>
Module Graph
</button>
<button
v-if="!isReport"
tab-button
data-testid="btn-code"
class="flex items-center gap-2"
:class="{ 'tab-button-active': viewMode === 'editor' }"
@click="changeViewMode('editor')"
>
<span class="block w-1.4em h-1.4em i-carbon:code"></span>
{{ draft ? '*&#160;' : '' }}Code
</button>
<button
tab-button
data-testid="btn-console"
class="flex items-center gap-2"
:class="{ 'tab-button-active': viewMode === 'console', 'op20': viewMode !== 'console' && consoleCount === 0 }"
@click="changeViewMode('console')"
>
<span class="block w-1.4em h-1.4em i-carbon:terminal-3270"></span>
Console ({{ consoleCount }})
</button>
</div>
</div>
<div flex flex-col flex-1 overflow="hidden">
<div v-if="hasGraphBeenDisplayed" :flex-1="viewMode === 'graph' && ''">
<ViewModuleGraph v-show="viewMode === 'graph'" :graph="graph" data-testid="graph" :project-name="current.file.projectName || ''" />
<ViewModuleGraph v-show="viewMode === 'graph' && !loadingModuleGraph" :graph="graph" data-testid="graph" :project-name="current.file.projectName || ''" />
</div>
<ViewEditor v-if="viewMode === 'editor'" :key="current.filepath" :file="current" data-testid="editor" @draft="onDraft" />
<ViewConsoleOutput v-else-if="viewMode === 'console'" :file="current" data-testid="console" />
Expand Down
12 changes: 6 additions & 6 deletions packages/ui/client/components/Navigation.vue
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ import {
disableCoverage,
showCoverage,
showDashboard,
} from '../composables/navigation'
import { client, findById } from '../composables/client'
} from '~/composables/navigation'
import { client, findById } from '~/composables/client'
import { isDark, toggleDark } from '~/composables'
import { files, isReport, runAll } from '~/composables/client'
import { activeFileId } from '~/composables/params'
Expand Down Expand Up @@ -63,18 +63,18 @@ function expandTests() {
<img w-6 h-6 src="/favicon.svg" alt="Vitest logo">
<span font-light text-sm flex-1>Vitest</span>
<div class="flex text-lg">
<IconButton
<IconButton
v-show="openedTreeItems.length > 0"
v-tooltip.bottom="'Collapse tests'"
title="Collapse tests"
icon="i-carbon:collapse-all"
icon="i-carbon:collapse-all"
@click="collapseTests()"
/>
<IconButton
<IconButton
v-show="openedTreeItems.length === 0"
v-tooltip.bottom="'Expand tests'"
title="Expand tests"
icon="i-carbon:expand-all"
icon="i-carbon:expand-all"
@click="expandTests()"
/>
<IconButton
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/client/components/ProgressBar.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { files } from '../composables/client'
import { filesFailed, filesSuccess, finished } from '../composables/summary'
import { files } from '~/composables/client'
import { filesFailed, filesSuccess, finished } from '~/composables/summary'
const { width } = useWindowSize()
const classes = computed(() => {
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/client/components/dashboard/DashboardEntry.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
withDefaults(defineProps<{ tail?: boolean }>(), { tail: false })
// const { tail = false } = defineProps<{ tail?: boolean }>()
</script>

<template>
Expand Down
8 changes: 5 additions & 3 deletions packages/ui/client/components/dashboard/ErrorEntry.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
<script setup lang="ts">
const props = defineProps<{
error: ErrorWithDiff
}>()
import type { ErrorWithDiff } from '@vitest/utils'
defineProps<{
error: ErrorWithDiff
}>()
</script>

<template>
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/client/components/dashboard/TestFilesEntry.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { files, unhandledErrors } from '../../composables/client'
import { filesFailed, filesSnapshotFailed, filesSuccess, time } from '../../composables/summary'
import { files, unhandledErrors } from '~/composables/client'
import { filesFailed, filesSnapshotFailed, filesSuccess, time } from '~/composables/summary'
</script>

<template>
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/client/components/dashboard/TestsEntry.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { tests, testsFailed, testsSkipped, testsSuccess, testsTodo } from '../../composables/summary'
import { tests, testsFailed, testsSkipped, testsSuccess, testsTodo } from '~/composables/summary'
const total = computed(() => tests.value.length)
const pass = computed(() => testsSuccess.value.length)
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/client/components/views/ViewEditor.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import type CodeMirror from 'codemirror'
import type { ErrorWithDiff, File } from 'vitest'
import { createTooltip, destroyTooltip } from 'floating-vue'
import { openInEditor } from '../../composables/error'
import { openInEditor } from '~/composables/error'
import { client } from '~/composables/client'
const props = defineProps<{
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/client/components/views/ViewReportError.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import type { ErrorWithDiff } from 'vitest'
import { openInEditor, shouldOpenInEditor } from '~/composables/error'
import { escapeHtml } from '~/utils/escape';
import { escapeHtml } from '~/utils/escape'
const props = defineProps<{
root: string
Expand Down
8 changes: 4 additions & 4 deletions packages/ui/client/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,19 @@ function resizeMain() {
<Navigation />
</Pane>
<Pane :size="mainSizes[1]">
<transition v-if="!browserState">
<transition v-if="!browserState" key="ui-detail">
<Dashboard v-if="dashboardVisible" key="summary" />
<Coverage v-else-if="coverageVisible" key="coverage" :src="coverageUrl" />
<FileDetails v-else />
<FileDetails v-else key="details" />
</transition>
<Splitpanes v-else key="detail" id="details-splitpanes" @resize="onBrowserPanelResizing(true)" @resized="onModuleResized">
<Splitpanes v-else key="browser-detail" id="details-splitpanes" @resize="onBrowserPanelResizing(true)" @resized="onModuleResized">
<Pane :size="detailSizes[0]" min-size="10">
<BrowserIframe v-once />
</Pane>
<Pane :size="detailSizes[1]" min-size="5">
<Dashboard v-if="dashboardVisible" key="summary" />
<Coverage v-else-if="coverageVisible" key="coverage" :src="coverageUrl" />
<FileDetails v-else />
<FileDetails v-else key="details" />
</Pane>
</Splitpanes>
</Pane>
Expand Down

0 comments on commit b117e87

Please sign in to comment.