Merge pull request 'feat: collection move' (#19) from feat/collection-move into main
Reviewed-on: #19
This commit was merged in pull request #19.
This commit is contained in:
@@ -23,6 +23,7 @@ const emit = defineEmits<{
|
|||||||
select: [folder: CollectionObject]
|
select: [folder: CollectionObject]
|
||||||
createFolder: [service: ServiceObject, parentFolder: CollectionObject | null]
|
createFolder: [service: ServiceObject, parentFolder: CollectionObject | null]
|
||||||
editFolder: [service: ServiceObject, folder: CollectionObject]
|
editFolder: [service: ServiceObject, folder: CollectionObject]
|
||||||
|
moveFolder: [service: ServiceObject, folder: CollectionObject]
|
||||||
deleteFolder: [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
|
// Get folders for current page level
|
||||||
const getCurrentPageFolders = (service: ServiceObject): CollectionObject[] => {
|
const getCurrentPageFolders = (service: ServiceObject): CollectionObject[] => {
|
||||||
|
if (service.identifier === null) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
const level = getCurrentPageLevel(service)
|
const level = getCurrentPageLevel(service)
|
||||||
const currentParent = level[level.length - 1]
|
const currentParent = level[level.length - 1]
|
||||||
return collectionsStore.collectionsInCollection(service.provider, service.identifier, currentParent)
|
return collectionsStore.collectionsInCollection(service.provider, service.identifier, currentParent)
|
||||||
@@ -54,6 +59,10 @@ const hasChildren = (folder: CollectionObject): boolean => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const getServiceFolders = (service: ServiceObject): CollectionObject[] => {
|
const getServiceFolders = (service: ServiceObject): CollectionObject[] => {
|
||||||
|
if (service.identifier === null) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
return collectionsStore.collectionsForService(service.provider, service.identifier)
|
return collectionsStore.collectionsForService(service.provider, service.identifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +141,10 @@ const navigateBack = (service: ServiceObject) => {
|
|||||||
|
|
||||||
// Get breadcrumb label for current page
|
// Get breadcrumb label for current page
|
||||||
const getCurrentBreadcrumb = (service: ServiceObject): string => {
|
const getCurrentBreadcrumb = (service: ServiceObject): string => {
|
||||||
|
if (service.identifier === null) {
|
||||||
|
return 'Folders'
|
||||||
|
}
|
||||||
|
|
||||||
const level = getCurrentPageLevel(service)
|
const level = getCurrentPageLevel(service)
|
||||||
const currentParent = level[level.length - 1]
|
const currentParent = level[level.length - 1]
|
||||||
if (currentParent === null) return 'All Folders'
|
if (currentParent === null) return 'All Folders'
|
||||||
@@ -148,6 +161,10 @@ const getCurrentBreadcrumb = (service: ServiceObject): string => {
|
|||||||
|
|
||||||
// Get current parent folder for dialog context
|
// Get current parent folder for dialog context
|
||||||
const getCurrentParentFolder = (service: ServiceObject): CollectionObject | null => {
|
const getCurrentParentFolder = (service: ServiceObject): CollectionObject | null => {
|
||||||
|
if (service.identifier === null) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const level = getCurrentPageLevel(service)
|
const level = getCurrentPageLevel(service)
|
||||||
const currentParent = level[level.length - 1]
|
const currentParent = level[level.length - 1]
|
||||||
if (currentParent === null) return null
|
if (currentParent === null) return null
|
||||||
@@ -276,6 +293,12 @@ const getCurrentParentFolder = (service: ServiceObject): CollectionObject | null
|
|||||||
>
|
>
|
||||||
<v-list-item-title>New Subfolder</v-list-item-title>
|
<v-list-item-title>New Subfolder</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
<v-list-item
|
||||||
|
prepend-icon="mdi-folder-move"
|
||||||
|
@click="emit('moveFolder', group.service, folder)"
|
||||||
|
>
|
||||||
|
<v-list-item-title>Move Folder</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
<v-list-item
|
<v-list-item
|
||||||
v-if="canDeleteFolder(folder)"
|
v-if="canDeleteFolder(folder)"
|
||||||
prepend-icon="mdi-delete"
|
prepend-icon="mdi-delete"
|
||||||
@@ -433,6 +456,12 @@ const getCurrentParentFolder = (service: ServiceObject): CollectionObject | null
|
|||||||
>
|
>
|
||||||
<v-list-item-title>New Subfolder</v-list-item-title>
|
<v-list-item-title>New Subfolder</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
<v-list-item
|
||||||
|
prepend-icon="mdi-folder-move"
|
||||||
|
@click="emit('moveFolder', group.service, folder)"
|
||||||
|
>
|
||||||
|
<v-list-item-title>Move Folder</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
<v-list-item
|
<v-list-item
|
||||||
v-if="canDeleteFolder(folder)"
|
v-if="canDeleteFolder(folder)"
|
||||||
prepend-icon="mdi-delete"
|
prepend-icon="mdi-delete"
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref, watch } from 'vue'
|
import { computed, ref, watch } from 'vue'
|
||||||
import { useCollectionsStore } from '@MailManager/stores/collectionsStore'
|
import { useCollectionsStore } from '@MailManager/stores/collectionsStore'
|
||||||
import { useServicesStore } from '@MailManager/stores/servicesStore'
|
|
||||||
import { useMailStore } from '@/stores/mailStore'
|
import { useMailStore } from '@/stores/mailStore'
|
||||||
import type { ServiceObject, CollectionObject } from '@MailManager/models'
|
import type { ServiceObject, CollectionObject } from '@MailManager/models'
|
||||||
import FolderSelectionTreeNode from './FolderSelectionTreeNode.vue'
|
import FolderSelectionTreeNode from './FolderSelectionTreeNode.vue'
|
||||||
@@ -12,6 +11,8 @@ interface Props {
|
|||||||
title?: string
|
title?: string
|
||||||
confirmText?: string
|
confirmText?: string
|
||||||
emptyText?: string
|
emptyText?: string
|
||||||
|
service?: ServiceObject | null
|
||||||
|
disabledFolderKeys?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = withDefaults(defineProps<Props>(), {
|
const props = withDefaults(defineProps<Props>(), {
|
||||||
@@ -19,6 +20,8 @@ const props = withDefaults(defineProps<Props>(), {
|
|||||||
title: 'Move To',
|
title: 'Move To',
|
||||||
confirmText: 'Move',
|
confirmText: 'Move',
|
||||||
emptyText: 'No folders are available.',
|
emptyText: 'No folders are available.',
|
||||||
|
service: null,
|
||||||
|
disabledFolderKeys: () => [],
|
||||||
})
|
})
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
@@ -28,7 +31,6 @@ const emit = defineEmits<{
|
|||||||
}>()
|
}>()
|
||||||
|
|
||||||
const collectionsStore = useCollectionsStore()
|
const collectionsStore = useCollectionsStore()
|
||||||
const servicesStore = useServicesStore()
|
|
||||||
const mailStore = useMailStore()
|
const mailStore = useMailStore()
|
||||||
|
|
||||||
const selectedFolderKey = ref<string | null>(null)
|
const selectedFolderKey = ref<string | null>(null)
|
||||||
@@ -50,13 +52,7 @@ interface ServiceGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const serviceGroups = computed<ServiceGroup[]>(() => {
|
const serviceGroups = computed<ServiceGroup[]>(() => {
|
||||||
const context = mailStore.moveDialogService
|
const service = props.service ?? mailStore.moveDialogService
|
||||||
|
|
||||||
if (!context) {
|
|
||||||
return []
|
|
||||||
}
|
|
||||||
|
|
||||||
const service = servicesStore.serviceByIdentifier(mailStore.moveDialogService)
|
|
||||||
|
|
||||||
if (!service) {
|
if (!service) {
|
||||||
return []
|
return []
|
||||||
@@ -173,6 +169,7 @@ const handleConfirm = () => {
|
|||||||
:folder="folder"
|
:folder="folder"
|
||||||
:service="group.service"
|
:service="group.service"
|
||||||
:selected-folder-key="selectedFolderKey"
|
:selected-folder-key="selectedFolderKey"
|
||||||
|
:disabled-folder-keys="disabledFolderKeys"
|
||||||
@select="handleSelect"
|
@select="handleSelect"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ interface Props {
|
|||||||
folder: CollectionObject
|
folder: CollectionObject
|
||||||
service: ServiceObject
|
service: ServiceObject
|
||||||
selectedFolderKey: string | null
|
selectedFolderKey: string | null
|
||||||
|
disabledFolderKeys?: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
const props = defineProps<Props>()
|
||||||
@@ -66,6 +67,7 @@ const folderColorFor = (folder: CollectionObject): string | undefined => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const key = computed(() => folderKeyFor(props.folder))
|
const key = computed(() => folderKeyFor(props.folder))
|
||||||
|
const isDisabled = computed(() => (props.disabledFolderKeys ?? []).includes(key.value))
|
||||||
|
|
||||||
const childFolders = computed(() => {
|
const childFolders = computed(() => {
|
||||||
const serviceIdentifier = props.service.identifier
|
const serviceIdentifier = props.service.identifier
|
||||||
@@ -89,6 +91,10 @@ const hasChildren = computed(() => {
|
|||||||
const isSelected = computed(() => props.selectedFolderKey === key.value)
|
const isSelected = computed(() => props.selectedFolderKey === key.value)
|
||||||
|
|
||||||
const onSelect = () => {
|
const onSelect = () => {
|
||||||
|
if (isDisabled.value) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
emit('select', props.folder)
|
emit('select', props.folder)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,6 +117,7 @@ const onGroupDoubleClick = () => {
|
|||||||
class="folder-node"
|
class="folder-node"
|
||||||
:title="folderLabelFor(folder)"
|
:title="folderLabelFor(folder)"
|
||||||
:active="isSelected"
|
:active="isSelected"
|
||||||
|
:disabled="isDisabled"
|
||||||
@click="onSelect"
|
@click="onSelect"
|
||||||
@dblclick.stop="onGroupDoubleClick"
|
@dblclick.stop="onGroupDoubleClick"
|
||||||
>
|
>
|
||||||
@@ -152,6 +159,7 @@ const onGroupDoubleClick = () => {
|
|||||||
class="folder-node"
|
class="folder-node"
|
||||||
:title="folderLabelFor(folder)"
|
:title="folderLabelFor(folder)"
|
||||||
:active="isSelected"
|
:active="isSelected"
|
||||||
|
:disabled="isDisabled"
|
||||||
@click="onSelect"
|
@click="onSelect"
|
||||||
>
|
>
|
||||||
<template #prepend>
|
<template #prepend>
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import FolderTreeView from './FolderTreeView.vue'
|
|||||||
import FolderPageView from './FolderPageView.vue'
|
import FolderPageView from './FolderPageView.vue'
|
||||||
import CreateFolderDialog from './CreateFolderDialog.vue'
|
import CreateFolderDialog from './CreateFolderDialog.vue'
|
||||||
import DeleteFolderDialog from './DeleteFolderDialog.vue'
|
import DeleteFolderDialog from './DeleteFolderDialog.vue'
|
||||||
|
import FolderSelectionDialog from './FolderSelectionDialog.vue'
|
||||||
import RenameFolderDialog from './RenameFolderDialog.vue'
|
import RenameFolderDialog from './RenameFolderDialog.vue'
|
||||||
import type { CollectionObject } from '@MailManager/models/collection'
|
import type { CollectionObject } from '@MailManager/models/collection'
|
||||||
import type { ServiceObject } from '@MailManager/models'
|
import type { ServiceObject } from '@MailManager/models'
|
||||||
@@ -44,6 +45,9 @@ const createDialogParent = ref<CollectionObject | null>(null)
|
|||||||
const renameDialogVisible = ref(false)
|
const renameDialogVisible = ref(false)
|
||||||
const renameDialogService = ref<ServiceObject | null>(null)
|
const renameDialogService = ref<ServiceObject | null>(null)
|
||||||
const renameDialogFolder = ref<CollectionObject | null>(null)
|
const renameDialogFolder = ref<CollectionObject | null>(null)
|
||||||
|
const moveDialogVisible = ref(false)
|
||||||
|
const moveDialogService = ref<ServiceObject | null>(null)
|
||||||
|
const moveDialogFolder = ref<CollectionObject | null>(null)
|
||||||
const deleteDialogVisible = ref(false)
|
const deleteDialogVisible = ref(false)
|
||||||
const deleteDialogService = ref<ServiceObject | null>(null)
|
const deleteDialogService = ref<ServiceObject | null>(null)
|
||||||
const deleteDialogFolder = ref<CollectionObject | null>(null)
|
const deleteDialogFolder = ref<CollectionObject | null>(null)
|
||||||
@@ -67,6 +71,12 @@ const handleEditFolder = (service: ServiceObject, folder: CollectionObject) => {
|
|||||||
renameDialogVisible.value = true
|
renameDialogVisible.value = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleMoveFolder = (service: ServiceObject, folder: CollectionObject) => {
|
||||||
|
moveDialogService.value = service
|
||||||
|
moveDialogFolder.value = folder
|
||||||
|
moveDialogVisible.value = true
|
||||||
|
}
|
||||||
|
|
||||||
const handleDeleteFolder = (service: ServiceObject, folder: CollectionObject) => {
|
const handleDeleteFolder = (service: ServiceObject, folder: CollectionObject) => {
|
||||||
deleteDialogService.value = service
|
deleteDialogService.value = service
|
||||||
deleteDialogFolder.value = folder
|
deleteDialogFolder.value = folder
|
||||||
@@ -77,6 +87,39 @@ const handleFolderRenamed = (updatedFolder: CollectionObject) => {
|
|||||||
emit('select', updatedFolder)
|
emit('select', updatedFolder)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const folderKeyFor = (folder: CollectionObject): string => {
|
||||||
|
return `${folder.provider}:${String(folder.service)}:${String(folder.identifier)}`
|
||||||
|
}
|
||||||
|
|
||||||
|
const moveDialogInvalidFolderKeys = computed(() => {
|
||||||
|
const sourceFolder = moveDialogFolder.value
|
||||||
|
|
||||||
|
if (!sourceFolder) {
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
|
||||||
|
const invalidKeys = new Set<string>()
|
||||||
|
const queue: CollectionObject[] = [sourceFolder]
|
||||||
|
|
||||||
|
while (queue.length > 0) {
|
||||||
|
const currentFolder = queue.shift()
|
||||||
|
|
||||||
|
if (!currentFolder) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
invalidKeys.add(folderKeyFor(currentFolder))
|
||||||
|
|
||||||
|
collectionsStore
|
||||||
|
.collectionsInCollection(currentFolder.provider, currentFolder.service, currentFolder.identifier)
|
||||||
|
.forEach(childFolder => {
|
||||||
|
queue.push(childFolder)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return Array.from(invalidKeys)
|
||||||
|
})
|
||||||
|
|
||||||
const isSameFolder = (left: CollectionObject | null | undefined, right: CollectionObject | null | undefined) => {
|
const isSameFolder = (left: CollectionObject | null | undefined, right: CollectionObject | null | undefined) => {
|
||||||
if (!left || !right) {
|
if (!left || !right) {
|
||||||
return false
|
return false
|
||||||
@@ -95,6 +138,35 @@ const handleFolderDeleted = (deletedFolder: CollectionObject) => {
|
|||||||
mailStore.notify(`Folder "${deletedFolder.properties.label || String(deletedFolder.identifier)}" deleted`, 'success')
|
mailStore.notify(`Folder "${deletedFolder.properties.label || String(deletedFolder.identifier)}" deleted`, 'success')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const handleMoveDialogCancel = () => {
|
||||||
|
moveDialogVisible.value = false
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFolderMove = async (targetFolder: CollectionObject) => {
|
||||||
|
const sourceFolder = moveDialogFolder.value
|
||||||
|
|
||||||
|
if (!sourceFolder) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const movedFolder = await collectionsStore.move(folderKeyFor(targetFolder), folderKeyFor(sourceFolder))
|
||||||
|
moveDialogVisible.value = false
|
||||||
|
|
||||||
|
if (isSameFolder(props.selectedFolder, sourceFolder)) {
|
||||||
|
emit('select', movedFolder)
|
||||||
|
}
|
||||||
|
|
||||||
|
mailStore.notify(
|
||||||
|
`Folder "${sourceFolder.properties.label || String(sourceFolder.identifier)}" moved to "${targetFolder.properties.label || String(targetFolder.identifier)}"`,
|
||||||
|
'success',
|
||||||
|
)
|
||||||
|
} catch (error: unknown) {
|
||||||
|
console.error('[FolderTree] Failed to move folder:', error)
|
||||||
|
mailStore.notify(error instanceof Error ? error.message : 'Failed to move folder', 'error')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Computed: all folders for validation
|
// Computed: all folders for validation
|
||||||
const allFolders = computed(() =>
|
const allFolders = computed(() =>
|
||||||
servicesStore.servicesEnabled.flatMap(service =>
|
servicesStore.servicesEnabled.flatMap(service =>
|
||||||
@@ -134,6 +206,7 @@ const serviceGroups = computed(() => {
|
|||||||
@select="emit('select', $event)"
|
@select="emit('select', $event)"
|
||||||
@create-folder="handleCreateFolder"
|
@create-folder="handleCreateFolder"
|
||||||
@edit-folder="handleEditFolder"
|
@edit-folder="handleEditFolder"
|
||||||
|
@move-folder="handleMoveFolder"
|
||||||
@delete-folder="handleDeleteFolder"
|
@delete-folder="handleDeleteFolder"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -145,6 +218,7 @@ const serviceGroups = computed(() => {
|
|||||||
@select="emit('select', $event)"
|
@select="emit('select', $event)"
|
||||||
@create-folder="handleCreateFolder"
|
@create-folder="handleCreateFolder"
|
||||||
@edit-folder="handleEditFolder"
|
@edit-folder="handleEditFolder"
|
||||||
|
@move-folder="handleMoveFolder"
|
||||||
@delete-folder="handleDeleteFolder"
|
@delete-folder="handleDeleteFolder"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -175,6 +249,19 @@ const serviceGroups = computed(() => {
|
|||||||
@updated="handleFolderRenamed"
|
@updated="handleFolderRenamed"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<FolderSelectionDialog
|
||||||
|
v-if="moveDialogService && moveDialogFolder"
|
||||||
|
v-model="moveDialogVisible"
|
||||||
|
:service="moveDialogService"
|
||||||
|
:loading="collectionsStore.transceiving"
|
||||||
|
title="Move Folder"
|
||||||
|
confirm-text="Move Folder"
|
||||||
|
empty-text="No valid target folders are available."
|
||||||
|
:disabled-folder-keys="moveDialogInvalidFolderKeys"
|
||||||
|
@cancel="handleMoveDialogCancel"
|
||||||
|
@select="handleFolderMove"
|
||||||
|
/>
|
||||||
|
|
||||||
<DeleteFolderDialog
|
<DeleteFolderDialog
|
||||||
v-if="deleteDialogService && deleteDialogFolder"
|
v-if="deleteDialogService && deleteDialogFolder"
|
||||||
v-model="deleteDialogVisible"
|
v-model="deleteDialogVisible"
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ const emit = defineEmits<{
|
|||||||
select: [folder: CollectionObject]
|
select: [folder: CollectionObject]
|
||||||
createSubfolder: [service: ServiceObject, parentFolder: CollectionObject]
|
createSubfolder: [service: ServiceObject, parentFolder: CollectionObject]
|
||||||
editFolder: [service: ServiceObject, folder: CollectionObject]
|
editFolder: [service: ServiceObject, folder: CollectionObject]
|
||||||
|
moveFolder: [service: ServiceObject, folder: CollectionObject]
|
||||||
deleteFolder: [service: ServiceObject, folder: CollectionObject]
|
deleteFolder: [service: ServiceObject, folder: CollectionObject]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
@@ -140,6 +141,12 @@ const isSelected = (folder: CollectionObject): boolean => {
|
|||||||
>
|
>
|
||||||
<v-list-item-title>New Subfolder</v-list-item-title>
|
<v-list-item-title>New Subfolder</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
<v-list-item
|
||||||
|
prepend-icon="mdi-folder-move"
|
||||||
|
@click="emit('moveFolder', service, folder)"
|
||||||
|
>
|
||||||
|
<v-list-item-title>Move Folder</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
<v-list-item
|
<v-list-item
|
||||||
v-if="canDeleteFolder"
|
v-if="canDeleteFolder"
|
||||||
prepend-icon="mdi-delete"
|
prepend-icon="mdi-delete"
|
||||||
@@ -164,6 +171,7 @@ const isSelected = (folder: CollectionObject): boolean => {
|
|||||||
@select="emit('select', $event)"
|
@select="emit('select', $event)"
|
||||||
@create-subfolder="(service, parentFolder) => emit('createSubfolder', service, parentFolder)"
|
@create-subfolder="(service, parentFolder) => emit('createSubfolder', service, parentFolder)"
|
||||||
@edit-folder="(service, folder) => emit('editFolder', service, folder)"
|
@edit-folder="(service, folder) => emit('editFolder', service, folder)"
|
||||||
|
@move-folder="(service, folder) => emit('moveFolder', service, folder)"
|
||||||
@delete-folder="(service, folder) => emit('deleteFolder', service, folder)"
|
@delete-folder="(service, folder) => emit('deleteFolder', service, folder)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
@@ -219,6 +227,12 @@ const isSelected = (folder: CollectionObject): boolean => {
|
|||||||
>
|
>
|
||||||
<v-list-item-title>New Subfolder</v-list-item-title>
|
<v-list-item-title>New Subfolder</v-list-item-title>
|
||||||
</v-list-item>
|
</v-list-item>
|
||||||
|
<v-list-item
|
||||||
|
prepend-icon="mdi-folder-move"
|
||||||
|
@click="emit('moveFolder', service, folder)"
|
||||||
|
>
|
||||||
|
<v-list-item-title>Move Folder</v-list-item-title>
|
||||||
|
</v-list-item>
|
||||||
<v-list-item
|
<v-list-item
|
||||||
v-if="canDeleteFolder"
|
v-if="canDeleteFolder"
|
||||||
prepend-icon="mdi-delete"
|
prepend-icon="mdi-delete"
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ interface Props {
|
|||||||
}>
|
}>
|
||||||
}
|
}
|
||||||
|
|
||||||
const props = defineProps<Props>()
|
defineProps<Props>()
|
||||||
const collectionsStore = useCollectionsStore()
|
const collectionsStore = useCollectionsStore()
|
||||||
|
|
||||||
// Emits
|
// Emits
|
||||||
@@ -23,6 +23,7 @@ const emit = defineEmits<{
|
|||||||
select: [folder: CollectionObject]
|
select: [folder: CollectionObject]
|
||||||
createFolder: [service: ServiceObject, parentFolder: CollectionObject | null]
|
createFolder: [service: ServiceObject, parentFolder: CollectionObject | null]
|
||||||
editFolder: [service: ServiceObject, folder: CollectionObject]
|
editFolder: [service: ServiceObject, folder: CollectionObject]
|
||||||
|
moveFolder: [service: ServiceObject, folder: CollectionObject]
|
||||||
deleteFolder: [service: ServiceObject, folder: CollectionObject]
|
deleteFolder: [service: ServiceObject, folder: CollectionObject]
|
||||||
}>()
|
}>()
|
||||||
|
|
||||||
@@ -75,6 +76,7 @@ const getServiceFolders = (service: ServiceObject): CollectionObject[] => {
|
|||||||
@select="emit('select', $event)"
|
@select="emit('select', $event)"
|
||||||
@create-subfolder="(service, parentFolder) => emit('createFolder', service, parentFolder)"
|
@create-subfolder="(service, parentFolder) => emit('createFolder', service, parentFolder)"
|
||||||
@edit-folder="(service, folder) => emit('editFolder', service, folder)"
|
@edit-folder="(service, folder) => emit('editFolder', service, folder)"
|
||||||
|
@move-folder="(service, folder) => emit('moveFolder', service, folder)"
|
||||||
@delete-folder="(service, folder) => emit('deleteFolder', service, folder)"
|
@delete-folder="(service, folder) => emit('deleteFolder', service, folder)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@@ -157,6 +159,7 @@ const getServiceFolders = (service: ServiceObject): CollectionObject[] => {
|
|||||||
@select="emit('select', $event)"
|
@select="emit('select', $event)"
|
||||||
@create-subfolder="(service, parentFolder) => emit('createFolder', service, parentFolder)"
|
@create-subfolder="(service, parentFolder) => emit('createFolder', service, parentFolder)"
|
||||||
@edit-folder="(service, folder) => emit('editFolder', service, folder)"
|
@edit-folder="(service, folder) => emit('editFolder', service, folder)"
|
||||||
|
@move-folder="(service, folder) => emit('moveFolder', service, folder)"
|
||||||
@delete-folder="(service, folder) => emit('deleteFolder', service, folder)"
|
@delete-folder="(service, folder) => emit('deleteFolder', service, folder)"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user