feat: use module store
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -0,0 +1,424 @@
|
||||
import { computed, ref, shallowRef } from 'vue'
|
||||
import { defineStore } from 'pinia'
|
||||
import { useUserStore } from '@KTXC/stores/userStore'
|
||||
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 { ServiceObject } from '@ChronoManager/models/service'
|
||||
import { useCollectionsStore } from '@ChronoManager/stores/collectionsStore'
|
||||
import { useEntitiesStore } from '@ChronoManager/stores/entitiesStore'
|
||||
import type { SourceSelector } from '@ChronoManager/types'
|
||||
import type { CalendarView as CalendarViewType } from '@/types'
|
||||
import {
|
||||
AGENDA_VIEW_SPANS,
|
||||
DAYS_VIEW_SPANS,
|
||||
type AgendaViewSpan,
|
||||
type DaysViewSpan,
|
||||
} from '@/types/spans'
|
||||
import { useChronoEntityActions } from '@/composables/useChronoEntityActions'
|
||||
|
||||
type EntitySources = Record<string, Record<string, Record<string | number, true>>>
|
||||
|
||||
export const useChronoStore = defineStore('chronoStore', () => {
|
||||
const userStore = useUserStore()
|
||||
const collectionsStore = useCollectionsStore()
|
||||
const entitiesStore = useEntitiesStore()
|
||||
const entityActions = useChronoEntityActions(entitiesStore, collectionsStore)
|
||||
|
||||
const savedCalendarView = userStore.getSetting('chrono.calendarView')
|
||||
const savedDaysViewSpan = userStore.getSetting('chrono.daysViewSpan')
|
||||
const savedAgendaViewSpan = userStore.getSetting('chrono.agendaViewSpan')
|
||||
|
||||
const viewMode = ref<'calendar' | 'tasks'>('calendar')
|
||||
const calendarView = ref<CalendarViewType>(
|
||||
savedCalendarView === 'month' || savedCalendarView === 'agenda' || savedCalendarView === 'days'
|
||||
? savedCalendarView
|
||||
: 'days',
|
||||
)
|
||||
const daysViewSpan = ref<DaysViewSpan>(
|
||||
typeof savedDaysViewSpan === 'string' && DAYS_VIEW_SPANS.includes(savedDaysViewSpan as DaysViewSpan)
|
||||
? (savedDaysViewSpan as DaysViewSpan)
|
||||
: '7d',
|
||||
)
|
||||
|
||||
const agendaViewSpan = ref<AgendaViewSpan>(
|
||||
typeof savedAgendaViewSpan === 'string' && AGENDA_VIEW_SPANS.includes(savedAgendaViewSpan as AgendaViewSpan)
|
||||
? (savedAgendaViewSpan as AgendaViewSpan)
|
||||
: '1w',
|
||||
)
|
||||
const currentDate = ref(new Date())
|
||||
const sidebarVisible = ref(true)
|
||||
|
||||
const selectedCollection = shallowRef<CollectionObject | null>(null)
|
||||
const selectedEntity = shallowRef<EntityObject | null>(null)
|
||||
|
||||
const showEventEditor = ref(false)
|
||||
const showTaskEditor = ref(false)
|
||||
const showCollectionEditor = ref(false)
|
||||
|
||||
const entityEditorMode = ref<'edit' | 'view'>('view')
|
||||
const editingCollection = shallowRef<CollectionObject | null>(null)
|
||||
const collectionEditorMode = ref<'create' | 'edit'>('create')
|
||||
const collectionEditorType = ref<'calendar' | 'tasklist'>('calendar')
|
||||
|
||||
const loading = ref(false)
|
||||
|
||||
const collections = computed(() => collectionsStore.collections)
|
||||
const entities = computed(() => entitiesStore.entities)
|
||||
|
||||
const calendars = computed(() => {
|
||||
return collections.value.filter(col => col.properties.contents?.event)
|
||||
})
|
||||
|
||||
const taskLists = computed(() => {
|
||||
return collections.value.filter(col => col.properties.contents?.task)
|
||||
})
|
||||
|
||||
const events = computed(() => {
|
||||
return entities.value.filter(entity => entity.properties instanceof EventObject)
|
||||
})
|
||||
|
||||
const tasks = computed(() => {
|
||||
return entities.value.filter(entity => entity.properties instanceof TaskObject)
|
||||
})
|
||||
|
||||
const isTaskView = computed(() => viewMode.value === 'tasks')
|
||||
|
||||
const filteredEvents = computed(() => {
|
||||
const visibleCalendarIds = calendars.value
|
||||
.filter(cal => cal.properties.visibility !== false)
|
||||
.map(cal => cal.identifier)
|
||||
|
||||
return events.value.filter(event => visibleCalendarIds.includes(event.collection))
|
||||
})
|
||||
|
||||
const filteredTasks = computed(() => tasks.value)
|
||||
|
||||
function buildSources(collectionItems: CollectionObject[]): EntitySources {
|
||||
return collectionItems.reduce<EntitySources>((acc, collection) => {
|
||||
if (!acc[collection.provider]) {
|
||||
acc[collection.provider] = {}
|
||||
}
|
||||
|
||||
const serviceKey = String(collection.service)
|
||||
if (!acc[collection.provider][serviceKey]) {
|
||||
acc[collection.provider][serviceKey] = {}
|
||||
}
|
||||
|
||||
acc[collection.provider][serviceKey][collection.identifier] = true
|
||||
return acc
|
||||
}, {})
|
||||
}
|
||||
|
||||
function setViewMode(mode: 'calendar' | 'tasks') {
|
||||
viewMode.value = mode
|
||||
}
|
||||
|
||||
function setCalendarView(view: CalendarViewType) {
|
||||
calendarView.value = view
|
||||
userStore.setSetting('chrono.calendarView', view)
|
||||
}
|
||||
|
||||
function setDaysViewSpan(span: DaysViewSpan) {
|
||||
if (!DAYS_VIEW_SPANS.includes(span)) {
|
||||
return
|
||||
}
|
||||
|
||||
daysViewSpan.value = span
|
||||
userStore.setSetting('chrono.daysViewSpan', span)
|
||||
}
|
||||
|
||||
function setAgendaViewSpan(span: AgendaViewSpan) {
|
||||
agendaViewSpan.value = span
|
||||
userStore.setSetting('chrono.agendaViewSpan', span)
|
||||
}
|
||||
|
||||
function selectCalendar(calendar: CollectionObject) {
|
||||
selectedCollection.value = calendar
|
||||
}
|
||||
|
||||
function selectTaskList(list: CollectionObject) {
|
||||
selectedCollection.value = list
|
||||
}
|
||||
|
||||
function openCreateCalendar() {
|
||||
editingCollection.value = new CollectionObject()
|
||||
editingCollection.value.properties.fromJson({
|
||||
...editingCollection.value.properties.toJson(),
|
||||
contents: { event: true },
|
||||
})
|
||||
collectionEditorMode.value = 'create'
|
||||
collectionEditorType.value = 'calendar'
|
||||
showCollectionEditor.value = true
|
||||
}
|
||||
|
||||
function openCreateTaskList() {
|
||||
editingCollection.value = new CollectionObject()
|
||||
editingCollection.value.properties.fromJson({
|
||||
...editingCollection.value.properties.toJson(),
|
||||
contents: { task: true },
|
||||
})
|
||||
collectionEditorMode.value = 'create'
|
||||
collectionEditorType.value = 'tasklist'
|
||||
showCollectionEditor.value = true
|
||||
}
|
||||
|
||||
function openEditCalendar(collection: CollectionObject) {
|
||||
editingCollection.value = collection
|
||||
collectionEditorMode.value = 'edit'
|
||||
collectionEditorType.value = 'calendar'
|
||||
showCollectionEditor.value = true
|
||||
}
|
||||
|
||||
function openEditTaskList(collection: CollectionObject) {
|
||||
editingCollection.value = collection
|
||||
collectionEditorMode.value = 'edit'
|
||||
collectionEditorType.value = 'tasklist'
|
||||
showCollectionEditor.value = true
|
||||
}
|
||||
|
||||
function ensureSelectedCollection(targetType: 'calendar' | 'tasklist'): CollectionObject | null {
|
||||
const list = targetType === 'calendar' ? calendars.value : taskLists.value
|
||||
|
||||
if (!selectedCollection.value && list.length > 0) {
|
||||
selectedCollection.value = list[0]
|
||||
}
|
||||
|
||||
return selectedCollection.value
|
||||
}
|
||||
|
||||
function createEvent() {
|
||||
const collection = ensureSelectedCollection('calendar')
|
||||
if (!collection) {
|
||||
return
|
||||
}
|
||||
|
||||
const entity = new EntityObject()
|
||||
entity.properties = new EventObject()
|
||||
selectedEntity.value = entity
|
||||
entityEditorMode.value = 'edit'
|
||||
showEventEditor.value = true
|
||||
}
|
||||
|
||||
function editEvent(entity: EntityObject) {
|
||||
selectedEntity.value = entity
|
||||
entityEditorMode.value = 'view'
|
||||
showEventEditor.value = true
|
||||
}
|
||||
|
||||
function createTask() {
|
||||
const collection = ensureSelectedCollection('tasklist')
|
||||
if (!collection) {
|
||||
return
|
||||
}
|
||||
|
||||
const entity = new EntityObject()
|
||||
entity.properties = new TaskObject()
|
||||
selectedEntity.value = entity
|
||||
entityEditorMode.value = 'edit'
|
||||
showTaskEditor.value = true
|
||||
}
|
||||
|
||||
function editTask(entity: EntityObject) {
|
||||
selectedEntity.value = entity
|
||||
entityEditorMode.value = 'view'
|
||||
showTaskEditor.value = true
|
||||
}
|
||||
|
||||
function createEventFromDate(date: Date) {
|
||||
const collection = ensureSelectedCollection('calendar')
|
||||
if (!collection) {
|
||||
return
|
||||
}
|
||||
|
||||
const entity = new EntityObject()
|
||||
entity.properties = new EventObject()
|
||||
const eventData = entity.properties as EventObject
|
||||
eventData.startsOn = date.toISOString()
|
||||
eventData.endsOn = new Date(date.getTime() + 60 * 60 * 1000).toISOString()
|
||||
|
||||
selectedEntity.value = entity
|
||||
entityEditorMode.value = 'edit'
|
||||
showEventEditor.value = true
|
||||
}
|
||||
|
||||
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 toggleCalendarVisibility(collection: CollectionObject) {
|
||||
const nextVisibility = collection.properties.visibility === false
|
||||
const updated = collection.clone()
|
||||
updated.properties.visibility = nextVisibility
|
||||
|
||||
await collectionsStore.update(
|
||||
updated.provider,
|
||||
updated.service,
|
||||
updated.identifier,
|
||||
updated.properties,
|
||||
)
|
||||
}
|
||||
|
||||
async function saveEvent(entity: EntityObject, collection?: CollectionObject | null) {
|
||||
const targetCollection = collection instanceof CollectionObject
|
||||
? collection
|
||||
: selectedCollection.value
|
||||
|
||||
if (!targetCollection) {
|
||||
throw new Error('No calendar collection selected')
|
||||
}
|
||||
|
||||
selectedEntity.value = await entityActions.saveEntity(entity, targetCollection)
|
||||
selectedCollection.value = targetCollection
|
||||
entityEditorMode.value = 'view'
|
||||
}
|
||||
|
||||
async function saveTask(entity: EntityObject, collection?: CollectionObject | null) {
|
||||
const targetCollection = collection instanceof CollectionObject
|
||||
? collection
|
||||
: selectedCollection.value
|
||||
|
||||
if (!targetCollection) {
|
||||
throw new Error('No task list selected')
|
||||
}
|
||||
|
||||
selectedEntity.value = await entityActions.saveEntity(entity, targetCollection)
|
||||
selectedCollection.value = targetCollection
|
||||
entityEditorMode.value = 'view'
|
||||
}
|
||||
|
||||
async function deleteEvent(entity: EntityObject, collection?: CollectionObject | null) {
|
||||
await entityActions.deleteEntity(entity, collection)
|
||||
closeEntityEditor()
|
||||
}
|
||||
|
||||
async function deleteTask(entity: EntityObject, collection?: CollectionObject | null) {
|
||||
await entityActions.deleteEntity(entity, collection)
|
||||
closeEntityEditor()
|
||||
}
|
||||
|
||||
async function toggleTaskComplete(taskId: string | number) {
|
||||
const taskEntity = tasks.value.find(task => task.identifier === taskId)
|
||||
if (!taskEntity) {
|
||||
return
|
||||
}
|
||||
|
||||
await entityActions.toggleTaskCompletion(taskEntity)
|
||||
}
|
||||
|
||||
async function saveCollection(collection: CollectionObject, service: ServiceObject) {
|
||||
if (collectionEditorMode.value === 'create') {
|
||||
await collectionsStore.create(
|
||||
service.provider,
|
||||
service.identifier || '',
|
||||
null,
|
||||
collection.properties,
|
||||
)
|
||||
} else {
|
||||
await collectionsStore.update(
|
||||
collection.provider,
|
||||
collection.service,
|
||||
collection.identifier,
|
||||
collection.properties,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async function deleteCollection(collection: CollectionObject) {
|
||||
await collectionsStore.delete(collection.provider, collection.service, collection.identifier)
|
||||
|
||||
if (selectedCollection.value?.identifier === collection.identifier) {
|
||||
selectedCollection.value = null
|
||||
}
|
||||
}
|
||||
|
||||
async function initialize() {
|
||||
loading.value = true
|
||||
try {
|
||||
await collectionsStore.list()
|
||||
|
||||
const sources = buildSources(collections.value)
|
||||
if (Object.keys(sources).length > 0) {
|
||||
await entitiesStore.list(sources as SourceSelector)
|
||||
}
|
||||
|
||||
if (
|
||||
selectedCollection.value
|
||||
&& !collections.value.find(collection => collection.identifier === selectedCollection.value?.identifier)
|
||||
) {
|
||||
selectedCollection.value = null
|
||||
}
|
||||
} finally {
|
||||
loading.value = false
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
viewMode,
|
||||
calendarView,
|
||||
daysViewSpan,
|
||||
agendaViewSpan,
|
||||
currentDate,
|
||||
sidebarVisible,
|
||||
selectedCollection,
|
||||
selectedEntity,
|
||||
showEventEditor,
|
||||
showTaskEditor,
|
||||
showCollectionEditor,
|
||||
entityEditorMode,
|
||||
editingCollection,
|
||||
collectionEditorMode,
|
||||
collectionEditorType,
|
||||
loading,
|
||||
|
||||
collections,
|
||||
entities,
|
||||
calendars,
|
||||
taskLists,
|
||||
events,
|
||||
tasks,
|
||||
isTaskView,
|
||||
filteredEvents,
|
||||
filteredTasks,
|
||||
|
||||
setViewMode,
|
||||
setCalendarView,
|
||||
setDaysViewSpan,
|
||||
setAgendaViewSpan,
|
||||
selectCalendar,
|
||||
selectTaskList,
|
||||
openCreateCalendar,
|
||||
openCreateTaskList,
|
||||
openEditCalendar,
|
||||
openEditTaskList,
|
||||
createEvent,
|
||||
editEvent,
|
||||
createTask,
|
||||
editTask,
|
||||
createEventFromDate,
|
||||
startEditingSelectedEntity,
|
||||
cancelEditingSelectedEntity,
|
||||
closeEntityEditor,
|
||||
toggleCalendarVisibility,
|
||||
toggleTaskComplete,
|
||||
saveEvent,
|
||||
deleteEvent,
|
||||
saveTask,
|
||||
deleteTask,
|
||||
saveCollection,
|
||||
deleteCollection,
|
||||
initialize,
|
||||
}
|
||||
})
|
||||
Reference in New Issue
Block a user