Some ignored filles was missing
This commit is contained in:
parent
7db22245e2
commit
fd5ab6bc0d
268 changed files with 31970 additions and 4 deletions
194
wwwroot/js/managers/ResizeHandleManager.js
Normal file
194
wwwroot/js/managers/ResizeHandleManager.js
Normal file
|
|
@ -0,0 +1,194 @@
|
|||
import { eventBus } from '../core/EventBus';
|
||||
export class ResizeHandleManager {
|
||||
constructor(config, positionUtils) {
|
||||
this.config = config;
|
||||
this.positionUtils = positionUtils;
|
||||
this.isResizing = false;
|
||||
this.targetEl = null;
|
||||
this.startY = 0;
|
||||
this.startDurationMin = 0;
|
||||
this.animationId = null;
|
||||
this.currentHeight = 0;
|
||||
this.targetHeight = 0;
|
||||
this.pointerCaptured = false;
|
||||
// Constants for better maintainability
|
||||
this.ANIMATION_SPEED = 0.35;
|
||||
this.Z_INDEX_RESIZING = '1000';
|
||||
this.EVENT_REFRESH_THRESHOLD = 0.5;
|
||||
this.onMouseOver = (e) => {
|
||||
const target = e.target;
|
||||
const eventElement = target.closest('swp-event');
|
||||
if (eventElement && !this.isResizing) {
|
||||
// Check if handle already exists
|
||||
if (!eventElement.querySelector(':scope > swp-resize-handle')) {
|
||||
const handle = this.createResizeHandle();
|
||||
eventElement.appendChild(handle);
|
||||
}
|
||||
}
|
||||
};
|
||||
this.onPointerDown = (e) => {
|
||||
const handle = e.target.closest('swp-resize-handle');
|
||||
if (!handle)
|
||||
return;
|
||||
const element = handle.parentElement;
|
||||
this.startResizing(element, e);
|
||||
};
|
||||
this.onPointerMove = (e) => {
|
||||
if (!this.isResizing || !this.targetEl)
|
||||
return;
|
||||
this.updateResizeHeight(e.clientY);
|
||||
};
|
||||
this.animate = () => {
|
||||
if (!this.isResizing || !this.targetEl) {
|
||||
this.animationId = null;
|
||||
return;
|
||||
}
|
||||
const diff = this.targetHeight - this.currentHeight;
|
||||
if (Math.abs(diff) > this.EVENT_REFRESH_THRESHOLD) {
|
||||
this.currentHeight += diff * this.ANIMATION_SPEED;
|
||||
this.targetEl.updateHeight?.(this.currentHeight);
|
||||
this.animationId = requestAnimationFrame(this.animate);
|
||||
}
|
||||
else {
|
||||
this.finalizeAnimation();
|
||||
}
|
||||
};
|
||||
this.onPointerUp = (e) => {
|
||||
if (!this.isResizing || !this.targetEl)
|
||||
return;
|
||||
this.cleanupAnimation();
|
||||
this.snapToGrid();
|
||||
this.emitResizeEndEvent();
|
||||
this.cleanupResizing(e);
|
||||
};
|
||||
const grid = this.config.gridSettings;
|
||||
this.snapMin = grid.snapInterval;
|
||||
this.minDurationMin = this.snapMin;
|
||||
}
|
||||
initialize() {
|
||||
this.attachGlobalListeners();
|
||||
}
|
||||
destroy() {
|
||||
this.removeEventListeners();
|
||||
}
|
||||
removeEventListeners() {
|
||||
const calendarContainer = document.querySelector('swp-calendar-container');
|
||||
if (calendarContainer) {
|
||||
calendarContainer.removeEventListener('mouseover', this.onMouseOver, true);
|
||||
}
|
||||
document.removeEventListener('pointerdown', this.onPointerDown, true);
|
||||
document.removeEventListener('pointermove', this.onPointerMove, true);
|
||||
document.removeEventListener('pointerup', this.onPointerUp, true);
|
||||
}
|
||||
createResizeHandle() {
|
||||
const handle = document.createElement('swp-resize-handle');
|
||||
handle.setAttribute('aria-label', 'Resize event');
|
||||
handle.setAttribute('role', 'separator');
|
||||
return handle;
|
||||
}
|
||||
attachGlobalListeners() {
|
||||
const calendarContainer = document.querySelector('swp-calendar-container');
|
||||
if (calendarContainer) {
|
||||
calendarContainer.addEventListener('mouseover', this.onMouseOver, true);
|
||||
}
|
||||
document.addEventListener('pointerdown', this.onPointerDown, true);
|
||||
document.addEventListener('pointermove', this.onPointerMove, true);
|
||||
document.addEventListener('pointerup', this.onPointerUp, true);
|
||||
}
|
||||
startResizing(element, event) {
|
||||
this.targetEl = element;
|
||||
this.isResizing = true;
|
||||
this.startY = event.clientY;
|
||||
const startHeight = element.offsetHeight;
|
||||
this.startDurationMin = Math.max(this.minDurationMin, Math.round(this.positionUtils.pixelsToMinutes(startHeight)));
|
||||
this.setZIndexForResizing(element);
|
||||
this.capturePointer(event);
|
||||
document.documentElement.classList.add('swp--resizing');
|
||||
event.preventDefault();
|
||||
}
|
||||
setZIndexForResizing(element) {
|
||||
const container = element.closest('swp-event-group') ?? element;
|
||||
this.prevZ = container.style.zIndex;
|
||||
container.style.zIndex = this.Z_INDEX_RESIZING;
|
||||
}
|
||||
capturePointer(event) {
|
||||
try {
|
||||
event.target.setPointerCapture?.(event.pointerId);
|
||||
this.pointerCaptured = true;
|
||||
}
|
||||
catch (error) {
|
||||
console.warn('Pointer capture failed:', error);
|
||||
}
|
||||
}
|
||||
updateResizeHeight(currentY) {
|
||||
const deltaY = currentY - this.startY;
|
||||
const startHeight = this.positionUtils.minutesToPixels(this.startDurationMin);
|
||||
const rawHeight = startHeight + deltaY;
|
||||
const minHeight = this.positionUtils.minutesToPixels(this.minDurationMin);
|
||||
this.targetHeight = Math.max(minHeight, rawHeight);
|
||||
if (this.animationId == null) {
|
||||
this.currentHeight = this.targetEl?.offsetHeight;
|
||||
this.animate();
|
||||
}
|
||||
}
|
||||
finalizeAnimation() {
|
||||
if (!this.targetEl)
|
||||
return;
|
||||
this.currentHeight = this.targetHeight;
|
||||
this.targetEl.updateHeight?.(this.currentHeight);
|
||||
this.animationId = null;
|
||||
}
|
||||
cleanupAnimation() {
|
||||
if (this.animationId != null) {
|
||||
cancelAnimationFrame(this.animationId);
|
||||
this.animationId = null;
|
||||
}
|
||||
}
|
||||
snapToGrid() {
|
||||
if (!this.targetEl)
|
||||
return;
|
||||
const currentHeight = this.targetEl.offsetHeight;
|
||||
const snapDistancePx = this.positionUtils.minutesToPixels(this.snapMin);
|
||||
const snappedHeight = Math.round(currentHeight / snapDistancePx) * snapDistancePx;
|
||||
const minHeight = this.positionUtils.minutesToPixels(this.minDurationMin);
|
||||
const finalHeight = Math.max(minHeight, snappedHeight) - 3; // Small gap to grid lines
|
||||
this.targetEl.updateHeight?.(finalHeight);
|
||||
}
|
||||
emitResizeEndEvent() {
|
||||
if (!this.targetEl)
|
||||
return;
|
||||
const eventId = this.targetEl.dataset.eventId || '';
|
||||
const resizeEndPayload = {
|
||||
eventId,
|
||||
element: this.targetEl,
|
||||
finalHeight: this.targetEl.offsetHeight
|
||||
};
|
||||
eventBus.emit('resize:end', resizeEndPayload);
|
||||
}
|
||||
cleanupResizing(event) {
|
||||
this.restoreZIndex();
|
||||
this.releasePointer(event);
|
||||
this.isResizing = false;
|
||||
this.targetEl = null;
|
||||
document.documentElement.classList.remove('swp--resizing');
|
||||
}
|
||||
restoreZIndex() {
|
||||
if (!this.targetEl || this.prevZ === undefined)
|
||||
return;
|
||||
const container = this.targetEl.closest('swp-event-group') ?? this.targetEl;
|
||||
container.style.zIndex = this.prevZ;
|
||||
this.prevZ = undefined;
|
||||
}
|
||||
releasePointer(event) {
|
||||
if (!this.pointerCaptured)
|
||||
return;
|
||||
try {
|
||||
event.target.releasePointerCapture?.(event.pointerId);
|
||||
this.pointerCaptured = false;
|
||||
}
|
||||
catch (error) {
|
||||
console.warn('Pointer release failed:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
//# sourceMappingURL=ResizeHandleManager.js.map
|
||||
Loading…
Add table
Add a link
Reference in a new issue