diff options
author | Julius Härtl <jus@bitgrid.net> | 2020-09-01 12:07:48 +0200 |
---|---|---|
committer | npmbuildbot[bot] <npmbuildbot[bot]@users.noreply.github.com> | 2020-09-03 19:16:13 +0000 |
commit | 7a1748e6f02988891c6e70e50aa9e4d791fa0211 (patch) | |
tree | 1ae702c782c7f8ce703adce76228969003c900da /apps/settings/src | |
parent | 5826b75c4025529805135595da46d63c7d46560f (diff) | |
download | nextcloud-server-7a1748e6f02988891c6e70e50aa9e4d791fa0211.tar.gz nextcloud-server-7a1748e6f02988891c6e70e50aa9e4d791fa0211.zip |
Show changelog in apps management
Signed-off-by: Julius Härtl <jus@bitgrid.net>
Signed-off-by: npmbuildbot[bot] <npmbuildbot[bot]@users.noreply.github.com>
Diffstat (limited to 'apps/settings/src')
-rw-r--r-- | apps/settings/src/components/AppDetails.vue | 67 | ||||
-rw-r--r-- | apps/settings/src/components/Markdown.vue | 197 | ||||
-rw-r--r-- | apps/settings/src/views/Apps.vue | 40 |
3 files changed, 239 insertions, 65 deletions
diff --git a/apps/settings/src/components/AppDetails.vue b/apps/settings/src/components/AppDetails.vue index 55519bf9f80..d79f799fbb9 100644 --- a/apps/settings/src/components/AppDetails.vue +++ b/apps/settings/src/components/AppDetails.vue @@ -139,24 +139,23 @@ target="_blank" rel="noreferrer noopener">{{ t('settings', 'Developer documentation') }} ↗</a> </p> - - <div class="app-details__description" v-html="renderMarkdown" /> + <Markdown class="app-details__description" :text="app.description" /> </div> </template> <script> import { Multiselect } from '@nextcloud/vue' -import marked from 'marked' -import dompurify from 'dompurify' import AppManagement from '../mixins/AppManagement' import PrefixMixin from './PrefixMixin' +import Markdown from './Markdown' export default { name: 'AppDetails', components: { Multiselect, + Markdown, }, mixins: [AppManagement, PrefixMixin], @@ -204,66 +203,6 @@ export default { .filter(group => group.id !== 'disabled') .sort((a, b) => a.name.localeCompare(b.name)) }, - renderMarkdown() { - const renderer = new marked.Renderer() - renderer.link = function(href, title, text) { - let prot - try { - prot = decodeURIComponent(unescape(href)) - .replace(/[^\w:]/g, '') - .toLowerCase() - } catch (e) { - return '' - } - - if (prot.indexOf('http:') !== 0 && prot.indexOf('https:') !== 0) { - return '' - } - - let out = '<a href="' + href + '" rel="noreferrer noopener"' - if (title) { - out += ' title="' + title + '"' - } - out += '>' + text + '</a>' - return out - } - renderer.image = function(href, title, text) { - if (text) { - return text - } - return title - } - renderer.blockquote = function(quote) { - return quote - } - return dompurify.sanitize( - marked(this.app.description.trim(), { - renderer, - gfm: false, - highlight: false, - tables: false, - breaks: false, - pedantic: false, - sanitize: true, - smartLists: true, - smartypants: false, - }), - { - SAFE_FOR_JQUERY: true, - ALLOWED_TAGS: [ - 'strong', - 'p', - 'a', - 'ul', - 'ol', - 'li', - 'em', - 'del', - 'blockquote', - ], - } - ) - }, }, mounted() { if (this.app.groups.length > 0) { diff --git a/apps/settings/src/components/Markdown.vue b/apps/settings/src/components/Markdown.vue new file mode 100644 index 00000000000..74c333d8398 --- /dev/null +++ b/apps/settings/src/components/Markdown.vue @@ -0,0 +1,197 @@ +<!-- + - @copyright Copyright (c) 2020 Julius Härtl <jus@bitgrid.net> + - + - @author Julius Härtl <jus@bitgrid.net> + - + - @license GNU AGPL version 3 or any later version + - + - 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/>. + - + --> + +<template> + <div class="settings-markdown" v-html="renderMarkdown" /> +</template> + +<script> +import marked from 'marked' +import dompurify from 'dompurify' + +export default { + name: 'Markdown', + props: { + text: { + type: String, + default: '', + }, + }, + computed: { + renderMarkdown() { + const renderer = new marked.Renderer() + renderer.link = function(href, title, text) { + let prot + try { + prot = decodeURIComponent(unescape(href)) + .replace(/[^\w:]/g, '') + .toLowerCase() + } catch (e) { + return '' + } + + if (prot.indexOf('http:') !== 0 && prot.indexOf('https:') !== 0) { + return '' + } + + let out = '<a href="' + href + '" rel="noreferrer noopener"' + if (title) { + out += ' title="' + title + '"' + } + out += '>' + text + '</a>' + return out + } + renderer.image = function(href, title, text) { + if (text) { + return text + } + return title + } + renderer.blockquote = function(quote) { + return quote + } + return dompurify.sanitize( + marked(this.text.trim(), { + renderer, + gfm: false, + highlight: false, + tables: false, + breaks: false, + pedantic: false, + sanitize: true, + smartLists: true, + smartypants: false, + }), + { + SAFE_FOR_JQUERY: true, + ALLOWED_TAGS: [ + 'h1', + 'h2', + 'h3', + 'h4', + 'h5', + 'h6', + 'strong', + 'p', + 'a', + 'ul', + 'ol', + 'li', + 'em', + 'del', + 'blockquote', + ], + } + ) + }, + }, +} +</script> + +<style scoped lang="scss"> + .settings-markdown::v-deep { + + h1, + h2, + h3, + h4, + h5, + h6 { + font-weight: 600; + line-height: 120%; + margin-top: 24px; + margin-bottom: 12px; + color: var(--color-main-text); + } + + h1 { + font-size: 36px; + margin-top: 48px; + } + + h2 { + font-size: 28px; + margin-top: 48px; + } + + h3 { + font-size: 24px; + } + + h4 { + font-size: 21px; + } + + h5 { + font-size: 17px; + } + + h6 { + font-size: 14px; + } + + pre { + white-space: pre; + overflow-x: auto; + background-color: var(--color-background-dark); + border-radius: var(--border-radius); + padding: 1em 1.3em; + margin-bottom: 1em; + } + + p code { + background-color: var(--color-background-dark); + border-radius: var(--border-radius); + padding: .1em .3em; + } + + li { + position: relative; + } + + ul, ol { + padding-left: 10px; + margin-left: 10px; + } + + ul li { + list-style-type: disc; + } + + ul > li > ul > li { + list-style-type: circle; + } + + ul > li > ul > li ul li { + list-style-type: square; + } + + blockquote { + padding-left: 1em; + border-left: 4px solid var(--color-primary-element); + color: var(--color-text-maxcontrast); + margin-left: 0; + margin-right: 0; + } + + } +</style> diff --git a/apps/settings/src/views/Apps.vue b/apps/settings/src/views/Apps.vue index 313c58afbd9..a95127b77d6 100644 --- a/apps/settings/src/views/Apps.vue +++ b/apps/settings/src/views/Apps.vue @@ -119,7 +119,23 @@ </template> <!-- Tab content --> - <AppDetails :app="app" /> + + <AppSidebarTab id="desc" + icon="icon-category-office" + :name="t('settings', 'Details')" + :order="0"> + <AppDetails :app="app" /> + </AppSidebarTab> + <AppSidebarTab v-if="app.appstoreData && app.releases[0].translations.en.changelog" + id="desca" + icon="icon-category-organization" + :name="t('settings', 'Changelog')" + :order="1"> + <div v-for="release in app.releases" :key="release.version" class="app-sidebar-tabs__release"> + <h2>{{ release.version }}</h2> + <Markdown v-if="changelog(release)" :text="changelog(release)" /> + </div> + </AppSidebarTab> </AppSidebar> </Content> </template> @@ -131,6 +147,7 @@ import AppNavigationCounter from '@nextcloud/vue/dist/Components/AppNavigationCo import AppNavigationItem from '@nextcloud/vue/dist/Components/AppNavigationItem' import AppNavigationSpacer from '@nextcloud/vue/dist/Components/AppNavigationSpacer' import AppSidebar from '@nextcloud/vue/dist/Components/AppSidebar' +import AppSidebarTab from '@nextcloud/vue/dist/Components/AppSidebarTab' import Content from '@nextcloud/vue/dist/Components/Content' import Vue from 'vue' import VueLocalStorage from 'vue-localstorage' @@ -139,6 +156,7 @@ import AppList from '../components/AppList' import AppDetails from '../components/AppDetails' import AppManagement from '../mixins/AppManagement' import AppScore from '../components/AppList/AppScore' +import Markdown from '../components/Markdown' Vue.use(VueLocalStorage) @@ -155,7 +173,9 @@ export default { AppNavigationSpacer, AppScore, AppSidebar, + AppSidebarTab, Content, + Markdown, }, mixins: [AppManagement], @@ -228,6 +248,9 @@ export default { } }, + changelog() { + return (release) => release.translations.en.changelog + }, }, watch: { @@ -326,4 +349,19 @@ export default { } } + .app-sidebar-tabs__release { + h2 { + border-bottom: 1px solid var(--color-border); + } + + // Overwrite changelog heading styles + ::v-deep { + h3 { + font-size: 20px; + } + h4 { + font-size: 17px; + } + } + } </style> |