appv2: misc fixes (semantic, linting) + reorganization on AppInstalll & appInfo

This commit is contained in:
axolotle 2022-12-12 18:15:03 +01:00
parent 771a5b7f25
commit ecb31a6d1c
2 changed files with 156 additions and 185 deletions

View file

@ -1,48 +1,52 @@
<template> <template>
<view-base :queries="queries" @queries-response="onQueriesResponse" ref="view"> <view-base :queries="queries" @queries-response="onQueriesResponse" ref="view">
<section v-if="app" class="mb-5">
<template v-if="app"> <div class="d-md-flex align-items-center mb-4">
<h1> <h1 class="mb-3 mb-md-0">
<icon iname="cube" /> <icon iname="cube" />
{{ app.label }} {{ app.label }}
<span class="text-secondary tiny"> <span class="text-secondary tiny">
{{ app.id }} {{ app.id }}
</span> </span>
</h1>
<b-button <b-button
class="mx-3"
v-if="app.url" v-if="app.url"
size="xs" :href="app.url" target="_blank"
:href="app.url" variant="success" target="_blank" variant="success" class="ml-auto mr-2"
> >
<icon iname="external-link" /> <icon iname="external-link" />
{{ $t('app.open_this_app') }} {{ $t('app.open_this_app') }}
</b-button> </b-button>
<b-button <b-button
class="float-right"
@click="uninstall" @click="uninstall"
id="uninstall" id="uninstall"
variant="danger" variant="danger"
> >
<icon iname="trash-o" /> {{ $t('uninstall') }} <icon iname="trash-o" />
{{ $t('uninstall') }}
</b-button> </b-button>
</h1> </div>
<section> <p class="text-secondary">
<p> {{ $t('app.installed_version', { version: app.version }) }}<br>
<span class="text-secondary">{{ $t('app.installed_version', { version: app.version }) }}</span><br/>
<icon iname="comments" /> {{ $t('app.info.problem') }} <template v-if="app.alternativeTo">
<a :href="`https://forum.yunohost.org/tag/${id}`" target="_blank" {{ $t('app.potential_alternative_to') }} {{ app.alternativeTo }}
>{{ $t('app.info.forum') }} </template>
</a>
{{ app.alternativeTo }}
</p> </p>
<vue-showdown :markdown="doc.about.description" flavor="github" /> <p>
<icon iname="comments" /> {{ $t('app.info.problem') }}
<a :href="`https://forum.yunohost.org/tag/${id}`" target="_blank">
{{ $t('app.info.forum') }}
</a>
</p>
<vue-showdown :markdown="app.description" flavor="github" />
</section> </section>
</template>
<!-- BASIC INFOS --> <!-- BASIC INFOS -->
<config-panels v-bind="config" @submit="onConfigSubmit"> <config-panels v-bind="config" @submit="onConfigSubmit">
@ -152,14 +156,14 @@
</template> </template>
</config-panels> </config-panels>
<b-card v-if="doc" no-body> <b-card v-if="app && (app.doc.notifications || app.doc.admin)" no-body>
<b-tabs card fill pills> <b-tabs card fill pills>
<b-tab :title="$t('app.doc.notifications.title')" active> <b-tab v-if="app.doc.notifications" :title="$t('app.doc.notifications.title')" active>
<section v-if="doc.notifications.postUpgrade.length"> <section v-if="app.doc.notifications.postUpgrade.length">
<b-card-title title-tag="h3" v-t="'app.doc.notifications.post_upgrade'" /> <b-card-title title-tag="h3" v-t="'app.doc.notifications.post_upgrade'" />
<div <div
v-for="[name, notif] in doc.notifications.postUpgrade" :key="name" v-for="[name, notif] in app.doc.notifications.postUpgrade" :key="name"
> >
<b-card-title v-if="name !== 'main'"> <b-card-title v-if="name !== 'main'">
{{ name }} {{ name }}
@ -168,13 +172,13 @@
</div> </div>
</section> </section>
<section v-if="doc.notifications.postInstall.length"> <section v-if="app.doc.notifications.postInstall.length">
<b-card-title title-tag="h3"> <b-card-title title-tag="h3">
{{ $t('app.doc.notifications.post_install') }} {{ $t('app.doc.notifications.post_install') }}
</b-card-title> </b-card-title>
<div <div
v-for="[name, notif] in doc.notifications.postInstall" :key="name" v-for="[name, notif] in app.doc.notifications.postInstall" :key="name"
> >
<b-card-title tag="h5" v-if="name !== 'main'"> <b-card-title tag="h5" v-if="name !== 'main'">
{{ name }} {{ name }}
@ -184,55 +188,43 @@
</section> </section>
</b-tab> </b-tab>
<b-tab :title="$t('app.doc.admin.title')" no-body> <b-tab :title="$t('app.doc.admin.title')">
{{ doc.admin.links }} <vue-showdown :markdown="app.doc.admin" flavor="github" />
<vue-showdown :markdown="doc.admin.content" flavor="github" />
</b-tab> </b-tab>
</b-tabs> </b-tabs>
</b-card> </b-card>
<card <card
id="app-integration" v-if="app && app.integration"
collapsable :collapsed="1" id="app-integration" :title="$t('app.integration.title')"
flush visible collapsable collapsed no-body
v-if="packaging_format >= 2 && doc"
> >
<template #header> <b-list-group flush>
<h2>{{ $t('app.integration.title') }}</h2>
</template>
<b-list-group flush tag="section">
<yuno-list-group-item variant="info"> <yuno-list-group-item variant="info">
{{ $t('app.integration.archs') }} {{ doc.about.integration.archs }} {{ $t('app.integration.archs') }} {{ app.integration.archs }}
</yuno-list-group-item> </yuno-list-group-item>
<yuno-list-group-item v-if="doc.about.integration.ldap" :variant="doc.about.integration.ldap === true ? 'success' : 'warning'"> <yuno-list-group-item v-if="app.integration.ldap" :variant="app.integration.ldap === true ? 'success' : 'warning'">
{{ $t(`app.integration.ldap.${doc.about.integration.ldap}`) }} {{ $t(`app.integration.ldap.${app.integration.ldap}`) }}
</yuno-list-group-item> </yuno-list-group-item>
<yuno-list-group-item v-if="doc.about.integration.sso" :variant="doc.about.integration.sso === true ? 'success' : 'warning'"> <yuno-list-group-item v-if="app.integration.sso" :variant="app.integration.sso === true ? 'success' : 'warning'">
{{ $t(`app.integration.sso.${doc.about.integration.sso}`) }} {{ $t(`app.integration.sso.${app.integration.sso}`) }}
</yuno-list-group-item> </yuno-list-group-item>
<yuno-list-group-item variant="info"> <yuno-list-group-item variant="info">
{{ $t(`app.integration.multi_instance.${doc.about.integration.multi_instance}`) }} {{ $t(`app.integration.multi_instance.${app.integration.multi_instance}`) }}
</yuno-list-group-item> </yuno-list-group-item>
<yuno-list-group-item variant="info"> <yuno-list-group-item variant="info">
{{ $t('app.integration.resources', doc.about.integration.resources) }} {{ $t('app.integration.resources', app.integration.resources) }}
</yuno-list-group-item> </yuno-list-group-item>
</b-list-group> </b-list-group>
</card> </card>
<card <card
id="app-links" v-if="app"
collapsable :collapsed="1" id="app-links" icon="link" :title="$t('app.links.title')"
no-body button-unbreak="lg" collapsable collapsed no-body
flush visible
v-if="doc"
> >
<template #header> <b-list-group flush>
<h2><icon iname="link" /> {{ $t('app.links.title') }}</h2> <yuno-list-group-item v-for="[key, link] in app.links" :key="key" no-status>
</template>
<b-list-group flush tag="section">
<yuno-list-group-item v-for="[key, link] in doc.about.links" :key="key" no-status>
<b-link :href="link" target="_blank"> <b-link :href="link" target="_blank">
<icon :iname="appLinksIcons(key)" /> <icon :iname="appLinksIcons(key)" />
{{ $t('app.links.' + key) }} {{ $t('app.links.' + key) }}
@ -282,7 +274,6 @@ export default {
['GET', { uri: 'domains' }], ['GET', { uri: 'domains' }],
['GET', `apps/${this.id}/config?full`] ['GET', `apps/${this.id}/config?full`]
], ],
packaging_format: undefined,
app: undefined, app: undefined,
form: undefined, form: undefined,
config: { config: {
@ -325,17 +316,17 @@ export default {
}, },
methods: { methods: {
appLinksIcons (link_type) { appLinksIcons (linkType) {
const links_icons = { const linksIcons = {
license: "institution", license: 'institution',
website: "globe", website: 'globe',
admindoc: "book", admindoc: 'book',
userdoc: "book", userdoc: 'book',
code: "code", code: 'code',
package: "code", package: 'code',
forum: "comments" forum: 'comments'
} }
return links_icons[link_type] return linksIcons[linkType]
}, },
onQueriesResponse (app, _, __, config) { onQueriesResponse (app, _, __, config) {
if (app.supports_config_panel) { if (app.supports_config_panel) {
@ -366,14 +357,44 @@ export default {
form.labels.push({ label: perm.sublabel, show_tile: perm.show_tile }) form.labels.push({ label: perm.sublabel, show_tile: perm.show_tile })
} }
} }
this.packaging_format = app.packaging_format
this.form = form this.form = form
const { DESCRIPTION, ADMIN, ...doc } = app.manifest.doc
const notifs = app.manifest.notifications
const { ldap, sso, multi_instance, ram, disk, architectures: archs } = app.manifest.integration
this.app = { this.app = {
id: this.id, id: this.id,
version: app.version, version: app.version,
label: mainPermission.label, label: mainPermission.label,
domain: app.settings.domain, domain: app.settings.domain,
alternativeTo: app.from_catalog.potential_alternative_to?.length
? app.from_catalog.potential_alternative_to.join(this.$i18n.t('words.separator'))
: null,
description: DESCRIPTION ? formatI18nField(DESCRIPTION) : app.description,
integration: app.manifest.packaging_format >= 2 ? {
archs: Array.isArray(archs) ? archs.join(this.$i18n.t('words.separator')) : archs,
ldap: ldap === 'not_relevant' ? null : ldap,
sso: sso === 'not_relevant' ? null : sso,
multi_instance,
resources: { ram: ram.runtime, disk }
} : null,
links: [
['license', `https://spdx.org/licenses/${app.manifest.upstream.license}`],
...['website', 'admindoc', 'userdoc', 'code'].map((key) => ([key, app.manifest.upstream[key]])),
['forum', `https://forum.yunohost.org/tag/${this.id}`]
].filter(([key, val]) => !!val),
doc: {
notifications: {
postInstall: notifs.post_install.main ? [['main', formatI18nField(notifs.post_install.main)]] : [],
postUpgrade: Object.entries(notifs.post_upgrade).map(([key, content]) => {
return [key, formatI18nField(content)]
})
},
admin: [
formatI18nField(ADMIN),
...Object.keys(doc).sort().map((key) => formatI18nField(doc[key]))
].join('\n\n')
},
is_webapp: app.is_webapp, is_webapp: app.is_webapp,
is_default: app.is_default, is_default: app.is_default,
supports_change_url: app.supports_change_url, supports_change_url: app.supports_change_url,
@ -388,45 +409,8 @@ export default {
} }
} }
const notifs = app.manifest.notifications if (!Object.values(this.app.doc.notifications).some((notif) => notif.length)) {
const { DESCRIPTION, ADMIN, ...doc } = app.manifest.doc this.app.doc.notifications = null
const { ldap, sso, multi_instance, ram, disk, architectures: archs } = app.manifest.integration
this.doc = {
notifications: {
postInstall: [['main', formatI18nField(notifs.post_install.main)]],
postUpgrade: Object.entries(notifs.post_upgrade).map(([key, content]) => {
return [key, formatI18nField(content)]
})
},
admin: {
content: [
formatI18nField(ADMIN),
...Object.keys(doc).sort().map((key) => formatI18nField(doc[key]))
].join('\n\n')
},
about: {
alternativeTo: app.from_catalog.potential_alternative_to.length
? app.from_catalog.potential_alternative_to.join(this.$i18n.t('words.separator'))
: null,
description: DESCRIPTION ? formatI18nField(DESCRIPTION) : app.description,
license: app.manifest.upstream.license,
integration: {
archs: Array.isArray(archs) ? archs.join(this.$i18n.t('words.separator')) : archs,
ldap: ldap === 'not_relevant' ? null : ldap,
sso: sso === 'not_relevant' ? null : sso,
multi_instance,
resources: { ram: ram.runtime, disk }
},
links: [
['license', `https://spdx.org/licenses/${app.manifest.upstream.license}`],
...['website', 'admindoc', 'userdoc', 'code'].map((key) => ([key, app.manifest.upstream[key]])),
['forum', `https://forum.yunohost.org/tag/${this.id}`]
].filter(([key, val]) => !!val)
}
}
if (this.app.is_webapp) {
this.app.is_default = app.is_default
} }
}, },
@ -513,8 +497,4 @@ select {
font-size: 50%; font-size: 50%;
font-weight: normal; font-weight: normal;
} }
.float-right {
float: right;
}
</style> </style>

View file

@ -1,48 +1,45 @@
<template> <template>
<view-base :queries="queries" @queries-response="onQueriesResponse"> <view-base :queries="queries" @queries-response="onQueriesResponse">
<template v-if="app"> <template v-if="app">
<section class="mb-5">
<h1> <div class="d-md-flex align-items-center mb-4">
{{ app.name}} <h1 class="mb-3 mb-md-0">
{{ app.name }}
</h1>
<b-button <b-button
class="ml-3 float-right"
v-if="app.demo" v-if="app.demo"
:href="app.demo" variant="primary" target="_blank" :href="app.demo" target="_blank"
variant="primary" class="ml-auto"
> >
<icon iname="external-link" /> <icon iname="external-link" />
{{ $t('app.install.try_demo') }} {{ $t('app.install.try_demo') }}
</b-button> </b-button>
</h1> </div>
<section> <p class="text-secondary">
<p class="text-secondary small mb-0">
{{ $t('app.install.version', { version: app.version }) }}<br> {{ $t('app.install.version', { version: app.version }) }}<br>
</p>
<p class="text-secondary small mb-0" v-if="app.alternativeTo"> <template v-if="app.alternativeTo">
{{ $t('app.potential_alternative_to') }} {{ app.alternativeTo }} {{ $t('app.potential_alternative_to') }} {{ app.alternativeTo }}
</template>
</p> </p>
<vue-showdown class="mt-3" :markdown="app.description" flavor="github" /> <vue-showdown :markdown="app.description" flavor="github" />
<b-img <b-img
v-if="app.screenshot" v-if="app.screenshot"
:src="app.screenshot" :src="app.screenshot"
aria-hidden="true" class="d-block mb-3" fluid aria-hidden="true" class="d-block" fluid
/> />
</section> </section>
<card <card
id="app-integration" v-if="app.integration"
collapsable :collapsed="1" id="app-integration" :title="$t('app.integration.title')"
no-body button-unbreak="lg" collapsable collapsed no-body
v-if="packaging_format >= 2"
> >
<template #header> <b-list-group flush>
<h2>{{ $t('app.integration.title') }}</h2>
</template>
<b-list-group flush tag="section">
<yuno-list-group-item variant="info"> <yuno-list-group-item variant="info">
{{ $t('app.integration.archs') }} {{ app.integration.archs }} {{ $t('app.integration.archs') }} {{ app.integration.archs }}
</yuno-list-group-item> </yuno-list-group-item>
@ -62,15 +59,14 @@
</card> </card>
<card <card
id="app-links" id="app-links" icon="link" :title="$t('app.links.title')"
collapsable :collapsed="1" collapsable collapsed no-body
no-body button-unbreak="lg"
> >
<template #header> <template #header>
<h2><icon iname="link" /> {{ $t('app.links.title') }}</h2> <h2><icon iname="link" /> {{ $t('app.links.title') }}</h2>
</template> </template>
<b-list-group flush tag="section"> <b-list-group flush>
<yuno-list-group-item v-for="[key, link] in app.links" :key="key" no-status> <yuno-list-group-item v-for="[key, link] in app.links" :key="key" no-status>
<b-link :href="link" target="_blank"> <b-link :href="link" target="_blank">
<icon :iname="appLinksIcons(key)" /> <icon :iname="appLinksIcons(key)" />
@ -196,8 +192,7 @@ export default {
validations: null, validations: null,
errors: undefined, errors: undefined,
serverError: '', serverError: '',
force: false, force: false
packaging_format: undefined
} }
}, },
@ -206,23 +201,24 @@ export default {
}, },
methods: { methods: {
appLinksIcons (link_type) { appLinksIcons (linkType) {
const links_icons = { const linksIcons = {
license: "institution", license: 'institution',
website: "globe", website: 'globe',
admindoc: "book", admindoc: 'book',
userdoc: "book", userdoc: 'book',
code: "code", code: 'code',
package: "code", package: 'code',
forum: "comments" forum: 'comments'
} }
return links_icons[link_type] return linksIcons[linkType]
}, },
onQueriesResponse (catalog, _app) { onQueriesResponse (catalog, _app) {
const antifeaturesList = Object.fromEntries(catalog.antifeatures.map((af) => ([af.id, af]))) const antifeaturesList = Object.fromEntries(catalog.antifeatures.map((af) => ([af.id, af])))
const { id, name, version, requirements } = _app const { id, name, version, requirements } = _app
const _archs = _app.integration.architectures const { ldap, sso, multi_instance, ram, disk, architectures: archs } = _app.integration
const quality = { state: _app.quality.state, variant: 'danger' } const quality = { state: _app.quality.state, variant: 'danger' }
if (quality.state === 'working') { if (quality.state === 'working') {
@ -258,13 +254,13 @@ export default {
demo: _app.upstream.demo, demo: _app.upstream.demo,
version, version,
license: _app.upstream.license, license: _app.upstream.license,
integration: { integration: _app.packaging_format >= 2 ? {
archs: Array.isArray(_archs) ? _archs.join(this.$i18n.t('words.separator')) : _archs, archs: Array.isArray(archs) ? archs.join(this.$i18n.t('words.separator')) : archs,
ldap: _app.integration.ldap === 'not_relevant' ? null : _app.integration.ldap, ldap: ldap === 'not_relevant' ? null : ldap,
sso: _app.integration.sso === 'not_relevant' ? null : _app.integration.sso, sso: sso === 'not_relevant' ? null : sso,
multi_instance: _app.integration.multi_instance, multi_instance,
resources: { ram: _app.integration.ram.runtime, disk: _app.integration.disk } resources: { ram: ram.runtime, disk }
}, } : null,
links: [ links: [
['license', `https://spdx.org/licenses/${_app.upstream.license}`], ['license', `https://spdx.org/licenses/${_app.upstream.license}`],
...['website', 'admindoc', 'userdoc', 'code'].map((key) => ([key, _app.upstream[key]])), ...['website', 'admindoc', 'userdoc', 'code'].map((key) => ([key, _app.upstream[key]])),
@ -301,7 +297,6 @@ export default {
this.form = form this.form = form
this.validations = { form: validations } this.validations = { form: validations }
this.errors = errors this.errors = errors
this.packaging_format = _app.packaging_format
}, },
formatAppNotifs (notifs) { formatAppNotifs (notifs) {
@ -353,8 +348,4 @@ export default {
list-style: none; list-style: none;
} }
} }
.float-right {
float: right;
}
</style> </style>