From df7b3e0dcf707dd9de8f287d951071d74ee813be Mon Sep 17 00:00:00 2001 From: Jannik Stehle Date: Tue, 16 Jan 2024 14:36:11 +0100 Subject: [PATCH] refactor: remove vuex store in external app --- .../change-registering-app-file-editors | 3 + packages/web-app-external/package.json | 3 +- packages/web-app-external/src/index.ts | 71 +++++++- packages/web-app-external/src/schemas.ts | 20 +++ packages/web-app-external/src/store/index.ts | 70 -------- .../src/components/AppBar/CreateAndUpload.vue | 52 +++--- .../components/AppBar/CreateAndUpload.spec.ts | 43 ++--- .../CreateAndUpload.spec.ts.snap | 101 +---------- packages/web-pkg/src/apps/types.ts | 7 +- .../components/FilesList/ContextActions.vue | 8 +- .../actions/files/useFileActions.ts | 135 ++------------- .../files/useFileActionsCreateNewFile.ts | 157 +++++------------- .../web-pkg/src/composables/actions/types.ts | 1 + .../src/composables/piniaStores/apps.ts | 3 +- .../files/useFileActionsCreateNewFile.spec.ts | 54 ++---- .../components/Topbar/ApplicationsMenu.vue | 9 +- pnpm-lock.yaml | 3 + 17 files changed, 220 insertions(+), 520 deletions(-) create mode 100644 packages/web-app-external/src/schemas.ts delete mode 100644 packages/web-app-external/src/store/index.ts diff --git a/changelog/unreleased/change-registering-app-file-editors b/changelog/unreleased/change-registering-app-file-editors index 70665897d06..01aa0bda3fa 100644 --- a/changelog/unreleased/change-registering-app-file-editors +++ b/changelog/unreleased/change-registering-app-file-editors @@ -2,5 +2,8 @@ Change: Registering app file editors BREAKING CHANGE for developers: The `announceExtensions` method inside the app's `ready` hook, which could be used to register file editors, has been removed. Developers should use the `extensions` property inside the `appInfo` object instead. +Note that the `handler` property of such an extension has been renamed to `createFileHandler`. + https://github.com/owncloud/web/pull/10330 +https://github.com/owncloud/web/pull/10346 https://github.com/owncloud/web/issues/10210 diff --git a/packages/web-app-external/package.json b/packages/web-app-external/package.json index 76d10079fce..433fb40a63e 100644 --- a/packages/web-app-external/package.json +++ b/packages/web-app-external/package.json @@ -13,6 +13,7 @@ "uuid": "9.0.1", "vue-concurrency": "4.0.1", "vue3-gettext": "2.4.0", - "vuex": "4.1.0" + "vuex": "4.1.0", + "zod": "3.22.4" } } diff --git a/packages/web-app-external/src/index.ts b/packages/web-app-external/src/index.ts index 183fdb7fad1..34c0cbbbb77 100644 --- a/packages/web-app-external/src/index.ts +++ b/packages/web-app-external/src/index.ts @@ -2,11 +2,16 @@ import { AppWrapperRoute, defineWebApplication, useCapabilityStore, - useConfigStore + useAppsStore, + useClientService, + useRequest } from '@ownclouders/web-pkg' import translations from '../l10n/translations.json' import App from './App.vue' -import store from './store' +import { stringify } from 'qs' +import { Resource, SpaceResource } from '@ownclouders/web-client' +import { join } from 'path' +import { AppListSchema } from './schemas' const appInfo = { name: 'External', @@ -30,15 +35,69 @@ const routes = [ export default defineWebApplication({ setup() { const capabilityStore = useCapabilityStore() - const configStore = useConfigStore() + const appsStore = useAppsStore() + const { makeRequest } = useRequest() + const clientService = useClientService() return { appInfo, routes, - store, translations, - ready({ store }) { - store.dispatch('External/fetchMimeTypes', { capabilityStore, configStore }) + ready: async () => { + if (!capabilityStore.filesAppProviders[0]?.enabled) { + return + } + + const { + data: { 'mime-types': mimeTypes } + } = await clientService.httpUnAuthenticated.get( + capabilityStore.filesAppProviders[0].apps_url, + { + schema: AppListSchema + } + ) + + mimeTypes.forEach((mimeType) => { + mimeType.app_providers.forEach((provider) => { + appsStore.registerFileExtension({ + appId: 'external', + data: { + extension: mimeType.ext, + label: mimeType.name, + mimeType: mimeType.mime_type, + routeName: 'external-apps', + hasPriority: mimeType.default_application === provider.name, + ...(mimeType.allow_creation && { newFileMenu: { menuTitle: () => mimeType.name } }), + createFileHandler: async ({ + fileName, + space, + currentFolder + }: { + fileName: string + space: SpaceResource + currentFolder: Resource + }) => { + if (fileName === '') { + return + } + + const query = stringify({ + parent_container_id: currentFolder.fileId, + filename: fileName + }) + const url = `${capabilityStore.filesAppProviders[0].new_url}?${query}` + const response = await makeRequest('POST', url) + if (response.status !== 200) { + throw new Error(`An error has occurred: ${response.status}`) + } + + const path = join(currentFolder.path, fileName) || '' + return clientService.webdav.getFileInfo(space, { path }) + } + } + }) + }) + }) } } } diff --git a/packages/web-app-external/src/schemas.ts b/packages/web-app-external/src/schemas.ts new file mode 100644 index 00000000000..ef197f0065f --- /dev/null +++ b/packages/web-app-external/src/schemas.ts @@ -0,0 +1,20 @@ +import { z } from 'zod' + +const AppProviderSchema = z.object({ + icon: z.string(), + name: z.string() +}) + +const MimeTypeSchema = z.object({ + allow_creation: z.boolean().optional(), + app_providers: z.array(AppProviderSchema), + default_application: z.string().optional(), + description: z.string().optional(), + ext: z.string().optional(), + mime_type: z.string(), + name: z.string().optional() +}) + +export const AppListSchema = z.object({ + 'mime-types': z.array(MimeTypeSchema) +}) diff --git a/packages/web-app-external/src/store/index.ts b/packages/web-app-external/src/store/index.ts deleted file mode 100644 index c368fd83cd8..00000000000 --- a/packages/web-app-external/src/store/index.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { Commit } from 'vuex' -import { urlJoin } from '@ownclouders/web-client/src/utils' -import { CapabilityStore, ConfigStore } from '@ownclouders/web-pkg' -import { v4 as uuidV4 } from 'uuid' - -interface AppProvider { - icon: string - name: string -} - -/* eslint-disable camelcase */ -interface MimeType { - allow_creation?: boolean - app_providers: Array - default_application?: string - description?: string - ext?: string - mime_type: string - name?: string -} -/* eslint-enable camelcase */ - -const State = { - mimeTypes: [] -} - -const actions = { - async fetchMimeTypes( - { - commit - }: { - commit: Commit - }, - { capabilityStore, configStore }: { capabilityStore: CapabilityStore; configStore: ConfigStore } - ): Promise { - if (!capabilityStore.filesAppProviders[0]?.enabled) { - return - } - - const url = urlJoin(configStore.serverUrl, capabilityStore.filesAppProviders[0].apps_url) - const response = await fetch(url, { headers: { 'X-Request-ID': uuidV4() } }) - - if (!response.ok) { - throw new Error('Error fetching app provider MIME types') - } - - const { 'mime-types': mimeTypes } = await response.json() - commit('SET_MIME_TYPES', mimeTypes) - } -} - -const getters = { - mimeTypes: (state: typeof State): Array => { - return state.mimeTypes - } -} - -const mutations = { - SET_MIME_TYPES(state: typeof State, mimeTypes: Array): void { - state.mimeTypes = mimeTypes - } -} - -export default { - namespaced: true, - state: State, - actions, - mutations, - getters -} diff --git a/packages/web-app-files/src/components/AppBar/CreateAndUpload.vue b/packages/web-app-files/src/components/AppBar/CreateAndUpload.vue index 2cb88d5be1c..c18242d1bc6 100644 --- a/packages/web-app-files/src/components/AppBar/CreateAndUpload.vue +++ b/packages/web-app-files/src/components/AppBar/CreateAndUpload.vue @@ -30,32 +30,26 @@ -