fix(app): keep the last document tab closable
This commit is contained in:
parent
52a8e5da62
commit
a9e998f9e4
|
|
@ -46,6 +46,7 @@
|
|||
|
||||
### Changed
|
||||
|
||||
- Open new tabs on Recent Files so users can choose a document before creating a blank canvas.
|
||||
- Pan horizontally with Shift+wheel while preserving native horizontal trackpad movement.
|
||||
- Move MCP connections into their own Settings destination instead of presenting them as part of model configuration.
|
||||
|
||||
|
|
|
|||
|
|
@ -45,6 +45,7 @@ export const allTabs = computed(() =>
|
|||
tabsRef.value.map((t) => ({
|
||||
id: t.id,
|
||||
name: t.store.state.documentName,
|
||||
isHome: t.showHome,
|
||||
isActive: t.id === activeTabId.value
|
||||
}))
|
||||
)
|
||||
|
|
@ -81,8 +82,9 @@ export function createTab(store?: EditorStore, initialGraph?: SceneGraph, showHo
|
|||
|
||||
export function leaveHome(tabId: string): void {
|
||||
const tabIndex = tabsRef.value.findIndex((candidate) => candidate.id === tabId)
|
||||
if (tabIndex === -1) return
|
||||
const tab = tabsRef.value[tabIndex]
|
||||
if (!tab?.showHome) return
|
||||
if (!tab.showHome) return
|
||||
tabsRef.value = tabsRef.value.with(tabIndex, { ...tab, showHome: false })
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,10 @@ const modelValue = computed({
|
|||
set: (id: string) => switchTab(id)
|
||||
})
|
||||
|
||||
function openRecentFilesTab() {
|
||||
createTab(undefined, undefined, true)
|
||||
}
|
||||
|
||||
function onMiddleClick(e: MouseEvent, tabId: string) {
|
||||
if (e.button === 1) {
|
||||
e.preventDefault()
|
||||
|
|
@ -34,7 +38,7 @@ function onClose(e: MouseEvent, tabId: string) {
|
|||
|
||||
<template>
|
||||
<TabsRoot
|
||||
v-if="tabs.length > 1"
|
||||
v-if="tabs.length > 0"
|
||||
v-model="modelValue"
|
||||
activation-mode="automatic"
|
||||
:class="baseStyles.root()"
|
||||
|
|
@ -49,14 +53,15 @@ function onClose(e: MouseEvent, tabId: string) {
|
|||
:data-active="tab.isActive || undefined"
|
||||
@mousedown="onMiddleClick($event, tab.id)"
|
||||
>
|
||||
<icon-lucide-file :class="baseStyles.icon()" />
|
||||
<span :class="baseStyles.label()">{{ tab.name }}</span>
|
||||
<Tip :label="dialogs.closeTab({ name: tab.name })">
|
||||
<icon-lucide-house v-if="tab.isHome" :class="baseStyles.icon()" />
|
||||
<icon-lucide-file v-else :class="baseStyles.icon()" />
|
||||
<span :class="baseStyles.label()">{{ tab.isHome ? dialogs.recentFiles : tab.name }}</span>
|
||||
<Tip :label="dialogs.closeTab({ name: tab.isHome ? dialogs.recentFiles : tab.name })">
|
||||
<button
|
||||
data-test-id="tabbar-close"
|
||||
:class="tabBarStyles({ active: tab.isActive }).close()"
|
||||
:data-active="tab.isActive || undefined"
|
||||
:aria-label="dialogs.closeTab({ name: tab.name })"
|
||||
:aria-label="dialogs.closeTab({ name: tab.isHome ? dialogs.recentFiles : tab.name })"
|
||||
tabindex="-1"
|
||||
@click="onClose($event, tab.id)"
|
||||
>
|
||||
|
|
@ -70,7 +75,7 @@ function onClose(e: MouseEvent, tabId: string) {
|
|||
data-test-id="tabbar-new"
|
||||
:class="baseStyles.newAction()"
|
||||
:aria-label="dialogs.newTab"
|
||||
@click="createTab()"
|
||||
@click="openRecentFilesTab"
|
||||
>
|
||||
<icon-lucide-plus :class="baseStyles.newIcon()" />
|
||||
</button>
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ onUnmounted(() => {
|
|||
<FontStatusBanner />
|
||||
<RenameSelectionDialog />
|
||||
<RecentFilesHome v-if="showingHome" @new-document="activeTab && leaveHome(activeTab.id)" />
|
||||
<TabBar v-if="!showingHome" />
|
||||
<TabBar />
|
||||
|
||||
<!-- Desktop layout -->
|
||||
<SplitterGroup
|
||||
|
|
|
|||
|
|
@ -9,5 +9,17 @@ test('opens to the recent-files home and starts a new document', async ({ page }
|
|||
await page.getByTestId('home-new-document').click()
|
||||
|
||||
await expect(page.getByTestId('recent-files-home')).toBeHidden()
|
||||
await expect(page.getByRole('group', { name: 'Layers' })).toBeVisible()
|
||||
const tab = page.getByTestId('tabbar-tab')
|
||||
await expect(tab).toBeVisible()
|
||||
|
||||
await page.getByTestId('tabbar-new').click()
|
||||
|
||||
await expect(page.getByTestId('recent-files-home')).toBeVisible()
|
||||
await expect(page.getByTestId('tabbar-tab')).toHaveCount(2)
|
||||
await expect(page.getByTestId('tabbar-tab').last()).toContainText('Recent files')
|
||||
|
||||
await page.getByTestId('tabbar-tab').last().hover()
|
||||
await page.getByTestId('tabbar-tab').last().getByTestId('tabbar-close').click()
|
||||
|
||||
await expect(page.getByTestId('recent-files-home')).toBeHidden()
|
||||
})
|
||||
|
|
|
|||
Loading…
Reference in a new issue