Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Help sidebar: Move docs to docs repo & Integrate them into the UI #2253

Merged
merged 11 commits into from
Jan 27, 2024
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,18 @@
</f7-block-title>
</f7-block>

<thing-context v-if="($store.state.pagePath).indexOf('things') >= 0" />
<item-context v-else-if="($store.state.pagePath).indexOf('items') >= 0" />
<model-context v-else-if="($store.state.pagePath).indexOf('model') >= 0" />
<page-context v-else-if="($store.state.pagePath).indexOf('pages') >= 0" />
<rule-context v-else-if="($store.state.pagePath).indexOf('rules') >= 0 || ($store.state.pagePath).indexOf('schedule') >= 0" type="Rules" />
<rule-context v-else-if="($store.state.pagePath).indexOf('scenes') >= 0" type="Scenes" />
<rule-context v-else-if="($store.state.pagePath).indexOf('scripts') >= 0" type="Scripts" />
<widget-context v-else-if="($store.state.pagePath).indexOf('widgets') >= 0" />
<transform-context v-else-if="($store.state.pagePath).indexOf('transformations') >= 0" />
<addon-context v-else-if="($store.state.pagePath).indexOf('addons') >= 0" />
<default-context v-else style="width: 100%" />
<!-- /settings/* docs -->
<context v-if="($store.state.pagePath) === '/settings/'" path="/settings/index" />
<context v-else-if="/\/settings\/[A-z]+/.test($store.state.pagePath)" :path="/(\/[A-z]+\/[A-z]+)/.exec($store.state.pagePath)[0]" />
<!-- /addons/ docs -->
<context v-else-if="($store.state.pagePath).indexOf('/addons/') >= 0" path="/addons" />
<!-- /developer/* docs -->
<context v-else-if="($store.state.pagePath) === '/developer/'" path="/developer/index" />
<context v-else-if="($store.state.pagePath).indexOf('/developer/widgets') >= 0" path="/developer/widgets" />
<!-- /about/ docs -->
<context v-else-if="($store.state.pagePath).indexOf('/about/') >= 0" path="/about" />
<!-- default docs -->
<context v-else path="/index" />

<f7-block class="no-padding no-margin">
<f7-block-title class="padding-horizontal" medium>
Expand Down Expand Up @@ -142,27 +143,11 @@

<script>
import { loadLocaleMessages } from '@/js/i18n'
import ThingContext from './help/thing-context.vue'
import ItemContext from './help/item-context.vue'
import ModelContext from './help/model-context.vue'
import PageContext from './help/page-context.vue'
import RuleContext from './help/rule-context.vue'
import WidgetContext from './help/widget-context.vue'
import AddonContext from './help/addon-context.vue'
import TransformContext from './help/transform-context.vue'
import DefaultContext from './help/default-context.vue'
import Context from '@/components/developer/help/context.vue'

export default {
components: {
ThingContext,
ItemContext,
ModelContext,
PageContext,
RuleContext,
WidgetContext,
AddonContext,
TransformContext,
DefaultContext
Context
},
props: ['activeHelpTab'],
data () {
Expand Down

This file was deleted.

126 changes: 126 additions & 0 deletions bundles/org.openhab.ui/web/src/components/developer/help/context.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
<template>
<f7-block class="no-margin no-padding">
<f7-block>
<div v-show="ready" v-html="parsedDocs" />
</f7-block>
<f7-block>
<f7-link external :href="documentationLink" target="_blank" text="Open full documentation" color="blue" />
</f7-block>
</f7-block>
</template>

<script>
export default {
props: ['path'],
data () {
return {
ready: false,
parsedDocs: null,
cache: {} // Use some simple caching mechanism to avoid reloading .md file every time the context changes
}
},
computed: {
docsBranch () {
if (this.$store.state.runtimeInfo.buildString === 'Release Build') return 'final-stable'
return 'final'
},
docUrl () {
return `https://${this.$store.state.runtimeInfo.buildString === 'Release Build' ? 'www' : 'next'}.openhab.org/docs`
},
docSrcUrl () {
return `https://raw.githubusercontent.com/openhab/openhab-docs/${this.docsBranch}/mainui`
},
localUrl () {
if (!this.$store.state.pagePath.endsWith('/')) return '/'
return this.$store.state.pagePath
},
documentationLink () {
if (this.path.endsWith('index')) return `${this.docUrl}/mainui${this.path.replace('index', '')}`
return `${this.docUrl}/mainui${this.path}`
}
},
watch: {
path () {
if (this.ready) {
this.ready = false
this.load()
}
}
},
methods: {
load () {
console.debug('Sidebar Help: Loading docs for ' + this.path + ' ...')
if (this.cache[this.path]) {
console.debug('Sidebar Help: Using docs from cache.')
this.parsedDocs = this.cache[this.path]
this.ready = true
return
}
console.debug('Sidebar Help: Docs not found in cache, loading from GitHub ...')
fetch(this.docSrcUrl + this.path + '.md').then((response) => {
if (response.status === 404) {
this.parsedDocs = '<p>Failed to load docs. It seems they are missing.</p><p>Please <a class="external" target="_blank" href="https://github.com/openhab/openhab-docs/issues/new">report this on the openHAB docs repo</a>.</p>'
this.ready = true
return
}
response.text().then((text) => {
import('marked').then((marked) => {
const startComment = '<!-- START MAINUI SIDEBAR DOC - DO NOT REMOVE -->'
const endComment = '<!-- END MAINUI SIDEBAR DOC - DO NOT REMOVE -->'

// Remove frontmatter stuff
const frontmatterSeparators = [...text.matchAll(/^---$/gm)]
if (frontmatterSeparators.length > 0) {
text = text.substring(frontmatterSeparators[1].index + 4)
}
// Remove anything before the start comment (if existent)
const startIndex = text.indexOf(startComment)
if (startIndex > -1) {
text = text.substring(startIndex + startComment.length)
}
// Remove anything after the end comment (if existent)
const endIndex = text.indexOf(endComment)
if (endIndex > -1) {
text = text.substring(0, endIndex)
}
let body = marked.parse(text)

// Perform a few replaces on HTML body for Markdown readmes on GitHub
body = body.replace(/<p>{% include base.html %}<\/p>\n/gm, '')
body = body.replace(/<h1 .*$/gm, '') // Remove h1 headings
body = body.replace(/<img src=".*$/gm, '') // Remove images

// Fix {{base}} and /docs anchor href for doc pages
body = body.replace(/<a href="(%7B%7Bbase%7D%7D|\/docs)/gm, `<a class="external" target="_blank" href="${this.docUrl}`)
// Fix local folder anchor href: Rewrite folder to /folder/
body = body.replace(/(<a href=")([A-z]+)(")/gm, '$1' + this.localUrl + '$2/$3')

// Allow embedding framework7 icons by using <!--F7(:blue|:green) ICON_NAME --> comments
body = body.replace(/<!--F7 ([A-z]*) -->/gm, '<i class="f7-icons size-22">$1</i>')
body = body.replace(/<!--F7:blue ([A-z]*) -->/gm, '<i class="f7-icons size-22" style="color: #2196f3">$1</i>')
body = body.replace(/<!--F7:green ([A-z]*) -->/gm, '<i class="f7-icons size-22" style="color: #4cd964">$1</i>')

body = body.replace(/<pre>/gm, '<div class="block block-strong no-padding"><pre class="padding-half">')
body = body.replace(/<\/pre>/gm, '</pre></div>')
body = body.replace(/<table>/gm, '<div class="data-table"><table>')
body = body.replace(/<\/table>/gm, '</table></div>')

this.cache[this.path] = body
this.parsedDocs = body
this.ready = true
}).catch((err) => {
this.parsedDocs = '<p>Failed to parse docs.</p><h3>Debug Information</h3><blockquote>' + err + '</blockquote>'
this.ready = true
})
})
}).catch((err) => {
this.parsedDocs = '<p>Failed to load docs.</p><p>This might be an issue with your internet connection.</p><h3>Debug Information</h3><blockquote>' + err + '</blockquote>'
this.ready = true
})
}
},
created () {
this.load()
}
}
</script>

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Loading
Loading