refactor: rename main entry point
Signed-off-by: Sebastian Krupinski <krupinski01@gmail.com>
This commit is contained in:
@@ -0,0 +1,332 @@
|
||||
<script setup lang="ts">
|
||||
import { computed, onMounted, watch } from 'vue';
|
||||
import { storeToRefs } from 'pinia';
|
||||
import { useRoute } from 'vue-router';
|
||||
import { useModuleStore } from '@KTXC/stores/moduleStore';
|
||||
import { useChronoOperationsStore } from '@/stores/chronoOperationsStore';
|
||||
import { useChronoSettingsStore } from '@/stores/chronoSettingsStore';
|
||||
import { useChronoUiStore } from '@/stores/chronoUiStore';
|
||||
import type { CalendarView as CalendarViewType } from '@/types';
|
||||
import { spanToDays, type AgendaViewSpan, type DaysViewSpan } from '@/types/spans';
|
||||
import { daysVisibleRange, monthGridVisibleRange } from '@/utils/date';
|
||||
import Sidebar from '@/components/Sidebar.vue';
|
||||
import CollectionEditor from '@/components/CollectionEditor.vue';
|
||||
import CalendarView from '@/components/CalendarView.vue';
|
||||
import TaskView from '@/components/TaskView.vue';
|
||||
import EventEditor from '@/components/EventEditor.vue';
|
||||
import TaskEditor from '@/components/TaskEditor.vue';
|
||||
import ImportDialog from '@/components/ImportDialog.vue';
|
||||
import { EpochSpan } from '@/types/date';
|
||||
|
||||
// Check if chrono manager is available
|
||||
const moduleStore = useModuleStore();
|
||||
const isChronoManagerAvailable = computed(() => {
|
||||
return moduleStore.has('chrono_manager') || moduleStore.has('ChronoManager')
|
||||
});
|
||||
|
||||
const chronoOperationsStore = useChronoOperationsStore();
|
||||
const chronoSettingsStore = useChronoSettingsStore();
|
||||
const chronoUiStore = useChronoUiStore();
|
||||
const route = useRoute();
|
||||
|
||||
const {
|
||||
calendarView,
|
||||
daysViewSpan,
|
||||
agendaViewSpan,
|
||||
} = storeToRefs(chronoSettingsStore);
|
||||
|
||||
const {
|
||||
loading,
|
||||
calendars,
|
||||
taskLists,
|
||||
filteredTasks,
|
||||
collections,
|
||||
} = storeToRefs(chronoOperationsStore);
|
||||
|
||||
const {
|
||||
currentDate,
|
||||
sidebarVisible,
|
||||
selectedCollection,
|
||||
showEventEditor,
|
||||
showTaskEditor,
|
||||
showCollectionEditor,
|
||||
showImportDialog,
|
||||
selectedEntity,
|
||||
entityEditorMode,
|
||||
editingCollection,
|
||||
collectionEditorMode,
|
||||
collectionEditorType,
|
||||
isTasksSection,
|
||||
} = storeToRefs(chronoUiStore);
|
||||
|
||||
const { loadVisibleRange: loadVisibleRangeOperations } = chronoOperationsStore;
|
||||
|
||||
const {
|
||||
initialize,
|
||||
selectSection,
|
||||
selectDate,
|
||||
createEventFromDate,
|
||||
startEditingSelectedEntity,
|
||||
cancelEditingSelectedEntity,
|
||||
closeEntityEditor,
|
||||
editEvent,
|
||||
editTask,
|
||||
saveEvent,
|
||||
deleteEvent,
|
||||
saveTask,
|
||||
deleteTask,
|
||||
saveCollection,
|
||||
deleteCollection,
|
||||
closeImport,
|
||||
} = chronoUiStore;
|
||||
|
||||
const {
|
||||
toggleTaskComplete,
|
||||
ensureTasksLoaded,
|
||||
} = chronoOperationsStore;
|
||||
|
||||
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 handleCalendarViewChange(view: CalendarViewType) {
|
||||
chronoSettingsStore.calendarView = view;
|
||||
}
|
||||
|
||||
function handleCalendarDaysViewSpanChange(span: DaysViewSpan) {
|
||||
chronoSettingsStore.daysViewSpan = span;
|
||||
}
|
||||
|
||||
function handleCalendarAgendaViewSpanChange(span: AgendaViewSpan) {
|
||||
chronoSettingsStore.agendaViewSpan = span;
|
||||
}
|
||||
|
||||
function computeVisibleRange(): EpochSpan {
|
||||
if (calendarView.value === 'month') {
|
||||
return monthGridVisibleRange(currentDate.value);
|
||||
}
|
||||
|
||||
const span = calendarView.value === 'agenda'
|
||||
? agendaViewSpan.value
|
||||
: daysViewSpan.value;
|
||||
|
||||
return daysVisibleRange(currentDate.value, spanToDays(span));
|
||||
}
|
||||
|
||||
function selectSectionFromRoute() {
|
||||
const routePath = route.path;
|
||||
const section = routePath.endsWith('/tasks') ? 'tasks' : 'calendar';
|
||||
selectSection(section);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="chrono-container">
|
||||
<!-- Top Navigation Bar -->
|
||||
<v-toolbar elevation="0" density="compact" class="chrono-toolbar">
|
||||
<template #prepend>
|
||||
<v-btn
|
||||
icon="mdi-menu"
|
||||
variant="text"
|
||||
@click="sidebarVisible = !sidebarVisible"
|
||||
></v-btn>
|
||||
</template>
|
||||
|
||||
<v-toolbar-title class="d-flex align-center">
|
||||
<v-icon size="24" color="primary" class="mr-2">mdi-calendar-month</v-icon>
|
||||
<span class="text-subtitle-1 font-weight-bold">Chrono</span>
|
||||
</v-toolbar-title>
|
||||
|
||||
<v-spacer></v-spacer>
|
||||
|
||||
<!-- View Switcher for Calendar -->
|
||||
<v-btn-toggle
|
||||
v-if="!isTasksSection"
|
||||
:model-value="calendarView"
|
||||
color="primary"
|
||||
variant="outlined"
|
||||
density="compact"
|
||||
mandatory
|
||||
class="mr-2"
|
||||
@update:model-value="handleCalendarViewChange"
|
||||
>
|
||||
<v-btn value="days" size="small">Days</v-btn>
|
||||
<v-btn value="month" size="small">Month</v-btn>
|
||||
<v-btn value="agenda" size="small">Agenda</v-btn>
|
||||
</v-btn-toggle>
|
||||
</v-toolbar>
|
||||
|
||||
<!-- Main Content Area -->
|
||||
<div class="chrono-content">
|
||||
<!-- Sidebar Navigation Drawer -->
|
||||
<Sidebar />
|
||||
|
||||
<!-- Main Calendar/Task View -->
|
||||
<div class="chrono-main">
|
||||
<v-alert
|
||||
v-if="!isChronoManagerAvailable"
|
||||
type="warning"
|
||||
variant="tonal"
|
||||
closable
|
||||
class="mb-4"
|
||||
>
|
||||
<v-alert-title class="d-flex align-center">
|
||||
<v-icon icon="mdi-alert-circle" class="mr-2" />
|
||||
Chrono Manager Not Available
|
||||
</v-alert-title>
|
||||
<div class="mt-2">
|
||||
<p>
|
||||
The Chrono Manager module is not installed or enabled.
|
||||
This module requires the <strong>chrono_manager</strong> module to function properly.
|
||||
</p>
|
||||
<p class="mt-2 mb-0">
|
||||
Please contact your system administrator to install and enable the
|
||||
<code>chrono_manager</code> module.
|
||||
</p>
|
||||
</div>
|
||||
</v-alert>
|
||||
|
||||
<div v-if="isChronoManagerAvailable" class="chrono-wrapper">
|
||||
<v-progress-linear v-if="loading" indeterminate color="primary" />
|
||||
|
||||
<CalendarView
|
||||
v-if="!isTasksSection"
|
||||
:view="calendarView"
|
||||
:current-date="currentDate"
|
||||
:calendars="calendars"
|
||||
:initial-days-span="daysViewSpan"
|
||||
:initial-agenda-view-span="agendaViewSpan"
|
||||
@event-click="editEvent"
|
||||
@date-click="createEventFromDate"
|
||||
@date-range-select="createEventFromDate($event.start, $event.end)"
|
||||
@update:current-date="selectDate"
|
||||
@update:days-span="handleCalendarDaysViewSpanChange"
|
||||
@update:agenda-span="handleCalendarAgendaViewSpanChange"
|
||||
/>
|
||||
|
||||
<TaskView
|
||||
v-else
|
||||
:tasks="filteredTasks"
|
||||
:lists="taskLists"
|
||||
@task-click="editTask"
|
||||
@toggle-complete="toggleTaskComplete"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Event Editor Dialog -->
|
||||
<v-dialog v-model="showEventEditor" max-width="800px" scrollable>
|
||||
<EventEditor
|
||||
v-if="showEventEditor"
|
||||
:mode="entityEditorMode"
|
||||
:entity="selectedEntity"
|
||||
:collection="selectedCollection"
|
||||
:calendars="calendars"
|
||||
@save="saveEvent"
|
||||
@delete="deleteEvent"
|
||||
@edit="startEditingSelectedEntity"
|
||||
@cancel="cancelEditingSelectedEntity"
|
||||
@close="closeEntityEditor"
|
||||
/>
|
||||
</v-dialog>
|
||||
|
||||
<!-- Task Editor Dialog -->
|
||||
<v-dialog v-model="showTaskEditor" max-width="700px" scrollable>
|
||||
<TaskEditor
|
||||
v-if="showTaskEditor"
|
||||
:mode="entityEditorMode"
|
||||
:entity="selectedEntity"
|
||||
:collection="selectedCollection"
|
||||
:lists="taskLists"
|
||||
@save="saveTask"
|
||||
@delete="deleteTask"
|
||||
@edit="startEditingSelectedEntity"
|
||||
@cancel="cancelEditingSelectedEntity"
|
||||
@close="closeEntityEditor"
|
||||
/>
|
||||
</v-dialog>
|
||||
|
||||
<!-- Collection Editor Dialog -->
|
||||
<CollectionEditor
|
||||
v-model="showCollectionEditor"
|
||||
:collection="editingCollection"
|
||||
:mode="collectionEditorMode"
|
||||
:type="collectionEditorType"
|
||||
@save="saveCollection"
|
||||
@delete="deleteCollection"
|
||||
/>
|
||||
|
||||
<ImportDialog v-model="showImportDialog" :collections="collections" @close="closeImport" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.chrono-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
height: 100%;
|
||||
min-height: 0;
|
||||
isolation: isolate; /* Create stacking context to prevent style leakage */
|
||||
}
|
||||
|
||||
.chrono-toolbar {
|
||||
flex-shrink: 0;
|
||||
border-bottom: 1px solid rgb(var(--v-border-color)) !important;
|
||||
}
|
||||
|
||||
.chrono-content {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.chrono-main {
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.chrono-wrapper {
|
||||
display: flex;
|
||||
flex: 1;
|
||||
min-height: 0;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 960px) {
|
||||
.chrono-main {
|
||||
padding: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 600px) {
|
||||
.chrono-main {
|
||||
padding: 12px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user