Graph calculator improvmentes
All checks were successful
Build and Deploy Nuxt / build (push) Successful in 24s

This commit is contained in:
2026-10-02 14:53:00 +02:00
parent e36fef7290
commit 68b74eb60b
21 changed files with 1092 additions and 392 deletions

View File

@@ -18,6 +18,8 @@
Narrow screens fold the book to the one page in view, with its neighbours
as chips along the top. */
import type { ArticleTab } from '~/composables/useArticleTabs'
const api = `${useRuntimeConfig().public.apiBase}/api`
const route = useRoute()
const router = useRouter()
@@ -34,7 +36,18 @@ const { collapsed } = useSidebar()
const activeTab = computed(() => tabAt(tabs.value, route.path))
const activeIdentity = computed(() => activeTab.value?.identity ?? null)
const visible = computed(() => isReaderPath(route.path) && tabs.value.length > 0)
/* the book lies open on a reader route, and on one of the wiki's own pages
while the book holds a page of it — asked plain, those pages draw
themselves instead */
const visible = computed(
() => (isReaderPath(route.path) || tabAt(tabs.value, route.path) !== null) && tabs.value.length > 0
)
/* what a page of the book is called: an article wears its title; one of the
wiki's own pages is called by what it is, in the reader's language */
function tabLabel(tab: ArticleTab): string {
return tab.tool ? t(TOOL_LABEL_KEYS[tab.tool]) : tab.title
}
const trackEl = ref<HTMLElement | null>(null)
@@ -157,11 +170,13 @@ watch(collapsed, () => {
})
/* every page of the book should hold its article: pull the ones the route
host hasn't already written in (background pages, client-side only) */
host hasn't already written in (background pages, client-side only). The
wiki's own pages carry no article to fetch — their surface fetches its
own map when it is turned to */
watch(
tabs,
() => {
for (const t of tabs.value) void load(t.slug)
for (const t of tabs.value) if (!t.tool) void load(t.slug)
},
{ immediate: true }
)
@@ -215,11 +230,11 @@ onBeforeUnmount(() => window.removeEventListener('keydown', onGlobalKeydown))
role="tab"
tabindex="0"
:aria-selected="tab.identity === activeIdentity"
:title="t('book.chipHint', { title: tab.title })"
:title="t('book.chipHint', { title: tabLabel(tab) })"
@click="turnTo(tab.identity)"
@keydown.enter.prevent="turnTo(tab.identity)"
>
<span class="chip-title">{{ tab.title }}</span>
<span class="chip-title">{{ tabLabel(tab) }}</span>
<button type="button" class="chip-close" :aria-label="t('common.closeTab')" @click.stop="closeTab(tab.identity)">
<svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.8" stroke-linecap="round" aria-hidden="true">
<path d="M6 6l12 12M18 6L6 18" />
@@ -229,17 +244,28 @@ onBeforeUnmount(() => window.removeEventListener('keydown', onGlobalKeydown))
</nav>
<div ref="trackEl" class="book-track" @scroll.passive="watchDock">
<ArticlePane
v-for="(tab, i) in tabs"
:key="tab.identity"
:identity="tab.identity"
:slug="tab.slug"
:index="i"
:active="tab.identity === activeIdentity"
@activate="turnTo(tab.identity)"
@close="closeTab(tab.identity)"
@remove="removeArticle(tab.identity)"
/>
<!-- an article's page holds its text; one of the wiki's own pages
holds the live surface itself, the map or the plane -->
<template v-for="(tab, i) in tabs" :key="tab.identity">
<ToolPane
v-if="tab.tool"
:tool="tab.tool"
:index="i"
:active="tab.identity === activeIdentity"
@activate="turnTo(tab.identity)"
@close="closeTab(tab.identity)"
/>
<ArticlePane
v-else
:identity="tab.identity"
:slug="tab.slug"
:index="i"
:active="tab.identity === activeIdentity"
@activate="turnTo(tab.identity)"
@close="closeTab(tab.identity)"
@remove="removeArticle(tab.identity)"
/>
</template>
</div>
<nav v-if="waiting.length" class="book-dock" :aria-label="t('book.dockAria')">
@@ -249,7 +275,7 @@ onBeforeUnmount(() => window.removeEventListener('keydown', onGlobalKeydown))
class="dock-spine"
role="button"
tabindex="0"
:title="t('book.dockHint', { title: tab.title })"
:title="t('book.dockHint', { title: tabLabel(tab) })"
@click="turnTo(tab.identity)"
@keydown.enter.prevent="turnTo(tab.identity)"
>
@@ -258,7 +284,7 @@ onBeforeUnmount(() => window.removeEventListener('keydown', onGlobalKeydown))
<path d="M6 6l12 12M18 6L6 18" />
</svg>
</button>
<span class="spine-title">{{ tab.title }}</span>
<span class="spine-title">{{ tabLabel(tab) }}</span>
</div>
</nav>
</div>