import { computed, ref, shallowRef } from 'vue' import { defineStore } from 'pinia' import { CollectionObject } from '@ChronoManager/models/collection' import { EntityObject } from '@ChronoManager/models/entity' import { EventObject } from '@ChronoManager/models/event' import { TaskObject } from '@ChronoManager/models/task' import type { ServiceObject } from '@ChronoManager/models/service' import type { ChronoSection } from '@/types' import { useChronoOperationsStore } from '@/stores/chronoOperationsStore' export const useChronoUiStore = defineStore('chronoUiStore', () => { const operationsStore = useChronoOperationsStore() const section = ref('calendar') const currentDate = ref(new Date()) const sidebarVisible = ref(true) const selectedCollection = shallowRef(null) const selectedEntity = shallowRef(null) const showEventEditor = ref(false) const showTaskEditor = ref(false) const showCollectionEditor = ref(false) const showImportDialog = ref(false) const entityEditorMode = ref<'edit' | 'view'>('view') const editingCollection = shallowRef(null) const collectionEditorMode = ref<'create' | 'edit'>('create') const collectionEditorType = ref<'calendar' | 'tasklist'>('calendar') const isTasksSection = computed(() => section.value === 'tasks') function selectSection(target: ChronoSection) { section.value = target } function selectDate(date: Date) { currentDate.value = new Date(date) } function selectCollection(collection: CollectionObject) { selectedCollection.value = collection } function openCollectionEditor(type: 'calendar' | 'tasklist', collection?: CollectionObject) { const target = collection ?? new CollectionObject() if (!collection) { target.properties.fromJson({ ...target.properties.toJson(), content: [type === 'calendar' ? 'event' : 'task'], }) } editingCollection.value = target collectionEditorMode.value = collection ? 'edit' : 'create' collectionEditorType.value = type showCollectionEditor.value = true } function openEntityEditor(entity: EntityObject, type: 'event' | 'task', mode: 'edit' | 'view') { selectedEntity.value = entity entityEditorMode.value = mode showEventEditor.value = type === 'event' showTaskEditor.value = type === 'task' } function createEventFromDate(start?: Date, end?: Date) { const entity = new EntityObject() entity.properties = new EventObject() if (start) { entity.properties.startsOn = start.toISOString() entity.properties.endsOn = (end ?? new Date(start.getTime() + 60 * 60 * 1000)).toISOString() } openEntityEditor(entity, 'event', 'edit') } function createEvent() { createEventFromDate() } function editEvent(entity: EntityObject) { openEntityEditor(entity, 'event', 'view') } function createTask() { const entity = new EntityObject() entity.properties = new TaskObject() openEntityEditor(entity, 'task', 'edit') } function editTask(entity: EntityObject) { openEntityEditor(entity, 'task', 'view') } function startEditingSelectedEntity() { entityEditorMode.value = 'edit' } function cancelEditingSelectedEntity() { entityEditorMode.value = 'view' } function closeEntityEditor() { selectedEntity.value = null entityEditorMode.value = 'view' showEventEditor.value = false showTaskEditor.value = false } async function saveSelectedEntity(entity: EntityObject, collection: CollectionObject | null | undefined, kind: string) { const targetCollection = collection instanceof CollectionObject ? collection : selectedCollection.value if (!targetCollection) throw new Error(`No ${kind} collection selected`) selectedEntity.value = await operationsStore.saveEntity(entity, targetCollection) selectedCollection.value = targetCollection entityEditorMode.value = 'view' } async function saveEvent(entity: EntityObject, collection?: CollectionObject | null) { await saveSelectedEntity(entity, collection, 'calendar') } async function saveTask(entity: EntityObject, collection?: CollectionObject | null) { await saveSelectedEntity(entity, collection, 'task list') } async function deleteSelectedEntity(entity: EntityObject, collection: CollectionObject | null | undefined, kind: string) { if (!(collection instanceof CollectionObject) && !selectedCollection.value) { throw new Error(`No ${kind} collection selected`) } await operationsStore.deleteEntity(entity) closeEntityEditor() } async function deleteEvent(entity: EntityObject, collection?: CollectionObject | null) { await deleteSelectedEntity(entity, collection, 'calendar') } async function deleteTask(entity: EntityObject, collection?: CollectionObject | null) { await deleteSelectedEntity(entity, collection, 'task list') } async function saveCollection(collection: CollectionObject, service: ServiceObject) { await operationsStore.saveCollection(collection, service, collectionEditorMode.value) showCollectionEditor.value = false } async function deleteCollection(collection: CollectionObject) { await operationsStore.deleteCollection(collection) if (selectedCollection.value?.identifier === collection.identifier) { selectedCollection.value = null selectedEntity.value = null } showCollectionEditor.value = false } async function openImport(files: File[]) { await operationsStore.prepareImport(files, selectedCollection.value) showImportDialog.value = true } async function closeImport(refresh = false) { showImportDialog.value = false await operationsStore.finishImport(refresh) } async function initialize(initialSection: ChronoSection = 'calendar') { await operationsStore.initialize(initialSection) if (selectedCollection.value && !operationsStore.collections.some( collection => collection.identifier === selectedCollection.value?.identifier, )) { selectedCollection.value = null } } return { section, currentDate, sidebarVisible, selectedCollection, selectedEntity, showEventEditor, showTaskEditor, showCollectionEditor, showImportDialog, entityEditorMode, editingCollection, collectionEditorMode, collectionEditorType, isTasksSection, selectSection, selectDate, selectCollection, openCollectionEditor, createEvent, editEvent, createTask, editTask, createEventFromDate, startEditingSelectedEntity, cancelEditingSelectedEntity, closeEntityEditor, saveEvent, deleteEvent, saveTask, deleteTask, saveCollection, deleteCollection, openImport, closeImport, initialize, } })