chore: standardize chrono provider

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-02-17 03:12:12 -05:00
parent cc4e467cef
commit f2f7bfc391
11 changed files with 282 additions and 224 deletions
+116 -58
View File
@@ -8,6 +8,8 @@ import { useEntitiesStore } from '@ChronoManager/stores/entitiesStore';
import { useServicesStore } from '@ChronoManager/stores/servicesStore';
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 type { CalendarView as CalendarViewType } from '@/types';
import CollectionList from '@/components/CollectionList.vue';
@@ -45,19 +47,19 @@ const selectedCollection = ref<CollectionObject | null>(null);
// Computed - filter collections and entities
const calendars = computed(() => {
return collections.value.filter(col => col.contents?.event);
return collections.value.filter(col => col.properties.contents?.event);
});
const taskLists = computed(() => {
return collections.value.filter(col => col.contents?.task);
return collections.value.filter(col => col.properties.contents?.task);
});
const events = computed(() => {
return entities.value.filter(entity => entity.data && (entity.data as any).type === 'event');
return entities.value.filter(entity => entity.properties && (entity.properties as any).type === 'event');
});
const tasks = computed(() => {
return entities.value.filter(entity => entity.data && (entity.data as any).type === 'task');
return entities.value.filter(entity => entity.properties && (entity.properties as any).type === 'task');
});
// Dialog state
@@ -75,11 +77,11 @@ const isTaskView = computed(() => viewMode.value === 'tasks');
const filteredEvents = computed(() => {
const visibleCalendarIds = calendars.value
.filter(cal => cal.enabled !== false)
.map(cal => cal.id);
.filter(cal => cal.properties.visibility !== false)
.map(cal => cal.identifier);
return events.value.filter(event =>
visibleCalendarIds.includes(event.in)
visibleCalendarIds.includes(event.collection)
);
});
@@ -94,8 +96,8 @@ function selectCalendar(calendar: CollectionObject) {
}
function createCalendar() {
editingCollection.value = collectionsStore.fresh();
editingCollection.value.contents = { event: true };
editingCollection.value = new CollectionObject();
editingCollection.value.properties.contents = { event: true };
collectionEditorMode.value = 'create';
collectionEditorType.value = 'calendar';
showCollectionEditor.value = true;
@@ -110,7 +112,12 @@ function editCalendar(collection: CollectionObject) {
async function toggleCalendarVisibility(collection: CollectionObject) {
try {
await collectionsStore.modify(collection);
await collectionsStore.update(
collection.provider,
collection.service,
collection.identifier,
collection.properties
);
console.log('[Chrono] - Toggled calendar visibility:', collection);
} catch (error) {
console.error('[Chrono] - Failed to toggle calendar visibility:', error);
@@ -123,8 +130,8 @@ function selectTaskList(list: CollectionObject) {
}
function createTaskList() {
editingCollection.value = collectionsStore.fresh();
editingCollection.value.contents = { task: true };
editingCollection.value = new CollectionObject();
editingCollection.value.properties.contents = { task: true };
collectionEditorMode.value = 'create';
collectionEditorType.value = 'tasklist';
showCollectionEditor.value = true;
@@ -148,9 +155,8 @@ function createEvent() {
return;
}
// Create fresh event entity
selectedEntity.value = entitiesStore.fresh('event');
selectedEntity.value.in = selectedCollection.value.id;
selectedEntity.value = new EntityObject();
selectedEntity.value.properties = new EventObject();
entityEditorMode.value = 'edit';
showEventEditor.value = true;
}
@@ -171,15 +177,25 @@ async function saveEvent(entity: EntityObject, collection?: CollectionObject | n
return;
}
if (entity.data) {
entity.data.modified = new Date();
}
const eventData = entity.properties as EventObject;
eventData.modified = new Date().toISOString();
if (entity.id === null) {
entity.data.created = new Date();
selectedEntity.value = await entitiesStore.create(collection, entity);
if (!entity.identifier) {
eventData.created = new Date().toISOString();
selectedEntity.value = await entitiesStore.create(
collection.provider,
collection.service,
collection.identifier,
eventData.toJson()
);
} else {
selectedEntity.value = await entitiesStore.modify(collection, entity);
selectedEntity.value = await entitiesStore.update(
collection.provider,
collection.service,
collection.identifier,
entity.identifier,
eventData.toJson()
);
}
entityEditorMode.value = 'view';
@@ -191,14 +207,14 @@ async function saveEvent(entity: EntityObject, collection?: CollectionObject | n
async function deleteEvent(entity: EntityObject, collection?: CollectionObject | null) {
try {
if (!(collection instanceof CollectionObject)) {
collection = collections.value.find(c => c.id === entity.in);
collection = collections.value.find(c => c.identifier === entity.collection);
}
if (!collection) {
console.error('[Chrono] - No collection found');
return;
}
await entitiesStore.destroy(collection, entity);
await entitiesStore.delete(collection.provider, collection.service, collection.identifier, entity.identifier);
selectedEntity.value = null;
entityEditorMode.value = 'view';
showEventEditor.value = false;
@@ -218,12 +234,11 @@ function handleDateClick(date: Date) {
return;
}
selectedEntity.value = entitiesStore.fresh('event');
selectedEntity.value.in = selectedCollection.value.id;
if (selectedEntity.value.data) {
selectedEntity.value.data.startsOn = date;
selectedEntity.value.data.endsOn = new Date(date.getTime() + 60 * 60 * 1000);
}
selectedEntity.value = new EntityObject();
selectedEntity.value.properties = new EventObject();
const eventData = selectedEntity.value.properties as EventObject;
eventData.startsOn = date.toISOString();
eventData.endsOn = new Date(date.getTime() + 60 * 60 * 1000).toISOString();
entityEditorMode.value = 'edit';
showEventEditor.value = true;
}
@@ -257,9 +272,8 @@ function createTask() {
return;
}
// Create fresh task entity
selectedEntity.value = entitiesStore.fresh('task');
selectedEntity.value.in = selectedCollection.value.id;
selectedEntity.value = new EntityObject();
selectedEntity.value.properties = new TaskObject();
entityEditorMode.value = 'edit';
showTaskEditor.value = true;
}
@@ -280,15 +294,25 @@ async function saveTask(entity: EntityObject, collection?: CollectionObject | nu
return;
}
if (entity.data) {
entity.data.modified = new Date();
}
const taskData = entity.properties as TaskObject;
taskData.modified = new Date().toISOString();
if (entity.id === null) {
entity.data.created = new Date();
selectedEntity.value = await entitiesStore.create(collection, entity);
if (!entity.identifier) {
taskData.created = new Date().toISOString();
selectedEntity.value = await entitiesStore.create(
collection.provider,
collection.service,
collection.identifier,
taskData.toJson()
);
} else {
selectedEntity.value = await entitiesStore.modify(collection, entity);
selectedEntity.value = await entitiesStore.update(
collection.provider,
collection.service,
collection.identifier,
entity.identifier,
taskData.toJson()
);
}
entityEditorMode.value = 'view';
@@ -300,14 +324,14 @@ async function saveTask(entity: EntityObject, collection?: CollectionObject | nu
async function deleteTask(entity: EntityObject, collection?: CollectionObject | null) {
try {
if (!(collection instanceof CollectionObject)) {
collection = collections.value.find(c => c.id === entity.in);
collection = collections.value.find(c => c.identifier === entity.collection);
}
if (!collection) {
console.error('[Chrono] - No collection found');
return;
}
await entitiesStore.destroy(collection, entity);
await entitiesStore.delete(collection.provider, collection.service, collection.identifier, entity.identifier);
selectedEntity.value = null;
entityEditorMode.value = 'view';
showTaskEditor.value = false;
@@ -318,21 +342,27 @@ async function deleteTask(entity: EntityObject, collection?: CollectionObject |
async function toggleTaskComplete(taskId: string | number) {
try {
const entity = entities.value.find(e => e.id === taskId);
if (!entity || !entity.data) return;
const entity = entities.value.find(e => e.identifier === taskId);
if (!entity || !entity.properties) return;
const collection = collections.value.find(c => c.id === entity.in);
const collection = collections.value.find(c => c.identifier === entity.collection);
if (!collection) return;
const taskData = entity.data as any;
const taskData = entity.properties as TaskObject;
const isCompleted = taskData.status === 'completed';
taskData.status = isCompleted ? 'needs-action' : 'completed';
taskData.completedOn = isCompleted ? null : new Date();
taskData.completedOn = isCompleted ? null : new Date().toISOString();
taskData.progress = isCompleted ? null : 100;
taskData.modified = new Date();
taskData.modified = new Date().toISOString();
await entitiesStore.modify(collection, entity);
await entitiesStore.update(
collection.provider,
collection.service,
collection.identifier,
entity.identifier,
taskData.toJson()
);
} catch (error) {
console.error('[Chrono] - Failed to toggle task completion:', error);
}
@@ -341,14 +371,24 @@ async function toggleTaskComplete(taskId: string | number) {
async function saveCollection(collection: CollectionObject, service: ServiceObject) {
try {
if (collectionEditorMode.value === 'create') {
await collectionsStore.create(service, collection);
await collectionsStore.create(
service.provider,
service.identifier || '',
null,
collection.properties
);
console.log('[Chrono] - Created collection:', collection);
} else {
await collectionsStore.modify(collection);
await collectionsStore.update(
collection.provider,
collection.service,
collection.identifier,
collection.properties
);
console.log('[Chrono] - Modified collection:', collection);
}
// Reload collections
collections.value = await collectionsStore.list();
collections.value = Object.values(await collectionsStore.list());
} catch (error) {
console.error('[Chrono] - Failed to save collection:', error);
}
@@ -356,11 +396,11 @@ async function saveCollection(collection: CollectionObject, service: ServiceObje
async function deleteCollection(collection: CollectionObject) {
try {
await collectionsStore.destroy(collection);
await collectionsStore.delete(collection.provider, collection.service, collection.identifier);
console.log('[Chrono] - Deleted collection:', collection);
// Reload collections
collections.value = await collectionsStore.list();
if (selectedCollection.value?.id === collection.id) {
collections.value = Object.values(await collectionsStore.list());
if (selectedCollection.value?.identifier === collection.identifier) {
selectedCollection.value = null;
}
} catch (error) {
@@ -372,10 +412,28 @@ async function deleteCollection(collection: CollectionObject) {
onMounted(async () => {
try {
// Load collections (calendars and task lists)
collections.value = await collectionsStore.list();
collections.value = Object.values(await collectionsStore.list());
// Load entities (events and tasks)
entities.value = await entitiesStore.list(null, null, null);
// Load entities (events and tasks) for available collection sources only
const sources = collections.value.reduce<Record<string, Record<string, Record<string | number, true>>>>((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;
}, {});
if (Object.keys(sources).length > 0) {
entities.value = Object.values(await entitiesStore.list(sources));
} else {
entities.value = [];
}
console.log('[Chrono] - Loaded data from ChronoManager:', {
collections: collections.value.length,