You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Navigation.vue 4.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <!--
  2. - @copyright Copyright (c) 2019 Gary Kim <gary@garykim.dev>
  3. -
  4. - @author Gary Kim <gary@garykim.dev>
  5. -
  6. - @license GNU AGPL version 3 or any later version
  7. -
  8. - This program is free software: you can redistribute it and/or modify
  9. - it under the terms of the GNU Affero General Public License as
  10. - published by the Free Software Foundation, either version 3 of the
  11. - License, or (at your option) any later version.
  12. -
  13. - This program is distributed in the hope that it will be useful,
  14. - but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. - GNU Affero General Public License for more details.
  17. -
  18. - You should have received a copy of the GNU Affero General Public License
  19. - along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. -
  21. -->
  22. <template>
  23. <NcAppNavigation>
  24. <NcAppNavigationItem v-for="view in parentViews"
  25. :key="view.id"
  26. :allow-collapse="true"
  27. :to="{name: 'filelist', params: { view: view.id }}"
  28. :icon="view.iconClass"
  29. :open="view.expanded"
  30. :pinned="view.sticky"
  31. :title="view.name"
  32. @update:open="onToggleExpand(view)">
  33. <NcAppNavigationItem v-for="child in childViews[view.id]"
  34. :key="child.id"
  35. :to="{name: 'filelist', params: { view: child.id }}"
  36. :icon="child.iconClass"
  37. :title="child.name" />
  38. </NcAppNavigationItem>
  39. </NcAppNavigation>
  40. </template>
  41. <script>
  42. import { emit } from '@nextcloud/event-bus'
  43. import { generateUrl } from '@nextcloud/router'
  44. import axios from '@nextcloud/axios'
  45. import NcAppNavigation from '@nextcloud/vue/dist/Components/NcAppNavigation.js'
  46. import NcAppNavigationItem from '@nextcloud/vue/dist/Components/NcAppNavigationItem.js'
  47. import Navigation from '../services/Navigation.ts'
  48. import logger from '../logger.js'
  49. export default {
  50. name: 'Navigation',
  51. components: {
  52. NcAppNavigation,
  53. NcAppNavigationItem,
  54. },
  55. props: {
  56. // eslint-disable-next-line vue/prop-name-casing
  57. Navigation: {
  58. type: Navigation,
  59. required: true,
  60. },
  61. },
  62. data() {
  63. return {
  64. key: 'value',
  65. }
  66. },
  67. computed: {
  68. currentViewId() {
  69. return this.$route.params.view || 'files'
  70. },
  71. currentView() {
  72. return this.views.find(view => view.id === this.currentViewId)
  73. },
  74. /** @return {Navigation[]} */
  75. views() {
  76. return this.Navigation.views
  77. },
  78. parentViews() {
  79. return this.views
  80. // filter child views
  81. .filter(view => !view.parent)
  82. // sort views by order
  83. .sort((a, b) => {
  84. return a.order - b.order
  85. })
  86. },
  87. childViews() {
  88. return this.views
  89. // filter parent views
  90. .filter(view => !!view.parent)
  91. // create a map of parents and their children
  92. .reduce((list, view) => {
  93. list[view.parent] = [...(list[view.parent] || []), view]
  94. // Sort children by order
  95. list[view.parent].sort((a, b) => {
  96. return a.order - b.order
  97. })
  98. return list
  99. }, {})
  100. },
  101. },
  102. watch: {
  103. currentView(view, oldView) {
  104. logger.debug('View changed', { view })
  105. this.showView(view, oldView)
  106. },
  107. },
  108. beforeMount() {
  109. if (this.currentView) {
  110. logger.debug('Navigation mounted. Showing requested view', { view: this.currentView })
  111. this.showView(this.currentView)
  112. }
  113. },
  114. methods: {
  115. /**
  116. * @param {Navigation} view the new active view
  117. * @param {Navigation} oldView the old active view
  118. */
  119. showView(view, oldView) {
  120. if (view.legacy) {
  121. document.querySelectorAll('#app-content .viewcontainer').forEach(el => {
  122. el.classList.add('hidden')
  123. })
  124. document.querySelector('#app-content #app-content-' + this.currentView.id + '.viewcontainer').classList.remove('hidden')
  125. }
  126. this.Navigation.setActive(view)
  127. emit('files:view:changed', view)
  128. },
  129. onToggleExpand(view) {
  130. // Invert state
  131. view.expanded = !view.expanded
  132. axios.post(generateUrl(`/apps/files/api/v1/toggleShowFolder/${view.id}`), { show: view.expanded })
  133. },
  134. },
  135. }
  136. </script>
  137. <style scoped lang="scss">
  138. // TODO: remove when https://github.com/nextcloud/nextcloud-vue/pull/3539 is in
  139. .app-navigation::v-deep .app-navigation-entry-icon {
  140. background-repeat: no-repeat;
  141. background-position: center;
  142. }
  143. </style>