refactor: code clean up

Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
2026-07-07 20:48:20 -04:00
parent 3c0ea698b1
commit 41a2de2b3d
4 changed files with 82 additions and 108 deletions
+10 -5
View File
@@ -49,6 +49,10 @@ const calendarOptions = computed(() =>
})) }))
) )
const selectedCalendar = computed(() =>
(props.calendars || []).find(calendar => calendar.identifier === selectedCollectionId.value) ?? null
)
// Permissions // Permissions
const isExternalEvent = computed(() => { const isExternalEvent = computed(() => {
return false return false
@@ -77,13 +81,12 @@ const cancelEdit = () => {
} }
const saveEntity = async () => { const saveEntity = async () => {
if (!editableEntity.value) { if (!editableEntity.value || !selectedCalendar.value) {
return return
} }
saving.value = true saving.value = true
const targetCollection = (props.calendars || []).find(cal => cal.identifier === selectedCollectionId.value) emit('save', editableEntity.value as EntityObject, selectedCalendar.value)
emit('save', editableEntity.value as EntityObject, targetCollection || props.collection)
saving.value = false saving.value = false
} }
@@ -127,7 +130,7 @@ watch(
(newEntity) => { (newEntity) => {
const entity = newEntity as EntityObject | null const entity = newEntity as EntityObject | null
draftEntity.value = entity?.clone ? entity.clone() : null draftEntity.value = entity?.clone ? entity.clone() : null
selectedCollectionId.value = entity?.collection || props.collection?.identifier || props.calendars?.[0]?.identifier || '' selectedCollectionId.value = entity?.collection || props.collection?.identifier || ''
}, },
{ immediate: true }, { immediate: true },
) )
@@ -138,7 +141,7 @@ watch(
const entity = props.entity as EntityObject | null const entity = props.entity as EntityObject | null
if (newMode === 'edit' && entity?.clone) { if (newMode === 'edit' && entity?.clone) {
draftEntity.value = entity.clone() draftEntity.value = entity.clone()
selectedCollectionId.value = entity.collection || props.collection?.identifier || props.calendars?.[0]?.identifier || '' selectedCollectionId.value = entity.collection || props.collection?.identifier || ''
} }
}, },
) )
@@ -194,6 +197,7 @@ watch(
v-model="selectedCollectionId" v-model="selectedCollectionId"
:items="calendarOptions" :items="calendarOptions"
label="Calendar" label="Calendar"
:rules="[value => (value !== '' && value != null) || 'Calendar is required']"
variant="outlined" variant="outlined"
density="compact" density="compact"
class="mb-4" class="mb-4"
@@ -293,6 +297,7 @@ watch(
color="primary" color="primary"
variant="elevated" variant="elevated"
@click="saveEntity" @click="saveEntity"
:disabled="!selectedCalendar"
:loading="saving"> :loading="saving">
Save Save
</v-btn> </v-btn>
+10 -4
View File
@@ -34,6 +34,7 @@
v-model="selectedCollectionId" v-model="selectedCollectionId"
:items="listOptions" :items="listOptions"
label="Task List" label="Task List"
:rules="[value => (value !== '' && value != null) || 'Task list is required']"
:readonly="!isEditing || !canChangeCollection" :readonly="!isEditing || !canChangeCollection"
:variant="isEditing && canChangeCollection ? 'outlined' : 'plain'" :variant="isEditing && canChangeCollection ? 'outlined' : 'plain'"
class="mb-4" class="mb-4"
@@ -243,13 +244,13 @@ watch(() => props.entity, (newEntity) => {
startDate.value = ''; startDate.value = '';
} }
selectedCollectionId.value = draftEntity.value?.collection || props.collection?.identifier || props.lists[0]?.identifier || ''; selectedCollectionId.value = draftEntity.value?.collection || props.collection?.identifier || '';
}, { immediate: true }); }, { immediate: true });
watch(() => props.mode, (newMode) => { watch(() => props.mode, (newMode) => {
if (newMode === 'edit' && props.entity) { if (newMode === 'edit' && props.entity) {
draftEntity.value = cloneEntity(props.entity); draftEntity.value = cloneEntity(props.entity);
selectedCollectionId.value = draftEntity.value?.collection || props.collection?.identifier || props.lists[0]?.identifier || ''; selectedCollectionId.value = draftEntity.value?.collection || props.collection?.identifier || '';
} }
}); });
@@ -260,6 +261,10 @@ const listOptions = computed(() =>
})) }))
); );
const selectedTaskList = computed(() =>
props.lists.find(list => list.identifier === selectedCollectionId.value) ?? null
);
const priorityOptions = [ const priorityOptions = [
{ title: 'Low', value: 3 }, { title: 'Low', value: 3 },
{ title: 'Medium', value: 2 }, { title: 'Medium', value: 2 },
@@ -288,8 +293,9 @@ async function handleSave() {
const { valid } = await formRef.value.validate(); const { valid } = await formRef.value.validate();
if (!valid) return; if (!valid) return;
const targetCollection = props.lists.find(list => list.identifier === selectedCollectionId.value); if (!selectedTaskList.value) return;
emit('save', editableEntity.value as EntityObject, targetCollection || props.collection);
emit('save', editableEntity.value as EntityObject, selectedTaskList.value);
} }
function handleCancel() { function handleCancel() {
+50 -55
View File
@@ -1,4 +1,3 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, onMounted, ref, watch } from 'vue'; import { computed, onMounted, ref, watch } from 'vue';
import { storeToRefs } from 'pinia'; import { storeToRefs } from 'pinia';
@@ -72,8 +71,7 @@ const {
selectSection, selectSection,
selectDate, selectDate,
selectCollection, selectCollection,
openEditCalendar, openCollectionEditor,
openEditTaskList,
createEventFromDate, createEventFromDate,
startEditingSelectedEntity, startEditingSelectedEntity,
cancelEditingSelectedEntity, cancelEditingSelectedEntity,
@@ -86,8 +84,6 @@ const {
deleteTask, deleteTask,
saveCollection, saveCollection,
deleteCollection, deleteCollection,
openCreateCalendar,
openCreateTaskList,
openImport, openImport,
closeImport, closeImport,
} = chronoUiStore; } = chronoUiStore;
@@ -98,35 +94,51 @@ const {
ensureTasksLoaded, ensureTasksLoaded,
} = chronoOperationsStore; } = chronoOperationsStore;
function setCalendarView(view: CalendarViewType) {
chronoSettingsStore.calendarView = view;
}
function setDaysViewSpan(span: DaysViewSpan) {
chronoSettingsStore.daysViewSpan = span;
}
function setAgendaViewSpan(span: AgendaViewSpan) {
chronoSettingsStore.agendaViewSpan = span;
}
const fileInputRef = ref<HTMLInputElement | null>(null) const fileInputRef = ref<HTMLInputElement | null>(null)
function triggerFileInput() { fileInputRef.value?.click() }
async function onFilesSelected(event: Event) { watch(() => route.fullPath, async () => {
selectSectionFromRoute();
if (isTasksSection.value) {
await ensureTasksLoaded();
}
});
watch(
[calendarView, currentDate, daysViewSpan, agendaViewSpan],
() => { loadVisibleRangeOperations(computeVisibleRange()); },
{ immediate: true },
);
onMounted(async () => {
try {
selectSectionFromRoute();
await initialize(isTasksSection.value ? 'tasks' : 'calendar');
} catch (error) {
console.error('[Chrono] - Failed to load data from Chrono Manager:', error);
}
});
function handleImportStart() {
fileInputRef.value?.click()
}
async function handleImportSelect(event: Event) {
const input = event.target as HTMLInputElement const input = event.target as HTMLInputElement
const files = Array.from(input.files ?? []) const files = Array.from(input.files ?? [])
input.value = '' input.value = ''
if (files.length) await openImport(files) if (files.length) await openImport(files)
} }
function selectSectionFromRoute() { function handleCalendarViewChange(view: CalendarViewType) {
const routePath = route.path; chronoSettingsStore.calendarView = view;
const section = routePath.endsWith('/tasks') ? 'tasks' : 'calendar';
selectSection(section);
} }
function handleCalendarViewChange(view: CalendarViewType) { function handleCalendarDaysViewSpanChange(span: DaysViewSpan) {
setCalendarView(view); chronoSettingsStore.daysViewSpan = span;
}
function handleCalendarAgendaViewSpanChange(span: AgendaViewSpan) {
chronoSettingsStore.agendaViewSpan = span;
} }
function computeVisibleRange(): EpochSpan { function computeVisibleRange(): EpochSpan {
@@ -141,28 +153,11 @@ function computeVisibleRange(): EpochSpan {
return daysVisibleRange(currentDate.value, spanToDays(span)); return daysVisibleRange(currentDate.value, spanToDays(span));
} }
watch( function selectSectionFromRoute() {
[calendarView, currentDate, daysViewSpan, agendaViewSpan], const routePath = route.path;
() => { loadVisibleRangeOperations(computeVisibleRange()); }, const section = routePath.endsWith('/tasks') ? 'tasks' : 'calendar';
{ immediate: true }, selectSection(section);
); }
onMounted(async () => {
try {
selectSectionFromRoute();
await initialize(isTasksSection.value ? 'tasks' : 'calendar');
} catch (error) {
console.error('[Chrono] - Failed to load data from ChronoManager:', error);
}
});
watch(() => route.fullPath, async () => {
selectSectionFromRoute();
if (isTasksSection.value) {
await ensureTasksLoaded();
}
});
</script> </script>
<template> <template>
@@ -218,7 +213,7 @@ watch(() => route.fullPath, async () => {
:selected-collection="selectedCollection" :selected-collection="selectedCollection"
type="calendar" type="calendar"
@select="selectCollection" @select="selectCollection"
@edit="openEditCalendar" @edit="openCollectionEditor('calendar', $event)"
@toggle-visibility="toggleCalendarVisibility" @toggle-visibility="toggleCalendarVisibility"
/> />
<CollectionList <CollectionList
@@ -227,7 +222,7 @@ watch(() => route.fullPath, async () => {
:selected-collection="selectedCollection" :selected-collection="selectedCollection"
type="tasklist" type="tasklist"
@select="selectCollection" @select="selectCollection"
@edit="openEditTaskList" @edit="openCollectionEditor('tasklist', $event)"
/> />
<v-btn <v-btn
@@ -236,7 +231,7 @@ watch(() => route.fullPath, async () => {
color="primary" color="primary"
block block
class="mt-3" class="mt-3"
@click="openCreateCalendar" @click="openCollectionEditor('calendar')"
> >
<v-icon start>mdi-plus</v-icon> <v-icon start>mdi-plus</v-icon>
New Calendar New Calendar
@@ -248,17 +243,17 @@ watch(() => route.fullPath, async () => {
color="primary" color="primary"
block block
class="mt-3" class="mt-3"
@click="openCreateTaskList" @click="openCollectionEditor('tasklist')"
> >
<v-icon start>mdi-plus</v-icon> <v-icon start>mdi-plus</v-icon>
New Task List New Task List
</v-btn> </v-btn>
<v-divider class="my-3" /> <v-divider class="my-3" />
<v-btn variant="text" prepend-icon="mdi-calendar-import" block class="justify-start" @click="triggerFileInput"> <v-btn variant="text" prepend-icon="mdi-calendar-import" block class="justify-start" @click="handleImportStart">
Import iCalendar Import iCalendar
</v-btn> </v-btn>
<input ref="fileInputRef" type="file" accept=".ics,text/calendar" multiple class="d-none" @change="onFilesSelected" /> <input ref="fileInputRef" type="file" accept=".ics,text/calendar" multiple class="d-none" @change="handleImportSelect" />
<!-- Mini Calendar Widget --> <!-- Mini Calendar Widget -->
<v-card v-if="!isTasksSection" class="mt-4" variant="outlined"> <v-card v-if="!isTasksSection" class="mt-4" variant="outlined">
@@ -307,8 +302,8 @@ watch(() => route.fullPath, async () => {
@event-click="editEvent" @event-click="editEvent"
@date-click="createEventFromDate" @date-click="createEventFromDate"
@update:current-date="selectDate" @update:current-date="selectDate"
@update:days-span="setDaysViewSpan" @update:days-span="handleCalendarDaysViewSpanChange"
@update:agenda-span="setAgendaViewSpan" @update:agenda-span="handleCalendarAgendaViewSpanChange"
/> />
<TaskView <TaskView
+12 -44
View File
@@ -39,46 +39,21 @@ export const useChronoUiStore = defineStore('chronoUiStore', () => {
selectedCollection.value = collection selectedCollection.value = collection
} }
function openCollectionEditor(type: 'calendar' | 'tasklist') { function openCollectionEditor(type: 'calendar' | 'tasklist', collection?: CollectionObject) {
const collection = new CollectionObject() const target = collection ?? new CollectionObject()
collection.properties.fromJson({ if (!collection) {
...collection.properties.toJson(), target.properties.fromJson({
content: [type === 'calendar' ? 'event' : 'task'], ...target.properties.toJson(),
}) content: [type === 'calendar' ? 'event' : 'task'],
editingCollection.value = collection })
collectionEditorMode.value = 'create' }
editingCollection.value = target
collectionEditorMode.value = collection ? 'edit' : 'create'
collectionEditorType.value = type collectionEditorType.value = type
showCollectionEditor.value = true showCollectionEditor.value = true
} }
function openCreateCalendar() {
openCollectionEditor('calendar')
}
function openCreateTaskList() {
openCollectionEditor('tasklist')
}
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(type: 'calendar' | 'tasklist'): CollectionObject | null {
const candidates = type === 'calendar' ? operationsStore.calendars : operationsStore.taskLists
if (!selectedCollection.value && candidates.length > 0) selectedCollection.value = candidates[0]
return selectedCollection.value
}
function openEntityEditor(entity: EntityObject, type: 'event' | 'task', mode: 'edit' | 'view') { function openEntityEditor(entity: EntityObject, type: 'event' | 'task', mode: 'edit' | 'view') {
selectedEntity.value = entity selectedEntity.value = entity
entityEditorMode.value = mode entityEditorMode.value = mode
@@ -87,8 +62,6 @@ export const useChronoUiStore = defineStore('chronoUiStore', () => {
} }
function createEventFromDate(date?: Date) { function createEventFromDate(date?: Date) {
if (!ensureSelectedCollection('calendar')) return
const entity = new EntityObject() const entity = new EntityObject()
entity.properties = new EventObject() entity.properties = new EventObject()
if (date) { if (date) {
@@ -107,8 +80,6 @@ export const useChronoUiStore = defineStore('chronoUiStore', () => {
} }
function createTask() { function createTask() {
if (!ensureSelectedCollection('tasklist')) return
const entity = new EntityObject() const entity = new EntityObject()
entity.properties = new TaskObject() entity.properties = new TaskObject()
openEntityEditor(entity, 'task', 'edit') openEntityEditor(entity, 'task', 'edit')
@@ -217,10 +188,7 @@ export const useChronoUiStore = defineStore('chronoUiStore', () => {
selectSection, selectSection,
selectDate, selectDate,
selectCollection, selectCollection,
openCreateCalendar, openCollectionEditor,
openCreateTaskList,
openEditCalendar,
openEditTaskList,
createEvent, createEvent,
editEvent, editEvent,
createTask, createTask,