Compare commits
7 Commits
7119e04ba5
...
fe9f4d9656
| Author | SHA1 | Date | |
|---|---|---|---|
| fe9f4d9656 | |||
| 46632d2454 | |||
| f007d5a514 | |||
| a5f33e5f7b | |||
| 603c0caf17 | |||
| 49a067e4ff | |||
| 85a7f23889 |
1254
package-lock.json
generated
1254
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -23,13 +23,13 @@
|
|||||||
"vue": "^3.4.0",
|
"vue": "^3.4.0",
|
||||||
"vue-router": "^4.2.5",
|
"vue-router": "^4.2.5",
|
||||||
"pinia": "^3.0.0",
|
"pinia": "^3.0.0",
|
||||||
"vuetify": "^3.5.0"
|
"vuetify": "^4.0.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@vitejs/plugin-vue": "^6.0.0",
|
"@vitejs/plugin-vue": "^6.0.0",
|
||||||
"@vue/tsconfig": "^0.9.0",
|
"@vue/tsconfig": "^0.9.0",
|
||||||
"typescript": "^6.0.0",
|
"typescript": "^6.0.0",
|
||||||
"vite": "^5.0.0",
|
"vite": "^8.0.0",
|
||||||
"vue-tsc": "^3.0.0"
|
"vue-tsc": "^3.0.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<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'
|
||||||
@@ -31,6 +32,7 @@ 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)
|
||||||
@@ -52,7 +54,8 @@ interface ServiceGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const serviceGroups = computed<ServiceGroup[]>(() => {
|
const serviceGroups = computed<ServiceGroup[]>(() => {
|
||||||
const service = props.service ?? mailStore.moveDialogService
|
const service = props.service ??
|
||||||
|
(mailStore.moveDialogService ? servicesStore.serviceByIdentifier(mailStore.moveDialogService) : null)
|
||||||
|
|
||||||
if (!service) {
|
if (!service) {
|
||||||
return []
|
return []
|
||||||
|
|||||||
@@ -255,26 +255,6 @@ export const useMailStore = defineStore('mailStore', () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function _formatMoveNotification(successCount: number, failureCount: number, targetFolder: CollectionObject) {
|
|
||||||
const folderLabel = targetFolder.properties.label || String(targetFolder.identifier)
|
|
||||||
|
|
||||||
if (failureCount === 0) {
|
|
||||||
return {
|
|
||||||
message: successCount === 1
|
|
||||||
? `Message moved to "${folderLabel}"`
|
|
||||||
: `${successCount} messages moved to "${folderLabel}"`,
|
|
||||||
color: 'success' as const,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
message: successCount === 0
|
|
||||||
? `Move failed for ${failureCount === 1 ? '1 message' : `${failureCount} messages`}`
|
|
||||||
: `Moved ${successCount} ${successCount === 1 ? 'message' : 'messages'} to "${folderLabel}". ${failureCount} failed.`,
|
|
||||||
color: successCount === 0 ? 'error' as const : 'warning' as const,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(currentMessages, () => {
|
watch(currentMessages, () => {
|
||||||
_reconcileSelection()
|
_reconcileSelection()
|
||||||
})
|
})
|
||||||
@@ -430,32 +410,26 @@ export const useMailStore = defineStore('mailStore', () => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await entitiesStore.move(_collectionIdentifier(target), movableIdentifiers)
|
const [successes, failures] = await entitiesStore.move(_collectionIdentifier(target), movableIdentifiers)
|
||||||
const operationSucceeded: EntityIdentifier[] = []
|
|
||||||
const operationFailures: EntityIdentifier[] = []
|
|
||||||
|
|
||||||
Object.entries(response).forEach(([sourceIdentifier, result]) => {
|
|
||||||
if (result.success) {
|
|
||||||
operationSucceeded.push(sourceIdentifier as EntityIdentifier)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
operationFailures.push(sourceIdentifier as EntityIdentifier)
|
|
||||||
})
|
|
||||||
|
|
||||||
if (operationSucceeded.length === 0) {
|
|
||||||
throw new Error(operationFailures[0] ?? 'Failed to move messages')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedMessage.value && operationSucceeded.includes(_entityIdentifier(selectedMessage.value))) {
|
|
||||||
selectedMessage.value = null
|
|
||||||
}
|
|
||||||
|
|
||||||
clearSelection()
|
clearSelection()
|
||||||
closeMoveDialog()
|
closeMoveDialog()
|
||||||
|
|
||||||
const notification = _formatMoveNotification(operationSucceeded.length, operationFailures.length, target)
|
if (failures.length === 0) {
|
||||||
notify(notification.message, notification.color)
|
notify(
|
||||||
|
successes.length === 1 ? 'Message moved' : `${successes.length} messages moved`,
|
||||||
|
'success',
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (failures.length > 0) {
|
||||||
|
notify(
|
||||||
|
successes.length === 0
|
||||||
|
? `Move failed for ${failures.length === 1 ? '1 message' : `${failures.length} messages`}`
|
||||||
|
: `Moved ${successes.length} ${successes.length === 1 ? 'message' : 'messages'}. ${failures.length} failed.`,
|
||||||
|
successes.length === 0 ? 'error' : 'warning',
|
||||||
|
)
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
const messageText = error instanceof Error ? error.message : 'Failed to move messages'
|
const messageText = error instanceof Error ? error.message : 'Failed to move messages'
|
||||||
console.error('[Mail] Failed to move messages:', error)
|
console.error('[Mail] Failed to move messages:', error)
|
||||||
@@ -474,43 +448,23 @@ export const useMailStore = defineStore('mailStore', () => {
|
|||||||
loading.value = true
|
loading.value = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await entitiesStore.delete(entityIdentifiers)
|
const [successes, failures] = await entitiesStore.delete(entityIdentifiers)
|
||||||
const operationSucceeded: EntityIdentifier[] = []
|
|
||||||
const operationFailures: EntityIdentifier[] = []
|
|
||||||
|
|
||||||
Object.entries(response).forEach(([sourceIdentifier, result]) => {
|
|
||||||
if (result.success) {
|
|
||||||
operationSucceeded.push(sourceIdentifier as EntityIdentifier)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
operationFailures.push(sourceIdentifier as EntityIdentifier)
|
|
||||||
})
|
|
||||||
|
|
||||||
if (operationSucceeded.length === 0) {
|
|
||||||
throw new Error(operationFailures[0] ?? 'Failed to delete messages')
|
|
||||||
}
|
|
||||||
|
|
||||||
if (selectedMessage.value && operationSucceeded.includes(_entityIdentifier(selectedMessage.value))) {
|
|
||||||
selectedMessage.value = null
|
|
||||||
}
|
|
||||||
|
|
||||||
clearSelection()
|
clearSelection()
|
||||||
|
|
||||||
const successCount = operationSucceeded.length
|
if (failures.length === 0) {
|
||||||
const failureCount = operationFailures.length
|
|
||||||
|
|
||||||
if (failureCount === 0) {
|
|
||||||
notify(
|
notify(
|
||||||
successCount === 1 ? 'Message deleted' : `${successCount} messages deleted`,
|
successes.length === 1 ? 'Message deleted' : `${successes.length} messages deleted`,
|
||||||
'success',
|
'success',
|
||||||
)
|
)
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
if (failures.length > 0) {
|
||||||
notify(
|
notify(
|
||||||
successCount === 0
|
successes.length === 0
|
||||||
? `Delete failed for ${failureCount === 1 ? '1 message' : `${failureCount} messages`}`
|
? `Delete failed for ${failures.length === 1 ? '1 message' : `${failures.length} messages`}`
|
||||||
: `Deleted ${successCount} ${successCount === 1 ? 'message' : 'messages'}. ${failureCount} failed.`,
|
: `Deleted ${successes.length} ${successes.length === 1 ? 'message' : 'messages'}. ${failures.length} failed.`,
|
||||||
successCount === 0 ? 'error' : 'warning',
|
successes.length === 0 ? 'error' : 'warning',
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|||||||
Reference in New Issue
Block a user