Skip to content

Commit

Permalink
refactor: remove vuex store in external app
Browse files Browse the repository at this point in the history
  • Loading branch information
JammingBen committed Jan 16, 2024
1 parent cb02b98 commit df7b3e0
Show file tree
Hide file tree
Showing 17 changed files with 220 additions and 520 deletions.
3 changes: 3 additions & 0 deletions changelog/unreleased/change-registering-app-file-editors
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 2 additions & 1 deletion packages/web-app-external/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
}
}
71 changes: 65 additions & 6 deletions packages/web-app-external/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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 })
}
}
})
})
})
}
}
}
Expand Down
20 changes: 20 additions & 0 deletions packages/web-app-external/src/schemas.ts
Original file line number Diff line number Diff line change
@@ -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)
})
70 changes: 0 additions & 70 deletions packages/web-app-external/src/store/index.ts

This file was deleted.

52 changes: 19 additions & 33 deletions packages/web-app-files/src/components/AppBar/CreateAndUpload.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,32 +30,26 @@
<span v-text="$gettext('Folder')" />
</oc-button>
</li>
<template v-if="mimetypesAllowedForCreation">
<template v-if="externalFileActions">
<li
v-for="(mimeTypeAction, key) in createNewFileMimeTypeActions"
v-for="(fileAction, key) in externalFileActions"
:key="`file-creation-item-external-${key}`"
class="create-list-file oc-menu-item-hover"
>
<oc-button appearance="raw" @click="mimeTypeAction.handler">
<resource-icon :resource="getIconResource(mimeTypeAction)" size="medium" />
<oc-button appearance="raw" @click="fileAction.handler">
<resource-icon :resource="getIconResource(fileAction)" size="medium" />
<span class="create-list-file-item-text" v-text="fileAction.label()" />
<span
class="create-list-file-item-text"
v-text="$gettext(mimeTypeAction.label())"
/>
<span
v-if="areFileExtensionsShown && mimeTypeAction.ext"
v-if="areFileExtensionsShown && fileAction.ext"
class="create-list-file-item-extension"
v-text="mimeTypeAction.ext"
v-text="fileAction.ext"
/>
</oc-button>
</li>
</template>
<li v-if="externalFileActions.length && appFileActions.length" class="bottom-seperator" />
<li
v-if="mimetypesAllowedForCreation && createNewFileMimeTypeActions.length > 0"
class="bottom-seperator"
/>
<li
v-for="(fileAction, key) in createNewFileActions"
v-for="(fileAction, key) in appFileActions"
:key="`file-creation-item-${key}`"
class="create-list-file oc-menu-item-hover"
>
Expand Down Expand Up @@ -314,23 +308,16 @@ export default defineComponent({
const { actions: createNewFileActions } = useFileActionsCreateNewFile({
store,
space: props.space,
appNewFileMenuExtensions
space: props.space
})
const mimetypesAllowedForCreation = computed(() => {
const mimeTypes = store.getters['External/mimeTypes']
if (!mimeTypes) {
return []
}
return mimeTypes.filter((mimetype) => mimetype.allow_creation) || []
})
const appFileActions = computed(() =>
unref(createNewFileActions).filter(({ isExternal }) => !isExternal)
)
const { actions: createNewFileMimeTypeActions } = useFileActionsCreateNewFile({
store,
space: props.space,
mimetypesAllowedForCreation: mimetypesAllowedForCreation
})
const externalFileActions = computed(() =>
unref(createNewFileActions).filter(({ isExternal }) => isExternal)
)
const extensionRegistry = useExtensionRegistry()
const extensionActions = computed(() => {
Expand Down Expand Up @@ -444,10 +431,9 @@ export default defineComponent({
hasSpaces: capabilityRefs.spacesEnabled,
canUpload,
currentFolder,
createNewFileActions,
createNewFileMimeTypeActions,
createNewFolder,
mimetypesAllowedForCreation,
appFileActions,
externalFileActions,
createNewFolderAction,
createNewShortcutAction,
extensionActions,
Expand Down Expand Up @@ -476,7 +462,7 @@ export default defineComponent({
},
createFileActionsAvailable() {
return this.appNewFileMenuExtensions.length > 0 || this.mimetypesAllowedForCreation.length > 0
return this.appFileActions.length > 0 || this.externalFileActions.length > 0
},
newButtonTooltip() {
if (!this.canUpload) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,21 +41,6 @@ const elSelector = {
clearClipboardBtn: '.clear-clipboard-btn'
}

const fileExtensionMocks = [
{
extension: 'txt',
newFileMenu: { menuTitle: () => 'Plain text file' }
},
{
extension: 'md',
newFileMenu: { menuTitle: () => 'Mark-down file' }
},
{
extension: 'drawio',
newFileMenu: { menuTitle: () => 'Draw.io document' }
}
]

describe('CreateAndUpload component', () => {
describe('action buttons', () => {
it('should show and be enabled if file creation is possible', () => {
Expand All @@ -66,7 +51,7 @@ describe('CreateAndUpload component', () => {
})
it('should be disabled if file creation is not possible', () => {
const currentFolder = mock<Resource>({ canUpload: () => false })
const { wrapper } = getWrapper({ currentFolder })
const { wrapper } = getWrapper({ currentFolder, createActions: [] })
expect(wrapper.findComponent<any>(elSelector.uploadBtn).props().disabled).toBeTruthy()
expect(wrapper.findComponent<any>(elSelector.newFolderBtn).props().disabled).toBeTruthy()
})
Expand All @@ -81,15 +66,8 @@ describe('CreateAndUpload component', () => {
const { wrapper } = getWrapper()
expect(wrapper.findAll(elSelector.resourceUpload).length).toBe(2)
})
it('should show additional handlers', () => {
const { wrapper } = getWrapper({ fileExtensions: fileExtensionMocks })
expect(wrapper.html()).toMatchSnapshot()
})
it('should show file extension if file extensions are enabled', () => {
const { wrapper } = getWrapper({
fileExtensions: fileExtensionMocks,
areFileExtensionsShown: true
})
it('should show entries for all new file handlers', () => {
const { wrapper } = getWrapper()
expect(wrapper.html()).toMatchSnapshot()
})
})
Expand Down Expand Up @@ -167,7 +145,6 @@ describe('CreateAndUpload component', () => {
})

function getWrapper({
fileExtensions = [],
clipboardResources = [],
files = [],
currentFolder = mock<Resource>({ canUpload: () => true }),
Expand All @@ -177,7 +154,12 @@ function getWrapper({
item = undefined,
itemId = undefined,
newFileAction = false,
areFileExtensionsShown = false
areFileExtensionsShown = false,
createActions = [
mock<FileAction>({ label: () => 'Plain text file', ext: 'txt' }),
mock<FileAction>({ label: () => 'Mark-down file', ext: 'md' }),
mock<FileAction>({ label: () => 'Draw.io document', ext: 'drawio' })
]
} = {}) {
jest.mocked(useRequest).mockImplementation(() => ({
makeRequest: jest.fn().mockResolvedValue({ status: 200 })
Expand All @@ -186,11 +168,7 @@ function getWrapper({

jest.mocked(useFileActionsCreateNewFile).mockReturnValue(
mock<ReturnType<typeof useFileActionsCreateNewFile>>({
actions: ref([
mock<FileAction>({ label: () => 'Plain text file', ext: 'txt' }),
mock<FileAction>({ label: () => 'Mark-down file', ext: 'md' }),
mock<FileAction>({ label: () => 'Draw.io document', ext: 'drawio' })
])
actions: ref(createActions)
})
)

Expand Down Expand Up @@ -222,7 +200,6 @@ function getWrapper({
plugins: [
...defaultPlugins({
piniaOptions: {
appsState: { fileExtensions },
spacesState: { spaces: spaces as any },
capabilityState: { capabilities }
}
Expand Down
Loading

0 comments on commit df7b3e0

Please sign in to comment.