diff options
author | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2020-10-04 00:30:50 +0200 |
---|---|---|
committer | John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com> | 2020-10-07 09:40:58 +0200 |
commit | 843d799a2e2c884026883e3f41b81066801a877d (patch) | |
tree | b427d0296556488e34e0892f01c858ed5294b954 | |
parent | 678ef8466d5d1788bab1cf66786e47515a1bcbd9 (diff) | |
download | nextcloud-server-843d799a2e2c884026883e3f41b81066801a877d.tar.gz nextcloud-server-843d799a2e2c884026883e3f41b81066801a877d.zip |
Move Files Sidebar to proper javascript standard
Signed-off-by: John Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>
-rw-r--r-- | apps/files/js/filelist.js | 11 | ||||
-rw-r--r-- | apps/files/src/components/SidebarTab.vue (renamed from apps/files/src/components/LegacyTab.vue) | 67 | ||||
-rw-r--r-- | apps/files/src/models/Tab.js | 59 | ||||
-rw-r--r-- | apps/files/src/sidebar.js | 3 | ||||
-rw-r--r-- | apps/files/src/views/Sidebar.vue | 40 | ||||
-rw-r--r-- | apps/files_sharing/src/files_sharing_tab.js | 26 | ||||
-rw-r--r-- | apps/files_sharing/src/views/SharingTab.vue | 35 |
7 files changed, 124 insertions, 117 deletions
diff --git a/apps/files/js/filelist.js b/apps/files/js/filelist.js index 5e6225a48e9..3f144cc1f24 100644 --- a/apps/files/js/filelist.js +++ b/apps/files/js/filelist.js @@ -3700,7 +3700,16 @@ console.warn('registerTabView is deprecated! It will be removed in nextcloud 20.'); const enabled = tabView.canDisplay || undefined if (tabView.id) { - OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab(tabView.id, tabView, enabled, true)) + OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab({ + id: tabView.id, + name: tabView.getLabel(), + icon: tabView.getIcon(), + render: function(el, fileInfo) { + tabView.setFileInfo(fileInfo) + el.appendChild(tabView.el) + }, + enabled, + })) } }, diff --git a/apps/files/src/components/LegacyTab.vue b/apps/files/src/components/SidebarTab.vue index c8308dd6209..ecf04e9c9b3 100644 --- a/apps/files/src/components/LegacyTab.vue +++ b/apps/files/src/components/SidebarTab.vue @@ -1,3 +1,4 @@ + <!-- - @copyright Copyright (c) 2019 John Molakvoæ <skjnldsv@protonmail.com> - @@ -19,74 +20,74 @@ - along with this program. If not, see <http://www.gnu.org/licenses/>. - --> - <template> <AppSidebarTab :id="id" - :icon="icon" :name="name" - :active-tab="activeTab" /> + :icon="icon"> + <!-- Using a dummy div as Vue mount replace the element directly + It does NOT append to the content --> + <div ref="mount"></div> + </AppSidebarTab> </template> + <script> import AppSidebarTab from '@nextcloud/vue/dist/Components/AppSidebarTab' - export default { - name: 'LegacyTab', + name: 'SidebarTab', + components: { AppSidebarTab, }, + props: { - component: { + fileInfo: { type: Object, + default: () => {}, required: true, }, id: { type: String, required: true, }, - fileInfo: { - type: Object, - default: () => {}, + name: { + type: String, required: true, }, - }, - computed: { - icon() { - return this.component.getIcon() - }, - name() { - return this.component.getLabel() + icon: { + type: String, + required: true, }, - order() { - return this.component.order - ? this.component.order - : 0 + render: { + type: Function, + required: true, }, - // needed because AppSidebarTab also uses $parent.activeTab + }, + + computed: { + // TODO: implement a better way to force pass a prop fromm Sidebar activeTab() { return this.$parent.activeTab }, }, + watch: { - fileInfo(fileInfo) { - if (fileInfo) { - this.setFileInfo(fileInfo) + fileInfo(newFile, oldFile) { + if (newFile.id !== oldFile.id) { + this.mountTab() } }, }, + mounted() { - // append the backbone element and set the FileInfo - this.component.$el.appendTo(this.$el) - }, - beforeDestroy() { - this.component.remove() + this.mountTab() }, + methods: { - setFileInfo(fileInfo) { - this.component.setFileInfo(new OCA.Files.FileInfoModel(fileInfo)) + mountTab() { + // Mount the tab into this component + this.render(this.$refs.mount, this.fileInfo) }, }, } </script> -<style> -</style> diff --git a/apps/files/src/models/Tab.js b/apps/files/src/models/Tab.js index fd1ea9888d9..753b9c9c282 100644 --- a/apps/files/src/models/Tab.js +++ b/apps/files/src/models/Tab.js @@ -22,32 +22,49 @@ export default class Tab { - #component - #legacy #id + #name + #icon + #render #enabled /** * Create a new tab instance * - * @param {string} id the unique id of this tab - * @param {Object} component the vue component - * @param {Function} [enabled] function that returns if the tab should be shown or not - * @param {boolean} [legacy] is this a legacy tab + * @param {Object} options destructuring object + * @param {string} options.id the unique id of this tab + * @param {string} options.name the translated tab name + * @param {string} options.icon the vue component + * @param {Function} options.render function to render the tab + * @param {Function} [options.enabled] define conditions whether this tab is active. Must returns a boolean */ - constructor(id, component, enabled = () => true, legacy) { + constructor({ id, name, icon, render, enabled }) { + if (enabled === undefined) { + enabled = () => true + } + + // Sanity checks + if (typeof id !== 'string' || id.trim() === '') { + throw new Error('The id argument is not a valid string') + } + if (typeof name !== 'string' || name.trim() === '') { + throw new Error('The name argument is not a valid string') + } + if (typeof icon !== 'string' || icon.trim() === '') { + throw new Error('The icon argument is not a valid string') + } + if (typeof render !== 'function') { + throw new Error('The render argument should be a function') + } if (typeof enabled !== 'function') { throw new Error('The enabled argument should be a function') } this.#id = id - this.#component = component + this.#name = name + this.#icon = icon + this.#render = render this.#enabled = enabled - this.#legacy = legacy === true - - if (this.#legacy) { - console.warn('Legacy tabs are deprecated! They will be removed in nextcloud 20.') - } } @@ -55,16 +72,20 @@ export default class Tab { return this.#id } - get component() { - return this.#component + get name() { + return this.#name } - get isEnabled() { - return this.#enabled + get icon() { + return this.#icon } - get isLegacyTab() { - return this.#legacy === true + get render() { + return this.#render + } + + get enabled() { + return this.#enabled } } diff --git a/apps/files/src/sidebar.js b/apps/files/src/sidebar.js index f815a498938..508093465d4 100644 --- a/apps/files/src/sidebar.js +++ b/apps/files/src/sidebar.js @@ -24,9 +24,6 @@ import Vue from 'vue' import SidebarView from './views/Sidebar.vue' import Sidebar from './services/Sidebar' import Tab from './models/Tab' -import VueClipboard from 'vue-clipboard2' - -Vue.use(VueClipboard) Vue.prototype.t = t diff --git a/apps/files/src/views/Sidebar.vue b/apps/files/src/views/Sidebar.vue index 1fc89c6a7ee..6fa5c35dca2 100644 --- a/apps/files/src/views/Sidebar.vue +++ b/apps/files/src/views/Sidebar.vue @@ -58,15 +58,14 @@ </div> <!-- If fileInfo fetch is complete, display tabs --> - <template v-for="tab in tabs" v-else-if="fileInfo"> - <component - :is="tabComponent(tab).is" - v-if="canDisplay(tab)" + <template v-else-if="fileInfo" v-for="tab in tabs"> + <SidebarTab + v-if="tab.enabled(fileInfo)" :id="tab.id" :key="tab.id" - :component="tabComponent(tab).component" :name="tab.name" - :dav-path="davPath" + :icon="tab.icon" + :render="tab.render" :file-info="fileInfo" /> </template> </AppSidebar> @@ -77,7 +76,7 @@ import axios from '@nextcloud/axios' import AppSidebar from '@nextcloud/vue/dist/Components/AppSidebar' import ActionButton from '@nextcloud/vue/dist/Components/ActionButton' import FileInfo from '../services/FileInfo' -import LegacyTab from '../components/LegacyTab' +import SidebarTab from '../components/SidebarTab' import LegacyView from '../components/LegacyView' import { encodePath } from '@nextcloud/paths' @@ -87,6 +86,7 @@ export default { components: { ActionButton, AppSidebar, + SidebarTab, LegacyView, }, @@ -258,8 +258,8 @@ export default { }) this.$nextTick(() => { - if (this.$refs.sidebar) { - this.$refs.sidebar.updateTabs() + if (this.$refs.tabs) { + this.$refs.tabs.updateTabs() } }) } catch (error) { @@ -278,14 +278,14 @@ export default { * @returns {boolean} */ canDisplay(tab) { - return tab.isEnabled(this.fileInfo) + return tab.enabled(this.fileInfo) }, resetData() { this.error = null this.fileInfo = null this.$nextTick(() => { - if (this.$refs.sidebar) { - this.$refs.sidebar.updateTabs() + if (this.$refs.tabs) { + this.$refs.tabs.updateTabs() } }) }, @@ -327,18 +327,6 @@ export default { return OC.MimeType.getIconUrl(mimeType) }, - tabComponent(tab) { - if (tab.isLegacyTab) { - return { - is: LegacyTab, - component: tab.component, - } - } - return { - is: tab.component, - } - }, - /** * Set current active tab * @@ -430,8 +418,8 @@ export default { }) this.$nextTick(() => { - if (this.$refs.sidebar) { - this.$refs.sidebar.updateTabs() + if (this.$refs.tabs) { + this.$refs.tabs.updateTabs() } }) } catch (error) { diff --git a/apps/files_sharing/src/files_sharing_tab.js b/apps/files_sharing/src/files_sharing_tab.js index ffb6cdec30a..e8988e8c40a 100644 --- a/apps/files_sharing/src/files_sharing_tab.js +++ b/apps/files_sharing/src/files_sharing_tab.js @@ -19,11 +19,13 @@ * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ +import Vue from 'vue' +import VueClipboard from 'vue-clipboard2' +import { translate as t, translatePlural as n } from '@nextcloud/l10n' import SharingTab from './views/SharingTab' import ShareSearch from './services/ShareSearch' import ExternalLinkActions from './services/ExternalLinkActions' - import TabSections from './services/TabSections' // Init Sharing Tab Service @@ -34,8 +36,28 @@ Object.assign(window.OCA.Sharing, { ShareSearch: new ShareSearch() }) Object.assign(window.OCA.Sharing, { ExternalLinkActions: new ExternalLinkActions() }) Object.assign(window.OCA.Sharing, { ShareTabSections: new TabSections() }) +Vue.prototype.t = t +Vue.prototype.n = n +Vue.use(VueClipboard) + +// Init Sharing tab component +const View = Vue.extend(SharingTab) + window.addEventListener('DOMContentLoaded', function() { if (OCA.Files && OCA.Files.Sidebar) { - OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab('sharing', SharingTab)) + OCA.Files.Sidebar.registerTab(new OCA.Files.Sidebar.Tab({ + id: 'sharing', + name: t('files_sharing', 'Sharing'), + icon: 'icon-share', + + render: (el, fileInfo) => { + new View({ + propsData: { + fileInfo, + }, + }).$mount(el) + console.info(el) + }, + })) } }) diff --git a/apps/files_sharing/src/views/SharingTab.vue b/apps/files_sharing/src/views/SharingTab.vue index 40c8572912f..c92aac40d0a 100644 --- a/apps/files_sharing/src/views/SharingTab.vue +++ b/apps/files_sharing/src/views/SharingTab.vue @@ -21,10 +21,7 @@ --> <template> - <Tab :id="id" - :icon="icon" - :name="name" - :class="{ 'icon-loading': loading }"> + <div :class="{ 'icon-loading': loading }"> <!-- error message --> <div v-if="error" class="emptycontent"> <div class="icon icon-error" /> @@ -84,7 +81,7 @@ <component :is="section($refs['section-'+index], fileInfo)" :file-info="fileInfo" /> </div> </template> - </Tab> + </div> </template> <script> @@ -92,7 +89,6 @@ import { CollectionList } from 'nextcloud-vue-collections' import { generateOcsUrl } from '@nextcloud/router' import Avatar from '@nextcloud/vue/dist/Components/Avatar' import axios from '@nextcloud/axios' -import Tab from '@nextcloud/vue/dist/Components/AppSidebarTab' import { shareWithTitle } from '../utils/SharedWithMe' import Share from '../models/Share' @@ -117,7 +113,6 @@ export default { SharingInput, SharingLinkList, SharingList, - Tab, }, mixins: [ShareTypes], @@ -134,9 +129,7 @@ export default { return { error: '', expirationInterval: null, - icon: 'icon-share', loading: true, - name: t('files_sharing', 'Sharing'), // reshare Share object reshare: null, sharedWithMe: {}, @@ -148,26 +141,6 @@ export default { computed: { /** - * Needed to differenciate the tabs - * pulled from the AppSidebarTab component - * - * @returns {string} - */ - id() { - return 'sharing' - }, - - /** - * Returns the current active tab - * needed because AppSidebarTab also uses $parent.activeTab - * - * @returns {string} - */ - activeTab() { - return this.$parent.activeTab - }, - - /** * Is this share shared with me? * * @returns {boolean} @@ -341,7 +314,3 @@ export default { }, } </script> - -<style lang="scss" scoped> - -</style> |