From 47b3fbc9da0a10ad457c20961edfde8249158100 Mon Sep 17 00:00:00 2001 From: Sebastian Date: Wed, 6 May 2026 12:21:23 -0400 Subject: [PATCH] feat: collection move Signed-off-by: Sebastian --- src/components/FolderPageView.vue | 29 ++++++++ src/components/FolderSelectionDialog.vue | 15 ++-- src/components/FolderSelectionTreeNode.vue | 8 ++ src/components/FolderTree.vue | 87 ++++++++++++++++++++++ src/components/FolderTreeNode.vue | 14 ++++ src/components/FolderTreeView.vue | 5 +- 6 files changed, 148 insertions(+), 10 deletions(-) diff --git a/src/components/FolderPageView.vue b/src/components/FolderPageView.vue index 03b04bd..891393b 100644 --- a/src/components/FolderPageView.vue +++ b/src/components/FolderPageView.vue @@ -23,6 +23,7 @@ const emit = defineEmits<{ select: [folder: CollectionObject] createFolder: [service: ServiceObject, parentFolder: CollectionObject | null] editFolder: [service: ServiceObject, folder: CollectionObject] + moveFolder: [service: ServiceObject, folder: CollectionObject] deleteFolder: [service: ServiceObject, folder: CollectionObject] }>() @@ -43,6 +44,10 @@ const getCurrentPageLevel = (service: ServiceObject): (string | number | null)[] // Get folders for current page level const getCurrentPageFolders = (service: ServiceObject): CollectionObject[] => { + if (service.identifier === null) { + return [] + } + const level = getCurrentPageLevel(service) const currentParent = level[level.length - 1] return collectionsStore.collectionsInCollection(service.provider, service.identifier, currentParent) @@ -54,6 +59,10 @@ const hasChildren = (folder: CollectionObject): boolean => { } const getServiceFolders = (service: ServiceObject): CollectionObject[] => { + if (service.identifier === null) { + return [] + } + return collectionsStore.collectionsForService(service.provider, service.identifier) } @@ -132,6 +141,10 @@ const navigateBack = (service: ServiceObject) => { // Get breadcrumb label for current page const getCurrentBreadcrumb = (service: ServiceObject): string => { + if (service.identifier === null) { + return 'Folders' + } + const level = getCurrentPageLevel(service) const currentParent = level[level.length - 1] if (currentParent === null) return 'All Folders' @@ -148,6 +161,10 @@ const getCurrentBreadcrumb = (service: ServiceObject): string => { // Get current parent folder for dialog context const getCurrentParentFolder = (service: ServiceObject): CollectionObject | null => { + if (service.identifier === null) { + return null + } + const level = getCurrentPageLevel(service) const currentParent = level[level.length - 1] if (currentParent === null) return null @@ -276,6 +293,12 @@ const getCurrentParentFolder = (service: ServiceObject): CollectionObject | null > New Subfolder + + Move Folder + New Subfolder + + Move Folder + import { computed, ref, watch } from 'vue' import { useCollectionsStore } from '@MailManager/stores/collectionsStore' -import { useServicesStore } from '@MailManager/stores/servicesStore' import { useMailStore } from '@/stores/mailStore' import type { ServiceObject, CollectionObject } from '@MailManager/models' import FolderSelectionTreeNode from './FolderSelectionTreeNode.vue' @@ -12,6 +11,8 @@ interface Props { title?: string confirmText?: string emptyText?: string + service?: ServiceObject | null + disabledFolderKeys?: string[] } const props = withDefaults(defineProps(), { @@ -19,6 +20,8 @@ const props = withDefaults(defineProps(), { title: 'Move To', confirmText: 'Move', emptyText: 'No folders are available.', + service: null, + disabledFolderKeys: () => [], }) const emit = defineEmits<{ @@ -28,7 +31,6 @@ const emit = defineEmits<{ }>() const collectionsStore = useCollectionsStore() -const servicesStore = useServicesStore() const mailStore = useMailStore() const selectedFolderKey = ref(null) @@ -50,13 +52,7 @@ interface ServiceGroup { } const serviceGroups = computed(() => { - const context = mailStore.moveDialogService - - if (!context) { - return [] - } - - const service = servicesStore.serviceByIdentifier(mailStore.moveDialogService) + const service = props.service ?? mailStore.moveDialogService if (!service) { return [] @@ -173,6 +169,7 @@ const handleConfirm = () => { :folder="folder" :service="group.service" :selected-folder-key="selectedFolderKey" + :disabled-folder-keys="disabledFolderKeys" @select="handleSelect" /> diff --git a/src/components/FolderSelectionTreeNode.vue b/src/components/FolderSelectionTreeNode.vue index 0a0aeb7..799d37e 100644 --- a/src/components/FolderSelectionTreeNode.vue +++ b/src/components/FolderSelectionTreeNode.vue @@ -8,6 +8,7 @@ interface Props { folder: CollectionObject service: ServiceObject selectedFolderKey: string | null + disabledFolderKeys?: string[] } const props = defineProps() @@ -66,6 +67,7 @@ const folderColorFor = (folder: CollectionObject): string | undefined => { } const key = computed(() => folderKeyFor(props.folder)) +const isDisabled = computed(() => (props.disabledFolderKeys ?? []).includes(key.value)) const childFolders = computed(() => { const serviceIdentifier = props.service.identifier @@ -89,6 +91,10 @@ const hasChildren = computed(() => { const isSelected = computed(() => props.selectedFolderKey === key.value) const onSelect = () => { + if (isDisabled.value) { + return + } + emit('select', props.folder) } @@ -111,6 +117,7 @@ const onGroupDoubleClick = () => { class="folder-node" :title="folderLabelFor(folder)" :active="isSelected" + :disabled="isDisabled" @click="onSelect" @dblclick.stop="onGroupDoubleClick" > @@ -152,6 +159,7 @@ const onGroupDoubleClick = () => { class="folder-node" :title="folderLabelFor(folder)" :active="isSelected" + :disabled="isDisabled" @click="onSelect" >