Some time ago I created an unpublished app that allows a user to use a simple form to write a specific file to a folder by using the sidebar. Simplified here’s what it does:
Registers a new tab view in the sidebar if selected item is a directory
Shows a form to enter some information in the tab view
Sends the information to a Nextcloud REST endpoint
Backend saves a specific file to the folder with the user input properly formatted for an external script
However, I’ve been adapting a lot of code from the versions app back then.
Now I’d like to update the app, because some JS APIs broke over time. But I’d like to do so in a future-proof way. Actually, I’d like to mount a Vue component into a tab view. Is that even possible? Is there any app that does that already?
For example
registerTabView
is now deprecated. But no-where it says how to register your tab view instead. Core apps still seem to be using it on
master
. How’s the way forward? Where do I find references to the future of interacting with the filelist?
Also,
@skjnldsv
, you’ve been editing the sidebar class recently and added the warning or moved it over to a new version (
https://github.com/nextcloud/server/blame/cb2695df8d47f9d5b08a7d6f1a9dbc55f63b6e59/apps/files/js/filelist.js#L3700
). Hope I’m allowe to ping you. Can you help?
See some example:
https://github.com/nextcloud/server/blob/6fcd075730dbd63d5dbb69da0ca5983b51a7240e/apps/files_sharing/src/files_sharing_tab.js
https://github.com/nextcloud/server/blob/4485cb30a1bd4b86492203b20c43e0c8fdd47f71/apps/files_sharing/src/views/SharingTab.vue
Your tab needs to provide a Name and an id
github.com
required: true,
data() {
return {
error: '',
expirationInterval: null,
icon: 'icon-share',
loading: true,
name: t('files_sharing', 'Sharing'),
// reshare Share object
reshare: null,
sharedWithMe: {},
shares: [],
linkShares: [],
sections: OCA.Sharing.ShareTabSections.getSections(),
computed: {
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
<template v-for="tab in tabs" v-else-if="fileInfo">
<component
:is="tabComponent(tab).is"
v-if="canDisplay(tab)"
:id="tab.id"
:key="tab.id"
:component="tabComponent(tab).component"
:name="tab.name"
:dav-path="davPath"
:file-info="fileInfo" />
</template>
Hey! This was such a helpful pointer, thanks a lot!
The tricky part was to set up webpack, because the structure is a bit different in the
server
repository than it would be for a simple app, but it’s do-able.
It feels like a lot less code to interface with the sidebar component than it used to be…
That’s really helpful!
One more question that came up just now: How do I implement the previous
canDisplay
method?
It seems like there’s a
isEnabled
method that is being called on the component, but if I pass it as a prop to the component for me it’s not being executed. How does this work?
* 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
constructor(id, component, enabled = () => true, legacy) {
@skjnldsv
Cool, thanks, I wasn’t realizing that this would be done through the constructor. I’ll check it out. My issue is more that it requires async operations for this app (to load app settings). So I’ll probably stick with the current solution: Having the tab be always enabled and then show a helpful message when the app is not active in that folder.
Quick question at the end: Will this change be breaking? So I need to refactor the Vue component again?
– Thomas
te-online:
Quick question at the end: Will this change be breaking? So I need to refactor the Vue component again?
Yes, but the change is very simple.
You can check it out
Move Files Sidebar to proper javascript standard · nextcloud/server@843d799 · GitHub
Feat/files sidebar cleanup standards by skjnldsv · Pull Request #23164 · nextcloud/server · GitHub
github.com/nextcloud/server
Long time needed! Before it gets too messy, let's do this!
- This move the Vu
…
e requirement and allow any javascript to register a Tab. With this PR we can now have React Tabs for example! :rocket:
- The migration of existing tabs isn't too complicated (see Sharing Tab)
- This also remove any dependency between the Sidebar and the Tab, before any library used my the Tab needed to be registered at the Sidebar level. Making it absolutely counter-intuitive and badly implemented.
![Capture d’écran_2020-10-04_01-24-35](https://user-images.githubusercontent.com/14975046/95003528-7f362480-05e0-11eb-812d-6c781cbe2485.png)
![Capture d’écran_2020-10-04_01-25-09](https://user-images.githubusercontent.com/14975046/95003529-7fcebb00-05e0-11eb-83fc-4465bea7a332.png)
```js
* Create a new tab instance
* @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.mount function to mount the tab
* @param {Function} options.update function to update the tab
* @param {Function} options.destroy function to destroy the tab
* @param {Function} [options.enabled] define conditions whether this tab is active. Must returns a boolean
constructor({ id, name, icon, mount, update, destroy, enabled } = {}) {