mirror of
https://github.com/Memo-2023/mana-monorepo.git
synced 2026-05-16 20:39:39 +02:00
feat(calendar): add context menu support to MonthView and MultiDayView
- Add oncontextmenu handler to event-pill in MonthView - Add oncontextmenu handler to event-card in MultiDayView - Move EventContextMenu to layout level for proper z-index stacking - Context menu now appears above DateStrip and other fixed elements 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
parent
10d4170ee8
commit
a1c3eafee6
3 changed files with 32 additions and 3 deletions
|
|
@ -5,6 +5,7 @@
|
|||
import { settingsStore } from '$lib/stores/settings.svelte';
|
||||
import { searchStore } from '$lib/stores/search.svelte';
|
||||
import { todosStore } from '$lib/stores/todos.svelte';
|
||||
import { eventContextMenuStore } from '$lib/stores/eventContextMenu.svelte';
|
||||
import TodoDayCell from './TodoDayCell.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import {
|
||||
|
|
@ -241,6 +242,14 @@
|
|||
viewStore.setDate(day);
|
||||
viewStore.setViewType('day');
|
||||
}
|
||||
|
||||
function handleEventContextMenu(event: CalendarEvent, e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
// Don't show context menu for draft events
|
||||
if (eventsStore.isDraftEvent(event.id)) return;
|
||||
eventContextMenuStore.show(event, e.clientX, e.clientY);
|
||||
}
|
||||
</script>
|
||||
|
||||
<div class="month-view" style="--column-count: {columnCount}" bind:this={monthViewRef}>
|
||||
|
|
@ -297,6 +306,7 @@
|
|||
style="background-color: {calendarsStore.getColor(event.calendarId)}"
|
||||
onpointerdown={(e) => startDrag(event, e)}
|
||||
onclick={(e) => !isDraft && handleEventClick(event, e)}
|
||||
oncontextmenu={(e) => handleEventContextMenu(event, e)}
|
||||
role="button"
|
||||
tabindex="0"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
import { settingsStore } from '$lib/stores/settings.svelte';
|
||||
import { searchStore } from '$lib/stores/search.svelte';
|
||||
import { todosStore, type Task } from '$lib/stores/todos.svelte';
|
||||
import { eventContextMenuStore } from '$lib/stores/eventContextMenu.svelte';
|
||||
import TaskBlock from './TaskBlock.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import {
|
||||
|
|
@ -299,6 +300,14 @@
|
|||
}
|
||||
}
|
||||
|
||||
function handleEventContextMenu(event: CalendarEvent, e: MouseEvent) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
// Don't show context menu for draft events
|
||||
if (eventsStore.isDraftEvent(event.id)) return;
|
||||
eventContextMenuStore.show(event, e.clientX, e.clientY);
|
||||
}
|
||||
|
||||
// ========== Drag & Drop Functions ==========
|
||||
|
||||
function getDayFromX(clientX: number): Date | null {
|
||||
|
|
@ -935,6 +944,7 @@
|
|||
tabindex="0"
|
||||
onpointerdown={(e) => startDrag(event, e)}
|
||||
onclick={(e) => !isDraft && handleEventClick(event, e)}
|
||||
oncontextmenu={(e) => handleEventContextMenu(event, e)}
|
||||
onkeydown={(e) => !isDraft && e.key === 'Enter' && goto(`/?event=${event.id}`)}
|
||||
title={`${formatEventTime(event.startTime)} - ${formatEventTime(event.endTime)}: ${event.title || (isDraft ? '(Neuer Termin)' : '')}`}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -50,6 +50,8 @@
|
|||
import CalendarToolbar from '$lib/components/calendar/CalendarToolbar.svelte';
|
||||
import CalendarToolbarContent from '$lib/components/calendar/CalendarToolbarContent.svelte';
|
||||
import DateStrip from '$lib/components/calendar/DateStrip.svelte';
|
||||
import EventContextMenu from '$lib/components/event/EventContextMenu.svelte';
|
||||
import { eventContextMenuStore } from '$lib/stores/eventContextMenu.svelte';
|
||||
|
||||
// App switcher items
|
||||
const appItems = getPillAppItems('calendar');
|
||||
|
|
@ -275,6 +277,11 @@
|
|||
goto('/login');
|
||||
}
|
||||
|
||||
// Context menu edit handler - navigate to event
|
||||
function handleContextMenuEdit(event: { id: string }) {
|
||||
goto(`/?event=${event.id}`);
|
||||
}
|
||||
|
||||
onMount(async () => {
|
||||
// Redirect to login if not authenticated
|
||||
if (!authStore.isAuthenticated) {
|
||||
|
|
@ -408,7 +415,6 @@
|
|||
onParseCreate={handleParseCreate}
|
||||
createText="Erstellen"
|
||||
appIcon="calendar"
|
||||
primaryColor="#3b82f6"
|
||||
autoFocus={true}
|
||||
bottomOffset={isSidebarMode
|
||||
? '0px'
|
||||
|
|
@ -420,6 +426,9 @@
|
|||
</div>
|
||||
</SplitPaneContainer>
|
||||
|
||||
<!-- Global Event Context Menu - rendered at top level for proper z-index -->
|
||||
<EventContextMenu onEdit={handleContextMenuEdit} />
|
||||
|
||||
<style>
|
||||
.layout-container {
|
||||
display: flex;
|
||||
|
|
@ -456,8 +465,8 @@
|
|||
200px + env(safe-area-inset-bottom)
|
||||
); /* DateStrip + BottomNav + QuickInputBar */
|
||||
}
|
||||
.main-content.floating-mode.has-toolbar {
|
||||
padding-top: 70px;
|
||||
.main-content.floating-mode {
|
||||
padding-top: 0; /* No top padding on mobile - everything is at bottom */
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue