import { computed, ref } from 'vue' import { defineStore } from 'pinia' import { useProvidersStore, useServicesStore, useNodesStore, ROOT_ID } from '@DocumentsManager/stores' import { CollectionObject } from '@DocumentsManager/models/collection' import { EntityObject } from '@DocumentsManager/models/entity' import type { SortField, SortOrder, ViewMode, BreadcrumbItem } from '@/types' type NodeRecord = CollectionObject | EntityObject export const useDocumentsStore = defineStore('documentsStore', () => { const providersStore = useProvidersStore() const servicesStore = useServicesStore() const nodesStore = useNodesStore() const activeProviderId = ref('default') const activeServiceId = ref('personal') const currentLocation = ref(ROOT_ID) const viewMode = ref('grid') const sortField = ref('label') const sortOrder = ref('asc') const searchQuery = ref('') const sidebarVisible = ref(true) const transceiving = computed(() => providersStore.transceiving || servicesStore.transceiving || nodesStore.transceiving, ) const provider = computed(() => providersStore.provider(activeProviderId.value)) const service = computed(() => servicesStore.service(activeProviderId.value, activeServiceId.value)) const currentCollections = computed(() => nodesStore.getChildCollections(activeProviderId.value, activeServiceId.value, currentLocation.value), ) const currentEntities = computed(() => nodesStore.getChildEntities(activeProviderId.value, activeServiceId.value, currentLocation.value), ) const breadcrumbs = computed(() => { const nodes = nodesStore.getPath(activeProviderId.value, activeServiceId.value, currentLocation.value) return [ { id: ROOT_ID, label: 'Home', isRoot: true }, ...nodes.map((node) => ({ id: String(node.identifier), label: node.properties.label, isRoot: false, })), ] }) function sortCollections(items: CollectionObject[]): CollectionObject[] { return [...items].sort((a, b) => { const aVal = sortField.value === 'label' ? a.properties.label : sortField.value === 'modifiedOn' ? (a.modified?.getTime() ?? 0) : sortField.value === 'createdOn' ? (a.created?.getTime() ?? 0) : '' const bVal = sortField.value === 'label' ? b.properties.label : sortField.value === 'modifiedOn' ? (b.modified?.getTime() ?? 0) : sortField.value === 'createdOn' ? (b.created?.getTime() ?? 0) : '' const cmp = String(aVal).localeCompare(String(bVal)) return sortOrder.value === 'asc' ? cmp : -cmp }) } function sortEntities(items: EntityObject[]): EntityObject[] { return [...items].sort((a, b) => { const aVal = sortField.value === 'label' ? a.properties.label : sortField.value === 'mime' ? (a.properties.mime ?? '') : sortField.value === 'size' ? a.properties.size : sortField.value === 'modifiedOn' ? (a.modified?.getTime() ?? 0) : sortField.value === 'createdOn' ? (a.created?.getTime() ?? 0) : '' const bVal = sortField.value === 'label' ? b.properties.label : sortField.value === 'mime' ? (b.properties.mime ?? '') : sortField.value === 'size' ? b.properties.size : sortField.value === 'modifiedOn' ? (b.modified?.getTime() ?? 0) : sortField.value === 'createdOn' ? (b.created?.getTime() ?? 0) : '' const cmp = String(aVal).localeCompare(String(bVal)) return sortOrder.value === 'asc' ? cmp : -cmp }) } function filterNode(node: NodeRecord): boolean { if (!searchQuery.value) return true return node.properties.label.toLowerCase().includes(searchQuery.value.toLowerCase()) } const sortedItems = computed(() => ({ collections: sortCollections(currentCollections.value).filter(filterNode), entities: sortEntities(currentEntities.value).filter(filterNode), })) const hasItems = computed(() => sortedItems.value.collections.length > 0 || sortedItems.value.entities.length > 0, ) const isAtRoot = computed(() => currentLocation.value === ROOT_ID) async function initialize() { await providersStore.list() await servicesStore.list({ [activeProviderId.value]: true }) await refresh() } async function refresh() { await nodesStore.fetchNodes(activeProviderId.value, activeServiceId.value, currentLocation.value) } async function navigateTo(collectionId: string | null) { currentLocation.value = collectionId || ROOT_ID await refresh() } async function navigateToRoot() { await navigateTo(ROOT_ID) } async function navigateUp() { if (currentLocation.value === ROOT_ID) return const currentNode = nodesStore.getNode(activeProviderId.value, activeServiceId.value, currentLocation.value) if (!currentNode) return const parentId = currentNode.collection ? String(currentNode.collection) : ROOT_ID await navigateTo(parentId) } async function createFolder(label: string) { await nodesStore.createCollection( activeProviderId.value, activeServiceId.value, currentLocation.value, { label, owner: '' }, ) await refresh() } async function renameNode(node: NodeRecord, label: string) { if (node instanceof CollectionObject) { await nodesStore.updateCollection( activeProviderId.value, activeServiceId.value, node.identifier, { label, owner: node.properties.owner }, ) } else { await nodesStore.updateEntity( activeProviderId.value, activeServiceId.value, node.collection, node.identifier, { '@type': 'documents.properties', urid: node.properties.urid, size: node.properties.size, label, mime: node.properties.mime, format: node.properties.format, encoding: node.properties.encoding, }, ) } await refresh() } async function deleteNode(node: NodeRecord) { if (node instanceof CollectionObject) { await nodesStore.deleteCollection(activeProviderId.value, activeServiceId.value, node.identifier) } else { await nodesStore.deleteEntity(activeProviderId.value, activeServiceId.value, node.collection, node.identifier) } await refresh() } return { activeProviderId, activeServiceId, currentLocation, viewMode, sortField, sortOrder, searchQuery, sidebarVisible, transceiving, provider, service, currentCollections, currentEntities, sortedItems, hasItems, breadcrumbs, isAtRoot, initialize, refresh, navigateTo, navigateToRoot, navigateUp, createFolder, renameNode, deleteNode, ROOT_ID, } })