feat: entity move
All checks were successful
Build Test / test (pull_request) Successful in 27s
JS Unit Tests / test (pull_request) Successful in 28s
PHP Unit Tests / test (pull_request) Successful in 50s

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-03-28 09:32:04 -04:00
parent 7322bb16da
commit 1c918ca55c
6 changed files with 216 additions and 6 deletions

View File

@@ -6,8 +6,20 @@ import { ref, computed, readonly } from 'vue'
import { defineStore } from 'pinia'
import { entityService } from '../services'
import { EntityObject } from '../models'
import type { EntityTransmitRequest, EntityTransmitResponse, EntityStreamRequest } from '../types/entity'
import type { SourceSelector, ListFilter, ListSort, ListRange } from '../types/common'
import type {
EntityMoveResponse,
EntityStreamRequest,
EntityTransmitRequest,
EntityTransmitResponse,
} from '../types/entity'
import type {
CollectionIdentifier,
EntityIdentifier,
ListFilter,
ListRange,
ListSort,
SourceSelector,
} from '../types/common'
export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
// State
@@ -88,6 +100,24 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
return `${provider}:${service}:${collection}:${identifier}`
}
/**
* Parse a full entity identifier into its components.
*/
function parseEntityIdentifier(identifier: EntityIdentifier): {
provider: string
service: string
collection: string
identifier: string
} {
const [provider, service, collection, entity] = identifier.split(':', 4)
return {
provider,
service,
collection,
identifier: entity,
}
}
// Actions
/**
@@ -315,6 +345,56 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
}
}
/**
* Move entities to another collection.
*
* Updates local store keys for successfully moved entities when they are
* already present in cache.
*
* @param target - target collection identifier
* @param sources - source entity identifiers
*
* @returns Promise with move results keyed by source identifier
*/
async function move(target: CollectionIdentifier, sources: EntityIdentifier[]): Promise<EntityMoveResponse> {
transceiving.value = true
try {
const response = await entityService.move({ target, sources })
Object.entries(response).forEach(([sourceIdentifier, result]) => {
if (!result.success) {
return
}
const cachedEntity = _entities.value[sourceIdentifier]
if (!cachedEntity) {
return
}
const destination = parseEntityIdentifier(result.identifier)
const movedEntity = cachedEntity.clone().fromJson({
...cachedEntity.toJson(),
provider: destination.provider,
service: destination.service,
collection: destination.collection,
identifier: destination.identifier,
})
delete _entities.value[sourceIdentifier]
_entities.value[result.identifier] = movedEntity
})
console.debug('[Mail Manager][Store] - Successfully moved', Object.keys(response).length, 'entities')
return response
} catch (error: any) {
console.error('[Mail Manager][Store] - Failed to move entities:', error)
throw error
} finally {
transceiving.value = false
}
}
/**
* Send/transmit an entity
*
@@ -390,6 +470,7 @@ export const useEntitiesStore = defineStore('mailEntitiesStore', () => {
update,
delete: remove,
delta,
move,
transmit,
stream,
}