122 lines
3.9 KiB
Vue
122 lines
3.9 KiB
Vue
<script setup lang="ts">
|
|
import type { CollectionObject } from '@MailManager/models/collection'
|
|
import type { ServiceInterface } from '@MailManager/types/service'
|
|
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[]
|
|
}>
|
|
}
|
|
|
|
const props = defineProps<Props>()
|
|
|
|
// Emits
|
|
const emit = defineEmits<{
|
|
select: [folder: CollectionObject]
|
|
createFolder: [service: ServiceInterface, parentFolder: CollectionObject | null]
|
|
editFolder: [service: ServiceInterface, folder: CollectionObject]
|
|
}>()
|
|
</script>
|
|
|
|
<template>
|
|
<div>
|
|
<template v-for="group in serviceGroups" :key="`${group.service.provider}-${group.service.identifier}`">
|
|
<!-- Service account group -->
|
|
<v-list-group v-if="serviceGroups.length > 1" class="no-indent">
|
|
<template v-slot:activator="{ props: activatorProps }">
|
|
<v-list-item
|
|
v-bind="activatorProps"
|
|
class="account-header-item"
|
|
: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>
|
|
</template>
|
|
|
|
<FolderTreeNode
|
|
v-for="node in group.folderTree"
|
|
:key="`${node.folder.provider}-${node.folder.service}-${node.folder.identifier}`"
|
|
:node="node"
|
|
: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-group>
|
|
|
|
<!-- Single service - show folders directly -->
|
|
<template v-else>
|
|
<!-- Header with New Folder button -->
|
|
<v-list-subheader class="d-flex align-center">
|
|
<span class="flex-grow-1">FOLDERS</span>
|
|
<v-btn
|
|
icon="mdi-folder-plus"
|
|
variant="text"
|
|
size="x-small"
|
|
@click="emit('createFolder', group.service, null)"
|
|
>
|
|
<v-icon size="small">mdi-folder-plus</v-icon>
|
|
<v-tooltip activator="parent" location="bottom">New Folder</v-tooltip>
|
|
</v-btn>
|
|
</v-list-subheader>
|
|
|
|
<FolderTreeNode
|
|
v-for="node in group.folderTree"
|
|
:key="`${node.folder.provider}-${node.folder.service}-${node.folder.identifier}`"
|
|
:node="node"
|
|
: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)"
|
|
/>
|
|
</template>
|
|
</template>
|
|
</div>
|
|
</template>
|
|
|
|
<style scoped>
|
|
.v-list-item--active {
|
|
background-color: rgba(var(--v-theme-primary), 0.12);
|
|
}
|
|
|
|
.account-header-item {
|
|
--v-list-item-prepend-size: 22px;
|
|
background-color: rgba(var(--v-theme-primary), 0.1);
|
|
border-radius: 6px;
|
|
}
|
|
|
|
.account-header-item :deep(.v-list-item__prepend) {
|
|
padding-inline-start: 4px;
|
|
margin-inline-end: 2px;
|
|
}
|
|
</style>
|