diff options
Diffstat (limited to 'apps/settings/src/views/Apps.vue')
-rw-r--r-- | apps/settings/src/views/Apps.vue | 132 |
1 files changed, 127 insertions, 5 deletions
diff --git a/apps/settings/src/views/Apps.vue b/apps/settings/src/views/Apps.vue index 2c7dd9dae0e..13ddd8bfaf8 100644 --- a/apps/settings/src/views/Apps.vue +++ b/apps/settings/src/views/Apps.vue @@ -22,7 +22,7 @@ <template> <Content app-name="settings" - :class="{ 'with-app-sidebar': currentApp}" + :class="{ 'with-app-sidebar': app}" :content-class="{ 'icon-loading': loadingList }" :navigation-class="{ 'icon-loading': loading }"> <AppNavigation> @@ -87,15 +87,70 @@ </template> </AppNavigation> <AppContent class="app-settings-content" :class="{ 'icon-loading': loadingList }"> - <AppList :category="category" :app="currentApp" :search="searchQuery" /> + <AppList :category="category" :app="app" :search="searchQuery" /> </AppContent> - <AppSidebar v-if="id && currentApp" @close="hideAppDetails"> - <AppDetails :category="category" :app="currentApp" /> + <AppSidebar + v-if="id && app" + v-bind="appSidebar" + :class="{'app-sidebar--without-background': !appSidebar.background}" + @close="hideAppDetails"> + <template v-if="!appSidebar.background" #header> + <div class="app-sidebar-header__figure--default-app-icon icon-settings-dark" /> + </template> + <template #primary-actions> + <div v-if="app.level === 300 || app.level === 200 || hasRating" class="app-level"> + <span v-if="app.level === 300" + v-tooltip.auto="t('settings', 'This app is supported via your current Nextcloud subscription.')" + class="supported icon-checkmark-color"> + {{ t('settings', 'Supported') }}</span> + <span v-if="app.level === 200" + v-tooltip.auto="t('settings', 'Featured apps are developed by and within the community. They offer central functionality and are ready for production use.')" + class="official icon-checkmark"> + {{ t('settings', 'Featured') }}</span> + <AppScore v-if="hasRating" :score="app.appstoreData.ratingOverall" /> + </div> + </template> + <template #secondary-actions> + <ActionButton v-if="app.update" + :disabled="installing || isLoading" + icon="icon-download" + @click="update(app.id)"> + {{ t('settings', 'Update to {version}', {version: app.update}) }} + </ActionButton> + <ActionButton v-if="app.canUnInstall" + :disabled="installing || isLoading" + icon="icon-delete" + @click="remove(app.id)"> + {{ t('settings', 'Remove') }} + </ActionButton> + <ActionButton v-if="app.active" + :disabled="installing || isLoading" + icon="icon-close" + @click="disable(app.id)"> + {{ t('settings','Disable') }} + </ActionButton> + <ActionButton v-if="!app.active && (app.canInstall || app.isCompatible)" + v-tooltip.auto="enableButtonTooltip" + :disabled="!app.canInstall || installing || isLoading" + icon="icon-checkmark" + @click="enable(app.id)"> + {{ enableButtonText }} + </ActionButton> + <ActionButton v-else-if="!app.active" + v-tooltip.auto="forceEnableButtonTooltip" + :disabled="installing || isLoading" + icon="icon-checkmark" + @click="forceEnable(app.id)"> + {{ forceEnableButtonText }} + </ActionButton> + </template> + <AppDetails :category="category" :app="app" /> </AppSidebar> </Content> </template> <script> +import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import AppContent from '@nextcloud/vue/dist/Components/AppContent' import AppNavigation from '@nextcloud/vue/dist/Components/AppNavigation' import AppNavigationCounter from '@nextcloud/vue/dist/Components/AppNavigationCounter' @@ -108,12 +163,14 @@ import VueLocalStorage from 'vue-localstorage' import AppList from '../components/AppList' import AppDetails from '../components/AppDetails' +import AppManagement from '../mixins/AppManagement' Vue.use(VueLocalStorage) export default { name: 'Apps', components: { + ActionButton, AppContent, AppDetails, AppList, @@ -124,6 +181,7 @@ export default { AppSidebar, Content, }, + mixins: [AppManagement], props: { category: { type: String, @@ -146,7 +204,7 @@ export default { loadingList() { return this.$store.getters.loading('list') }, - currentApp() { + app() { return this.apps.find(app => app.id === this.id) }, categories() { @@ -161,6 +219,30 @@ export default { settings() { return this.$store.getters.getServerData }, + + // sidebar app binding + appSidebar() { + const author = Array.isArray(this.app.author) + ? this.app.author[0]['@value'] + ? this.app.author.map(author => author['@value']).join(', ') + : this.app.author.join(', ') + : this.app.author['@value'] + ? this.app.author['@value'] + : this.app.author + const license = t('settings', '{license}-licensed', { license: ('' + this.app.licence).toUpperCase() }) + + const subtitle = t('settings', 'by {author}\n{license}', { author, license }) + + return { + subtitle, + background: this.app.screenshot + ? this.app.screenshot + : this.app.preview, + compact: !this.app.screenshot, + title: this.app.name, + + } + }, }, watch: { category(val, old) { @@ -195,3 +277,43 @@ export default { }, } </script> + +<style lang="scss" scoped> + +#app-sidebar::v-deep { + &:not(.app-sidebar--without-background) { + // with full screenshot, let's fill the figure + :not(.app-sidebar-header--compact) .app-sidebar-header__figure { + background-size: cover + } + // revert sidebar app icon so it is black + .app-sidebar-header--compact .app-sidebar-header__figure { + filter: invert(1); + background-size: 32px; + } + } + + // default icon slot styling + &.app-sidebar--without-background { + .app-sidebar-header__figure { + display: flex; + align-items: center; + justify-content: center; + &--default-app-icon { + height: 32px; + width: 32px; + background-size: 32px; + } + } + } + + // allow multi line subtitle for the license + .app-sidebar-header__subtitle { + white-space: pre-line !important; + line-height: 16px; + overflow: visible !important; + height: 22px; + } +} + +</style> |