]> source.dussan.org Git - nextcloud-server.git/commitdiff
fix(files): combine navigation and files list into single Vue app
authorGrigorii K. Shartsev <me@shgk.me>
Wed, 24 Jan 2024 16:58:16 +0000 (17:58 +0100)
committerGrigorii K. Shartsev <me@shgk.me>
Wed, 24 Jan 2024 23:25:54 +0000 (00:25 +0100)
Signed-off-by: Grigorii K. Shartsev <me@shgk.me>
apps/files/lib/Controller/ViewController.php
apps/files/src/FilesApp.vue [new file with mode: 0644]
apps/files/src/main.ts
apps/files/src/views/Navigation.cy.ts
apps/files/src/views/Navigation.vue
apps/files/templates/index.php
apps/files/tests/Controller/ViewControllerTest.php

index b8090e1cf29a73571676da1ce71dae0013316115..7931686c92e1fa78070fb86cefa7fa8b68bd758f 100644 (file)
@@ -283,16 +283,9 @@ class ViewController extends Controller {
                $this->initialState->provideInitialState('templates_path', $this->templateManager->hasTemplateDirectory() ? $this->templateManager->getTemplatePath() : false);
                $this->initialState->provideInitialState('templates', $this->templateManager->listCreators());
 
-               $params = [
-                       'fileNotFound' => $fileNotFound ? 1 : 0,
-                       'id-app-content' => '#app-content-vue',
-                       'id-app-navigation' => '#app-navigation-vue',
-               ];
-
                $response = new TemplateResponse(
                        Application::APP_ID,
                        'index',
-                       $params
                );
                $policy = new ContentSecurityPolicy();
                $policy->addAllowedFrameDomain('\'self\'');
diff --git a/apps/files/src/FilesApp.vue b/apps/files/src/FilesApp.vue
new file mode 100644 (file)
index 0000000..a2a7f49
--- /dev/null
@@ -0,0 +1,25 @@
+<template>
+       <NcContent app-name="files">
+               <Navigation />
+               <FilesList />
+       </NcContent>
+</template>
+
+<script lang="ts">
+import { defineComponent } from 'vue'
+
+import NcContent from '@nextcloud/vue/dist/Components/NcContent.js'
+
+import Navigation from './views/Navigation.vue'
+import FilesList from './views/FilesList.vue'
+
+export default defineComponent({
+       name: 'FilesApp',
+
+       components: {
+               NcContent,
+               FilesList,
+               Navigation,
+       },
+})
+</script>
index 1206b9cc7115b64fb2dc848dabd5c1c85710cc20..08fb3f562ab75149ce818c6fb53f5e212470ce96 100644 (file)
@@ -9,6 +9,7 @@ import router from './router/router'
 import RouterService from './services/RouterService'
 import SettingsModel from './models/Setting.js'
 import SettingsService from './services/Settings.js'
+import FilesApp from './FilesApp.vue'
 
 // @ts-expect-error __webpack_nonce__ is injected by webpack
 __webpack_nonce__ = btoa(getRequestToken())
@@ -42,23 +43,8 @@ const Settings = new SettingsService()
 Object.assign(window.OCA.Files, { Settings })
 Object.assign(window.OCA.Files.Settings, { Setting: SettingsModel })
 
-// Init Navigation View
-const View = Vue.extend(NavigationView)
-const FilesNavigationRoot = new View({
-       name: 'FilesNavigationRoot',
-       propsData: {
-               Navigation,
-       },
+const FilesAppVue = Vue.extend(FilesApp)
+new FilesAppVue({
        router,
        pinia,
-})
-FilesNavigationRoot.$mount('#app-navigation-files')
-
-// Init content list view
-const ListView = Vue.extend(FilesListView)
-const FilesList = new ListView({
-       name: 'FilesListRoot',
-       router,
-       pinia,
-})
-FilesList.$mount('#app-content-vue')
+}).$mount('#content')
index cf3512bce0e46655b6bb269ca11b75d643325382..07d9eee80cb1d8f61e6484b30d974e9e0407fc9c 100644 (file)
@@ -7,11 +7,15 @@ import router from '../router/router'
 import { useViewConfigStore } from '../store/viewConfig'
 import { Folder, View, getNavigation } from '@nextcloud/files'
 
+import Vue from 'vue'
+
 describe('Navigation renders', () => {
        delete window._nc_navigation
        const Navigation = getNavigation()
 
        before(() => {
+               Vue.prototype.$navigation = Navigation
+
                cy.mockInitialState('files', 'storageStats', {
                        used: 1000 * 1000 * 1000,
                        quota: -1,
@@ -22,9 +26,6 @@ describe('Navigation renders', () => {
 
        it('renders', () => {
                cy.mount(NavigationView, {
-                       propsData: {
-                               Navigation,
-                       },
                        global: {
                                plugins: [createTestingPinia({
                                        createSpy: cy.spy,
@@ -42,6 +43,10 @@ describe('Navigation API', () => {
        delete window._nc_navigation
        const Navigation = getNavigation()
 
+       before(() => {
+               Vue.prototype.$navigation = Navigation
+       })
+
        it('Check API entries rendering', () => {
                Navigation.register(new View({
                        id: 'files',
@@ -52,9 +57,6 @@ describe('Navigation API', () => {
                }))
 
                cy.mount(NavigationView, {
-                       propsData: {
-                               Navigation,
-                       },
                        global: {
                                plugins: [createTestingPinia({
                                        createSpy: cy.spy,
@@ -79,9 +81,6 @@ describe('Navigation API', () => {
                }))
 
                cy.mount(NavigationView, {
-                       propsData: {
-                               Navigation,
-                       },
                        global: {
                                plugins: [createTestingPinia({
                                        createSpy: cy.spy,
@@ -107,9 +106,6 @@ describe('Navigation API', () => {
                }))
 
                cy.mount(NavigationView, {
-                       propsData: {
-                               Navigation,
-                       },
                        global: {
                                plugins: [createTestingPinia({
                                        createSpy: cy.spy,
@@ -159,13 +155,14 @@ describe('Quota rendering', () => {
        delete window._nc_navigation
        const Navigation = getNavigation()
 
+       before(() => {
+               Vue.prototype.$navigation = Navigation
+       })
+
        afterEach(() => cy.unmockInitialState())
 
        it('Unknown quota', () => {
                cy.mount(NavigationView, {
-                       propsData: {
-                               Navigation,
-                       },
                        global: {
                                plugins: [createTestingPinia({
                                        createSpy: cy.spy,
@@ -183,9 +180,6 @@ describe('Quota rendering', () => {
                })
 
                cy.mount(NavigationView, {
-                       propsData: {
-                               Navigation,
-                       },
                        global: {
                                plugins: [createTestingPinia({
                                        createSpy: cy.spy,
@@ -206,9 +200,6 @@ describe('Quota rendering', () => {
                })
 
                cy.mount(NavigationView, {
-                       propsData: {
-                               Navigation,
-                       },
                        global: {
                                plugins: [createTestingPinia({
                                        createSpy: cy.spy,
@@ -230,9 +221,6 @@ describe('Quota rendering', () => {
                })
 
                cy.mount(NavigationView, {
-                       propsData: {
-                               Navigation,
-                       },
                        global: {
                                plugins: [createTestingPinia({
                                        createSpy: cy.spy,
index 9e7a630128e94628325f32a16c549f2d30202029..0895bd060abe982ca8187d6934aa35dcc50b7ae0 100644 (file)
@@ -75,7 +75,7 @@
 </template>
 
 <script lang="ts">
-import { emit, subscribe } from '@nextcloud/event-bus'
+import { emit } from '@nextcloud/event-bus'
 import { translate } from '@nextcloud/l10n'
 import Cog from 'vue-material-design-icons/Cog.vue'
 import NcAppNavigation from '@nextcloud/vue/dist/Components/NcAppNavigation.js'
@@ -85,7 +85,7 @@ import NcIconSvgWrapper from '@nextcloud/vue/dist/Components/NcIconSvgWrapper.js
 import { setPageHeading } from '../../../../core/src/OCP/accessibility.js'
 import { useViewConfigStore } from '../store/viewConfig.ts'
 import logger from '../logger.js'
-import type { Navigation, View } from '@nextcloud/files'
+import type { View } from '@nextcloud/files'
 import NavigationQuota from '../components/NavigationQuota.vue'
 import SettingsModal from './Settings.vue'
 
@@ -101,14 +101,6 @@ export default {
                SettingsModal,
        },
 
-       props: {
-               // eslint-disable-next-line vue/prop-name-casing
-               Navigation: {
-                       type: Object as Navigation,
-                       required: true,
-               },
-       },
-
        setup() {
                const viewConfigStore = useViewConfigStore()
                return {
@@ -132,7 +124,7 @@ export default {
                },
 
                views(): View[] {
-                       return this.Navigation.views
+                       return this.$navigation.views
                },
 
                parentViews(): View[] {
@@ -164,7 +156,7 @@ export default {
        watch: {
                currentView(view, oldView) {
                        if (view.id !== oldView?.id) {
-                               this.Navigation.setActive(view)
+                               this.$navigation.setActive(view)
                                logger.debug('Navigation changed', { id: view.id, view })
 
                                this.showView(view)
@@ -183,7 +175,7 @@ export default {
                showView(view: View) {
                        // Closing any opened sidebar
                        window?.OCA?.Files?.Sidebar?.close?.()
-                       this.Navigation.setActive(view)
+                       this.$navigation.setActive(view)
                        setPageHeading(view.name)
                        emit('files:navigation:changed', view)
                },
@@ -191,6 +183,7 @@ export default {
                /**
                 * Expand/collapse a a view with children and permanently
                 * save this setting in the server.
+                * @param view
                 */
                onToggleExpand(view: View) {
                        // Invert state
@@ -203,6 +196,7 @@ export default {
                /**
                 * Check if a view is expanded by user config
                 * or fallback to the default value.
+                * @param view
                 */
                isExpanded(view: View): boolean {
                        return typeof this.viewConfigStore.getConfig(view.id)?.expanded === 'boolean'
@@ -212,6 +206,7 @@ export default {
 
                /**
                 * Generate the route to a view
+                * @param view
                 */
                generateToNavigation(view: View) {
                        if (view.params) {
index c974a37aa5bcdffbaba8f0afeadaf9d0d1f47ee6..9e4d6e56ec5fd89c8c03c523a20a2d8717d5c8f4 100644 (file)
@@ -1,9 +1,3 @@
-<!-- File navigation -->
-<div id="app-navigation-files" role="navigation"></div>
+<?php
 
-<!-- File list vue container -->
-<div id="app-content-vue" class="hidden"></div>
-
-<!-- config hints for javascript -->
-<input type="hidden" name="filesApp" id="filesApp" value="1" />
-<input type="hidden" name="fileNotFound" id="fileNotFound" value="<?php p($_['fileNotFound']); ?>" />
+// Empty template
index 8b6fc5a05a949db7204532394bd7c4469912a2b4..588c93f8316e166dad53bccbd021bb5f78e7a870 100644 (file)
@@ -184,11 +184,6 @@ class ViewControllerTest extends TestCase {
                $expected = new Http\TemplateResponse(
                        'files',
                        'index',
-                       [
-                               'fileNotFound' => 0,
-                               'id-app-content' => '#app-content-vue',
-                               'id-app-navigation' => '#app-navigation-vue',
-                       ]
                );
                $policy = new Http\ContentSecurityPolicy();
                $policy->addAllowedWorkerSrcDomain('\'self\'');