refactor: split stores and use events

Signed-off-by: Sebastian <krupinski01@gmail.com>
This commit is contained in:
2026-05-14 22:26:45 -04:00
parent 46632d2454
commit 232f588225
19 changed files with 1808 additions and 1210 deletions

View File

@@ -1,17 +1,21 @@
<script setup lang="ts">
import { computed, onMounted } from 'vue'
import { computed, onMounted, unref } from 'vue'
import { storeToRefs } from 'pinia'
import { useDisplay } from 'vuetify'
import { useModuleStore } from '@KTXC'
import { useCollectionsStore } from '@MailManager/stores/collectionsStore'
import { useMailStore } from '@/stores/mailStore'
import { useMailUiStore } from '@/stores/mailUiStore'
import type { CollectionObject, EntityObject } from '@MailManager/models'
import type { EntityIdentifier } from '@MailManager/types/common'
import FolderTree from '@/components/FolderTree.vue'
import MessageList from '@/components/MessageList.vue'
import MessageReader from '@/components/MessageReader.vue'
import MessageComposer from '@/components/MessageComposer.vue'
import CreateFolderDialog from '@/components/CreateFolderDialog.vue'
import DeleteFolderDialog from '@/components/DeleteFolderDialog.vue'
import FolderSelectionDialog from '@/components/FolderSelectionDialog.vue'
import RenameFolderDialog from '@/components/RenameFolderDialog.vue'
import SettingsDialog from '@/components/settings/SettingsDialog.vue'
import FolderView from '@/components/FolderView.vue'
// Vuetify display for responsive behavior
const display = useDisplay()
@@ -19,94 +23,175 @@ const isMobile = computed(() => display.mdAndDown.value)
// Check if mail manager is available
const moduleStore = useModuleStore()
const isMailManagerAvailable = computed(() => {
const isManagerAvailable = computed(() => {
return moduleStore.has('mail_manager') || moduleStore.has('MailManager')
})
const collectionsStore = useCollectionsStore()
// Mail module store
const mailStore = useMailStore()
const mailUiStore = useMailUiStore()
// storeToRefs preserves reactivity for state and computed properties
const {
sidebarVisible,
settingsDialogVisible,
loading,
selectedFolder,
selectedMessage,
currentMessages,
} = storeToRefs(mailStore)
const {
sidebarVisible,
settingsDialogVisible,
composeMode,
composeSource,
composeVisible,
selectionList,
selectionMode,
composeMode,
composeReplyTo,
currentMessages,
moveDialogVisible,
moveDialogCandidates,
} = storeToRefs(mailStore)
moveMessagesDialogVisible,
moveMessagesDialogService,
createFolderDialogVisible,
createFolderDialogService,
createFolderDialogParent,
createFolderDialogLoading,
createFolderDialogError,
renameFolderDialogVisible,
renameFolderDialogService,
renameFolderDialogFolder,
renameFolderDialogLoading,
renameFolderDialogError,
moveFolderDialogVisible,
moveFolderDialogService,
moveFolderDialogSource,
deleteFolderDialogVisible,
deleteFolderDialogService,
deleteFolderDialogFolder,
deleteFolderDialogLoading,
deleteFolderDialogError,
} = storeToRefs(mailUiStore)
// Complex store/composable objects accessed directly (not simple refs)
const { mailSync, entitiesStore } = mailStore
const lastSyncLabel = computed(() => {
if (!mailSync.lastSync) return ''
return `(Last: ${new Date(mailSync.lastSync).toLocaleTimeString()})`
const lastSync = unref(unref(mailSync.lastSync))
if (!(lastSync instanceof Date)) return ''
return `(Last: ${lastSync.toLocaleTimeString()})`
})
// Initialize
onMounted(async () => {
if (!isMailManagerAvailable.value) return
if (!isManagerAvailable.value) return
await mailStore.initialize()
})
// Handlers — thin wrappers that delegate to the store
const {
validateCreateFolderName,
validateRenameFolderName,
} = mailUiStore
const handleFolderSelect = (folder: CollectionObject) => mailStore.selectFolder(folder)
const handleMessageOpen = (message: EntityObject) => mailStore.selectMessage(message, isMobile.value)
const handleMessageOpen = (message: EntityObject) => {
mailStore.selectMessage(message)
const handleMessageSelectionToggle = (message: EntityObject) => mailStore.toggleMessageSelection(message)
if (isMobile.value) {
mailUiStore.closeSidebar()
}
}
const handleSelectionModeActivate = (message: EntityObject) => mailStore.activateSelectionMode(message)
const handleMessageSelectionToggle = (message: EntityObject) => mailUiStore.toggleMessageSelection(message)
const handleSelectionModeActivate = (message: EntityObject) => mailUiStore.activateSelectionMode(message)
const handleSelectAllToggle = (value: boolean) => {
if (value) {
mailStore.selectAllCurrentMessages()
mailUiStore.selectAllCurrentMessages()
return
}
mailStore.clearSelection()
mailUiStore.clearSelection()
}
const handleSelectionClear = () => mailStore.deactivateSelectionMode()
const handleSelectionClear = () => mailUiStore.deactivateSelectionMode()
const handleSelectionMove = () => mailStore.openMoveDialog()
const handleSelectionMove = () => mailUiStore.openMoveMessagesDialog()
const handleSelectionDelete = () => mailStore.deleteMessages([...selectionList.value])
const handleSelectionDelete = () => mailUiStore.deleteSelectedMessages()
const handleCompose = (message?: EntityObject) => mailStore.openCompose(message)
const handleCompose = () => mailUiStore.openCompose()
const handleComposeClose = () => mailStore.closeCompose()
const handleComposeReply = (message: EntityObject) => mailUiStore.openCompose(message, 'reply')
const handleComposeSent = () => mailStore.afterSent()
const handleComposeForward = (message: EntityObject) => mailUiStore.openCompose(message, 'forward')
const handleComposeClose = () => mailUiStore.closeCompose()
const handleComposeSent = () => mailUiStore.afterSent()
const handleDelete = (message: EntityObject) => {
const id = `${message.provider}:${String(message.service)}:${String(message.collection)}:${String(message.identifier)}` as EntityIdentifier
mailStore.deleteMessages([id])
mailStore.deleteMessages([message.identifier])
}
const handleMove = (message: EntityObject) => mailStore.openMoveDialog(message)
const handleMove = (message: EntityObject) => mailUiStore.openMoveMessagesDialog(message)
const handleMoveConfirm = async (target: CollectionObject) => { await mailStore.moveMessages(target, moveDialogCandidates.value ?? []) }
const handleMoveConfirm = async (target: CollectionObject) => { await mailUiStore.confirmMoveMessages(target) }
const handleMoveCancel = () => mailStore.closeMoveDialog()
const handleMoveCancel = () => mailUiStore.closeMoveMessagesDialog()
const toggleSidebar = () => mailStore.toggleSidebar()
const handleFolderCreateConfirm = async (folderName: string) => {
try {
const mutatedFolder = await mailUiStore.confirmCreateFolder(folderName)
const handleSettingsOpen = () => mailStore.openSettings()
if (mutatedFolder) {
handleFolderSelect(mutatedFolder)
}
} catch (error: unknown) {
console.error('[MailPage] Failed to create folder:', error)
}
}
const handleFolderRenameConfirm = async (folderName: string) => {
try {
const mutatedFolder = await mailUiStore.confirmRenameFolder(folderName)
if (mutatedFolder) {
handleFolderSelect(mutatedFolder)
}
} catch (error: unknown) {
console.error('[MailPage] Failed to rename folder:', error)
}
}
const handleFolderMoveConfirm = async (targetFolder: CollectionObject) => {
try {
await mailUiStore.confirmMoveFolder(targetFolder)
} catch (error: unknown) {
console.error('[MailPage] Failed to move folder:', error)
}
}
const handleFolderMoveCancel = () => mailUiStore.closeMoveFolderDialog()
const handleFolderDeleteConfirm = async () => {
try {
await mailUiStore.confirmDeleteFolder()
} catch (error: unknown) {
console.error('[MailPage] Failed to delete folder:', error)
}
}
const toggleSidebar = () => mailUiStore.toggleSidebar()
const handleSettingsOpen = () => mailUiStore.openSettings()
const handleFolderCreated = (folder: CollectionObject) => mailStore.notify(`Folder "${folder.properties.label}" created`, 'success')
</script>
<template>
<!-- Manager Unavailable -->
<div v-if="!isMailManagerAvailable" class="mail-unavailable">
<div v-if="!isManagerAvailable" class="mail-unavailable">
<v-alert
type="warning"
variant="outlined"
@@ -180,10 +265,10 @@ const handleFolderCreated = (folder: CollectionObject) => mailStore.notify(`Fold
width="280"
class="mail-sidebar"
>
<FolderTree
<FolderView
:selected-folder="selectedFolder"
@select="handleFolderSelect"
@folder-created="handleFolderCreated"
/>
<template #append>
@@ -225,8 +310,9 @@ const handleFolderCreated = (folder: CollectionObject) => mailStore.notify(`Fold
<!-- Reader/Composer panel -->
<div class="mail-reader-panel">
<MessageComposer
v-if="composeMode"
:reply-to="composeReplyTo"
v-if="composeVisible"
:mode="composeMode"
:source="composeSource"
:folder="selectedFolder"
@close="handleComposeClose"
@sent="handleComposeSent"
@@ -236,7 +322,8 @@ const handleFolderCreated = (folder: CollectionObject) => mailStore.notify(`Fold
v-else
:entity="selectedMessage"
@compose="handleCompose"
@reply="handleCompose"
@reply="handleComposeReply"
@forward="handleComposeForward"
@move="handleMove"
@delete="handleDelete"
/>
@@ -249,14 +336,62 @@ const handleFolderCreated = (folder: CollectionObject) => mailStore.notify(`Fold
<SettingsDialog v-model="settingsDialogVisible" />
<FolderSelectionDialog
v-model="moveDialogVisible"
v-if="moveMessagesDialogService && moveFolderDialogSource"
v-model="moveMessagesDialogVisible"
:service="moveMessagesDialogService"
:loading="loading"
title="Move To"
title="Move Messages To"
confirm-text="Move"
empty-text="No other folders are available in this account."
@select="handleMoveConfirm"
@cancel="handleMoveCancel"
/>
<FolderSelectionDialog
v-if="moveFolderDialogService && moveFolderDialogSource"
v-model="moveFolderDialogVisible"
:service="moveFolderDialogService"
:loading="collectionsStore.transceiving"
title="Move Folder To"
confirm-text="Move"
empty-text="No other folders are available in this account."
:disabled-folder-keys="mailUiStore.moveFolderDialogInvalidFolderKeys"
@select="handleFolderMoveConfirm"
@cancel="handleFolderMoveCancel"
/>
<CreateFolderDialog
v-if="createFolderDialogService"
v-model="createFolderDialogVisible"
:service="createFolderDialogService"
:parent-folder-label="mailUiStore.createFolderDialogParentLabel"
:validate-name="validateCreateFolderName"
:loading="createFolderDialogLoading"
:error-message="createFolderDialogError"
@confirm="handleFolderCreateConfirm"
/>
<RenameFolderDialog
v-if="renameFolderDialogService && renameFolderDialogFolder"
v-model="renameFolderDialogVisible"
:service="renameFolderDialogService"
:folder="renameFolderDialogFolder"
:parent-folder-label="mailUiStore.renameFolderDialogParentLabel"
:validate-name="validateRenameFolderName"
:loading="renameFolderDialogLoading"
:error-message="renameFolderDialogError"
@confirm="handleFolderRenameConfirm"
/>
<DeleteFolderDialog
v-if="deleteFolderDialogService && deleteFolderDialogFolder"
v-model="deleteFolderDialogVisible"
:service="deleteFolderDialogService"
:folder="deleteFolderDialogFolder"
:loading="deleteFolderDialogLoading"
:error-message="deleteFolderDialogError"
@confirm="handleFolderDeleteConfirm"
/>
</div>
</template>