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,7 +1,5 @@
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { useCollectionsStore } from '@MailManager/stores/collectionsStore'
import { CollectionPropertiesObject } from '@MailManager/models/collection'
import type { CollectionObject } from '@MailManager/models/collection'
import type { ServiceObject } from '@MailManager/models'
@@ -9,23 +7,25 @@ interface Props {
modelValue: boolean
service: ServiceObject
folder: CollectionObject
allFolders?: CollectionObject[]
parentFolderLabel?: string
validateName?: (name: string) => string[]
loading?: boolean
errorMessage?: string
}
const props = withDefaults(defineProps<Props>(), {
allFolders: () => []
parentFolderLabel: 'Root',
validateName: () => [],
loading: false,
errorMessage: '',
})
const emit = defineEmits<{
'update:modelValue': [value: boolean]
updated: [folder: CollectionObject]
confirm: [folderName: string]
}>()
const collectionsStore = useCollectionsStore()
const folderName = ref('')
const loading = ref(false)
const errorMessage = ref('')
const validationErrors = ref<string[]>([])
const dialogValue = computed({
@@ -37,74 +37,13 @@ const isValid = computed(() => {
return folderName.value.trim().length > 0 && validationErrors.value.length === 0
})
const parentFolderLabel = computed(() => {
const parentId = props.folder.collection
if (parentId === null || parentId === undefined) return 'Root'
const parent = props.allFolders.find(
f =>
String(f.identifier) === String(parentId) &&
f.provider === props.folder.provider &&
String(f.service) === String(props.folder.service)
)
return parent?.properties.label || 'Root'
})
const validateFolderName = (name: string): string[] => {
const errors: string[] = []
if (!name || name.trim().length === 0) {
errors.push('Folder name is required')
return errors
}
if (name.length > 255) {
errors.push('Folder name too long (max 255 characters)')
}
if (/[<>:"|?*\x00-\x1F]/.test(name)) {
errors.push('Folder name contains invalid characters')
}
if (props.service.provider === 'imap' && /[\/\\]/.test(name)) {
errors.push('IMAP folder names cannot contain / or \\')
}
if (name !== name.trim()) {
errors.push('Folder name cannot have leading or trailing spaces')
}
return errors
}
const checkDuplicateName = (name: string): boolean => {
const parentId = props.folder.collection ?? null
return props.allFolders.some(f => {
if (String(f.identifier) === String(props.folder.identifier)) return false
return (
f.properties.label === name &&
String(f.collection) === String(parentId) &&
f.provider === props.folder.provider &&
String(f.service) === String(props.folder.service)
)
})
}
watch(folderName, (newName) => {
errorMessage.value = ''
validationErrors.value = validateFolderName(newName)
if (validationErrors.value.length === 0 && newName.trim().length > 0 && checkDuplicateName(newName)) {
validationErrors.value.push('A folder with this name already exists in this location')
}
validationErrors.value = props.validateName(newName)
})
function resetForm() {
folderName.value = props.folder.properties.label || ''
errorMessage.value = ''
validationErrors.value = []
loading.value = false
}
watch(dialogValue, (isOpen) => {
@@ -114,54 +53,27 @@ watch(dialogValue, (isOpen) => {
}, { immediate: true })
const handleRename = async () => {
const errors = validateFolderName(folderName.value)
const errors = props.validateName(folderName.value)
if (errors.length > 0) {
validationErrors.value = errors
return
}
if (checkDuplicateName(folderName.value)) {
validationErrors.value = ['A folder with this name already exists in this location']
return
}
const newName = folderName.value.trim()
if (newName === props.folder.properties.label) {
dialogValue.value = false
return
}
loading.value = true
errorMessage.value = ''
try {
const properties = new CollectionPropertiesObject()
properties.label = newName
properties.rank = props.folder.properties.rank ?? 0
properties.subscribed = props.folder.properties.subscribed ?? true
const updatedFolder = await collectionsStore.update(
props.folder.provider,
props.folder.service,
props.folder.identifier,
properties
)
emit('updated', updatedFolder)
dialogValue.value = false
resetForm()
} catch (error: any) {
console.error('[RenameFolderDialog] Failed to rename folder:', error)
errorMessage.value = error.message || 'Failed to rename folder. Please try again.'
} finally {
loading.value = false
}
emit('confirm', newName)
}
const handleCancel = () => {
dialogValue.value = false
resetForm()
}
</script>
<template>