@@ -1,32 +1,37 @@
|
||||
<script setup lang="ts">
|
||||
import { useCollectionsStore } from '@MailManager/stores/collectionsStore'
|
||||
import type { CollectionObject } from '@MailManager/models/collection'
|
||||
import type { ServiceInterface } from '@MailManager/types/service'
|
||||
import type { ServiceObject } from '@MailManager/models'
|
||||
import FolderTreeNode from './FolderTreeNode.vue'
|
||||
|
||||
// Folder hierarchy helper type
|
||||
export interface FolderNode {
|
||||
folder: CollectionObject
|
||||
children: FolderNode[]
|
||||
}
|
||||
|
||||
// Props
|
||||
interface Props {
|
||||
selectedFolder?: CollectionObject | null
|
||||
serviceGroups: Array<{
|
||||
service: ServiceInterface
|
||||
folders: CollectionObject[]
|
||||
folderTree: FolderNode[]
|
||||
service: ServiceObject
|
||||
loading: boolean
|
||||
loaded: boolean
|
||||
error: string | null
|
||||
}>
|
||||
}
|
||||
|
||||
const props = defineProps<Props>()
|
||||
const collectionsStore = useCollectionsStore()
|
||||
|
||||
// Emits
|
||||
const emit = defineEmits<{
|
||||
select: [folder: CollectionObject]
|
||||
createFolder: [service: ServiceInterface, parentFolder: CollectionObject | null]
|
||||
editFolder: [service: ServiceInterface, folder: CollectionObject]
|
||||
createFolder: [service: ServiceObject, parentFolder: CollectionObject | null]
|
||||
editFolder: [service: ServiceObject, folder: CollectionObject]
|
||||
}>()
|
||||
|
||||
const getRootFolders = (service: ServiceObject): CollectionObject[] => {
|
||||
return collectionsStore.collectionsInCollection(service.provider, service.identifier, null)
|
||||
}
|
||||
|
||||
const getServiceFolders = (service: ServiceObject): CollectionObject[] => {
|
||||
return collectionsStore.collectionsForService(service.provider, service.identifier)
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -61,19 +66,72 @@ const emit = defineEmits<{
|
||||
</template>
|
||||
|
||||
<FolderTreeNode
|
||||
v-for="node in group.folderTree"
|
||||
:key="`${node.folder.provider}-${node.folder.service}-${node.folder.identifier}`"
|
||||
:node="node"
|
||||
v-for="folder in getRootFolders(group.service)"
|
||||
:key="`${folder.provider}-${folder.service}-${folder.identifier}`"
|
||||
:folder="folder"
|
||||
:service="group.service"
|
||||
:selected-folder="selectedFolder"
|
||||
@select="emit('select', $event)"
|
||||
@create-subfolder="(service, parentFolder) => emit('createFolder', service, parentFolder)"
|
||||
@edit-folder="(service, folder) => emit('editFolder', service, folder)"
|
||||
/>
|
||||
|
||||
<v-list-item v-if="group.loading && getServiceFolders(group.service).length === 0" disabled class="folder-status-item">
|
||||
<template v-slot:prepend>
|
||||
<v-progress-circular indeterminate size="18" width="2" color="primary" />
|
||||
</template>
|
||||
<v-list-item-title>Loading folders</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item
|
||||
v-else-if="group.error && getServiceFolders(group.service).length === 0"
|
||||
disabled
|
||||
class="folder-status-item"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<v-icon icon="mdi-alert-circle-outline" color="error" />
|
||||
</template>
|
||||
<v-list-item-title>Folders unavailable</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ group.error }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item
|
||||
v-else-if="group.loaded && getServiceFolders(group.service).length === 0"
|
||||
disabled
|
||||
class="folder-status-item"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<v-icon icon="mdi-folder-off-outline" />
|
||||
</template>
|
||||
<v-list-item-title>No folders found</v-list-item-title>
|
||||
</v-list-item>
|
||||
</v-list-group>
|
||||
|
||||
<!-- Single service - show folders directly -->
|
||||
<template v-else>
|
||||
<v-list-item
|
||||
class="account-header-item account-header-static"
|
||||
:title="group.service.label || 'Mail Account'"
|
||||
:subtitle="group.service.primaryAddress || undefined"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<v-icon icon="mdi-email-outline" />
|
||||
</template>
|
||||
|
||||
<template v-slot:append>
|
||||
<v-btn
|
||||
icon="mdi-folder-plus"
|
||||
variant="text"
|
||||
size="small"
|
||||
density="compact"
|
||||
@click.stop="emit('createFolder', group.service, null)"
|
||||
>
|
||||
<v-icon>mdi-folder-plus</v-icon>
|
||||
<v-tooltip activator="parent" location="bottom">New Folder</v-tooltip>
|
||||
</v-btn>
|
||||
</template>
|
||||
</v-list-item>
|
||||
|
||||
<!-- Header with New Folder button -->
|
||||
<v-list-subheader class="d-flex align-center">
|
||||
<span class="flex-grow-1">FOLDERS</span>
|
||||
@@ -89,15 +147,45 @@ const emit = defineEmits<{
|
||||
</v-list-subheader>
|
||||
|
||||
<FolderTreeNode
|
||||
v-for="node in group.folderTree"
|
||||
:key="`${node.folder.provider}-${node.folder.service}-${node.folder.identifier}`"
|
||||
:node="node"
|
||||
v-for="folder in getRootFolders(group.service)"
|
||||
:key="`${folder.provider}-${folder.service}-${folder.identifier}`"
|
||||
:folder="folder"
|
||||
:service="group.service"
|
||||
:selected-folder="selectedFolder"
|
||||
@select="emit('select', $event)"
|
||||
@create-subfolder="(service, parentFolder) => emit('createFolder', service, parentFolder)"
|
||||
@edit-folder="(service, folder) => emit('editFolder', service, folder)"
|
||||
/>
|
||||
|
||||
<v-list-item v-if="group.loading && getServiceFolders(group.service).length === 0" disabled class="folder-status-item">
|
||||
<template v-slot:prepend>
|
||||
<v-progress-circular indeterminate size="18" width="2" color="primary" />
|
||||
</template>
|
||||
<v-list-item-title>Loading folders</v-list-item-title>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item
|
||||
v-else-if="group.error && getServiceFolders(group.service).length === 0"
|
||||
disabled
|
||||
class="folder-status-item"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<v-icon icon="mdi-alert-circle-outline" color="error" />
|
||||
</template>
|
||||
<v-list-item-title>Folders unavailable</v-list-item-title>
|
||||
<v-list-item-subtitle>{{ group.error }}</v-list-item-subtitle>
|
||||
</v-list-item>
|
||||
|
||||
<v-list-item
|
||||
v-else-if="group.loaded && getServiceFolders(group.service).length === 0"
|
||||
disabled
|
||||
class="folder-status-item"
|
||||
>
|
||||
<template v-slot:prepend>
|
||||
<v-icon icon="mdi-folder-off-outline" />
|
||||
</template>
|
||||
<v-list-item-title>No folders found</v-list-item-title>
|
||||
</v-list-item>
|
||||
</template>
|
||||
</template>
|
||||
</div>
|
||||
@@ -114,8 +202,16 @@ const emit = defineEmits<{
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
.account-header-static {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.account-header-item :deep(.v-list-item__prepend) {
|
||||
padding-inline-start: 4px;
|
||||
margin-inline-end: 2px;
|
||||
}
|
||||
|
||||
.folder-status-item {
|
||||
padding-inline-start: 16px;
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user