aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFerdinand Thiessen <opensource@fthiessen.de>2024-03-17 03:20:06 +0100
committerFerdinand Thiessen <opensource@fthiessen.de>2024-03-18 01:03:33 +0100
commit8d750cfd1510177e27dd67bebd39ea748331b60c (patch)
treea31ad24e8c07fe161cdcc273171f979c8c3692fc
parent7bab308c68a835d7c65583b7668dee1589638e9a (diff)
downloadnextcloud-server-8d750cfd1510177e27dd67bebd39ea748331b60c.tar.gz
nextcloud-server-8d750cfd1510177e27dd67bebd39ea748331b60c.zip
fix(settings): Add event search listener on mounted to guarantee function exists
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
-rw-r--r--apps/settings/src/components/AppList.vue6
-rw-r--r--apps/settings/src/views/Apps.vue411
2 files changed, 3 insertions, 414 deletions
diff --git a/apps/settings/src/components/AppList.vue b/apps/settings/src/components/AppList.vue
index 320d6a60e95..33fb2c725f0 100644
--- a/apps/settings/src/components/AppList.vue
+++ b/apps/settings/src/components/AppList.vue
@@ -266,14 +266,14 @@ export default {
unsubscribe('nextcloud:unified-search.reset', this.resetSearch)
},
- beforeCreate() {
+ mounted() {
subscribe('nextcloud:unified-search.search', this.setSearch)
subscribe('nextcloud:unified-search.reset', this.resetSearch)
},
methods: {
- setSearch(value) {
- this.search = value
+ setSearch({ query }) {
+ this.search = query
},
resetSearch() {
this.search = ''
diff --git a/apps/settings/src/views/Apps.vue b/apps/settings/src/views/Apps.vue
deleted file mode 100644
index 43259b51d54..00000000000
--- a/apps/settings/src/views/Apps.vue
+++ /dev/null
@@ -1,411 +0,0 @@
-<!--
- - @copyright Copyright (c) 2018 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>
- <NcContent app-name="settings"
- :class="{ 'with-app-sidebar': app}">
- <!-- Categories & filters -->
- <NcAppNavigation :class="{ 'icon-loading': loading }"
- :aria-label="t('settings', 'Apps')">
- <template #list>
- <NcAppNavigationItem id="app-category-your-apps"
- :to="{ name: 'apps' }"
- :exact="true"
- icon="icon-category-installed"
- :name="$options.APPS_SECTION_ENUM.installed" />
- <NcAppNavigationItem id="app-category-enabled"
- :to="{ name: 'apps-category', params: { category: 'enabled' } }"
- icon="icon-category-enabled"
- :name="$options.APPS_SECTION_ENUM.enabled" />
- <NcAppNavigationItem id="app-category-disabled"
- :to="{ name: 'apps-category', params: { category: 'disabled' } }"
- icon="icon-category-disabled"
- :name="$options.APPS_SECTION_ENUM.disabled" />
- <NcAppNavigationItem v-if="updateCount > 0"
- id="app-category-updates"
- :to="{ name: 'apps-category', params: { category: 'updates' } }"
- icon="icon-download"
- :name="$options.APPS_SECTION_ENUM.updates">
- <template #counter>
- <NcCounterBubble>{{ updateCount }}</NcCounterBubble>
- </template>
- </NcAppNavigationItem>
- <NcAppNavigationItem v-if="isSubscribed"
- id="app-category-supported"
- :to="{ name: 'apps-category', params: { category: 'supported' } }"
- :name="$options.APPS_SECTION_ENUM.supported">
- <template #icon>
- <IconStarShooting :size="20" />
- </template>
- </NcAppNavigationItem>
- <NcAppNavigationItem id="app-category-your-bundles"
- :to="{ name: 'apps-category', params: { category: 'app-bundles' } }"
- icon="icon-category-app-bundles"
- :name="$options.APPS_SECTION_ENUM['app-bundles']" />
-
- <NcAppNavigationSpacer />
-
- <!-- App store categories -->
- <template v-if="appstoreEnabled">
- <NcAppNavigationItem id="app-category-featured"
- :to="{ name: 'apps-category', params: { category: 'featured' } }"
- icon="icon-favorite"
- :name="$options.APPS_SECTION_ENUM.featured" />
-
- <NcAppNavigationItem v-for="cat in categories"
- :key="'icon-category-' + cat.id"
- :icon="'icon-category-' + cat.id"
- :to="{
- name: 'apps-category',
- params: { category: cat.id },
- }"
- :name="cat.displayName" />
- </template>
-
- <NcAppNavigationItem id="app-developer-docs"
- :name="t('settings', 'Developer documentation') + ' ↗'"
- @click="openDeveloperDocumentation" />
- </template>
- </NcAppNavigation>
-
- <!-- Apps list -->
- <NcAppContent class="app-settings-content"
- :class="{ 'icon-loading': loadingList }"
- :page-heading="pageHeading">
- <AppList :category="category" :app="app" :search="searchQuery" />
- </NcAppContent>
-
- <!-- Selected app details -->
- <NcAppSidebar 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 #description>
- <!-- Featured/Supported badges -->
- <AppLevelBadge :level="app.level" />
- <AppScore v-if="hasRating" :score="app.appstoreData.ratingOverall" />
-
- <div class="app-version">
- <p>{{ app.version }}</p>
- </div>
- </template>
-
- <!-- Tab content -->
-
- <NcAppSidebarTab id="desc"
- icon="icon-category-office"
- :name="t('settings', 'Details')"
- :order="0">
- <AppDetails :app="app" />
- </NcAppSidebarTab>
- <NcAppSidebarTab 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)" :min-heading="3" :text="changelog(release)" />
- </div>
- </NcAppSidebarTab>
- </NcAppSidebar>
- </NcContent>
-</template>
-
-<script>
-import { subscribe, unsubscribe } from '@nextcloud/event-bus'
-import Vue from 'vue'
-import VueLocalStorage from 'vue-localstorage'
-
-import NcAppContent from '@nextcloud/vue/dist/Components/NcAppContent.js'
-import NcAppNavigation from '@nextcloud/vue/dist/Components/NcAppNavigation.js'
-import NcAppNavigationItem from '@nextcloud/vue/dist/Components/NcAppNavigationItem.js'
-import NcAppNavigationSpacer from '@nextcloud/vue/dist/Components/NcAppNavigationSpacer.js'
-import NcAppSidebar from '@nextcloud/vue/dist/Components/NcAppSidebar.js'
-import NcAppSidebarTab from '@nextcloud/vue/dist/Components/NcAppSidebarTab.js'
-import NcCounterBubble from '@nextcloud/vue/dist/Components/NcCounterBubble.js'
-import NcContent from '@nextcloud/vue/dist/Components/NcContent.js'
-import IconStarShooting from 'vue-material-design-icons/StarShooting.vue'
-
-import AppList from '../components/AppList.vue'
-import AppDetails from '../components/AppDetails.vue'
-import AppManagement from '../mixins/AppManagement.js'
-import AppLevelBadge from '../components/AppList/AppLevelBadge.vue'
-import AppScore from '../components/AppList/AppScore.vue'
-import Markdown from '../components/Markdown.vue'
-
-import { APPS_SECTION_ENUM } from './../constants/AppsConstants.js'
-import { loadState } from '@nextcloud/initial-state'
-
-Vue.use(VueLocalStorage)
-
-const appstoreEnabled = loadState('settings', 'appstoreEnabled')
-const developerDocumentation = loadState('settings', 'appstoreDeveloperDocs')
-
-export default {
- name: 'Apps',
- APPS_SECTION_ENUM,
- components: {
- NcAppContent,
- AppDetails,
- AppList,
- AppLevelBadge,
- IconStarShooting,
- NcAppNavigation,
- NcAppNavigationItem,
- NcAppNavigationSpacer,
- NcCounterBubble,
- AppScore,
- NcAppSidebar,
- NcAppSidebarTab,
- NcContent,
- Markdown,
- },
-
- mixins: [AppManagement],
-
- props: {
- category: {
- type: String,
- default: 'installed',
- },
- id: {
- type: String,
- default: '',
- },
- },
-
- data() {
- return {
- searchQuery: '',
- screenshotLoaded: false,
- }
- },
-
- computed: {
- appstoreEnabled() {
- return appstoreEnabled
- },
- pageHeading() {
- if (this.$options.APPS_SECTION_ENUM[this.category]) {
- return this.$options.APPS_SECTION_ENUM[this.category]
- }
- const category = this.$store.getters.getCategoryById(this.category)
- return category.displayName
- },
- loading() {
- return this.$store.getters.loading('categories')
- },
- loadingList() {
- return this.$store.getters.loading('list')
- },
- app() {
- return this.apps.find(app => app.id === this.id)
- },
- categories() {
- return this.$store.getters.getCategories
- },
- apps() {
- return this.$store.getters.getAllApps
- },
- updateCount() {
- return this.$store.getters.getUpdateCount
- },
-
- hasRating() {
- return this.app.appstoreData && this.app.appstoreData.ratingNumOverall > 5
- },
-
- // sidebar app binding
- appSidebar() {
- const authorName = (xmlNode) => {
- if (xmlNode['@value']) {
- // Complex node (with email or homepage attribute)
- return xmlNode['@value']
- }
-
- // Simple text node
- return xmlNode
- }
-
- const author = Array.isArray(this.app.author)
- ? this.app.author.map(authorName).join(', ')
- : authorName(this.app.author)
- const license = t('settings', '{license}-licensed', { license: ('' + this.app.licence).toUpperCase() })
-
- const subname = t('settings', 'by {author}\n{license}', { author, license })
-
- return {
- background: this.app.screenshot && this.screenshotLoaded
- ? this.app.screenshot
- : this.app.preview,
- compact: !(this.app.screenshot && this.screenshotLoaded),
- name: this.app.name,
- subname,
- }
- },
- changelog() {
- return (release) => release.translations.en.changelog
- },
- /**
- * Check if the current instance has a support subscription from the Nextcloud GmbH
- */
- isSubscribed() {
- // For customers of the Nextcloud GmbH the app level will be set to `300` for apps that are supported in their subscription
- return this.apps.some(app => app.level === 300)
- },
- },
-
- watch: {
- category() {
- this.searchQuery = ''
- },
-
- app() {
- this.screenshotLoaded = false
- if (this.app?.releases && this.app?.screenshot) {
- const image = new Image()
- image.onload = () => {
- this.screenshotLoaded = true
- }
- image.src = this.app.screenshot
- }
- },
- },
-
- beforeMount() {
- this.$store.dispatch('getCategories', { shouldRefetchCategories: true })
- this.$store.dispatch('getAllApps')
- this.$store.dispatch('getGroups', { offset: 0, limit: 5 })
- },
-
- mounted() {
- subscribe('nextcloud:unified-search.search', this.setSearch)
- subscribe('nextcloud:unified-search.reset', this.resetSearch)
- },
- beforeDestroy() {
- unsubscribe('nextcloud:unified-search.search', this.setSearch)
- unsubscribe('nextcloud:unified-search.reset', this.resetSearch)
- },
-
- methods: {
- setSearch({ query }) {
- this.searchQuery = query
- },
- resetSearch() {
- this.searchQuery = ''
- },
-
- hideAppDetails() {
- this.$router.push({
- name: 'apps-category',
- params: { category: this.category },
- })
- },
- openDeveloperDocumentation() {
- window.open(developerDocumentation)
- },
- },
-}
-</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 {
- background-size: 32px;
-
- filter: var(--background-invert-if-bright);
- }
- }
-
- .app-sidebar-header__description {
- .app-version {
- padding-left: 10px;
- }
- }
-
- // default icon slot styling
- &.app-sidebar--without-background {
- .app-sidebar-header__figure {
- display: flex;
- align-items: center;
- justify-content: center;
- &--default-app-icon {
- width: 32px;
- height: 32px;
- background-size: 32px;
- }
- }
- }
-
- // TODO: migrate to components
- .app-sidebar-header__desc {
- // allow multi line subtitle for the license
- .app-sidebar-header__subtitle {
- overflow: visible !important;
- height: auto;
- white-space: normal !important;
- line-height: 16px;
- }
- }
-
- .app-sidebar-header__action {
- // align with tab content
- margin: 0 20px;
- input {
- margin: 3px;
- }
- }
-}
-
-// Align the appNavigation toggle with the apps header toolbar
-.app-navigation::v-deep button.app-navigation-toggle {
- top: 8px;
- right: -8px;
-}
-
-.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>