diff options
author | Andrey Borysenko <andrey18106x@gmail.com> | 2024-10-21 15:39:49 +0300 |
---|---|---|
committer | Andrey Borysenko <andrey18106x@gmail.com> | 2024-10-30 20:36:56 +0200 |
commit | 606a9a3d648baf86233c763a848db901354550d5 (patch) | |
tree | d38180a9d808f790ff6ec5c77d330cf6003c34f1 /apps | |
parent | c53f5c43b4bd461f5dc6e42bae6a05a63b8701c5 (diff) | |
download | nextcloud-server-606a9a3d648baf86233c763a848db901354550d5.tar.gz nextcloud-server-606a9a3d648baf86233c763a848db901354550d5.zip |
WIP: migrate to Pinia, minor fixes
Signed-off-by: Andrey Borysenko <andrey18106x@gmail.com>
Diffstat (limited to 'apps')
-rw-r--r-- | apps/settings/src/components/AppList.vue | 12 | ||||
-rw-r--r-- | apps/settings/src/components/AppList/AppItem.vue | 6 | ||||
-rw-r--r-- | apps/settings/src/components/AppStoreSidebar/AppDeployDaemonTab.vue | 8 | ||||
-rw-r--r-- | apps/settings/src/components/AppStoreSidebar/AppDetailsTab.vue | 14 | ||||
-rw-r--r-- | apps/settings/src/composables/useAppIcon.ts | 6 | ||||
-rw-r--r-- | apps/settings/src/mixins/AppManagement.js | 104 | ||||
-rw-r--r-- | apps/settings/src/store/app-api-store.ts | 295 | ||||
-rw-r--r-- | apps/settings/src/store/index.js | 2 | ||||
-rw-r--r-- | apps/settings/src/views/AppStore.vue | 11 | ||||
-rw-r--r-- | apps/settings/src/views/AppStoreSidebar.vue | 4 |
10 files changed, 396 insertions, 66 deletions
diff --git a/apps/settings/src/components/AppList.vue b/apps/settings/src/components/AppList.vue index 3f8fa85039b..718ac44fa93 100644 --- a/apps/settings/src/components/AppList.vue +++ b/apps/settings/src/components/AppList.vue @@ -143,6 +143,7 @@ import { subscribe, unsubscribe } from '@nextcloud/event-bus' import AppItem from './AppList/AppItem.vue' import pLimit from 'p-limit' import NcButton from '@nextcloud/vue/dist/Components/NcButton.js' +import { useAppApiStore } from '../store/app-api-store' export default { name: 'AppList', @@ -158,6 +159,13 @@ export default { }, }, + setup() { + const appApiStore = useAppApiStore() + return { + appApiStore, + } + }, + data() { return { search: '', @@ -171,7 +179,7 @@ export default { if (!this.$store.getters['appApiApps/isAppApiEnabled']) { return this.$store.getters.loading('list') } - return this.$store.getters.loading('list') || this.$store.getters['appApiApps/loading']('list') + return this.$store.getters.loading('list') || this.appApiStore.getLoading('list') }, hasPendingUpdate() { return this.apps.filter(app => app.update).length > 0 @@ -181,7 +189,7 @@ export default { }, apps() { // Exclude ExApps from the list if AppAPI is disabled - const exApps = this.$store.getters.isAppApiEnabled ? this.$store.getters['appApiApps/getAllApps'] : [] + const exApps = this.$store.getters.isAppApiEnabled ? this.appApiStore.getAllApps : [] const apps = [...this.$store.getters.getAllApps, ...exApps] .filter(app => app.name.toLowerCase().search(this.search.toLowerCase()) !== -1) .sort(function(a, b) { diff --git a/apps/settings/src/components/AppList/AppItem.vue b/apps/settings/src/components/AppList/AppItem.vue index 0ff4e7346cd..0c5d39b6862 100644 --- a/apps/settings/src/components/AppList/AppItem.vue +++ b/apps/settings/src/components/AppList/AppItem.vue @@ -83,7 +83,7 @@ @click.stop="update(app.id)"> {{ t('settings', 'Update to {update}', {update:app.update}) }} </NcButton> - <NcButton v-if="app.canUnInstall" + <NcButton v-if="app.canUnInstall || app.canUninstall" class="uninstall" type="tertiary" :disabled="installing || isLoading" @@ -91,7 +91,7 @@ {{ t('settings', 'Remove') }} </NcButton> <NcButton v-if="app.active" - :disabled="installing || isLoading || isInitializing || isDeploying" + :disabled="installing || isLoading || isInitializing || isDeploying" @click.stop="disable(app.id)"> {{ disableButtonText }} </NcButton> @@ -184,7 +184,7 @@ export default { return !!this.$route.params.id }, shouldDisplayDefaultIcon() { - return this.listView && !this.app.preview || !this.listView && !this.screenshotLoaded + return (this.listView && !this.app.preview) || (!this.listView && !this.screenshotLoaded) }, }, watch: { diff --git a/apps/settings/src/components/AppStoreSidebar/AppDeployDaemonTab.vue b/apps/settings/src/components/AppStoreSidebar/AppDeployDaemonTab.vue index 36087cdd617..a082ab326cc 100644 --- a/apps/settings/src/components/AppStoreSidebar/AppDeployDaemonTab.vue +++ b/apps/settings/src/components/AppStoreSidebar/AppDeployDaemonTab.vue @@ -16,7 +16,8 @@ <p><b>{{ t('settings', 'Type') }}</b>: {{ app?.daemon.accepts_deploy_id }}</p> <p><b>{{ t('settings', 'Name') }}</b>: {{ app?.daemon.name }}</p> <p><b>{{ t('settings', 'Display Name') }}</b>: {{ app?.daemon.display_name }}</p> - <p><b>{{ t('settings', 'GPUs support') }}</b>: {{ app?.daemon.deploy_config?.computeDevice?.id !== 'cpu' || 'false' }}</p> + <p><b>{{ t('settings', 'GPUs support') }}</b>: {{ gpuSupport }}</p> + <p><b>{{ t('settings', 'Compute device') }}</b>: {{ app?.daemon?.deploy_config?.computeDevice?.label }}</p> </div> </NcAppSidebarTab> </template> @@ -28,10 +29,13 @@ import NcAppSidebarTab from '@nextcloud/vue/dist/Components/NcAppSidebarTab.js' import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js' import { mdiFileChart } from '@mdi/js' +import { ref } from 'vue' -defineProps<{ +const props = defineProps<{ app: IAppstoreExApp, }>() + +const gpuSupport = ref(props.app?.daemon?.deploy_config?.computeDevice?.id !== 'cpu' || false) </script> <style scoped lang="scss"> diff --git a/apps/settings/src/components/AppStoreSidebar/AppDetailsTab.vue b/apps/settings/src/components/AppStoreSidebar/AppDetailsTab.vue index b732c5b82f5..4772b97ecf6 100644 --- a/apps/settings/src/components/AppStoreSidebar/AppDetailsTab.vue +++ b/apps/settings/src/components/AppStoreSidebar/AppDetailsTab.vue @@ -49,7 +49,7 @@ :value="t('settings', 'Update to {version}', { version: app.update })" :disabled="installing || isLoading || isManualInstall" @click="update(app.id)"> - <input v-if="app.canUnInstall" + <input v-if="app.canUnInstall || app.canUninstall" class="uninstall" type="button" :value="t('settings', 'Remove')" @@ -78,7 +78,10 @@ :disabled="installing || isLoading" @click="forceEnable(app.id)"> </div> - <NcCheckboxRadioSwitch v-if="app.canUnInstall" + <p v-if="!defaultDeployDaemonAccessible" class="warning"> + {{ t('settings', 'Default Deploy daemon is not accessible') }} + </p> + <NcCheckboxRadioSwitch v-if="app.canUnInstall || app.canUninstall" :checked="removeData" :disabled="installing || isLoading || !defaultDeployDaemonAccessible" @update:checked="toggleRemoveData"> @@ -110,7 +113,7 @@ <NcDateTime :timestamp="lastModified" /> </div> - <div class="app-details__section"> + <div v-if="appAuthors" class="app-details__section"> <h4> {{ t('settings', 'Author') }} </h4> @@ -119,7 +122,7 @@ </p> </div> - <div class="app-details__section"> + <div v-if="appCategories" class="app-details__section"> <h4> {{ t('settings', 'Categories') }} </h4> @@ -194,6 +197,7 @@ import NcCheckboxRadioSwitch from '@nextcloud/vue/dist/Components/NcCheckboxRadi import AppManagement from '../../mixins/AppManagement.js' import { mdiBug, mdiFeatureSearch, mdiStar, mdiTextBox, mdiTooltipQuestion } from '@mdi/js' import { useAppsStore } from '../../store/apps-store' +import { useAppApiStore } from '../../store/app-api-store' export default { name: 'AppDetailsTab', @@ -217,9 +221,11 @@ export default { setup() { const store = useAppsStore() + const appApiStore = useAppApiStore() return { store, + appApiStore, mdiBug, mdiFeatureSearch, diff --git a/apps/settings/src/composables/useAppIcon.ts b/apps/settings/src/composables/useAppIcon.ts index 60c3ee6e3ea..b5e211aa1bc 100644 --- a/apps/settings/src/composables/useAppIcon.ts +++ b/apps/settings/src/composables/useAppIcon.ts @@ -29,9 +29,9 @@ export function useAppIcon(app: Ref<IAppstoreApp>) { path = mdiCogOutline } else { path = [app.value?.category ?? []].flat() - .map((name) => AppstoreCategoryIcons[name]) - .filter((icon) => !!icon) - .at(0) + .map((name) => AppstoreCategoryIcons[name]) + .filter((icon) => !!icon) + .at(0) ?? (!app.value?.app_api ? mdiCog : mdiCogOutline) } return path ? `<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><path d="${path}" /></svg>` : null diff --git a/apps/settings/src/mixins/AppManagement.js b/apps/settings/src/mixins/AppManagement.js index 6d4b97ea82d..1c88267bdbf 100644 --- a/apps/settings/src/mixins/AppManagement.js +++ b/apps/settings/src/mixins/AppManagement.js @@ -5,33 +5,40 @@ import { showError } from '@nextcloud/dialogs' import rebuildNavigation from '../service/rebuild-navigation.js' +import { useAppApiStore } from '../store/app-api-store' export default { + setup() { + const appApiStore = useAppApiStore() + return { + appApiStore, + } + }, computed: { appGroups() { return this.app.groups.map(group => { return { id: group, name: group } }) }, installing() { if (this.app?.app_api) { - return this.app && this.$store.getters['appApiApps/loading']('install') + return this.app && this?.appApiStore.getLoading('install') === true } return this.$store.getters.loading('install') }, isLoading() { if (this.app?.app_api) { - return this.app && this.$store.getters['appApiApps/loading'](this.app.id) + return this.app && this?.appApiStore.getLoading(this.app.id) === true } return this.app && this.$store.getters.loading(this.app.id) }, isInitializing() { if (this.app?.app_api) { - return this.app && Object.hasOwn(this.app?.status, 'action') && (this.app.status.action === 'init' || this.app.status.action === 'healthcheck') + return this.app && (this.app?.status?.action === 'init' || this.app?.status?.action === 'healthcheck') } return false }, isDeploying() { if (this.app?.app_api) { - return this.app && Object.hasOwn(this.app?.status, 'action') && this.app.status.action === 'deploy' + return this.app && this.app?.status?.action === 'deploy' } return false }, @@ -90,7 +97,7 @@ export default { return t('settings', 'Allow untested app') }, enableButtonTooltip() { - if (this.app.needsDownload) { + if (!this.app?.app_api && this.app.needsDownload) { return t('settings', 'The app will be downloaded from the App Store') } return null @@ -107,10 +114,11 @@ export default { if (this.app?.daemon && this.app?.daemon?.accepts_deploy_id === 'manual-install') { return true } - if (this.app?.daemon?.accepts_deploy_id === 'docker-install') { - return this.$store.getters['appApiApps/getDaemonAccessible'] === true + if (this.app?.daemon?.accepts_deploy_id === 'docker-install' + && this.appApiStore.getDefaultDaemon?.name === this.app?.daemon?.name) { + return this?.appApiStore.getDaemonAccessible === true } - return this.$store.getters['appApiApps/getDaemonAccessible'] + return this?.appApiStore.getDaemonAccessible } return true }, @@ -177,63 +185,73 @@ export default { this.$store.dispatch('enableApp', { appId: this.app.id, groups: currentGroups }) }, forceEnable(appId) { - let type = 'forceEnableApp' if (this.app?.app_api) { - type = 'appApiApps/forceEnableApp' + this.appApiStore.forceEnableApp(appId) + .then(() => { rebuildNavigation() }) + .catch((error) => { showError(error) }) + } else { + this.$store.dispatch('forceEnableApp', { appId, groups: [] }) + .then((response) => { rebuildNavigation() }) + .catch((error) => { showError(error) }) } - this.$store.dispatch(type, { appId, groups: [] }) - .then((response) => { rebuildNavigation() }) - .catch((error) => { showError(error) }) }, enable(appId) { - let type = 'enableApp' if (this.app?.app_api) { - type = 'appApiApps/enableApp' + this.appApiStore.enableApp(appId) + .then(() => { rebuildNavigation() }) + .catch((error) => { showError(error) }) + } else { + this.$store.dispatch('enableApp', { appId, groups: [] }) + .then((response) => { rebuildNavigation() }) + .catch((error) => { showError(error) }) } - this.$store.dispatch(type, { appId, groups: [] }) - .then((response) => { rebuildNavigation() }) - .catch((error) => { showError(error) }) }, disable(appId) { - let type = 'disableApp' if (this.app?.app_api) { - type = 'appApiApps/disableApp' + this.appApiStore.disableApp(appId) + .then(() => { rebuildNavigation() }) + .catch((error) => { showError(error) }) + } else { + this.$store.dispatch('disableApp', { appId }) + .then((response) => { rebuildNavigation() }) + .catch((error) => { showError(error) }) } - this.$store.dispatch(type, { appId }) - .then((response) => { rebuildNavigation() }) - .catch((error) => { showError(error) }) }, remove(appId, removeData = false) { - let type = 'uninstallApp' - let payload = { appId } if (this.app?.app_api) { - type = 'appApiApps/uninstallApp' - payload = { appId, removeData } + this.appApiStore.uninstallApp(appId, removeData) + .then(() => { rebuildNavigation() }) + .catch((error) => { showError(error) }) + } else { + this.$store.dispatch('appApiApps/uninstallApp', { appId, removeData }) + .then((response) => { rebuildNavigation() }) + .catch((error) => { showError(error) }) } - this.$store.dispatch(type, payload) - .then((response) => { rebuildNavigation() }) - .catch((error) => { showError(error) }) }, install(appId) { - let type = 'enableApp' if (this.app?.app_api) { - type = 'appApiApps/enableApp' + this.appApiStore.enableApp(appId) + .then(() => { rebuildNavigation() }) + .catch((error) => { showError(error) }) + } else { + this.$store.dispatch('enableApp', { appId }) + .then((response) => { rebuildNavigation() }) + .catch((error) => { showError(error) }) } - this.$store.dispatch(type, { appId }) - .then((response) => { rebuildNavigation() }) - .catch((error) => { showError(error) }) }, update(appId) { - let type = 'updateApp' if (this.app?.app_api) { - type = 'appApiApps/updateApp' + this.appApiStore.updateApp(appId) + .then(() => { rebuildNavigation() }) + .catch((error) => { showError(error) }) + } else { + this.$store.dispatch('updateApp', { appId }) + .catch((error) => { showError(error) }) + .then(() => { + rebuildNavigation() + this.store.updateCount = Math.max(this.store.updateCount - 1, 0) + }) } - this.$store.dispatch(type, { appId }) - .catch((error) => { showError(error) }) - .then(() => { - rebuildNavigation() - this.store.updateCount = Math.max(this.store.updateCount - 1, 0) - }) }, }, } diff --git a/apps/settings/src/store/app-api-store.ts b/apps/settings/src/store/app-api-store.ts new file mode 100644 index 00000000000..e056f5bc660 --- /dev/null +++ b/apps/settings/src/store/app-api-store.ts @@ -0,0 +1,295 @@ +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import axios from '@nextcloud/axios' +import { confirmPassword } from '@nextcloud/password-confirmation' +import { showError, showInfo } from '@nextcloud/dialogs' +import { loadState } from '@nextcloud/initial-state' +import { translate as t } from '@nextcloud/l10n' +import { generateUrl } from '@nextcloud/router' +import { defineStore } from 'pinia' + +import api from './api' +import logger from '../logger' + +import type { IAppstoreExApp, IDeployDaemon, IExAppStatus } from '../app-types' +import { reactive } from 'vue' + +interface AppApiState { + apps: IAppstoreExApp[] + updateCount: number + loading: Record<string, boolean> + loadingList: boolean + statusUpdater: number | null | undefined + daemonAccessible: boolean + defaultDaemon: IDeployDaemon | null +} + +export const useAppApiStore = defineStore('app-api-apps', { + state: (): AppApiState => ({ + apps: [], + updateCount: loadState('settings', 'appstoreExAppUpdateCount', 0), + loading: reactive({}), + loadingList: false, + statusUpdater: null, + daemonAccessible: loadState('settings', 'defaultDaemonConfigAccessible', false), + defaultDaemon: loadState('settings', 'defaultDaemonConfig', null), + }), + + getters: { + getLoading: (state) => (id: string) => state.loading[id] ?? false, + getAllApps: (state) => state.apps, + getUpdateCount: (state) => state.updateCount, + getDaemonAccessible: (state) => state.daemonAccessible, + getDefaultDaemon: (state) => state.defaultDaemon, + getAppStatus: (state) => (appId: string) => + state.apps.find((app) => app.id === appId)?.status || null, + getStatusUpdater: (state) => state.statusUpdater, + getInitializingOrDeployingApps: (state) => + state.apps.filter((app) => + app?.status?.action + && (app?.status?.action === 'deploy' || app.status.action === 'init' || app.status.action === 'healthcheck') + && app.status.type !== '', + ), + }, + + actions: { + appsApiFailure(error: any) { + showError(t('settings', 'An error occurred during the request. Unable to proceed.') + '<br>' + error.error.response.data.data.message, { isHTML: true }) + logger.error(error) + }, + + setError(appId: string | string[], error: string) { + const appIds = Array.isArray(appId) ? appId : [appId] + appIds.forEach((_id) => { + const app = this.apps.find((app) => app.id === _id) + if (app) { + app.error = error + } + }) + }, + + enableApp(appId: string) { + this.loading[appId] = true + this.loading.install = true + return confirmPassword().then(() => { + + return axios.post(generateUrl(`/apps/app_api/apps/enable/${appId}`)) + .then((response) => { + this.loading[appId] = false + this.loading.install = false + + const app = this.apps.find((app) => app.id === appId) + if (app) { + if (!app.installed) { + app.installed = true + app.needsDownload = false + app.daemon = this.defaultDaemon + app.status = { + type: 'install', + action: 'deploy', + init: 0, + deploy: 0, + } as IExAppStatus + } + app.active = true + app.canUninstall = false + app.removable = true + app.error = '' + } + + this.updateAppsStatus() + + return axios.get(generateUrl('apps/files')) + .then(() => { + if (response.data.update_required) { + showInfo( + t('settings', 'The app has been enabled but needs to be updated.'), + { + onClick: () => window.location.reload(), + close: false, + }, + ) + setTimeout(() => { + location.reload() + }, 5000) + } + }) + .catch(() => { + this.setError(appId, t('settings', 'Error: This app cannot be enabled because it makes the server unstable')) + }) + }) + .catch((error) => { + this.loading[appId] = false + this.loading.install = false + this.setError(appId, error.response.data.data.message) + this.appsApiFailure({ appId, error }) + }) + }) + }, + + forceEnableApp(appId: string) { + this.loading[appId] = true + this.loading.install = true + return confirmPassword().then(() => { + + return api.post(generateUrl('/apps/app_api/apps/force'), { appId }) + .then(() => { + location.reload() + }) + .catch((error) => { + this.loading[appId] = false + this.loading.install = false + this.setError(appId, error.response.data.data.message) + this.appsApiFailure({ appId, error }) + }) + }) + }, + + disableApp(appId: string) { + this.loading[appId] = true + return confirmPassword().then(() => { + + return api.get(generateUrl(`apps/app_api/apps/disable/${appId}`)) + .then(() => { + this.loading[appId] = false + const app = this.apps.find((app) => app.id === appId) + if (app) { + app.active = false + if (app.removable) { + app.canUninstall = true + } + } + return true + }) + .catch((error) => { + this.loading[appId] = false + this.appsApiFailure({ appId, error }) + }) + }) + }, + + uninstallApp(appId: string, removeData: boolean) { + this.loading[appId] = true + return confirmPassword().then(() => { + + return api.get(generateUrl(`/apps/app_api/apps/uninstall/${appId}?removeData=${removeData}`)) + .then(() => { + this.loading[appId] = false + const app = this.apps.find((app) => app.id === appId) + if (app) { + app.active = false + app.needsDownload = true + app.installed = false + app.canUninstall = false + app.canInstall = true + app.daemon = null + app.status = {} + if (app.update !== null) { + this.updateCount-- + } + app.update = null + } + return true + }) + .catch((error) => { + this.loading[appId] = false + this.appsApiFailure({ appId, error }) + }) + }) + }, + + updateApp(appId: string) { + this.loading[appId] = true + this.loading.install = true + return confirmPassword().then(() => { + + return api.get(generateUrl(`/apps/app_api/apps/update/${appId}`)) + .then(() => { + this.loading.install = false + this.loading[appId] = false + const app = this.apps.find((app) => app.id === appId) + if (app) { + const version = app.update + app.update = null + app.version = version || app.version + app.status = { + type: 'update', + action: 'deploy', + init: 0, + deploy: 0, + } as IExAppStatus + app.error = '' + } + this.updateCount-- + this.updateAppsStatus() + return true + }) + .catch((error) => { + this.loading[appId] = false + this.loading.install = false + this.appsApiFailure({ appId, error }) + }) + }) + }, + + async fetchAllApps() { + this.loadingList = true + try { + const response = await api.get(generateUrl('/apps/app_api/apps/list')) + this.apps = response.data.apps + this.loadingList = false + return true + } catch (error) { + logger.error(error as string) + showError(t('settings', 'An error occurred during the request. Unable to proceed.')) + this.loadingList = false + } + }, + + async fetchAppStatus(appId: string) { + return api.get(generateUrl(`/apps/app_api/apps/status/${appId}`)) + .then((response) => { + const app = this.apps.find((app) => app.id === appId) + if (app) { + app.status = response.data + } + const initializingOrDeployingApps = this.getInitializingOrDeployingApps + console.debug('initializingOrDeployingApps after setAppStatus', initializingOrDeployingApps) + if (initializingOrDeployingApps.length === 0) { + console.debug('clearing interval') + clearInterval(this.statusUpdater as number) + this.statusUpdater = null + } + if (Object.hasOwn(response.data, 'error') + && response.data.error !== '' + && initializingOrDeployingApps.length === 1) { + clearInterval(this.statusUpdater as number) + this.statusUpdater = null + } + }) + .catch((error) => { + this.appsApiFailure({ appId, error }) + this.apps = this.apps.filter((app) => app.id !== appId) + this.updateAppsStatus() + }) + }, + + updateAppsStatus() { + clearInterval(this.statusUpdater as number) + const initializingOrDeployingApps = this.getInitializingOrDeployingApps + if (initializingOrDeployingApps.length === 0) { + return + } + this.statusUpdater = setInterval(() => { + const initializingOrDeployingApps = this.getInitializingOrDeployingApps + console.debug('initializingOrDeployingApps', initializingOrDeployingApps) + initializingOrDeployingApps.forEach(app => { + this.fetchAppStatus(app.id) + }) + }, 2000) as unknown as number + }, + }, +}) diff --git a/apps/settings/src/store/index.js b/apps/settings/src/store/index.js index 62dab7246fc..910185edb51 100644 --- a/apps/settings/src/store/index.js +++ b/apps/settings/src/store/index.js @@ -7,7 +7,6 @@ import Vue from 'vue' import Vuex, { Store } from 'vuex' import users from './users.js' import apps from './apps.js' -import appApiApps from './app_api_apps.js' import settings from './users-settings.js' import oc from './oc.js' import { showError } from '@nextcloud/dialogs' @@ -36,7 +35,6 @@ export const useStore = () => { modules: { users, apps, - appApiApps, settings, oc, }, diff --git a/apps/settings/src/views/AppStore.vue b/apps/settings/src/views/AppStore.vue index 0c922ce7296..62a9a9290be 100644 --- a/apps/settings/src/views/AppStore.vue +++ b/apps/settings/src/views/AppStore.vue @@ -34,9 +34,11 @@ import NcEmptyContent from '@nextcloud/vue/dist/Components/NcEmptyContent.js' import NcLoadingIcon from '@nextcloud/vue/dist/Components/NcLoadingIcon.js' import AppList from '../components/AppList.vue' import AppStoreDiscoverSection from '../components/AppStoreDiscover/AppStoreDiscoverSection.vue' +import { useAppApiStore } from '../store/app-api-store.ts' const route = useRoute() const store = useAppsStore() +const appApiStore = useAppApiStore() /** * ID of the current active category, default is `discover` @@ -62,15 +64,12 @@ onBeforeMount(() => { (instance?.proxy as any).$store.dispatch('getAllApps') // eslint-disable-next-line @typescript-eslint/no-explicit-any if ((instance?.proxy as any).$store.getters.isAppApiEnabled) { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (instance?.proxy as any).$store.dispatch('appApiApps/getAllApps'); - // eslint-disable-next-line @typescript-eslint/no-explicit-any - (instance?.proxy as any).$store.dispatch('appApiApps/updateAppsStatus') + appApiStore.fetchAllApps() + appApiStore.updateAppsStatus() } }) onBeforeUnmount(() => { - // eslint-disable-next-line @typescript-eslint/no-explicit-any - clearInterval((instance?.proxy as any).$store.getters('appApiApps/getStatusUpdater')) + clearInterval(appApiStore.getStatusUpdater) }) </script> diff --git a/apps/settings/src/views/AppStoreSidebar.vue b/apps/settings/src/views/AppStoreSidebar.vue index c003174a1d2..1021837faaa 100644 --- a/apps/settings/src/views/AppStoreSidebar.vue +++ b/apps/settings/src/views/AppStoreSidebar.vue @@ -56,16 +56,18 @@ import AppLevelBadge from '../components/AppList/AppLevelBadge.vue' import AppDaemonBadge from '../components/AppList/AppDaemonBadge.vue' import { useAppIcon } from '../composables/useAppIcon.ts' import { useStore } from '../store' +import { useAppApiStore } from '../store/app-api-store.ts' const route = useRoute() const router = useRouter() const store = useAppsStore() +const appApiStore = useAppApiStore() const legacyStore = useStore() const appId = computed(() => route.params.id ?? '') const app = computed(() => { if (legacyStore.getters.isAppApiEnabled) { - const exApp = legacyStore.getters['appApiApps/getAllApps'] + const exApp = appApiStore.getAllApps .find((app) => app.id === appId.value) ?? null if (exApp) { return exApp |