Skip to content

Commit 97dbd3d

Browse files
susnuxnextcloud-command
authored andcommitted
chore: update @nextcloud/files to v4.0.0-rc.0
- update library - adjust sidebar tab handling Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent c9a7654 commit 97dbd3d

File tree

13 files changed

+91
-118
lines changed

13 files changed

+91
-118
lines changed

apps/comments/src/files-sidebar.ts

Lines changed: 14 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { t } from '@nextcloud/l10n'
1111
import wrap from '@vue/web-component-wrapper'
1212
import { createPinia, PiniaVuePlugin } from 'pinia'
1313
import Vue from 'vue'
14-
import FilesSidebarTab from './views/FilesSidebarTab.vue'
1514
import { registerCommentsPlugins } from './comments-activity-tab.ts'
1615

1716
__webpack_nonce__ = getCSPNonce()
@@ -30,28 +29,20 @@ if (loadState('comments', 'activityEnabled', false) && OCA?.Activity?.registerSi
3029
iconSvgInline: MessageReplyText,
3130
order: 50,
3231
tagName,
33-
enabled() {
34-
if (!window.customElements.get(tagName)) {
35-
setupSidebarTab()
36-
}
37-
return true
38-
},
39-
})
40-
}
32+
async onInit() {
33+
const { default: FilesSidebarTab } = await import('./views/FilesSidebarTab.vue')
4134

42-
/**
43-
* Setup the sidebar tab as a web component
44-
*/
45-
function setupSidebarTab() {
46-
Vue.use(PiniaVuePlugin)
47-
Vue.mixin({ pinia: createPinia() })
48-
const webComponent = wrap(Vue, FilesSidebarTab)
49-
// In Vue 2, wrap doesn't support disabling shadow. Disable with a hack
50-
Object.defineProperty(webComponent.prototype, 'attachShadow', {
51-
value() { return this },
52-
})
53-
Object.defineProperty(webComponent.prototype, 'shadowRoot', {
54-
get() { return this },
35+
Vue.use(PiniaVuePlugin)
36+
Vue.mixin({ pinia: createPinia() })
37+
const webComponent = wrap(Vue, FilesSidebarTab)
38+
// In Vue 2, wrap doesn't support disabling shadow. Disable with a hack
39+
Object.defineProperty(webComponent.prototype, 'attachShadow', {
40+
value() { return this },
41+
})
42+
Object.defineProperty(webComponent.prototype, 'shadowRoot', {
43+
get() { return this },
44+
})
45+
window.customElements.define(tagName, webComponent)
46+
},
5547
})
56-
window.customElements.define(tagName, webComponent)
5748
}

apps/comments/src/views/FilesSidebarTab.vue

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,24 +11,16 @@ import Comments from './Comments.vue'
1111
1212
const props = defineProps<{
1313
node?: INode
14+
15+
// eslint-disable-next-line vue/no-unused-properties -- Required on the web component interface
16+
active?: boolean
1417
// eslint-disable-next-line vue/no-unused-properties -- Required on the web component interface
1518
folder?: IFolder
1619
// eslint-disable-next-line vue/no-unused-properties -- Required on the web component interface
1720
view?: IView
1821
}>()
1922
20-
defineExpose({ setActive })
21-
2223
const resourceId = computed(() => props.node?.fileid)
23-
24-
/**
25-
* Set this tab as active
26-
*
27-
* @param active - The active state
28-
*/
29-
function setActive(active: boolean) {
30-
return active
31-
}
3224
</script>
3325

3426
<template>

apps/files/src/components/FilesSidebar/FilesSidebarTab.vue

Lines changed: 26 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,13 @@
44
-->
55

66
<script setup lang="ts">
7-
import type { ISidebarTab, SidebarComponent } from '@nextcloud/files'
7+
import type { ISidebarTab } from '@nextcloud/files'
88
99
import { NcIconSvgWrapper, NcLoadingIcon } from '@nextcloud/vue'
10-
import { ref, toRef, watch, watchEffect } from 'vue'
10+
import { ref, toRef, watch } from 'vue'
1111
import NcAppSidebarTab from '@nextcloud/vue/components/NcAppSidebarTab'
1212
import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
13+
import logger from '../../logger.ts'
1314
import { useActiveStore } from '../../store/active.ts'
1415
import { useSidebarStore } from '../../store/sidebar.ts'
1516
@@ -29,19 +30,31 @@ const sidebar = useSidebarStore()
2930
const activeStore = useActiveStore()
3031
3132
const loading = ref(true)
32-
watch(toRef(props, 'tab'), async () => {
33+
watch(toRef(props, 'active'), async (active) => {
34+
if (!active) {
35+
return
36+
}
37+
38+
logger.debug('sidebar: activating files sidebar tab ' + props.tab.id, { tab: props.tab })
3339
loading.value = true
34-
await window.customElements.whenDefined(props.tab.tagName)
35-
loading.value = false
40+
try {
41+
if (!initializedTabs.has(props.tab.tagName)) {
42+
initializedTabs.add(props.tab.tagName)
43+
logger.debug('sidebar: initializing ' + props.tab.id)
44+
await props.tab.onInit?.()
45+
}
46+
logger.debug('sidebar: waiting for sidebar tab component becoming defined ' + props.tab.id)
47+
await window.customElements.whenDefined(props.tab.tagName)
48+
logger.debug('sidebar: tab component defined and loaded ' + props.tab.id)
49+
loading.value = false
50+
} catch (error) {
51+
logger.error('Failed to get sidebar tab web component', { error })
52+
}
3653
}, { immediate: true })
54+
</script>
3755

38-
const tabElement = ref<SidebarComponent>()
39-
watchEffect(async () => {
40-
if (tabElement.value) {
41-
// Mark as active
42-
await tabElement.value.setActive?.(props.active)
43-
}
44-
})
56+
<script lang="ts">
57+
const initializedTabs = new Set<string>()
4558
</script>
4659

4760
<template>
@@ -61,7 +74,7 @@ watchEffect(async () => {
6174
<component
6275
:is="tab.tagName"
6376
v-else
64-
ref="tabElement"
77+
:active.prop="active"
6578
:node.prop="sidebar.currentNode"
6679
:folder.prop="activeStore.activeFolder"
6780
:view.prop="activeStore.activeView" />

apps/files/src/store/sidebar.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export const useSidebarStore = defineStore('sidebar', () => {
8383
function getTabs(context?: ISidebarContext) {
8484
let tabs = getSidebarTabs()
8585
if (context) {
86-
tabs = tabs.filter((tab) => tab.enabled(context))
86+
tabs = tabs.filter((tab) => tab.enabled === undefined || tab.enabled(context))
8787
}
8888
return tabs.sort((a, b) => a.order - b.order)
8989
}
@@ -97,7 +97,7 @@ export const useSidebarStore = defineStore('sidebar', () => {
9797
function getActions(context?: ISidebarContext) {
9898
let actions = getSidebarActions()
9999
if (context) {
100-
actions = actions.filter((tab) => tab.enabled(context))
100+
actions = actions.filter((action) => action.enabled === undefined || action.enabled(context))
101101
}
102102
return actions.sort((a, b) => a.order - b.order)
103103
}

apps/files_sharing/src/files_sharing_tab.js renamed to apps/files_sharing/src/files-sidebar.ts

Lines changed: 16 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,10 @@
55

66
import ShareVariant from '@mdi/svg/svg/share-variant.svg?raw'
77
import { getCSPNonce } from '@nextcloud/auth'
8-
import { registerSidebarTab } from '@nextcloud/files'
8+
import { getSidebar } from '@nextcloud/files'
99
import { n, t } from '@nextcloud/l10n'
1010
import wrap from '@vue/web-component-wrapper'
1111
import Vue from 'vue'
12-
import FilesSidebarTab from './views/FilesSidebarTab.vue'
1312
import ExternalShareActions from './services/ExternalShareActions.js'
1413
import ShareSearch from './services/ShareSearch.js'
1514
import TabSections from './services/TabSections.js'
@@ -27,32 +26,25 @@ Vue.prototype.n = n
2726

2827
const tagName = 'files_sharing-sidebar-tab'
2928

30-
registerSidebarTab({
29+
getSidebar().registerTab({
3130
id: 'sharing',
3231
displayName: t('files_sharing', 'Sharing'),
3332
iconSvgInline: ShareVariant,
3433
order: 10,
3534
tagName,
36-
enabled() {
37-
if (!window.customElements.get(tagName)) {
38-
setupSidebarTab()
39-
}
40-
return true
35+
36+
async onInit() {
37+
const { default: FilesSidebarTab } = await import('./views/FilesSidebarTab.vue')
38+
39+
const webComponent = wrap(Vue, FilesSidebarTab)
40+
// In Vue 2, wrap doesn't support diseabling shadow. Disable with a hack
41+
Object.defineProperty(webComponent.prototype, 'attachShadow', {
42+
value() { return this },
43+
})
44+
Object.defineProperty(webComponent.prototype, 'shadowRoot', {
45+
get() { return this },
46+
})
47+
48+
window.customElements.define(tagName, webComponent)
4149
},
4250
})
43-
44-
/**
45-
* Setup the sidebar tab as a web component
46-
*/
47-
function setupSidebarTab() {
48-
const webComponent = wrap(Vue, FilesSidebarTab)
49-
// In Vue 2, wrap doesn't support diseabling shadow. Disable with a hack
50-
Object.defineProperty(webComponent.prototype, 'attachShadow', {
51-
value() { return this },
52-
})
53-
Object.defineProperty(webComponent.prototype, 'shadowRoot', {
54-
get() { return this },
55-
})
56-
57-
window.customElements.define(tagName, webComponent)
58-
}

apps/files_sharing/src/views/FilesSidebarTab.vue

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ import FileInfo from '../services/FileInfo.ts'
1212
1313
const props = defineProps<{
1414
node?: INode
15+
16+
// eslint-disable-next-line vue/no-unused-properties -- Required on the web component interface
17+
active?: boolean
1518
// eslint-disable-next-line vue/no-unused-properties -- Required on the web component interface
1619
folder?: IFolder
1720
// eslint-disable-next-line vue/no-unused-properties -- Required on the web component interface

apps/files_versions/src/sidebar_tab.ts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ import { isPublicShare } from '@nextcloud/sharing/public'
1010
import { defineAsyncComponent, defineCustomElement } from 'vue'
1111

1212
const tagName = 'files-versions_sidebar-tab'
13-
const FilesVersionsSidebarTab = defineAsyncComponent(() => import('./views/FilesVersionsSidebarTab.vue'))
1413

1514
registerSidebarTab({
1615
id: 'files_versions',
16+
tagName,
1717
order: 90,
1818
displayName: t('files_versions', 'Versions'),
1919
iconSvgInline: BackupRestore,
@@ -24,23 +24,13 @@ registerSidebarTab({
2424
if (node.type !== FileType.File) {
2525
return false
2626
}
27-
// setup tab
28-
setupTab()
2927
return true
3028
},
31-
tagName,
32-
})
3329

34-
/**
35-
* Setup the custom element for the Files Versions sidebar tab.
36-
*/
37-
function setupTab() {
38-
if (window.customElements.get(tagName)) {
39-
// already defined
40-
return
41-
}
42-
43-
window.customElements.define(tagName, defineCustomElement(FilesVersionsSidebarTab, {
44-
shadowRoot: false,
45-
}))
46-
}
30+
async onInit() {
31+
const FilesVersionsSidebarTab = defineAsyncComponent(() => import('./views/FilesVersionsSidebarTab.vue'))
32+
window.customElements.define(tagName, defineCustomElement(FilesVersionsSidebarTab, {
33+
shadowRoot: false,
34+
}))
35+
},
36+
})

apps/files_versions/src/views/FilesVersionsSidebarTab.vue

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
:key="row.items[0].version.mtime"
1616
:can-view="canView"
1717
:can-compare="canCompare"
18-
:load-preview="isActive"
18+
:load-preview="active"
1919
:version="row.items[0].version"
2020
:node="node"
2121
:is-current="row.items[0].version.mtime === currentVersionMtime"
@@ -57,15 +57,16 @@ import logger from '../utils/logger.ts'
5757
import { deleteVersion, fetchVersions, restoreVersion, setVersionLabel } from '../utils/versions.ts'
5858
5959
const props = defineProps<{
60-
node?: INode
61-
folder?: IFolder
62-
view?: IView
63-
}>()
60+
active: boolean
61+
node: INode
6462
65-
defineExpose({ setActive })
63+
// eslint-disable-next-line vue/no-unused-properties -- required by SidebarTab but we do not need it
64+
folder: IFolder
65+
// eslint-disable-next-line vue/no-unused-properties -- required by SidebarTab but we do not need it
66+
view: IView
67+
}>()
6668
6769
const isMobile = useIsMobile()
68-
const isActive = ref<boolean>(false)
6970
const versions = ref<Version[]>([])
7071
const loading = ref(false)
7172
const showVersionLabelForm = ref(false)
@@ -138,15 +139,6 @@ const canCompare = computed(() => {
138139
&& window.OCA.Viewer?.mimetypesCompare?.includes(props.node?.mime)
139140
})
140141
141-
/**
142-
* This method is called by the files app if the sidebar tab state changes.
143-
*
144-
* @param active - The new active state
145-
*/
146-
function setActive(active: boolean) {
147-
isActive.value = active
148-
}
149-
150142
/**
151143
* Handle restored event from Version.vue
152144
*

build/frontend-legacy/package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

build/frontend-legacy/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
"@nextcloud/capabilities": "^1.2.1",
3636
"@nextcloud/dialogs": "^7.1.0",
3737
"@nextcloud/event-bus": "^3.3.3",
38-
"@nextcloud/files": "^4.0.0-beta.9",
38+
"@nextcloud/files": "^4.0.0-rc.0",
3939
"@nextcloud/initial-state": "^3.0.0",
4040
"@nextcloud/l10n": "^3.4.1",
4141
"@nextcloud/logger": "^3.0.3",

0 commit comments

Comments
 (0)