UNPKG

@josmangarsal/pragmatic-scheduler

Version:
193 lines (192 loc) 12.3 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var __read = (this && this.__read) || function (o, n) { var m = typeof Symbol === "function" && o[Symbol.iterator]; if (!m) return o; var i = m.call(o), r, ar = [], e; try { while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); } catch (error) { e = { error: error }; } finally { try { if (r && !r.done && (m = i["return"])) m.call(i); } finally { if (e) throw e.error; } } return ar; }; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.TimelineView = void 0; var jsx_runtime_1 = require("@emotion/react/jsx-runtime"); var react_1 = require("react"); var Scheduler_1 = require("../components/Scheduler"); var HeaderRow_1 = require("../components/HeaderRow"); var material_1 = require("@mui/material"); var ResourceCell_1 = require("../layout/ResourceCell"); var ResourceHeader_1 = require("../layout/ResourceHeader"); var GridCell_1 = require("../layout/GridCell"); var react_grid_layout_1 = __importDefault(require("react-grid-layout")); var EventTile_1 = require("../components/EventTile"); var UnassignedHeader_1 = require("../components/UnassignedHeader"); var useCalcEventPosition_1 = require("../hooks/useCalcEventPosition"); var useLayoutToCalEvent_1 = require("../hooks/useLayoutToCalEvent"); var useCalcGridPositions_1 = require("../hooks/useCalcGridPositions"); var date_fns_1 = require("date-fns"); var datePositionHelper_1 = require("../helpers/datePositionHelper"); var TimelineView = function () { var _a = (0, react_1.useContext)(Scheduler_1.SchedulerContext), resources = _a.resources, events = _a.events, days = _a.days, config = _a.config, activeDate = _a.activeDate, _b = _a.calendarBounds, totalDivisions = _b.totalDivisions, start = _b.start, end = _b.end, onEventChange = _a.onEventChange; var ref = (0, react_1.useRef)(null); var calcEventPosition = (0, useCalcEventPosition_1.useCalcEventPosition)(); var layoutToCalEvent = (0, useLayoutToCalEvent_1.useLayoutToCalEvent)(); var gridLayouts = (0, useCalcGridPositions_1.useCalcGridPositions)(); var _c = __read((0, react_1.useState)(false), 2), isDraggingOver = _c[0], setIsDraggingOver = _c[1]; var _d = __read((0, react_1.useState)(), 2), dragCalEvent = _d[0], setDragCalEvent = _d[1]; var _e = __read((0, react_1.useState)({ i: 'droppedItem', w: 4, h: 1, x: 0, y: 0 }), 2), droppingItem = _e[0], setDroppingItem = _e[1]; var _f = __read((0, react_1.useState)(gridLayouts), 2), layouts = _f[0], setLayouts = _f[1]; var updateLayout = (0, react_1.useCallback)(function (layout) { var gridIds = gridLayouts.map(function (l) { return l.i; }); var eventLayouts = layout.filter(function (l) { return !gridIds.includes(l.i); }); setLayouts(__spreadArray(__spreadArray([], __read(eventLayouts), false), __read(gridLayouts), false)); }, [gridLayouts]); var prevActiveDate = (0, react_1.useRef)(); var prevStartDate = (0, react_1.useRef)(); var prevEndDate = (0, react_1.useRef)(); (0, react_1.useEffect)(function () { var _a, _b, _c, _d, _e, _f, _g; // Scroll to start on expand end date if (prevStartDate.current && ((_a = prevStartDate.current) === null || _a === void 0 ? void 0 : _a.getTime()) !== start.getTime()) { prevStartDate.current = start; (_b = ref.current) === null || _b === void 0 ? void 0 : _b.scrollTo({ left: 0, behavior: 'smooth', }); return; } // Scroll to end on expand end date if (prevEndDate.current && ((_c = prevEndDate.current) === null || _c === void 0 ? void 0 : _c.getTime()) !== end.getTime()) { prevEndDate.current = end; (_d = ref.current) === null || _d === void 0 ? void 0 : _d.scrollTo({ left: ref.current.scrollWidth, behavior: 'smooth', }); return; } setTimeout(function () { prevStartDate.current = start; prevEndDate.current = end; }, 100); // Don't scroll if activeDate has not changed if (((_e = prevActiveDate.current) === null || _e === void 0 ? void 0 : _e.getTime()) === activeDate.getTime()) return; prevActiveDate.current = activeDate; if ((0, date_fns_1.isBefore)(start, activeDate) && (0, date_fns_1.isBefore)(activeDate, end)) { // scroll to activeDate, that must be inside the current date interval (_f = ref.current) === null || _f === void 0 ? void 0 : _f.scrollTo({ left: (0, datePositionHelper_1.dateToPosition)(activeDate, start, end, ref.current.scrollWidth), behavior: 'smooth', }); } else { // scroll to the current date (there is 1 day in the past) (_g = ref.current) === null || _g === void 0 ? void 0 : _g.scrollTo({ left: ref.current.scrollWidth * (1 / (config.daysToDisplay + 1)), behavior: 'smooth', }); } }, [activeDate, config.daysToDisplay, end, start]); (0, react_1.useEffect)(function () { var el = ref.current; if (el) { var onWheel_1 = function (e) { if (e.deltaY === 0) return; if (!(el.scrollLeft === 0 && e.deltaY < 0) && !(el.scrollWidth - el.clientWidth - Math.round(el.scrollLeft) === 0 && e.deltaY > 0)) { e.preventDefault(); } el.scrollLeft += e.deltaY * 0.25; }; el.addEventListener('wheel', onWheel_1); return function () { return el.removeEventListener('wheel', onWheel_1); }; } }, []); var cols = (0, react_1.useMemo)(function () { return totalDivisions * config.divisionParts; }, [config.divisionParts, totalDivisions]); var handleDrop = (0, react_1.useCallback)(function (_layout, layoutItem) { if (dragCalEvent && layoutItem) { var updatedEvent = layoutToCalEvent(layoutItem); onEventChange === null || onEventChange === void 0 ? void 0 : onEventChange(updatedEvent); setIsDraggingOver(false); } }, [dragCalEvent, layoutToCalEvent, onEventChange]); var handleDropDragOver = (0, react_1.useCallback)(function () { setIsDraggingOver(true); return undefined; }, [setIsDraggingOver]); var handleUnassignedDragStart = (0, react_1.useCallback)(function (event) { setDragCalEvent(event); var layout = calcEventPosition(event); setDroppingItem(layout); }, [calcEventPosition]); var handleDragResizeStop = (0, react_1.useCallback)(function (layout, _oldItem, newItem) { var updatedEvent = layoutToCalEvent(newItem); onEventChange === null || onEventChange === void 0 ? void 0 : onEventChange(updatedEvent); // be sure to unset this so that the handleLayoutChange updates the layout setIsDraggingOver(false); setTimeout(function () { // note this is required as the handleLayoutChange is not always triggered // see: https://github.com/react-grid-layout/react-grid-layout/issues/1606 // the setTimeout is a hack as sometime it ges into a loop depending on how quickly the event is dropped updateLayout(layout); }); }, [layoutToCalEvent, onEventChange, updateLayout]); var handleLayoutChange = (0, react_1.useCallback)(function (layout) { // note we have to check if we are dragging over as the handleLayoutChange can remove the droppingItem // which causes the handleDrop be called with an undefined layoutItem, and the "pink box" is not shown if (!isDraggingOver) { updateLayout(layout); } }, [isDraggingOver, updateLayout]); return ((0, jsx_runtime_1.jsxs)(material_1.Box, { children: [config.unAssignedRows ? (0, jsx_runtime_1.jsx)(UnassignedHeader_1.UnassignedHeader, {}) : null, (0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ display: "flex" }, { children: [(0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ marginTop: config.unAssignedRows ? "".concat(config.rowHeight * 2, "px") : 0, maxWidth: config.resourceColumnWidth, minWidth: config.resourceColumnWidth }, { children: [(0, jsx_runtime_1.jsx)(ResourceHeader_1.ResourceHeader, {}), resources.map(function (resource) { return ((0, jsx_runtime_1.jsx)(ResourceCell_1.ResourceCell, { resource: resource }, resource.id)); })] })), (0, jsx_runtime_1.jsxs)(material_1.Box, __assign({ position: "relative", flex: 1, overflow: "auto", ref: ref }, { children: [config.unAssignedRows ? (0, jsx_runtime_1.jsx)(HeaderRow_1.UnAssignedEvents, { onDragStart: handleUnassignedDragStart }) : null, (0, jsx_runtime_1.jsx)(HeaderRow_1.HeaderRow, { days: days }), (0, jsx_runtime_1.jsxs)(react_grid_layout_1.default, __assign({ className: "layout", margin: [0, 0], compactType: null, allowOverlap: true, cols: cols, rowHeight: config.rowHeight, width: (cols * config.divisionWidth) / config.divisionParts, isBounded: true, isDroppable: true, onDrop: handleDrop, onDropDragOver: handleDropDragOver, droppingItem: droppingItem, onDragStop: handleDragResizeStop, onResizeStop: handleDragResizeStop, layout: layouts, onLayoutChange: handleLayoutChange, draggableCancel: ".not-draggable" }, { children: [gridLayouts.map(function (layout) { return ((0, jsx_runtime_1.jsx)("div", { children: (0, jsx_runtime_1.jsx)(material_1.Box, __assign({ width: config.divisionWidth, height: config.rowHeight * layout.h - 2 }, { children: (0, jsx_runtime_1.jsx)(GridCell_1.GridCell, { layout: layout }) })) }, layout.i)); }), events .filter(function (e) { return e.resourceId; }) .sort(function (a, b) { return (a.allowOverlap ? 0 : 1) - (b.allowOverlap ? 0 : 1); }) .map(function (event) { var dataGridProps = calcEventPosition(event); return ((0, jsx_runtime_1.jsx)("div", __assign({ "data-grid": dataGridProps }, { children: (0, jsx_runtime_1.jsx)(EventTile_1.EventTile, { event: event, infoFlowData: { scrollRef: ref.current, dataGridProps: dataGridProps, config: config, }, overflowData: { leftOverflow: dataGridProps.leftOverflow, middleOverflow: dataGridProps.middleOverflow, rightOverflow: dataGridProps.rightOverflow, } }, event.id) }), event.id)); })] }))] }))] }))] })); }; exports.TimelineView = TimelineView;