From 79ff4e06fafb127ee06ef05263b62a34a96fbb86 Mon Sep 17 00:00:00 2001 From: Paul Neubauer Date: Mon, 16 Oct 2023 11:01:25 +0200 Subject: [PATCH 01/48] Integrate file editors in application menu, WIP texteditor --- packages/web-app-text-editor/src/index.ts | 13 +++++- .../components/Topbar/ApplicationsMenu.vue | 45 ++++++++++++++++--- .../web-runtime/src/layouts/Application.vue | 1 + 3 files changed, 52 insertions(+), 7 deletions(-) diff --git a/packages/web-app-text-editor/src/index.ts b/packages/web-app-text-editor/src/index.ts index 45b4e6a4c50..bed5d28ea52 100644 --- a/packages/web-app-text-editor/src/index.ts +++ b/packages/web-app-text-editor/src/index.ts @@ -1,6 +1,6 @@ import translations from '../l10n/translations.json' import TextEditor from './App.vue' -import { AppWrapperRoute } from '@ownclouders/web-pkg' +import { AppNavigationItem, AppWrapperRoute } from '@ownclouders/web-pkg' // just a dummy function to trick gettext tools function $gettext(msg) { @@ -92,7 +92,9 @@ const appInfo = { name: $gettext('Text Editor'), id: appId, icon: 'file-text', + color: '#2b2b2b', isFileEditor: true, + showInApplicationMenu: true, extensions: fileExtensions().map((extensionItem) => { return { extension: extensionItem.extension, @@ -103,8 +105,17 @@ const appInfo = { }) } +const navItems = (): AppNavigationItem[] => [ + { + enabled: () => { + return true + } + } +] + export default { appInfo, routes, translations + //navItems } diff --git a/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue b/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue index 8a5358effe8..67dbbd6c3e3 100644 --- a/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue +++ b/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue @@ -29,13 +29,11 @@
  • - ``` + } + }, + } + +``` diff --git a/packages/web-app-admin-settings/src/index.ts b/packages/web-app-admin-settings/src/index.ts index 86203706add..8210063e786 100644 --- a/packages/web-app-admin-settings/src/index.ts +++ b/packages/web-app-admin-settings/src/index.ts @@ -16,7 +16,11 @@ const appInfo = { id: 'admin-settings', icon: 'settings-4', color: '#2b2b2b', - isFileEditor: false + isFileEditor: false, + applicationMenu: { + enabled: () => true, + priority: 40 + } } const routes = ({ $ability }: { $ability: Ability }) => [ diff --git a/packages/web-app-draw-io/src/index.ts b/packages/web-app-draw-io/src/index.ts index 247af7a7cc0..77ed30890c6 100644 --- a/packages/web-app-draw-io/src/index.ts +++ b/packages/web-app-draw-io/src/index.ts @@ -26,7 +26,11 @@ const appInfo = { name: 'Draw.io', id: applicationId, icon: 'grid', - showInApplicationMenu: true, + applicationMenu: { + enabled: () => true, + priority: 30, + openAsEditor: true + }, defaultExtension: 'drawio', extensions: [ { diff --git a/packages/web-app-files/src/index.ts b/packages/web-app-files/src/index.ts index b43bf2473af..984466084a0 100644 --- a/packages/web-app-files/src/index.ts +++ b/packages/web-app-files/src/index.ts @@ -35,7 +35,11 @@ const appInfo = { color: 'var(--oc-color-swatch-primary-muted)', isFileEditor: false, extensions: [], - fileSideBars + fileSideBars, + applicationMenu: { + enabled: () => true, + priority: 10 + } } export const navItems = (context): AppNavigationItem[] => { return [ diff --git a/packages/web-app-text-editor/src/index.ts b/packages/web-app-text-editor/src/index.ts index 9cbf9853a1b..9ee73333fc7 100644 --- a/packages/web-app-text-editor/src/index.ts +++ b/packages/web-app-text-editor/src/index.ts @@ -94,7 +94,11 @@ const appInfo = { icon: 'file-text', color: '#EF6C00', isFileEditor: true, - showInApplicationMenu: true, + applicationMenu: { + enabled: () => true, + priority: 20, + openAsEditor: true + }, defaultExtension: 'txt', extensions: fileExtensions().map((extensionItem) => { return { diff --git a/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue b/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue index c16d2d732fa..80a2ecba6cf 100644 --- a/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue +++ b/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue @@ -77,7 +77,7 @@ export default defineComponent({ default: () => [] } }, - setup(props) { + setup() { const store = useStore() const { openEditor } = useFileActions() const clientService = useClientService() @@ -118,7 +118,7 @@ export default defineComponent({ ) } const getAdditionalEventBindings = (item: any) => { - if (item.showInApplicationMenu && item.defaultExtension) { + if (item.applicationMenu?.openAsEditor) { return { click: () => onEditorApplicationClick(item) } @@ -126,7 +126,7 @@ export default defineComponent({ return {} } const getAdditionalAttributes = (item: any) => { - if (item.showInApplicationMenu) { + if (item.applicationMenu?.openAsEditor) { return {} } return { @@ -159,12 +159,14 @@ export default defineComponent({ .oc-drop { width: 280px; } + .applications-list li { margin: var(--oc-space-xsmall) 0; &:first-child { margin-top: 0; } + &:last-child { margin-bottom: 0; } @@ -183,6 +185,7 @@ export default defineComponent({ color: var(--oc-color-swatch-primary-contrast) !important; } } + &.oc-button-passive-raw { &:focus, &:hover { @@ -193,6 +196,7 @@ export default defineComponent({ &:focus { text-decoration: none; } + &:hover { background-color: var(--oc-color-background-hover); text-decoration: none; diff --git a/packages/web-runtime/src/components/Topbar/TopBar.vue b/packages/web-runtime/src/components/Topbar/TopBar.vue index c940b0b9dc9..4abfe6c085a 100644 --- a/packages/web-runtime/src/components/Topbar/TopBar.vue +++ b/packages/web-runtime/src/components/Topbar/TopBar.vue @@ -110,7 +110,9 @@ export default { store.getters .getNavItemsByExtension(app.id) .filter((navItem) => isNavItemPermitted(permittedMenus, navItem)).length > 0 || - (app.showInApplicationMenu && !permittedMenus.includes('user')) + (app.applicationMenu.enabled instanceof Function && + app.applicationMenu.enabled() && + !permittedMenus.includes('user')) ) } return isNavItemPermitted(permittedMenus, app) @@ -142,7 +144,7 @@ export default { iconUrl: iconUrl, title: title, color: color, - showInApplicationMenu: item.showInApplicationMenu, + applicationMenu: item.applicationMenu, defaultExtension: item.defaultExtension } diff --git a/packages/web-runtime/src/layouts/Application.vue b/packages/web-runtime/src/layouts/Application.vue index fa21a6bca0a..b816a69dffe 100644 --- a/packages/web-runtime/src/layouts/Application.vue +++ b/packages/web-runtime/src/layouts/Application.vue @@ -189,17 +189,8 @@ export default defineComponent({ applicationsList() { const list = [] - // Get extensions which have at least one nav item - this.getExtensionsWithNavItems.forEach((extensionId) => { - list.push({ - ...this.apps[extensionId], - type: 'extension' - }) - }) - - // Add extensions with showInApplicationMenu Object.values(this.apps).forEach((app: any) => { - if (app.showInApplicationMenu) { + if (app.applicationMenu.enabled instanceof Function && app.applicationMenu.enabled()) { list.push({ ...app, type: 'extension' @@ -214,7 +205,12 @@ export default defineComponent({ type: 'link' }) }) - return list + + return list.sort( + (a, b) => + (a.applicationMenu?.priority || Number.MAX_SAFE_INTEGER) - + (b.applicationMenu?.priority || Number.MAX_SAFE_INTEGER) + ) } }, mounted() { diff --git a/packages/web-runtime/src/store/apps.ts b/packages/web-runtime/src/store/apps.ts index bc9451e660b..86f5c4fedd7 100644 --- a/packages/web-runtime/src/store/apps.ts +++ b/packages/web-runtime/src/store/apps.ts @@ -87,7 +87,7 @@ const mutations = { img: appInfo.img || null, config: (state.fileEditorConfigs || {})[appInfo.id], color: appInfo.color || '', - showInApplicationMenu: appInfo.showInApplicationMenu || false, + applicationMenu: appInfo.applicationMenu || {}, defaultExtension: appInfo.defaultExtension || '' } state.meta[app.id] = app From 6a6c6a99589c556d41b89c7ddd1b09adea82ca6e Mon Sep 17 00:00:00 2001 From: Jan Ackermann Date: Tue, 17 Oct 2023 14:45:01 +0200 Subject: [PATCH 14/48] Adjust colors --- packages/web-app-draw-io/src/index.ts | 1 + packages/web-app-text-editor/src/index.ts | 2 +- packages/web-pkg/src/components/AppTopBar.vue | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/web-app-draw-io/src/index.ts b/packages/web-app-draw-io/src/index.ts index 77ed30890c6..15ae4cf33ca 100644 --- a/packages/web-app-draw-io/src/index.ts +++ b/packages/web-app-draw-io/src/index.ts @@ -26,6 +26,7 @@ const appInfo = { name: 'Draw.io', id: applicationId, icon: 'grid', + color: '#EF6C00', applicationMenu: { enabled: () => true, priority: 30, diff --git a/packages/web-app-text-editor/src/index.ts b/packages/web-app-text-editor/src/index.ts index 9ee73333fc7..f8638b8ab87 100644 --- a/packages/web-app-text-editor/src/index.ts +++ b/packages/web-app-text-editor/src/index.ts @@ -92,7 +92,7 @@ const appInfo = { name: $gettext('Text Editor'), id: appId, icon: 'file-text', - color: '#EF6C00', + color: '#7b27b6', isFileEditor: true, applicationMenu: { enabled: () => true, diff --git a/packages/web-pkg/src/components/AppTopBar.vue b/packages/web-pkg/src/components/AppTopBar.vue index 5292e471408..404a1d6e37a 100644 --- a/packages/web-pkg/src/components/AppTopBar.vue +++ b/packages/web-pkg/src/components/AppTopBar.vue @@ -151,6 +151,12 @@ export default defineComponent({ flex-basis: 250px; margin: 0; } + + .oc-resource-indicators { + .text { + color: var(--oc-color-swatch-brand-contrast); + } + } } .open-file-bar { From a940746059369c01c4f387c8a280ce1664eda3b6 Mon Sep 17 00:00:00 2001 From: Paul Neubauer Date: Wed, 18 Oct 2023 14:09:34 +0200 Subject: [PATCH 15/48] WIP --- packages/web-runtime/src/App.vue | 25 +++++++++++++++-- .../components/Topbar/ApplicationsMenu.vue | 27 ++++++++++++++++--- 2 files changed, 46 insertions(+), 6 deletions(-) diff --git a/packages/web-runtime/src/App.vue b/packages/web-runtime/src/App.vue index 5699cda4481..5954f08c519 100644 --- a/packages/web-runtime/src/App.vue +++ b/packages/web-runtime/src/App.vue @@ -54,10 +54,10 @@ import SkipTo from './components/SkipTo.vue' import LayoutApplication from './layouts/Application.vue' import LayoutLoading from './layouts/Loading.vue' import LayoutPlain from './layouts/Plain.vue' -import { defineComponent } from 'vue' +import { computed, defineComponent, unref, watch } from 'vue' import { isPublicLinkContext, isUserContext } from './router' import { additionalTranslations } from './helpers/additionalTranslations' // eslint-disable-line -import { eventBus } from '@ownclouders/web-pkg' +import { eventBus, useRouter } from '@ownclouders/web-pkg' import { useHead } from './composables/head' import { useStore } from '@ownclouders/web-pkg' @@ -67,7 +67,28 @@ export default defineComponent({ }, setup() { const store = useStore() + const router = useRouter() useHead({ store }) + + const activeRoutePath = computed(() => router.resolve(unref(router.currentRoute)).path) + + watch( + () => unref(router.currentRoute), + (newValue, oldValue) => { + if (newValue === oldValue) { + return + } + const oldApp = oldValue.path.split('/')[1] + const newApp = newValue.path.split('/')[1] + if (oldApp === newApp) { + return + } + //store.commit('Files/SET_CURRENT_FOLDER', null) + console.log(newValue) + console.log(newValue.path) + } + ) + //activeRoutePath?.startsWith(app.path) }, data() { return { diff --git a/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue b/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue index 80a2ecba6cf..900f19a8520 100644 --- a/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue +++ b/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue @@ -51,7 +51,15 @@ -``` + }, + } + + ``` From 9109fcf665b7ff98127c5b64f362cd7956bb36c3 Mon Sep 17 00:00:00 2001 From: Jan Ackermann Date: Thu, 19 Oct 2023 16:14:50 +0200 Subject: [PATCH 32/48] Rm unused code --- .../composables/folderLink/useFolderLink.spec.ts | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/packages/web-pkg/tests/unit/composables/folderLink/useFolderLink.spec.ts b/packages/web-pkg/tests/unit/composables/folderLink/useFolderLink.spec.ts index 1e9a2ecc714..80385503afd 100644 --- a/packages/web-pkg/tests/unit/composables/folderLink/useFolderLink.spec.ts +++ b/packages/web-pkg/tests/unit/composables/folderLink/useFolderLink.spec.ts @@ -33,18 +33,6 @@ jest.mock('../../../../src/composables/configuration', () => ({ }) })) -/*jest.mock('../../../../src/composables', () => ({ - ...jest.requireActual('../../../../src/composables'), - useConfigurationManager: () => - mockDeep({ - options: { - routing: { - fullShareOwnerPaths: true - } - } - }) -}))*/ - describe('useFolderLink', () => { it('getFolderLink should return the correct folder link', () => { const resource = { From 9097560562fb9ceffe38653fd30b2d78a9f41fc4 Mon Sep 17 00:00:00 2001 From: Jan Ackermann Date: Thu, 19 Oct 2023 16:15:30 +0200 Subject: [PATCH 33/48] Rm unused code --- packages/web-runtime/src/App.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/web-runtime/src/App.vue b/packages/web-runtime/src/App.vue index 49bc90eed02..38f0983cbb7 100644 --- a/packages/web-runtime/src/App.vue +++ b/packages/web-runtime/src/App.vue @@ -83,7 +83,6 @@ export default defineComponent({ store.commit('Files/SET_CURRENT_FOLDER', null) } ) - //activeRoutePath?.startsWith(app.path) }, data() { return { From 842f3cfd5d84a9fe8303d8f2f9898aa1fd742e78 Mon Sep 17 00:00:00 2001 From: Jan Ackermann Date: Thu, 19 Oct 2023 16:16:49 +0200 Subject: [PATCH 34/48] Dont autoformat code that we don't touch --- tests/e2e/cucumber/features/smoke/search.feature | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/e2e/cucumber/features/smoke/search.feature b/tests/e2e/cucumber/features/smoke/search.feature index 34dbf20feea..929fffe36f6 100644 --- a/tests/e2e/cucumber/features/smoke/search.feature +++ b/tests/e2e/cucumber/features/smoke/search.feature @@ -1,4 +1,4 @@ - Feature: Search +Feature: Search As a user I want to search for resources So that I can find them quickly From 1d53a12ab697edb72c5e674099678a6a4d3025be Mon Sep 17 00:00:00 2001 From: Jan Ackermann Date: Fri, 20 Oct 2023 09:23:17 +0200 Subject: [PATCH 35/48] Dont destruct clientService and make use of appInfo type --- packages/web-pkg/src/apps/types.ts | 7 +++++++ .../src/components/Topbar/ApplicationsMenu.vue | 10 +++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/packages/web-pkg/src/apps/types.ts b/packages/web-pkg/src/apps/types.ts index bad8853b4a6..73144e60c89 100644 --- a/packages/web-pkg/src/apps/types.ts +++ b/packages/web-pkg/src/apps/types.ts @@ -52,6 +52,11 @@ export interface ApplicationQuickActions { export type AppConfigObject = Record +export interface ApplicationMenuItem { + enabled: () => boolean + priority: number +} + /** ApplicationInformation describes required information of an application */ export interface ApplicationInformation { id?: string @@ -59,7 +64,9 @@ export interface ApplicationInformation { icon?: string isFileEditor?: boolean extensions?: any[] + defaultExtension?: string fileSideBars?: any[] + applicationMenu?: ApplicationMenuItem } /** diff --git a/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue b/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue index efe344dda2d..47ac1deeac5 100644 --- a/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue +++ b/packages/web-runtime/src/components/Topbar/ApplicationsMenu.vue @@ -57,6 +57,7 @@ import OcApplicationIcon from 'design-system/src/components/OcApplicationIcon/Oc import { useGettext } from 'vue3-gettext' import * as uuid from 'uuid' import { + ApplicationInformation, EDITOR_MODE_EDIT, resolveFileNameDuplicate, useClientService, @@ -82,7 +83,6 @@ export default defineComponent({ const store = useStore() const { openEditor } = useFileActions() const clientService = useClientService() - const { webdav } = clientService const { $gettext } = useGettext() const appIconKey = ref('') const { getMatchingSpace } = useGetMatchingSpace() @@ -98,7 +98,7 @@ export default defineComponent({ }) const files = computed((): Array => store.getters['Files/files']) - const onEditorApplicationClick = async (item: any) => { + const onEditorApplicationClick = async (item: ApplicationInformation) => { let destinationSpace = unref(currentFolder) let destinationFiles = unref(files) @@ -106,7 +106,7 @@ export default defineComponent({ destinationSpace = unref(store.getters['runtime/spaces/spaces']).find( ({ drive }) => !isPersonalSpaceResource(drive as SpaceResource) ) - destinationFiles = (await webdav.listFiles(destinationSpace)).children + destinationFiles = (await clientService.webdav.listFiles(destinationSpace)).children } let fileName = $gettext('New file') + `.${item.defaultExtension}` @@ -115,7 +115,7 @@ export default defineComponent({ fileName = resolveFileNameDuplicate(fileName, item.defaultExtension, destinationFiles) } - const emptyResource = await webdav.putFileContents(destinationSpace, { + const emptyResource = await clientService.webdav.putFileContents(destinationSpace, { path: fileName }) @@ -130,7 +130,7 @@ export default defineComponent({ space.shareId ) } - const getAdditionalEventBindings = (item: any) => { + const getAdditionalEventBindings = (item: ApplicationInformation) => { if (item.applicationMenu?.openAsEditor) { return { click: () => onEditorApplicationClick(item) From 1c4ab821c7ec59c751fbec1b5d7cb560d327faee Mon Sep 17 00:00:00 2001 From: Jan Ackermann Date: Fri, 20 Oct 2023 09:35:46 +0200 Subject: [PATCH 36/48] Make set_current_folder more bullet proof --- packages/web-runtime/src/App.vue | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/packages/web-runtime/src/App.vue b/packages/web-runtime/src/App.vue index 38f0983cbb7..2edc8fc521b 100644 --- a/packages/web-runtime/src/App.vue +++ b/packages/web-runtime/src/App.vue @@ -60,6 +60,7 @@ import { additionalTranslations } from './helpers/additionalTranslations' // esl import { eventBus, useRouter } from '@ownclouders/web-pkg' import { useHead } from './composables/head' import { useStore } from '@ownclouders/web-pkg' +import { RouteLocation, Router } from 'vue-router' export default defineComponent({ components: { @@ -70,16 +71,29 @@ export default defineComponent({ const router = useRouter() useHead({ store }) - const activeApp = computed( - () => router.resolve(unref(router.currentRoute)).path.split('/')?.[1] - ) + const activeRoute = computed(() => router.resolve(unref(router.currentRoute))) watch( - () => unref(activeApp), - (newApp, oldApp) => { + () => unref(activeRoute), + (newRoute, oldRoute) => { + const getAppFromRoute = (route: RouteLocation): string => { + return route?.path?.split('/')?.[1] + } + + const oldApp = getAppFromRoute(oldRoute) + const newApp = getAppFromRoute(newRoute) + if (oldApp === newApp) { return } + + if ('driveAliasAndItem' in newRoute.params) { + return + } + + /* + * If app has been changed and no file context is set, we will reset current folder. + */ store.commit('Files/SET_CURRENT_FOLDER', null) } ) From 1c3ff733382f7b5e5725cb7fef7af264733c470c Mon Sep 17 00:00:00 2001 From: Jan Ackermann Date: Fri, 20 Oct 2023 09:47:35 +0200 Subject: [PATCH 37/48] Fix open preview app run into errors --- packages/web-pkg/src/components/AppTopBar.vue | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/packages/web-pkg/src/components/AppTopBar.vue b/packages/web-pkg/src/components/AppTopBar.vue index 404a1d6e37a..1dd0dd8bd1a 100644 --- a/packages/web-pkg/src/components/AppTopBar.vue +++ b/packages/web-pkg/src/components/AppTopBar.vue @@ -112,13 +112,19 @@ export default defineComponent({ const { getParentFolderName, getParentFolderLinkIconAdditionalAttributes } = useFolderLink() + const parentFolderName = computed(() => { + return props.resource ? getParentFolderName(props.resource) : null + }) + + const parentFolderLinkIconAdditionalAttributes = computed(() => { + return props.resource ? getParentFolderLinkIconAdditionalAttributes(props.resource) : null + }) + return { contextMenuLabel, closeButtonLabel, - parentFolderName: getParentFolderName(props.resource), - parentFolderLinkIconAdditionalAttributes: getParentFolderLinkIconAdditionalAttributes( - props.resource - ) + parentFolderName, + parentFolderLinkIconAdditionalAttributes } } }) From aa59e584bcb4b160b14888ec2e82ab834a51e76e Mon Sep 17 00:00:00 2001 From: Jan Ackermann Date: Fri, 20 Oct 2023 11:11:19 +0200 Subject: [PATCH 38/48] Fix wrong path displayed in AppTopBar --- packages/web-pkg/src/components/AppTopBar.vue | 14 +++++++++++--- .../src/composables/spaces/useGetMatchingSpace.ts | 5 +++++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/packages/web-pkg/src/components/AppTopBar.vue b/packages/web-pkg/src/components/AppTopBar.vue index 1dd0dd8bd1a..b6167d757e4 100644 --- a/packages/web-pkg/src/components/AppTopBar.vue +++ b/packages/web-pkg/src/components/AppTopBar.vue @@ -12,7 +12,7 @@ :parent-folder-link-icon-additional-attributes=" parentFolderLinkIconAdditionalAttributes " - :is-path-displayed="true" + :is-path-displayed="isPathDisplayed" />
    @@ -77,12 +77,13 @@