fix message docs WIP

This commit is contained in:
Nemo Godebski-Pedersen 2025-09-30 19:56:00 +07:00
parent cd1d5c8ec3
commit 7487c89d6e
4 changed files with 268 additions and 51 deletions

4
components.d.ts vendored
View File

@ -11,6 +11,7 @@ declare module 'vue' {
ChatMessage: typeof import('./src/components/ChatMessage.vue')['default']
ChatWidget: typeof import('./src/components/ChatWidget.vue')['default']
ChatWidgetOld: typeof import('./src/components/ChatWidgetOld.vue')['default']
CodeBlock: typeof import('./src/components/CodeBlock.vue')['default']
Collections: typeof import('./src/components/Collections.vue')['default']
Content: typeof import('./src/components/Content.vue')['default']
ElAlert: typeof import('element-plus/es')['ElAlert']
@ -21,6 +22,7 @@ declare module 'vue' {
ElCollapse: typeof import('element-plus/es')['ElCollapse']
ElCollapseItem: typeof import('element-plus/es')['ElCollapseItem']
ElContainer: typeof import('element-plus/es')['ElContainer']
ElContainter: typeof import('element-plus/es')['ElContainter']
ElDescriptions: typeof import('element-plus/es')['ElDescriptions']
ElDescriptionsItem: typeof import('element-plus/es')['ElDescriptionsItem']
ElDivider: typeof import('element-plus/es')['ElDivider']
@ -38,10 +40,12 @@ declare module 'vue' {
ElMenuItem: typeof import('element-plus/es')['ElMenuItem']
ElRow: typeof import('element-plus/es')['ElRow']
ElScrollbar: typeof import('element-plus/es')['ElScrollbar']
ElTag: typeof import('element-plus/es')['ElTag']
ElTooltip: typeof import('element-plus/es')['ElTooltip']
GlossarySearchNav: typeof import('./src/components/GlossarySearchNav.vue')['default']
HeaderNav: typeof import('./src/components/HeaderNav.vue')['default']
Menu: typeof import('./src/components/Menu.vue')['default']
MessageDocsContent: typeof import('./src/components/MessageDocsContent.vue')['default']
MessageDocsSearchNav: typeof import('./src/components/MessageDocsSearchNav.vue')['default']
Preview: typeof import('./src/components/Preview.vue')['default']
RouterLink: typeof import('vue-router')['RouterLink']

View File

@ -0,0 +1,149 @@
<!--
- Open Bank Project - API Explorer II
- Copyright (C) 2023-2024, TESOBE GmbH
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU Affero General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU Affero General Public License for more details.
-
- You should have received a copy of the GNU Affero General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>.
-
- Email: contact@tesobe.com
- TESOBE GmbH
- Osloerstrasse 16/17
- Berlin 13359, Germany
-
- This product includes software developed at
- TESOBE (http://www.tesobe.com/)
-
-->
<script setup lang="ts">
import { ref, onMounted, onUpdated, nextTick } from 'vue'
// Declare global hljs
declare global {
interface Window {
hljs: {
highlightElement: (element: HTMLElement) => void
}
}
}
interface Props {
code: any
language?: string
}
const props = withDefaults(defineProps<Props>(), {
language: 'json'
})
const codeBlockRef = ref<HTMLElement>()
const highlight = async () => {
await nextTick()
if (codeBlockRef.value && window.hljs) {
const codeElements = codeBlockRef.value.querySelectorAll('pre code')
codeElements.forEach((block) => {
window.hljs.highlightElement(block as HTMLElement)
})
}
}
onMounted(() => {
highlight()
})
onUpdated(() => {
highlight()
})
const formattedCode = typeof props.code === 'string'
? props.code
: JSON.stringify(props.code, null, 2)
</script>
<template>
<div ref="codeBlockRef" class="code-block">
<pre><code :class="language">{{ formattedCode }}</code></pre>
</div>
</template>
<style scoped>
.code-block {
margin: 1rem 0;
border-radius: 8px;
overflow: hidden;
background: #1e1e1e;
border: 1px solid #333;
}
.code-block pre {
margin: 0;
padding: 1.5rem;
background: #1e1e1e;
color: #ddd;
font-family: 'Fira Code', 'Courier New', monospace;
font-size: 14px;
line-height: 1.5;
overflow-x: auto;
white-space: pre-wrap;
word-wrap: break-word;
}
.code-block code {
background: transparent;
padding: 0;
border-radius: 0;
font-family: inherit;
font-size: inherit;
}
/* Custom scrollbar for code blocks */
.code-block pre::-webkit-scrollbar {
height: 8px;
width: 8px;
}
.code-block pre::-webkit-scrollbar-track {
background: #2d2d2d;
}
.code-block pre::-webkit-scrollbar-thumb {
background: #555;
border-radius: 4px;
}
.code-block pre::-webkit-scrollbar-thumb:hover {
background: #777;
}
/* Syntax highlighting enhancements */
.code-block :deep(.hljs-string) {
color: #98c379;
}
.code-block :deep(.hljs-number) {
color: #d19a66;
}
.code-block :deep(.hljs-literal) {
color: #56b6c2;
}
.code-block :deep(.hljs-attr) {
color: #e06c75;
}
.code-block :deep(.hljs-punctuation) {
color: #abb2bf;
}
</style>

View File

@ -36,6 +36,7 @@ import InternalServerErrorView from '../views/InternalServerErrorView.vue'
import APIServerErrorView from '../views/APIServerErrorView.vue'
import APIServerStatusView from '../views/APIServerStatusView.vue'
import { isServerUp } from '../obp'
import MessageDocsContent from '@/components/CodeBlock.vue'
export default async function router(): Promise<any> {
const isServerActive = await isServerUp()
@ -60,7 +61,7 @@ export default async function router(): Promise<any> {
{
path: '/message-docs/:id',
name: 'message-docs',
component: isServerActive ? MessageDocsView : InternalServerErrorView
component: isServerActive ? MessageDocsView : InternalServerErrorView,
},
{
path: '/operationid',

View File

@ -31,12 +31,16 @@ import { useRoute } from 'vue-router'
import SearchNav from '../components/MessageDocsSearchNav.vue'
import { connectors } from '../obp/message-docs'
import { obpGroupedMessageDocsKey } from '@/obp/keys';
import MessageDocsSearchNav from '../components/MessageDocsSearchNav.vue';
import CodeBlock from '../components/CodeBlock.vue';
let connector = connectors[0]
const route = useRoute()
const groupedMessageDocs = ref(inject(obpGroupedMessageDocsKey)!)
const messageDocs = ref({})
const activeNames = ref(['1', '2', '3', '4', '5', '6'])
onBeforeMount(() => {
setDoc()
})
@ -64,68 +68,126 @@ function showDependentEndpoints(value: any) {
</script>
<template>
<el-container>
<el-container class="root">
<el-aside class="search-nav" width="20%">
<SearchNav />
</el-aside>
<el-main>
<el-container class="main">
<el-container>
<main>
<el-backtop :right="100" :bottom="100" target="main" />
<div v-for="(group, key) of messageDocs" :key="key">
<div v-for="(value, key) of group" :key="value">
<el-divider content-position="left">{{ value.process }}</el-divider>
<a v-bind:href="`#${value.process}`" :id="value.process">
<h2>{{ value.description }}</h2>
</a>
<el-descriptions direction="vertical" :column="1" border>
<el-descriptions-item label="Outbound Topic">
{{ value.outbound_topic }}
</el-descriptions-item>
<el-descriptions-item label="Inbound Topic">
{{ value.inbound_topic }}
</el-descriptions-item>
<el-descriptions-item label="Outbound Message">
<pre>{{ JSON.stringify(value.example_outbound_message, null, 4) }}</pre>
</el-descriptions-item>
<el-descriptions-item label="Inbound Message">
<pre>{{ JSON.stringify(value.example_inbound_message, null, 4) }}</pre>
</el-descriptions-item>
<el-descriptions-item v-if="showRequiredFieldInfo(value.requiredFieldInfo)" label="Required Fields">
<pre>{{ JSON.stringify(value.requiredFieldInfo, null, 4) }}</pre>
</el-descriptions-item>
<el-descriptions-item v-if="showDependentEndpoints(value.dependent_endpoints)"
label="Dependent Endpoints">
<ul>
<li v-for="(endpoint, key) of value.dependent_endpoints">
{{ endpoint.version }}: {{ endpoint.name }}
</li>
</ul>
</el-descriptions-item>
</el-descriptions>
<el-divider content-position="right">{{ value.process }}</el-divider>
<br />
<br />
<br />
<br />
<div v-for="(group, key) of messageDocs" :key="key">
<div v-for="(value, key) of group" :key="value">
<el-divider></el-divider>
<header>
</header>
<a v-bind:href="`#${value.process}`" :id="value.process">
<h2>{{ value.process }}</h2>
</a>
<p>{{ value.description }}</p>
<section class="topics">
<div>
<strong>Outbound Topic: </strong>
<el-tag type="info" round>{{ value.outbound_topic }}</el-tag>
</div>
</div>
</main>
</el-container>
<div>
<strong>Inbound Topic: </strong>
<el-tag type="info" round>{{ value.inbound_topic }}</el-tag>
</div>
</section>
<section>
<h3>Example Outbound Message</h3>
<CodeBlock :code="value.example_outbound_message" />
</section>
<section>
<h3>Example Inbound Message</h3>
<CodeBlock :code="value.example_inbound_message" />
</section>
<section v-if="showRequiredFieldInfo(value.requiredFieldInfo)">
<h3>Required Fields</h3>
<CodeBlock :code="value.requiredFieldInfo" />
</section>
<section v-if="showDependentEndpoints(value.dependent_endpoints)">
<h3>Dependent Endpoints</h3>
<ul>
<li v-for="endpoint in value.dependent_endpoints" :key="endpoint.name">
{{ endpoint.version }} {{ endpoint.name }}
</li>
</ul>
</section>
</div>
</div>
</el-container>
</el-main>
</el-container>
<!-- <el-container>
<el-aside class="search-nav" width="20%">
<MessageDocsSearchNav />
</el-aside>
<el-main>
<el-backtop :right="100" :bottom="100" target="main" />
<div v-for="(group, key) of messageDocs" :key="key">
<div v-for="(value, key) of group" :key="value">
<el-divider content-position="left">{{ value.process }}</el-divider>
<a v-bind:href="`#${value.process}`" :id="value.process">
<h2>{{ value.description }}</h2>
</a>
<el-collapse v-model="activeNames" @change="handleChange">
<el-collapse-item title="Outbound Topic" name="1">
{{ value.outbound_topic }}
</el-collapse-item>
<el-collapse-item title="Inbound Topic" name="2">
{{ value.inbound_topic }}
</el-collapse-item>
<el-collapse-item title="Outbound Message" name="3">
<pre>{{ JSON.stringify(value.example_outbound_message, null, 4) }}</pre>
</el-collapse-item>
<el-collapse-item title="Inbound Message" name="4">
<pre>{{ JSON.stringify(value.example_inbound_message, null, 4) }}</pre>
</el-collapse-item>
<el-collapse-item v-if="showRequiredFieldInfo(value.requiredFieldInfo)" title="Required Fields" name="5">
<pre>{{ JSON.stringify(value.requiredFieldInfo, null, 4) }}</pre>
</el-collapse-item>
<el-collapse-item v-if="showDependentEndpoints(value.dependent_endpoints)" title="Dependent Endpoints"
name="6">
<ul>
<li v-for="(endpoint, key) of value.dependent_endpoints">
{{ endpoint.version }}: {{ endpoint.name }}
</li>
</ul>
</el-collapse-item>
</el-collapse>
<el-divider content-position="right">{{ value.process }}</el-divider>
<br />
<br />
<br />
<br />
</div>
</div>
</el-main>
</el-container> -->
</template>
<style scoped>
.main {
max-height: 90vh;
.root {
height: 100%;
}
template {
overflow: auto;
max-height: 900px;
.main {
height: 100%;
overflow: scroll;
}
.search-nav {
height: 100%;
max-height: 100%;
overflow: hidden;
}
main {
@ -141,6 +203,7 @@ span {
div {
font-size: 14px;
}
pre {
font-family: 'Roboto';
}
@ -154,7 +217,7 @@ a {
color: #39455f;
}
.content :deep(a) {
/* .content :deep(a) {
text-decoration: none;
color: #ffffff;
font-family: 'Roboto';
@ -162,7 +225,7 @@ a {
border-radius: 3px;
background-color: #52b165;
padding: 1px;
}
} */
.content :deep(a):hover {
background-color: #39455f;