mirror of
https://github.com/nextcloud/server.git
synced 2024-07-30 08:15:57 +02:00
Merge pull request #43108 from nextcloud/backport/43090/stable28
[stable28] fix(files): combine navigation and files list into single Vue app
This commit is contained in:
commit
8d1d8da6b5
@ -288,16 +288,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\'');
|
||||
|
25
apps/files/src/FilesApp.vue
Normal file
25
apps/files/src/FilesApp.vue
Normal file
@ -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>
|
@ -346,7 +346,7 @@ export default Vue.extend({
|
||||
<style lang="scss">
|
||||
// Allow right click to define the position of the menu
|
||||
// only if defined
|
||||
.app-content[style*="mouse-pos-x"] .v-popper__popper {
|
||||
.content[style*="mouse-pos-x"] .v-popper__popper {
|
||||
transform: translate3d(var(--mouse-pos-x), var(--mouse-pos-y), 0px) !important;
|
||||
|
||||
// If the menu is too close to the bottom, we move it up
|
||||
|
@ -3,12 +3,11 @@ import { createPinia, PiniaVuePlugin } from 'pinia'
|
||||
import { getNavigation } from '@nextcloud/files'
|
||||
import { getRequestToken } from '@nextcloud/auth'
|
||||
|
||||
import FilesListView from './views/FilesList.vue'
|
||||
import NavigationView from './views/Navigation.vue'
|
||||
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())
|
||||
@ -43,23 +42,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')
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
@ -193,7 +185,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)
|
||||
},
|
||||
@ -201,6 +193,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
|
||||
@ -213,6 +206,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'
|
||||
@ -222,6 +216,7 @@ export default {
|
||||
|
||||
/**
|
||||
* Generate the route to a view
|
||||
* @param view
|
||||
*/
|
||||
generateToNavigation(view: View) {
|
||||
if (view.params) {
|
||||
|
@ -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
|
||||
|
@ -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\'');
|
||||
|
4
dist/files-main.js
vendored
4
dist/files-main.js
vendored
File diff suppressed because one or more lines are too long
2
dist/files-main.js.map
vendored
2
dist/files-main.js.map
vendored
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user