51 lines
1.4 KiB
Vue
51 lines
1.4 KiB
Vue
<script setup lang="ts">
|
|
import type { GraphEdgeDto, GraphNodeDto } from '~/components/GraphView.vue'
|
|
|
|
export interface GraphDto {
|
|
nodes: GraphNodeDto[]
|
|
edges: GraphEdgeDto[]
|
|
}
|
|
|
|
/* matches the home page's transition so the two surfaces slide past
|
|
each other the way the reader does (see main.scss) */
|
|
definePageMeta({ transition: { name: 'page', mode: 'out-in' } })
|
|
|
|
const api = `${useRuntimeConfig().public.apiBase}/api`
|
|
const { t } = useI18n()
|
|
|
|
const { data, status, error } = await useFetch<GraphDto>(`${api}/articles/graph`, {
|
|
default: () => ({ nodes: [], edges: [] }),
|
|
})
|
|
|
|
useSeoMeta({
|
|
title: () => t('graph.metaTitle'),
|
|
description: () => t('graph.metaDescription'),
|
|
})
|
|
</script>
|
|
|
|
<template>
|
|
<div class="graph-stage">
|
|
<div v-if="error" class="graph-state">
|
|
<div class="banner">
|
|
<span class="glyph">!</span>
|
|
<span v-html="t('common.apiDown')"></span>
|
|
</div>
|
|
</div>
|
|
|
|
<GraphView
|
|
v-else-if="status !== 'pending' && data.nodes.length"
|
|
:nodes="data.nodes"
|
|
:edges="data.edges"
|
|
/>
|
|
|
|
<div v-else-if="status !== 'pending'" class="graph-state">
|
|
<div class="empty">
|
|
<div class="glyph">∅</div>
|
|
<h3>{{ t('graph.emptyTitle') }}</h3>
|
|
<p>{{ t('graph.emptyText') }}</p>
|
|
<NuxtLink to="/new" class="btn btn-primary">{{ t('common.startWriting') }}</NuxtLink>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</template>
|