Some ignored filles was missing
This commit is contained in:
parent
7db22245e2
commit
fd5ab6bc0d
268 changed files with 31970 additions and 4 deletions
183
wwwroot/js/features/all-day/AllDayDragService.js
Normal file
183
wwwroot/js/features/all-day/AllDayDragService.js
Normal file
|
|
@ -0,0 +1,183 @@
|
|||
/**
|
||||
* AllDayDragService - Manages drag and drop operations for all-day events
|
||||
*
|
||||
* STATELESS SERVICE - Reads all data from DOM via AllDayDomReader
|
||||
* - No persistent state
|
||||
* - Handles timed → all-day conversion
|
||||
* - Handles all-day → all-day repositioning
|
||||
* - Handles column changes during drag
|
||||
* - Calculates layouts on-demand from DOM
|
||||
*/
|
||||
import { SwpAllDayEventElement } from '../../elements/SwpEventElement';
|
||||
import { AllDayLayoutEngine } from '../../utils/AllDayLayoutEngine';
|
||||
import { ColumnDetectionUtils } from '../../utils/ColumnDetectionUtils';
|
||||
import { ALL_DAY_CONSTANTS } from '../../configurations/CalendarConfig';
|
||||
import { AllDayDomReader } from './AllDayDomReader';
|
||||
export class AllDayDragService {
|
||||
constructor(eventManager, allDayEventRenderer, dateService) {
|
||||
this.eventManager = eventManager;
|
||||
this.allDayEventRenderer = allDayEventRenderer;
|
||||
this.dateService = dateService;
|
||||
}
|
||||
/**
|
||||
* Handle conversion from timed event to all-day event
|
||||
* Called when dragging a timed event into the header
|
||||
*/
|
||||
handleConvertToAllDay(payload) {
|
||||
const allDayContainer = AllDayDomReader.getAllDayContainer();
|
||||
if (!allDayContainer)
|
||||
return;
|
||||
// Create SwpAllDayEventElement from ICalendarEvent
|
||||
const allDayElement = SwpAllDayEventElement.fromCalendarEvent(payload.calendarEvent);
|
||||
// Apply grid positioning
|
||||
allDayElement.style.gridRow = '1';
|
||||
allDayElement.style.gridColumn = payload.targetColumn.index.toString();
|
||||
// Remove old swp-event clone
|
||||
payload.draggedClone.remove();
|
||||
// Call delegate to update DragDropManager's draggedClone reference
|
||||
payload.replaceClone(allDayElement);
|
||||
// Append to container
|
||||
allDayContainer.appendChild(allDayElement);
|
||||
ColumnDetectionUtils.updateColumnBoundsCache();
|
||||
}
|
||||
/**
|
||||
* Handle column change during drag of all-day event
|
||||
* Updates grid position while maintaining event span
|
||||
*/
|
||||
handleColumnChange(payload) {
|
||||
const allDayContainer = AllDayDomReader.getAllDayContainer();
|
||||
if (!allDayContainer)
|
||||
return;
|
||||
const targetColumn = ColumnDetectionUtils.getColumnBounds(payload.mousePosition);
|
||||
if (!targetColumn || !payload.draggedClone)
|
||||
return;
|
||||
// Calculate event span from original grid positioning
|
||||
const { start: gridColumnStart, end: gridColumnEnd } = AllDayDomReader.getGridColumnRange(payload.draggedClone);
|
||||
const span = gridColumnEnd - gridColumnStart;
|
||||
// Update clone position maintaining the span
|
||||
const newStartColumn = targetColumn.index;
|
||||
const newEndColumn = newStartColumn + span;
|
||||
payload.draggedClone.style.gridColumn = `${newStartColumn} / ${newEndColumn}`;
|
||||
}
|
||||
/**
|
||||
* Handle drag end for all-day → all-day drops
|
||||
* Recalculates layouts and updates event positions
|
||||
*/
|
||||
async handleDragEnd(dragEndEvent) {
|
||||
if (!dragEndEvent.draggedClone)
|
||||
return;
|
||||
// Normalize clone ID
|
||||
dragEndEvent.draggedClone.dataset.eventId = dragEndEvent.draggedClone.dataset.eventId?.replace('clone-', '');
|
||||
dragEndEvent.draggedClone.style.pointerEvents = ''; // Re-enable pointer events
|
||||
dragEndEvent.originalElement.dataset.eventId += '_';
|
||||
const eventId = dragEndEvent.draggedClone.dataset.eventId;
|
||||
const eventDate = dragEndEvent.finalPosition.column?.date;
|
||||
const eventType = dragEndEvent.draggedClone.dataset.type;
|
||||
if (!eventDate || !eventId || !eventType)
|
||||
return;
|
||||
// Get original dates to preserve time
|
||||
const originalStartDate = new Date(dragEndEvent.draggedClone.dataset.start);
|
||||
const originalEndDate = new Date(dragEndEvent.draggedClone.dataset.end);
|
||||
// Calculate actual duration in milliseconds (preserves hours/minutes/seconds)
|
||||
const durationMs = originalEndDate.getTime() - originalStartDate.getTime();
|
||||
// Create new start date with the new day but preserve original time
|
||||
const newStartDate = new Date(eventDate);
|
||||
newStartDate.setHours(originalStartDate.getHours(), originalStartDate.getMinutes(), originalStartDate.getSeconds(), originalStartDate.getMilliseconds());
|
||||
// Create new end date by adding duration in milliseconds
|
||||
const newEndDate = new Date(newStartDate.getTime() + durationMs);
|
||||
// Update data attributes with new dates (convert to UTC)
|
||||
dragEndEvent.draggedClone.dataset.start = this.dateService.toUTC(newStartDate);
|
||||
dragEndEvent.draggedClone.dataset.end = this.dateService.toUTC(newEndDate);
|
||||
const droppedEvent = {
|
||||
id: eventId,
|
||||
title: dragEndEvent.draggedClone.dataset.title || '',
|
||||
start: newStartDate,
|
||||
end: newEndDate,
|
||||
type: eventType,
|
||||
allDay: true,
|
||||
syncStatus: 'synced'
|
||||
};
|
||||
// Get all events from DOM and recalculate layouts
|
||||
const allEventsFromDOM = AllDayDomReader.getEventsAsData();
|
||||
const weekDates = ColumnDetectionUtils.getColumns();
|
||||
// Replace old event with dropped event
|
||||
const updatedEvents = [
|
||||
...allEventsFromDOM.filter(event => event.id !== eventId),
|
||||
droppedEvent
|
||||
];
|
||||
// Calculate new layouts for ALL events
|
||||
const newLayouts = this.calculateLayouts(updatedEvents, weekDates);
|
||||
// Apply layout updates to DOM
|
||||
this.applyLayoutUpdates(newLayouts);
|
||||
// Clean up drag styles from the dropped clone
|
||||
dragEndEvent.draggedClone.classList.remove('dragging');
|
||||
dragEndEvent.draggedClone.style.zIndex = '';
|
||||
dragEndEvent.draggedClone.style.cursor = '';
|
||||
dragEndEvent.draggedClone.style.opacity = '';
|
||||
// Apply highlight class to show the dropped event with highlight color
|
||||
dragEndEvent.draggedClone.classList.add('highlight');
|
||||
// Update event in repository to mark as allDay=true
|
||||
await this.eventManager.updateEvent(eventId, {
|
||||
start: newStartDate,
|
||||
end: newEndDate,
|
||||
allDay: true
|
||||
});
|
||||
this.fadeOutAndRemove(dragEndEvent.originalElement);
|
||||
}
|
||||
/**
|
||||
* Calculate layouts for events using AllDayLayoutEngine
|
||||
*/
|
||||
calculateLayouts(events, weekDates) {
|
||||
const layoutEngine = new AllDayLayoutEngine(weekDates.map(column => column.date));
|
||||
return layoutEngine.calculateLayout(events);
|
||||
}
|
||||
/**
|
||||
* Apply layout updates to DOM elements
|
||||
* Only updates elements that have changed position
|
||||
* Public so AllDayCoordinator can use it for full recalculation
|
||||
*/
|
||||
applyLayoutUpdates(newLayouts) {
|
||||
const container = AllDayDomReader.getAllDayContainer();
|
||||
if (!container)
|
||||
return;
|
||||
// Read current layouts from DOM
|
||||
const currentLayoutsMap = AllDayDomReader.getCurrentLayouts();
|
||||
newLayouts.forEach((layout) => {
|
||||
const currentLayout = currentLayoutsMap.get(layout.calenderEvent.id);
|
||||
// Only update if layout changed
|
||||
if (currentLayout?.gridArea !== layout.gridArea) {
|
||||
const element = container.querySelector(`[data-event-id="${layout.calenderEvent.id}"]`);
|
||||
if (element) {
|
||||
element.classList.add('transitioning');
|
||||
element.style.gridArea = layout.gridArea;
|
||||
element.style.gridRow = layout.row.toString();
|
||||
element.style.gridColumn = `${layout.startColumn} / ${layout.endColumn + 1}`;
|
||||
// Update overflow classes based on row
|
||||
element.classList.remove('max-event-overflow-hide', 'max-event-overflow-show');
|
||||
if (layout.row > ALL_DAY_CONSTANTS.MAX_COLLAPSED_ROWS) {
|
||||
const isExpanded = AllDayDomReader.isExpanded();
|
||||
if (isExpanded) {
|
||||
element.classList.add('max-event-overflow-show');
|
||||
}
|
||||
else {
|
||||
element.classList.add('max-event-overflow-hide');
|
||||
}
|
||||
}
|
||||
// Remove transition class after animation
|
||||
setTimeout(() => element.classList.remove('transitioning'), 200);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
/**
|
||||
* Fade out and remove element
|
||||
*/
|
||||
fadeOutAndRemove(element) {
|
||||
element.style.transition = 'opacity 0.3s ease-out';
|
||||
element.style.opacity = '0';
|
||||
setTimeout(() => {
|
||||
element.remove();
|
||||
}, 300);
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=AllDayDragService.js.map
|
||||
Loading…
Add table
Add a link
Reference in a new issue