Refactors resize and position utility handling
Extracts position calculation logic into a separate utility class Introduces PositionUtils to centralize pixel and minute conversion methods Removes redundant calculation methods from ResizeHandleManager Updates Configuration to include default API endpoint Simplifies resize and height management across components
This commit is contained in:
parent
a1bee99d8e
commit
202074e391
3 changed files with 11 additions and 22 deletions
|
|
@ -66,6 +66,7 @@ export class Configuration {
|
||||||
public timeFormatConfig: ITimeFormatConfig;
|
public timeFormatConfig: ITimeFormatConfig;
|
||||||
public currentWorkWeek: string;
|
public currentWorkWeek: string;
|
||||||
public selectedDate: Date;
|
public selectedDate: Date;
|
||||||
|
public apiEndpoint: string = '/api';
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
config: ICalendarConfig,
|
config: ICalendarConfig,
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ import { eventBus } from '../core/EventBus';
|
||||||
import { CoreEvents } from '../constants/CoreEvents';
|
import { CoreEvents } from '../constants/CoreEvents';
|
||||||
import { Configuration } from '../configurations/CalendarConfig';
|
import { Configuration } from '../configurations/CalendarConfig';
|
||||||
import { IResizeEndEventPayload } from '../types/EventTypes';
|
import { IResizeEndEventPayload } from '../types/EventTypes';
|
||||||
|
import { PositionUtils } from '../utils/PositionUtils';
|
||||||
|
|
||||||
type SwpEventEl = HTMLElement & { updateHeight?: (h: number) => void };
|
type SwpEventEl = HTMLElement & { updateHeight?: (h: number) => void };
|
||||||
|
|
||||||
|
|
@ -18,7 +19,6 @@ export class ResizeHandleManager {
|
||||||
private startDurationMin = 0;
|
private startDurationMin = 0;
|
||||||
private direction: 'grow' | 'shrink' = 'grow';
|
private direction: 'grow' | 'shrink' = 'grow';
|
||||||
|
|
||||||
private hourHeightPx: number;
|
|
||||||
private snapMin: number;
|
private snapMin: number;
|
||||||
private minDurationMin: number;
|
private minDurationMin: number;
|
||||||
private animationId: number | null = null;
|
private animationId: number | null = null;
|
||||||
|
|
@ -30,11 +30,12 @@ export class ResizeHandleManager {
|
||||||
private pointerCaptured = false;
|
private pointerCaptured = false;
|
||||||
private prevZ?: string;
|
private prevZ?: string;
|
||||||
private config: Configuration;
|
private config: Configuration;
|
||||||
|
private positionUtils: PositionUtils;
|
||||||
|
|
||||||
constructor(config: Configuration) {
|
constructor(config: Configuration, positionUtils: PositionUtils) {
|
||||||
this.config = config;
|
this.config = config;
|
||||||
|
this.positionUtils = positionUtils;
|
||||||
const grid = this.config.gridSettings;
|
const grid = this.config.gridSettings;
|
||||||
this.hourHeightPx = grid.hourHeight;
|
|
||||||
this.snapMin = grid.snapInterval;
|
this.snapMin = grid.snapInterval;
|
||||||
this.minDurationMin = this.snapMin; // Use snap interval as minimum duration
|
this.minDurationMin = this.snapMin; // Use snap interval as minimum duration
|
||||||
}
|
}
|
||||||
|
|
@ -53,19 +54,6 @@ export class ResizeHandleManager {
|
||||||
this.unsubscribers.forEach(u => u());
|
this.unsubscribers.forEach(u => u());
|
||||||
}
|
}
|
||||||
|
|
||||||
private minutesPerPx(): number {
|
|
||||||
return 60 / this.hourHeightPx;
|
|
||||||
}
|
|
||||||
|
|
||||||
private pxFromMinutes(min: number): number {
|
|
||||||
return (min / 60) * this.hourHeightPx;
|
|
||||||
}
|
|
||||||
|
|
||||||
private roundSnap(min: number, dir: 'grow' | 'shrink'): number {
|
|
||||||
const q = min / this.snapMin;
|
|
||||||
return (dir === 'grow' ? Math.ceil(q) : Math.floor(q)) * this.snapMin;
|
|
||||||
}
|
|
||||||
|
|
||||||
private refreshEventCache(): void {
|
private refreshEventCache(): void {
|
||||||
this.cachedEvents = Array.from(
|
this.cachedEvents = Array.from(
|
||||||
document.querySelectorAll<SwpEventEl>('swp-day-columns swp-event')
|
document.querySelectorAll<SwpEventEl>('swp-day-columns swp-event')
|
||||||
|
|
@ -167,7 +155,7 @@ export class ResizeHandleManager {
|
||||||
const startHeight = el.offsetHeight;
|
const startHeight = el.offsetHeight;
|
||||||
this.startDurationMin = Math.max(
|
this.startDurationMin = Math.max(
|
||||||
this.minDurationMin,
|
this.minDurationMin,
|
||||||
Math.round(startHeight * this.minutesPerPx())
|
Math.round(this.positionUtils.pixelsToMinutes(startHeight))
|
||||||
);
|
);
|
||||||
|
|
||||||
this.prevZ = (el.closest<HTMLElement>('swp-event-group') ?? el).style.zIndex;
|
this.prevZ = (el.closest<HTMLElement>('swp-event-group') ?? el).style.zIndex;
|
||||||
|
|
@ -193,9 +181,9 @@ export class ResizeHandleManager {
|
||||||
this.direction = dy >= 0 ? 'grow' : 'shrink';
|
this.direction = dy >= 0 ? 'grow' : 'shrink';
|
||||||
|
|
||||||
// Calculate raw height from pixel delta (no snapping - 100% smooth like drag & drop)
|
// Calculate raw height from pixel delta (no snapping - 100% smooth like drag & drop)
|
||||||
const startHeight = this.pxFromMinutes(this.startDurationMin);
|
const startHeight = this.positionUtils.minutesToPixels(this.startDurationMin);
|
||||||
const rawHeight = startHeight + dy;
|
const rawHeight = startHeight + dy;
|
||||||
const minHeight = this.pxFromMinutes(this.minDurationMin);
|
const minHeight = this.positionUtils.minutesToPixels(this.minDurationMin);
|
||||||
|
|
||||||
this.targetHeight = Math.max(minHeight, rawHeight); // Raw height, no snap
|
this.targetHeight = Math.max(minHeight, rawHeight); // Raw height, no snap
|
||||||
|
|
||||||
|
|
@ -228,9 +216,9 @@ export class ResizeHandleManager {
|
||||||
|
|
||||||
// Snap to grid on pointer up (like DragDropManager does on mouseUp)
|
// Snap to grid on pointer up (like DragDropManager does on mouseUp)
|
||||||
const currentHeight = this.targetEl.offsetHeight;
|
const currentHeight = this.targetEl.offsetHeight;
|
||||||
const snapDistancePx = this.pxFromMinutes(this.snapMin);
|
const snapDistancePx = this.positionUtils.minutesToPixels(this.snapMin);
|
||||||
const snappedHeight = Math.round(currentHeight / snapDistancePx) * snapDistancePx;
|
const snappedHeight = Math.round(currentHeight / snapDistancePx) * snapDistancePx;
|
||||||
const minHeight = this.pxFromMinutes(this.minDurationMin);
|
const minHeight = this.positionUtils.minutesToPixels(this.minDurationMin);
|
||||||
const finalHeight = Math.max(minHeight, snappedHeight) - 3; // lille gap til grid-linjer
|
const finalHeight = Math.max(minHeight, snappedHeight) - 3; // lille gap til grid-linjer
|
||||||
|
|
||||||
this.targetEl.updateHeight?.(finalHeight);
|
this.targetEl.updateHeight?.(finalHeight);
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ export class ApiEventRepository {
|
||||||
private apiEndpoint: string;
|
private apiEndpoint: string;
|
||||||
|
|
||||||
constructor(config: Configuration) {
|
constructor(config: Configuration) {
|
||||||
this.apiEndpoint = config.apiEndpoint || '/api';
|
this.apiEndpoint = config.apiEndpoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue