refactor: code clean up
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -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>
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
+10
-42
@@ -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({
|
||||||
|
...target.properties.toJson(),
|
||||||
content: [type === 'calendar' ? 'event' : 'task'],
|
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,
|
||||||
|
|||||||
Reference in New Issue
Block a user