Render documentation diagrams as static Mermaid assets
This commit is contained in:
@@ -6,7 +6,7 @@ const props = defineProps<{
|
||||
chart: string;
|
||||
}>();
|
||||
|
||||
const svg = ref('');
|
||||
const container = ref<HTMLElement | null>(null);
|
||||
const error = ref('');
|
||||
|
||||
let initialized = false;
|
||||
@@ -20,7 +20,7 @@ function initMermaid() {
|
||||
mermaid.initialize({
|
||||
startOnLoad: false,
|
||||
theme: 'neutral',
|
||||
securityLevel: 'strict',
|
||||
securityLevel: 'loose',
|
||||
fontFamily: 'Inter, Arial, sans-serif',
|
||||
flowchart: {
|
||||
useMaxWidth: true,
|
||||
@@ -34,7 +34,7 @@ function initMermaid() {
|
||||
const source = computed(() => props.chart.trim());
|
||||
|
||||
async function renderDiagram() {
|
||||
if (!import.meta.client) {
|
||||
if (!import.meta.client || !container.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -42,10 +42,13 @@ async function renderDiagram() {
|
||||
initMermaid();
|
||||
error.value = '';
|
||||
diagramId += 1;
|
||||
const { svg: result } = await mermaid.render(`mermaid-diagram-${diagramId}`, source.value);
|
||||
svg.value = result;
|
||||
container.value.removeAttribute('data-processed');
|
||||
container.value.id = `mermaid-diagram-${diagramId}`;
|
||||
container.value.textContent = source.value;
|
||||
await mermaid.run({
|
||||
nodes: [container.value],
|
||||
});
|
||||
} catch (cause) {
|
||||
svg.value = '';
|
||||
error.value = cause instanceof Error ? cause.message : 'Failed to render Mermaid diagram.';
|
||||
}
|
||||
}
|
||||
@@ -62,7 +65,7 @@ watch(source, () => {
|
||||
<template>
|
||||
<div class="mermaid-diagram">
|
||||
<div v-if="error" class="mermaid-diagram__error">{{ error }}</div>
|
||||
<div v-else class="mermaid-diagram__canvas" v-html="svg" />
|
||||
<pre v-else ref="container" class="mermaid-diagram__canvas mermaid" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -77,6 +80,8 @@ watch(source, () => {
|
||||
|
||||
.mermaid-diagram__canvas {
|
||||
padding: 1rem;
|
||||
margin: 0;
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.mermaid-diagram__canvas :deep(svg) {
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
export const diagramSources: Record<string, string> = {
|
||||
'architecture-overview': `flowchart LR
|
||||
Browser[Браузер клиента]
|
||||
Frontend[web-frontend<br/>Nuxt 4 + Vue 3]
|
||||
Proxy[/api/graphql proxy]
|
||||
Backend[apollo-backend<br/>Apollo Server + Express]
|
||||
Prisma[Prisma ORM]
|
||||
Db[(PostgreSQL)]
|
||||
Vault[Vault]
|
||||
OneC[1С]
|
||||
Bots[Telegram / MAX / email]
|
||||
Dokploy[Dokploy]
|
||||
Browser["Браузер клиента"]
|
||||
Frontend["web-frontend<br/>Nuxt 4 + Vue 3"]
|
||||
Proxy["/api/graphql proxy"]
|
||||
Backend["apollo-backend<br/>Apollo Server + Express"]
|
||||
Prisma["Prisma ORM"]
|
||||
Db[("PostgreSQL")]
|
||||
Vault["Vault"]
|
||||
OneC["1С"]
|
||||
Bots["Telegram / MAX / email"]
|
||||
Dokploy["Dokploy"]
|
||||
|
||||
Browser --> Frontend
|
||||
Frontend --> Proxy
|
||||
@@ -22,32 +22,32 @@ export const diagramSources: Record<string, string> = {
|
||||
Frontend -.deploy.-> Dokploy
|
||||
Backend -.deploy.-> Dokploy`,
|
||||
'component-map': `flowchart LR
|
||||
subgraph UI[UI и маршруты]
|
||||
Pages[app/pages]
|
||||
Components[app/components]
|
||||
Composables[app/composables]
|
||||
Middleware[middleware / plugins]
|
||||
subgraph UI["UI и маршруты"]
|
||||
Pages["app/pages"]
|
||||
Components["app/components"]
|
||||
Composables["app/composables"]
|
||||
Middleware["middleware / plugins"]
|
||||
end
|
||||
|
||||
subgraph Transport[Контракт и transport]
|
||||
Ops[graphql/operations]
|
||||
Generated[generated.ts]
|
||||
Apollo[Apollo client]
|
||||
Api[server/api/graphql]
|
||||
subgraph Transport["Контракт и transport"]
|
||||
Ops["graphql/operations"]
|
||||
Generated["generated.ts"]
|
||||
Apollo["Apollo client"]
|
||||
Api["server/api/graphql"]
|
||||
end
|
||||
|
||||
subgraph Server[Backend logic]
|
||||
Schema[schema.graphql]
|
||||
Resolvers[resolvers.js]
|
||||
Auth[auth.js / access.js]
|
||||
Context[context.js]
|
||||
Messenger[messenger / telegram / max]
|
||||
subgraph Server["Backend logic"]
|
||||
Schema["schema.graphql"]
|
||||
Resolvers["resolvers.js"]
|
||||
Auth["auth.js / access.js"]
|
||||
Context["context.js"]
|
||||
Messenger["messenger / telegram / max"]
|
||||
end
|
||||
|
||||
subgraph Data[Data layer]
|
||||
Prisma[prisma-client.js]
|
||||
PrismaSchema[schema.prisma]
|
||||
Db[(PostgreSQL)]
|
||||
subgraph Data["Data layer"]
|
||||
Prisma["prisma-client.js"]
|
||||
PrismaSchema["schema.prisma"]
|
||||
Db[("PostgreSQL")]
|
||||
end
|
||||
|
||||
Pages --> Components
|
||||
@@ -67,33 +67,33 @@ export const diagramSources: Record<string, string> = {
|
||||
Prisma --> PrismaSchema
|
||||
Prisma --> Db`,
|
||||
'infrastructure-topology': `flowchart TB
|
||||
subgraph Repo[Репозиторий fregat]
|
||||
FrontendRepo[web-frontend]
|
||||
BackendRepo[apollo-backend]
|
||||
TgRepo[tg-bot]
|
||||
MaxRepo[max-bot]
|
||||
BonusRepo[bonus-bot]
|
||||
WorkerRepo[hatchet-worker]
|
||||
VaultRepo[vault]
|
||||
subgraph Repo["Репозиторий fregat"]
|
||||
FrontendRepo["web-frontend"]
|
||||
BackendRepo["apollo-backend"]
|
||||
TgRepo["tg-bot"]
|
||||
MaxRepo["max-bot"]
|
||||
BonusRepo["bonus-bot"]
|
||||
WorkerRepo["hatchet-worker"]
|
||||
VaultRepo["vault"]
|
||||
end
|
||||
|
||||
subgraph Dokploy[Dokploy]
|
||||
FrontendSvc[web-frontend service]
|
||||
BackendSvc[apollo-backend service]
|
||||
TgSvc[tg-bot service]
|
||||
MaxSvc[max-bot service]
|
||||
BonusSvc[bonus-bot service]
|
||||
WorkerSvc[hatchet-worker service]
|
||||
VaultSvc[vault service]
|
||||
subgraph Dokploy["Dokploy"]
|
||||
FrontendSvc["web-frontend service"]
|
||||
BackendSvc["apollo-backend service"]
|
||||
TgSvc["tg-bot service"]
|
||||
MaxSvc["max-bot service"]
|
||||
BonusSvc["bonus-bot service"]
|
||||
WorkerSvc["hatchet-worker service"]
|
||||
VaultSvc["vault service"]
|
||||
end
|
||||
|
||||
subgraph Infra[Инфраструктурный контур]
|
||||
VaultData[Vault raft storage /vault/data]
|
||||
BackendDb[(PostgreSQL for app)]
|
||||
HatchetEngine[Hatchet engine]
|
||||
HatchetPg[(PostgreSQL for Hatchet)]
|
||||
OneC[1С]
|
||||
Tailscale[Tailscale SSH / diagnostics]
|
||||
subgraph Infra["Инфраструктурный контур"]
|
||||
VaultData["Vault raft storage /vault/data"]
|
||||
BackendDb[("PostgreSQL for app")]
|
||||
HatchetEngine["Hatchet engine"]
|
||||
HatchetPg[("PostgreSQL for Hatchet")]
|
||||
OneC["1С"]
|
||||
Tailscale["Tailscale SSH / diagnostics"]
|
||||
end
|
||||
|
||||
FrontendRepo --> FrontendSvc
|
||||
@@ -160,78 +160,78 @@ export const diagramSources: Record<string, string> = {
|
||||
User "1" --> "*" ReferralLink : referrals
|
||||
CatalogProductTypeSetting --> Product : productType`,
|
||||
dashboard: `flowchart TB
|
||||
subgraph Page[Главная страница клиента]
|
||||
Header[Header / навигация]
|
||||
Quick[Быстрые действия]
|
||||
Active[Актуальные заказы и заявки]
|
||||
Notes[Последние уведомления]
|
||||
Bonus[Бонусный блок]
|
||||
subgraph Page["Главная страница клиента"]
|
||||
Header["Header / навигация"]
|
||||
Quick["Быстрые действия"]
|
||||
Active["Актуальные заказы и заявки"]
|
||||
Notes["Последние уведомления"]
|
||||
Bonus["Бонусный блок"]
|
||||
end
|
||||
|
||||
Header --> Quick --> Active --> Notes --> Bonus`,
|
||||
'catalog-grid': `flowchart TB
|
||||
subgraph Catalog[Каталог продукции]
|
||||
Title[Заголовок раздела]
|
||||
Search[Поиск]
|
||||
Grid[Сетка карточек товарных направлений]
|
||||
Cards[Упаковочный скотч | Алюминиевый скотч | Крепп | Вспененный | Двусторонний ПП | Двусторонний PVC]
|
||||
subgraph Catalog["Каталог продукции"]
|
||||
Title["Заголовок раздела"]
|
||||
Search["Поиск"]
|
||||
Grid["Сетка карточек товарных направлений"]
|
||||
Cards["Упаковочный скотч | Алюминиевый скотч | Крепп | Вспененный | Двусторонний ПП | Двусторонний PVC"]
|
||||
end
|
||||
|
||||
Title --> Search --> Grid --> Cards`,
|
||||
'product-card': `flowchart TB
|
||||
subgraph ProductPage[Карточка товара]
|
||||
Title[Заголовок товара и навигация]
|
||||
subgraph TopRow[Верхний блок]
|
||||
Image[Изображение товара]
|
||||
Params[Параметры выбора]
|
||||
Action[SKU / действие В корзину]
|
||||
subgraph ProductPage["Карточка товара"]
|
||||
Title["Заголовок товара и навигация"]
|
||||
subgraph TopRow["Верхний блок"]
|
||||
Image["Изображение товара"]
|
||||
Params["Параметры выбора"]
|
||||
Action["SKU / действие В корзину"]
|
||||
end
|
||||
Help[Пояснения по параметрам]
|
||||
Table[Таблица доступных вариантов]
|
||||
Help["Пояснения по параметрам"]
|
||||
Table["Таблица доступных вариантов"]
|
||||
end
|
||||
|
||||
Title --> TopRow --> Help --> Table`,
|
||||
cart: `flowchart TB
|
||||
subgraph CartPage[Корзина]
|
||||
Items[Список выбранных позиций]
|
||||
Delivery[Адрес доставки]
|
||||
Comment[Комментарий клиента]
|
||||
Submit[Отправить заявку]
|
||||
subgraph CartPage["Корзина"]
|
||||
Items["Список выбранных позиций"]
|
||||
Delivery["Адрес доставки"]
|
||||
Comment["Комментарий клиента"]
|
||||
Submit["Отправить заявку"]
|
||||
end
|
||||
|
||||
Items --> Delivery --> Comment --> Submit`,
|
||||
'client-order': `flowchart TB
|
||||
subgraph ClientOrder[Карточка заявки / заказа]
|
||||
Summary[Номер документа и статус]
|
||||
Composition[Состав позиций]
|
||||
Terms[Стоимость и условия поставки]
|
||||
History[История изменений]
|
||||
subgraph ClientOrder["Карточка заявки / заказа"]
|
||||
Summary["Номер документа и статус"]
|
||||
Composition["Состав позиций"]
|
||||
Terms["Стоимость и условия поставки"]
|
||||
History["История изменений"]
|
||||
end
|
||||
|
||||
Summary --> Composition --> Terms --> History`,
|
||||
'bonus-cabinet': `flowchart TB
|
||||
subgraph BonusPage[Бонусный кабинет]
|
||||
Balance[Текущий бонусный баланс]
|
||||
History[История операций]
|
||||
Referrals[Реферальные связи]
|
||||
Action[Подача заявки на использование или вывод]
|
||||
subgraph BonusPage["Бонусный кабинет"]
|
||||
Balance["Текущий бонусный баланс"]
|
||||
History["История операций"]
|
||||
Referrals["Реферальные связи"]
|
||||
Action["Подача заявки на использование или вывод"]
|
||||
end
|
||||
|
||||
Balance --> History --> Referrals --> Action`,
|
||||
'manager-order': `flowchart TB
|
||||
subgraph ManagerOrder[Карточка обработки заявки]
|
||||
Summary[Клиент / контрагент / менеджер]
|
||||
Payload[Состав заявки или расчетный payload]
|
||||
Terms[Стоимость и условия поставки]
|
||||
Actions[Опубликовать условия / перевести в работу / отменить]
|
||||
subgraph ManagerOrder["Карточка обработки заявки"]
|
||||
Summary["Клиент / контрагент / менеджер"]
|
||||
Payload["Состав заявки или расчетный payload"]
|
||||
Terms["Стоимость и условия поставки"]
|
||||
Actions["Опубликовать условия / перевести в работу / отменить"]
|
||||
end
|
||||
|
||||
Summary --> Payload --> Terms --> Actions`,
|
||||
'manager-orders': `flowchart TB
|
||||
subgraph ManagerOrders[Список заказов менеджера]
|
||||
Header[Заголовок раздела]
|
||||
Filters[Фильтры: статус / клиент / период]
|
||||
Table[Таблица заказов]
|
||||
subgraph ManagerOrders["Список заказов менеджера"]
|
||||
Header["Заголовок раздела"]
|
||||
Filters["Фильтры: статус / клиент / период"]
|
||||
Table["Таблица заказов"]
|
||||
end
|
||||
|
||||
Header --> Filters --> Table`,
|
||||
|
||||
@@ -1,15 +1,10 @@
|
||||
import DefaultTheme from 'vitepress/theme';
|
||||
import type { Theme } from 'vitepress';
|
||||
|
||||
import MermaidDiagram from './components/MermaidDiagram.vue';
|
||||
import NamedMermaidDiagram from './components/NamedMermaidDiagram.vue';
|
||||
|
||||
const theme: Theme = {
|
||||
...DefaultTheme,
|
||||
enhanceApp({ app }) {
|
||||
DefaultTheme.enhanceApp?.({ app });
|
||||
app.component('MermaidDiagram', MermaidDiagram);
|
||||
app.component('NamedMermaidDiagram', NamedMermaidDiagram);
|
||||
enhanceApp(ctx) {
|
||||
DefaultTheme.enhanceApp?.(ctx);
|
||||
},
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user