mirror of
https://github.com/nextcloud/server.git
synced 2026-06-11 01:30:50 -04:00
fix(files): make sure nested changes are propagated to sidebar tabs
If an object is passed from one app to another app through a web component, then only reference changes (new objects) are marked as reactive changes in the receiving app. In this case e.g. `mtime` changes were not properly propagated, so to fix this we explicitly clone the objects before passing to the sidebar tab. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
This commit is contained in:
parent
e01a54c53a
commit
9fdd019ed3
3 changed files with 45 additions and 22 deletions
|
|
@ -7,10 +7,9 @@
|
|||
import type { ISidebarTab } from '@nextcloud/files'
|
||||
|
||||
import { NcIconSvgWrapper, NcLoadingIcon } from '@nextcloud/vue'
|
||||
import { ref, toRef, watch } from 'vue'
|
||||
import { computed, ref, toRef, watch } from 'vue'
|
||||
import NcAppSidebarTab from '@nextcloud/vue/components/NcAppSidebarTab'
|
||||
import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'
|
||||
import { useActiveStore } from '../../store/active.ts'
|
||||
import { useSidebarStore } from '../../store/sidebar.ts'
|
||||
import { logger } from '../../utils/logger.ts'
|
||||
|
||||
|
|
@ -27,7 +26,17 @@ const props = defineProps<{
|
|||
}>()
|
||||
|
||||
const sidebar = useSidebarStore()
|
||||
const activeStore = useActiveStore()
|
||||
|
||||
const context = computed(() => {
|
||||
if (!sidebar.currentContext) {
|
||||
return undefined
|
||||
}
|
||||
return {
|
||||
folder: sidebar.currentContext.folder.clone(),
|
||||
node: sidebar.currentContext.node.clone(),
|
||||
view: sidebar.currentContext.view,
|
||||
}
|
||||
})
|
||||
|
||||
const loading = ref(true)
|
||||
watch(toRef(props, 'active'), async (active) => {
|
||||
|
|
@ -65,7 +74,7 @@ const initializedTabs = new Set<string>()
|
|||
<template #icon>
|
||||
<NcIconSvgWrapper :svg="tab.iconSvgInline" />
|
||||
</template>
|
||||
<NcEmptyContent v-if="loading">
|
||||
<NcEmptyContent v-if="loading || !context">
|
||||
<template #icon>
|
||||
<NcLoadingIcon />
|
||||
</template>
|
||||
|
|
@ -75,8 +84,8 @@ const initializedTabs = new Set<string>()
|
|||
:is="tab.tagName"
|
||||
v-else
|
||||
:active.prop="active"
|
||||
:node.prop="sidebar.currentNode"
|
||||
:folder.prop="activeStore.activeFolder"
|
||||
:view.prop="activeStore.activeView" />
|
||||
:node.prop="context.node"
|
||||
:folder.prop="context.folder"
|
||||
:view.prop="context.view" />
|
||||
</NcAppSidebarTab>
|
||||
</template>
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import { defineStore } from 'pinia'
|
|||
import Vue, { ref } from 'vue'
|
||||
import { fetchNode } from '../services/WebdavClient.ts'
|
||||
import { logger } from '../utils/logger.ts'
|
||||
import { useActiveStore } from './active.ts'
|
||||
import { usePathsStore } from './paths.ts'
|
||||
|
||||
/**
|
||||
|
|
@ -124,6 +125,12 @@ export const useFilesStore = defineStore('files', () => {
|
|||
}, {} as FilesStore)
|
||||
|
||||
files.value = { ...files.value, ...newNodes }
|
||||
|
||||
// handle updating the active node
|
||||
const activeStore = useActiveStore()
|
||||
if (activeStore.activeNode && activeStore.activeNode.source in newNodes) {
|
||||
activeStore.activeNode = files.value[activeStore.activeNode.source]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -232,7 +239,8 @@ export const useFilesStore = defineStore('files', () => {
|
|||
}
|
||||
|
||||
// Otherwise, it means we receive an event for a node that is not in the store
|
||||
fetchNode(node.path).then((n) => updateNodes([n]))
|
||||
const newNode = await fetchNode(node.path)
|
||||
updateNodes([newNode])
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -48,7 +48,8 @@ import { showError, showSuccess } from '@nextcloud/dialogs'
|
|||
import { emit } from '@nextcloud/event-bus'
|
||||
import { t } from '@nextcloud/l10n'
|
||||
import { useIsMobile } from '@nextcloud/vue/composables/useIsMobile'
|
||||
import { computed, ref, toRef, watch } from 'vue'
|
||||
import { watchDebounced } from '@vueuse/core'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
import NcLoadingIcon from '@nextcloud/vue/components/NcLoadingIcon'
|
||||
import VersionEntry from '../components/VersionEntry.vue'
|
||||
import VersionLabelDialog from '../components/VersionLabelDialog.vue'
|
||||
|
|
@ -72,19 +73,6 @@ const loading = ref(false)
|
|||
const showVersionLabelForm = ref(false)
|
||||
const editedVersion = ref<Version | null>(null)
|
||||
|
||||
watch(toRef(() => props.node), async () => {
|
||||
if (!props.node) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
loading.value = true
|
||||
versions.value = await fetchVersions(props.node)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}, { immediate: true })
|
||||
|
||||
const currentVersionMtime = computed(() => props.node?.mtime?.getTime() ?? 0)
|
||||
|
||||
/**
|
||||
|
|
@ -139,6 +127,24 @@ const canCompare = computed(() => {
|
|||
&& window.OCA.Viewer?.mimetypesCompare?.includes(props.node?.mime)
|
||||
})
|
||||
|
||||
// When either the current node to show or its mtime changes we need to refetch the versions
|
||||
// When the id changed we immediately show changes
|
||||
watch(() => props.node.id, loadVersions, { immediate: true })
|
||||
// On mtime changes we debounce to prevent too many requests.
|
||||
watchDebounced(currentVersionMtime, loadVersions, { debounce: 600 })
|
||||
|
||||
/**
|
||||
* Load versions for the current node
|
||||
*/
|
||||
async function loadVersions() {
|
||||
try {
|
||||
loading.value = true
|
||||
versions.value = await fetchVersions(props.node)
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle restored event from Version.vue
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in a new issue