react-big-schedule
Version:
React Big Schedule is a powerful and intuitive scheduler and resource planning solution built with React. Seamlessly integrate this modern browser-compatible component into your applications to effectively manage time, appointments, and resources. With d
851 lines (841 loc) • 43.5 kB
JavaScript
;
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "AddMorePopover", {
enumerable: true,
get: function get() {
return _AddMorePopover["default"];
}
});
Object.defineProperty(exports, "CellUnit", {
enumerable: true,
get: function get() {
return _default.CellUnit;
}
});
Object.defineProperty(exports, "DATETIME_FORMAT", {
enumerable: true,
get: function get() {
return _default.DATETIME_FORMAT;
}
});
Object.defineProperty(exports, "DATE_FORMAT", {
enumerable: true,
get: function get() {
return _default.DATE_FORMAT;
}
});
Object.defineProperty(exports, "DemoData", {
enumerable: true,
get: function get() {
return _sample["default"];
}
});
Object.defineProperty(exports, "DnDContext", {
enumerable: true,
get: function get() {
return _DnDContext["default"];
}
});
Object.defineProperty(exports, "DnDSource", {
enumerable: true,
get: function get() {
return _DnDSource["default"];
}
});
exports.Scheduler = Scheduler;
Object.defineProperty(exports, "SchedulerData", {
enumerable: true,
get: function get() {
return _SchedulerData["default"];
}
});
Object.defineProperty(exports, "SummaryPos", {
enumerable: true,
get: function get() {
return _default.SummaryPos;
}
});
Object.defineProperty(exports, "ViewType", {
enumerable: true,
get: function get() {
return _default.ViewType;
}
});
Object.defineProperty(exports, "wrapperFun", {
enumerable: true,
get: function get() {
return _WrapperFun["default"];
}
});
var _propTypes = _interopRequireDefault(require("prop-types"));
var _react = require("react");
var _default = require("../config/default");
var _sample = _interopRequireDefault(require("../sample-data/sample1"));
var _AddMorePopover = _interopRequireDefault(require("./AddMorePopover"));
var _AgendaView = _interopRequireDefault(require("./AgendaView"));
var _BodyView = _interopRequireDefault(require("./BodyView"));
var _DnDContext = _interopRequireDefault(require("./DnDContext"));
var _DnDSource = _interopRequireDefault(require("./DnDSource"));
var _HeaderView = _interopRequireDefault(require("./HeaderView"));
var _ResourceEvents = _interopRequireDefault(require("./ResourceEvents"));
var _ResourceView = _interopRequireDefault(require("./ResourceView"));
var _SchedulerData = _interopRequireDefault(require("./SchedulerData"));
var _SchedulerHeader = _interopRequireDefault(require("./SchedulerHeader"));
var _WrapperFun = _interopRequireDefault(require("./WrapperFun"));
var _jsxRuntime = require("react/jsx-runtime");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
function _slicedToArray(r, e) { return _arrayWithHoles(r) || _iterableToArrayLimit(r, e) || _unsupportedIterableToArray(r, e) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t["return"] && (u = t["return"](), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
function _toConsumableArray(r) { return _arrayWithoutHoles(r) || _iterableToArray(r) || _unsupportedIterableToArray(r) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
function _iterableToArray(r) { if ("undefined" != typeof Symbol && null != r[Symbol.iterator] || null != r["@@iterator"]) return Array.from(r); }
function _arrayWithoutHoles(r) { if (Array.isArray(r)) return _arrayLikeToArray(r); }
function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
var initDndContext = function initDndContext(schedulerData, dndSources) {
var sources = [];
sources.push(new _DnDSource["default"](function (dndProps) {
return dndProps.eventItem;
}, schedulerData.config.dragAndDropEnabled));
if (dndSources !== undefined && dndSources.length > 0) {
sources = [].concat(_toConsumableArray(sources), _toConsumableArray(dndSources));
}
return new _DnDContext["default"](sources);
};
/**
* Renders the scheduler UI with resource and agenda views, responsive sizing, and drag-and-drop support.
* Optimized to minimize unnecessary re-renders through memoized callbacks, stable refs, and
* selectively updated state.
*
* @param {object} props - Component properties.
* @param {SchedulerData} props.schedulerData - The view model driving all scheduler state,
* configuration, layout data, and rendering logic.
* @param {Array<DnDSource>} [props.dndSources] - Additional drag-and-drop sources merged into
* the scheduler's DnD context on first mount. The DnD context is initialized once and never rebuilt.
* @param {React.RefObject<HTMLElement>} [props.parentRef] - Ref to the parent container element.
* When provided alongside `responsiveByParent: true` in config, a ResizeObserver tracks the
* parent's dimensions and triggers layout updates instead of listening to the window resize event.
* @param {function(SchedulerData):void} props.prevClick - Callback invoked when the user navigates
* to the previous time range.
* @param {function(SchedulerData):void} props.nextClick - Callback invoked when the user navigates
* to the next time range.
* @param {function(SchedulerData, object):void} props.onViewChange - Callback invoked when the
* view type, agenda toggle, or event perspective changes.
* @param {function(SchedulerData, string|Date):void} props.onSelectDate - Callback invoked when
* the user selects a new date from the calendar popover.
* @param {function(SchedulerData, object):void} [props.onSetAddMoreState] - Callback invoked when
* a '+N more' overflow indicator is clicked, used to control the AddMorePopover visibility and position.
* @param {function(SchedulerData, object, string):void} [props.updateEventStart] - Callback invoked
* when the user resizes the start of an event.
* @param {function(SchedulerData, object, string):void} [props.updateEventEnd] - Callback invoked
* when the user resizes the end of an event.
* @param {function(SchedulerData, object, string, string, string, string):void} [props.moveEvent] -
* Callback invoked when an event is dragged to a new slot or time range.
* @param {function} [props.movingEvent] - Callback invoked continuously while an event is being dragged.
* * @param {function(SchedulerData, object, string, string, string, string, string, string):void}
* [props.conflictOccurred] -
* Callback invoked when a scheduling conflict is detected during create, move, or resize.
* @param {function(SchedulerData, object):string} [props.subtitleGetter] - Returns a subtitle string
* displayed in the event item popover.
* @param {function(SchedulerData, object):void} [props.eventItemClick] - Callback invoked when an
* event item is clicked.
* @param {function(SchedulerData, object):void} [props.viewEventClick] - Callback invoked when the
* primary action link in the event popover is clicked.
* @param {string} [props.viewEventText] - Label text for the primary action link in the event popover.
* @param {function(SchedulerData, object):void} [props.viewEvent2Click] - Callback invoked when the
* secondary action link in the event popover is clicked.
* @param {string} [props.viewEvent2Text] - Label text for the secondary action link in the event popover.
* @param {function(SchedulerData, string, string, string, string, string, object):void} [props.newEvent] -
* Callback invoked when a new event is created by clicking and dragging on an empty cell, or when
* an external item is dropped into the scheduler.
* @param {function} [props.eventItemTemplateResolver] - Returns a custom JSX element used to render
* each event item, overriding the default appearance.
* @param {function(SchedulerData, object):void} [props.slotClickedFunc] - Callback invoked when a
* resource slot label in the left column is clicked.
* @param {function(SchedulerData, string):void} [props.toggleExpandFunc] - Callback invoked when a
* parent resource slot's expand or collapse control is clicked.
* @param {function} [props.slotItemTemplateResolver] - Returns a custom JSX element used to render
* each resource slot cell in the left column.
* @param {function} [props.nonAgendaCellHeaderTemplateResolver] - Returns a custom JSX element used
* to render individual header cells in the timeline header row.
* @param {function(SchedulerData, HTMLElement, number):void} [props.onScrollLeft] - Callback invoked
* when the scheduler content is scrolled to the leftmost position.
* @param {function(SchedulerData, HTMLElement, number):void} [props.onScrollRight] - Callback invoked
* when the scheduler content is scrolled to the rightmost position.
* @param {function(SchedulerData, HTMLElement, number):void} [props.onScrollTop] - Callback invoked
* when the scheduler content is scrolled to the topmost position.
* @param {function(SchedulerData, HTMLElement, number):void} [props.onScrollBottom] - Callback invoked
* when the scheduler content is scrolled to the bottommost position.
* @param {React.ReactNode} [props.leftCustomHeader] - Custom content rendered on the left side of
* the scheduler header toolbar.
* @param {React.ReactNode} [props.rightCustomHeader] - Custom content rendered on the right side of
* the scheduler header toolbar.
* @param {function} [props.CustomResourceHeader] - Optional component rendered inside the resource
* column header cell, replacing the default resource name label.
* @param {function} [props.CustomResourceCell] - Optional component rendered inside each resource
* slot cell in the left column.
* @param {object} [props.configTableHeaderStyle] - Optional inline style object merged into the
* resource column header container, used to override default header styling.
* @returns {JSX.Element} The root scheduler table element containing the header toolbar, resource
* column, timeline header, and all resource event rows.
*/
function Scheduler(props) {
var schedulerData = props.schedulerData,
dndSources = props.dndSources,
parentRef = props.parentRef,
prevClick = props.prevClick,
nextClick = props.nextClick,
onViewChange = props.onViewChange,
onSelectDate = props.onSelectDate,
leftCustomHeader = props.leftCustomHeader,
rightCustomHeader = props.rightCustomHeader,
CustomResourceHeader = props.CustomResourceHeader,
configTableHeaderStyle = props.configTableHeaderStyle,
onScrollLeft = props.onScrollLeft,
onScrollRight = props.onScrollRight,
onScrollTop = props.onScrollTop,
onScrollBottom = props.onScrollBottom;
var _useState = (0, _react.useState)(function () {
return initDndContext(schedulerData, dndSources);
}),
_useState2 = _slicedToArray(_useState, 1),
dndContext = _useState2[0];
var _useState3 = (0, _react.useState)(17),
_useState4 = _slicedToArray(_useState3, 2),
contentScrollbarHeight = _useState4[0],
setContentScrollbarHeight = _useState4[1];
var _useState5 = (0, _react.useState)(17),
_useState6 = _slicedToArray(_useState5, 2),
contentScrollbarWidth = _useState6[0],
setContentScrollbarWidth = _useState6[1];
var _useState7 = (0, _react.useState)(17),
_useState8 = _slicedToArray(_useState7, 2),
resourceScrollbarHeight = _useState8[0],
setResourceScrollbarHeight = _useState8[1];
var _useState9 = (0, _react.useState)(17),
_useState0 = _slicedToArray(_useState9, 2),
resourceScrollbarWidth = _useState0[0],
setResourceScrollbarWidth = _useState0[1];
var _useState1 = (0, _react.useState)({
isSelecting: false,
selectedResourceIds: [],
left: 0,
width: 0
}),
_useState10 = _slicedToArray(_useState1, 2),
selectionState = _useState10[0],
setSelectionState = _useState10[1];
var _useState11 = (0, _react.useState)(0),
_useState12 = _slicedToArray(_useState11, 2),
setRenderTrigger = _useState12[1];
var schedulerRootRef = (0, _react.useRef)(null);
// Layout/header refs - declare before setSchedulerHeaderRef useCallback
var schedulerHeaderRef = (0, _react.useRef)(null);
// Callback ref pattern for ResizeObserver to handle schedulerHeader element reassignment
var _useState13 = (0, _react.useState)(null),
_useState14 = _slicedToArray(_useState13, 2),
schedulerHeaderEl = _useState14[0],
setSchedulerHeaderEl = _useState14[1];
var setSchedulerHeaderRef = (0, _react.useCallback)(function (el) {
schedulerHeaderRef.current = el;
setSchedulerHeaderEl(el);
}, []);
// Scroll sync refs
var schedulerHeadRef = (0, _react.useRef)(null);
var schedulerResourceRef = (0, _react.useRef)(null);
var schedulerContentRef = (0, _react.useRef)(null);
var schedulerContentBgTableRef = (0, _react.useRef)(null);
// Observer refs
var ulObserverRef = (0, _react.useRef)(null);
var headerObserverRef = (0, _react.useRef)(null);
// Scroll position tracking
var currentAreaRef = (0, _react.useRef)(-1);
var scrollLeftRef = (0, _react.useRef)(0);
var scrollTopRef = (0, _react.useRef)(0);
var scrollbarSizeRef = (0, _react.useRef)({
contentScrollbarHeight: 17,
contentScrollbarWidth: 17,
resourceScrollbarHeight: 17,
resourceScrollbarWidth: 17
});
(0, _react.useEffect)(function () {
if (typeof schedulerData.setVersionChangeNotifier === 'function') {
schedulerData.setVersionChangeNotifier(setRenderTrigger);
return function () {
return schedulerData.setVersionChangeNotifier(null);
};
}
return undefined;
}, [schedulerData]);
var onWindowResize = (0, _react.useCallback)(function () {
schedulerData.beginBatch();
try {
schedulerData._setDocumentWidth(document.documentElement.clientWidth);
schedulerData._setDocumentHeight(document.documentElement.clientHeight);
} finally {
schedulerData.endBatch();
}
}, [schedulerData]);
(0, _react.useEffect)(function () {
if (schedulerData.isSchedulerResponsive() && !schedulerData.config.responsiveByParent || parentRef === undefined) {
schedulerData.beginBatch();
try {
schedulerData._setDocumentWidth(document.documentElement.clientWidth);
schedulerData._setDocumentHeight(document.documentElement.clientHeight);
} finally {
schedulerData.endBatch();
}
window.addEventListener('resize', onWindowResize);
return function () {
return window.removeEventListener('resize', onWindowResize);
};
}
}, [schedulerData, parentRef, onWindowResize]);
(0, _react.useEffect)(function () {
var parentEl = parentRef === null || parentRef === void 0 ? void 0 : parentRef.current;
if (parentRef !== undefined && schedulerData.config.responsiveByParent && !!parentEl) {
var updateParentSize = function updateParentSize() {
schedulerData.beginBatch();
try {
schedulerData._setDocumentWidth(parentEl.clientWidth);
schedulerData._setDocumentHeight(parentEl.clientHeight);
} finally {
schedulerData.endBatch();
}
};
updateParentSize();
// Disconnect any previous observer to prevent memory leaks
if (ulObserverRef.current) {
ulObserverRef.current.disconnect();
}
ulObserverRef.current = new ResizeObserver(updateParentSize);
ulObserverRef.current.observe(parentEl);
return function () {
if (ulObserverRef.current) {
ulObserverRef.current.disconnect();
}
};
}
}, [parentRef, schedulerData]);
(0, _react.useEffect)(function () {
if (schedulerData.config.responsiveByParent && !!schedulerHeaderEl) {
var updateHeaderHeight = function updateHeaderHeight(node) {
var rect = node.getBoundingClientRect();
var style = window.getComputedStyle(node);
var totalHeight = rect.height + (parseFloat(style.marginTop) || 0) + (parseFloat(style.marginBottom) || 0) + (schedulerData.config.showWeekNumber ? schedulerData.config.weekNumberRowHeight || 0 : 0);
schedulerData._setSchedulerHeaderHeight(totalHeight);
};
updateHeaderHeight(schedulerHeaderEl);
headerObserverRef.current = new ResizeObserver(function (entries) {
entries.forEach(function (entry) {
return updateHeaderHeight(entry.target);
});
});
headerObserverRef.current.observe(schedulerHeaderEl);
return function () {
if (headerObserverRef.current) {
headerObserverRef.current.disconnect();
}
};
}
}, [schedulerHeaderEl, schedulerData, schedulerData.config.showWeekNumber, schedulerData.config.weekNumberRowHeight]);
var resolveScrollbarSize = (0, _react.useCallback)(function () {
var prev = scrollbarSizeRef.current;
var newContentHeight = schedulerContentRef.current ? schedulerContentRef.current.offsetHeight - schedulerContentRef.current.clientHeight : 17;
var newContentWidth = schedulerContentRef.current ? schedulerContentRef.current.offsetWidth - schedulerContentRef.current.clientWidth : 17;
var newResourceHeight = schedulerResourceRef.current ? schedulerResourceRef.current.offsetHeight - schedulerResourceRef.current.clientHeight : 17;
var newResourceWidth = schedulerResourceRef.current ? schedulerResourceRef.current.offsetWidth - schedulerResourceRef.current.clientWidth : 17;
if (newContentHeight !== prev.contentScrollbarHeight) {
setContentScrollbarHeight(newContentHeight);
scrollbarSizeRef.current.contentScrollbarHeight = newContentHeight;
}
if (newContentWidth !== prev.contentScrollbarWidth) {
setContentScrollbarWidth(newContentWidth);
scrollbarSizeRef.current.contentScrollbarWidth = newContentWidth;
}
if (newResourceHeight !== prev.resourceScrollbarHeight) {
setResourceScrollbarHeight(newResourceHeight);
scrollbarSizeRef.current.resourceScrollbarHeight = newResourceHeight;
}
if (newResourceWidth !== prev.resourceScrollbarWidth) {
setResourceScrollbarWidth(newResourceWidth);
scrollbarSizeRef.current.resourceScrollbarWidth = newResourceWidth;
}
}, []);
(0, _react.useEffect)(function () {
resolveScrollbarSize();
var localeDayjs = schedulerData.localeDayjs,
behaviors = schedulerData.behaviors;
if (schedulerData.getScrollToSpecialDayjs() && !!behaviors.getScrollSpecialDayjsFunc) {
if (!!schedulerContentRef.current && schedulerContentRef.current.scrollWidth > schedulerContentRef.current.clientWidth) {
var start = localeDayjs(new Date(schedulerData.startDate)).startOf('day');
var end = localeDayjs(new Date(schedulerData.endDate)).endOf('day');
var specialDayjs = behaviors.getScrollSpecialDayjsFunc(schedulerData, start, end);
if (specialDayjs >= start && specialDayjs <= end) {
var index = 0;
schedulerData.headers.forEach(function (item) {
if (specialDayjs >= localeDayjs(new Date(item.time))) index += 1;
});
schedulerContentRef.current.scrollLeft = (index - 1) * schedulerData.getContentCellWidth();
schedulerData.setScrollToSpecialDayjs(false);
}
}
}
}, [schedulerData, resolveScrollbarSize]);
var onSchedulerHeadMouseOver = (0, _react.useCallback)(function () {
currentAreaRef.current = 2;
}, []);
var onSchedulerHeadMouseOut = (0, _react.useCallback)(function () {
currentAreaRef.current = -1;
}, []);
var onSchedulerHeadScroll = (0, _react.useCallback)(function () {
if ((currentAreaRef.current === 2 || currentAreaRef.current === -1) && schedulerContentRef.current.scrollLeft !== schedulerHeadRef.current.scrollLeft) {
schedulerContentRef.current.scrollLeft = schedulerHeadRef.current.scrollLeft;
}
}, []);
var onSchedulerResourceMouseOver = (0, _react.useCallback)(function () {
currentAreaRef.current = 1;
}, []);
var onSchedulerResourceMouseOut = (0, _react.useCallback)(function () {
currentAreaRef.current = -1;
}, []);
var onSchedulerResourceScroll = (0, _react.useCallback)(function () {
if (schedulerResourceRef.current && (currentAreaRef.current === 1 || currentAreaRef.current === -1) && schedulerContentRef.current.scrollTop !== schedulerResourceRef.current.scrollTop) {
schedulerContentRef.current.scrollTop = schedulerResourceRef.current.scrollTop;
}
}, []);
var onSchedulerContentMouseOver = (0, _react.useCallback)(function () {
currentAreaRef.current = 0;
}, []);
var onSchedulerContentMouseOut = (0, _react.useCallback)(function () {
currentAreaRef.current = -1;
}, []);
var onSchedulerContentScroll = (0, _react.useCallback)(function () {
if (schedulerResourceRef.current) {
if (currentAreaRef.current === 0 || currentAreaRef.current === -1) {
if (schedulerHeadRef.current.scrollLeft !== schedulerContentRef.current.scrollLeft) {
schedulerHeadRef.current.scrollLeft = schedulerContentRef.current.scrollLeft;
}
if (schedulerResourceRef.current.scrollTop !== schedulerContentRef.current.scrollTop) {
schedulerResourceRef.current.scrollTop = schedulerContentRef.current.scrollTop;
}
}
}
if (schedulerContentRef.current.scrollLeft !== scrollLeftRef.current) {
if (schedulerContentRef.current.scrollLeft === 0 && onScrollLeft !== undefined) {
onScrollLeft(schedulerData, schedulerContentRef.current, schedulerContentRef.current.scrollWidth - schedulerContentRef.current.clientWidth);
}
if (Math.round(schedulerContentRef.current.scrollLeft) === schedulerContentRef.current.scrollWidth - schedulerContentRef.current.clientWidth && onScrollRight !== undefined) {
onScrollRight(schedulerData, schedulerContentRef.current, schedulerContentRef.current.scrollWidth - schedulerContentRef.current.clientWidth);
}
} else if (schedulerContentRef.current.scrollTop !== scrollTopRef.current) {
if (schedulerContentRef.current.scrollTop === 0 && onScrollTop !== undefined) {
onScrollTop(schedulerData, schedulerContentRef.current, schedulerContentRef.current.scrollHeight - schedulerContentRef.current.clientHeight);
}
if (Math.round(schedulerContentRef.current.scrollTop) === schedulerContentRef.current.scrollHeight - schedulerContentRef.current.clientHeight && onScrollBottom !== undefined) {
onScrollBottom(schedulerData, schedulerContentRef.current, schedulerContentRef.current.scrollHeight - schedulerContentRef.current.clientHeight);
}
}
scrollLeftRef.current = schedulerContentRef.current.scrollLeft;
scrollTopRef.current = schedulerContentRef.current.scrollTop;
}, [schedulerData, onScrollLeft, onScrollRight, onScrollTop, onScrollBottom]); // ✅ no props ref
var handleViewChange = (0, _react.useCallback)(function (e) {
var viewType = parseInt(e.target.value.charAt(0), 10);
var showAgenda = e.target.value.charAt(1) === '1';
var isEventPerspective = e.target.value.charAt(2) === '1';
onViewChange(schedulerData, {
viewType: viewType,
showAgenda: showAgenda,
isEventPerspective: isEventPerspective
});
}, [onViewChange, schedulerData]);
var goNext = (0, _react.useCallback)(function () {
return nextClick(schedulerData);
}, [nextClick, schedulerData]);
var goBack = (0, _react.useCallback)(function () {
return prevClick(schedulerData);
}, [prevClick, schedulerData]);
var onSelect = (0, _react.useCallback)(function (date) {
return onSelectDate(schedulerData, date);
}, [onSelectDate, schedulerData]);
var viewType = schedulerData.viewType,
renderData = schedulerData.renderData,
showAgenda = schedulerData.showAgenda,
config = schedulerData.config;
var width = schedulerData.getSchedulerWidth();
var showWeekNumber = config.showWeekNumber,
weekNumberRowHeight = config.weekNumberRowHeight;
var schedulerDataVersion = schedulerData.getVersion ? schedulerData.getVersion() : 0;
var schedulerWidth = schedulerData.getContentTableWidth() - 1;
var weekNumberRowStyle = (0, _react.useMemo)(function () {
return {
height: weekNumberRowHeight
};
}, [weekNumberRowHeight]);
var weekNumberThStyle = (0, _react.useMemo)(function () {
var _config$headerBorderC;
return {
borderBottom: "1px solid ".concat((_config$headerBorderC = config.headerBorderColor) !== null && _config$headerBorderC !== void 0 ? _config$headerBorderC : '#e9e9e9'),
fontSize: '0.85em',
opacity: 0.7,
padding: '4px 8px'
};
}, [config.headerBorderColor]);
var schedulerInnerStyle = (0, _react.useMemo)(function () {
return {
width: schedulerWidth
};
}, [schedulerWidth]);
var displayRenderData = (0, _react.useMemo)(function () {
return renderData.filter(function (o) {
return o.render;
});
}, [renderData]);
var eventDndSource = dndContext.getDndSource();
var handleSelectionChange = (0, _react.useCallback)(function (isSelecting, selectedResourceIds) {
var preview = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};
var nextSelectedResourceIds = selectedResourceIds || [];
var nextLeft = preview.left || 0;
var nextWidth = preview.width || 0;
setSelectionState(function (prev) {
var sameIdsLength = prev.selectedResourceIds.length === nextSelectedResourceIds.length;
var sameIds = sameIdsLength && prev.selectedResourceIds.every(function (id, index) {
return id === nextSelectedResourceIds[index];
});
if (prev.isSelecting === isSelecting && prev.left === nextLeft && prev.width === nextWidth && sameIds) {
return prev;
}
return {
isSelecting: isSelecting,
selectedResourceIds: nextSelectedResourceIds,
left: nextLeft,
width: nextWidth
};
});
}, []);
var selectionPreview = (0, _react.useMemo)(function () {
return {
isSelecting: selectionState.isSelecting,
left: selectionState.left,
width: selectionState.width
};
}, [selectionState.isSelecting, selectionState.left, selectionState.width]);
var selectedIdsSet = (0, _react.useMemo)(function () {
return new Set(selectionState.selectedResourceIds);
}, [selectionState.selectedResourceIds]);
var resourceEventsList = (0, _react.useMemo)(function () {
return displayRenderData.map(function (item) {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_ResourceEvents["default"], {
resourceEvents: item,
schedulerData: schedulerData,
schedulerDataVersion: schedulerDataVersion,
dndSource: eventDndSource,
dndContext: dndContext,
onSetAddMoreState: props.onSetAddMoreState,
updateEventStart: props.updateEventStart,
updateEventEnd: props.updateEventEnd,
moveEvent: props.moveEvent,
movingEvent: props.movingEvent,
conflictOccurred: props.conflictOccurred,
subtitleGetter: props.subtitleGetter,
eventItemClick: props.eventItemClick,
viewEventClick: props.viewEventClick,
viewEventText: props.viewEventText,
viewEvent2Click: props.viewEvent2Click,
viewEvent2Text: props.viewEvent2Text,
newEvent: props.newEvent,
eventItemTemplateResolver: props.eventItemTemplateResolver,
onSelectionChange: handleSelectionChange,
isRowSelected: selectedIdsSet.has(item.slotId),
selectionPreview: selectionPreview
}, item.slotId);
});
}, [displayRenderData, schedulerData, schedulerDataVersion, eventDndSource, dndContext, props.onSetAddMoreState, props.updateEventStart, props.updateEventEnd, props.moveEvent, props.movingEvent, props.conflictOccurred, props.subtitleGetter, props.eventItemClick, props.viewEventClick, props.viewEventText, props.viewEvent2Click, props.viewEvent2Text, props.newEvent, props.eventItemTemplateResolver, handleSelectionChange, selectedIdsSet, selectionPreview]);
var tbodyContent = /*#__PURE__*/(0, _jsxRuntime.jsx)("tr", {});
if (showAgenda) {
tbodyContent = /*#__PURE__*/(0, _jsxRuntime.jsx)(_AgendaView["default"], {
schedulerData: schedulerData,
subtitleGetter: props.subtitleGetter,
eventItemClick: props.eventItemClick,
viewEventClick: props.viewEventClick,
viewEventText: props.viewEventText,
viewEvent2Click: props.viewEvent2Click,
viewEvent2Text: props.viewEvent2Text,
slotClickedFunc: props.slotClickedFunc,
slotItemTemplateResolver: props.slotItemTemplateResolver,
eventItemTemplateResolver: props.eventItemTemplateResolver,
eventItemPopoverTemplateResolver: props.eventItemPopoverTemplateResolver
});
} else {
var _config$headerBorderC2, _config$headerBorderC3, _config$weekNumberLab;
var resourceTableWidth = schedulerData.getResourceTableWidth();
var schedulerContainerWidth = width - (config.resourceViewEnabled ? resourceTableWidth : 0);
var contentHeight = config.schedulerContentHeight;
var resourcePaddingBottom = resourceScrollbarHeight === 0 ? contentScrollbarHeight : 0;
var contentPaddingBottom = contentScrollbarHeight === 0 ? resourceScrollbarHeight : 0;
var schedulerContentStyle = {
overflowX: viewType === _default.ViewType.Week ? 'hidden' : 'auto',
overflowY: 'auto',
margin: '0px',
position: 'relative',
height: contentHeight,
paddingBottom: contentPaddingBottom
};
var resourceContentStyle = {
height: contentHeight,
overflowX: 'auto',
overflowY: 'auto',
width: resourceTableWidth + resourceScrollbarWidth - 2,
margin: "0px -".concat(contentScrollbarWidth, "px 0px 0px")
};
if (config.schedulerMaxHeight > 0) {
var totalHeaderHeight = config.tableHeaderHeight + (showWeekNumber ? weekNumberRowHeight : 0);
schedulerContentStyle = _objectSpread(_objectSpread({}, schedulerContentStyle), {}, {
maxHeight: config.schedulerMaxHeight - totalHeaderHeight
});
resourceContentStyle = _objectSpread(_objectSpread({}, resourceContentStyle), {}, {
maxHeight: config.schedulerMaxHeight - totalHeaderHeight
});
} else if (config.responsiveByParent && schedulerData.documentHeight > 0) {
var availableHeight = schedulerData.getSchedulerHeight();
schedulerContentStyle = _objectSpread(_objectSpread({}, schedulerContentStyle), {}, {
height: availableHeight
});
resourceContentStyle = _objectSpread(_objectSpread({}, resourceContentStyle), {}, {
height: availableHeight
});
}
var resourceName = schedulerData.isEventPerspective ? config.taskName : config.resourceName;
var resourceColumnStyle = {
display: config.resourceViewEnabled ? undefined : 'none',
width: resourceTableWidth,
verticalAlign: 'top'
};
var resourceHeaderStyle = _objectSpread({
borderBottom: "1px solid ".concat((_config$headerBorderC2 = config.headerBorderColor) !== null && _config$headerBorderC2 !== void 0 ? _config$headerBorderC2 : '#e9e9e9'),
height: config.tableHeaderHeight + (showWeekNumber ? weekNumberRowHeight : 0)
}, configTableHeaderStyle);
var resourceHeaderScrollStyle = {
overflowX: 'scroll',
overflowY: 'hidden',
margin: "0px 0px -".concat(contentScrollbarHeight, "px")
};
var schedulerViewStyle = {
width: schedulerContainerWidth,
verticalAlign: 'top'
};
var schedulerHeadWrapperStyle = {
overflow: 'hidden',
borderBottom: "1px solid ".concat((_config$headerBorderC3 = config.headerBorderColor) !== null && _config$headerBorderC3 !== void 0 ? _config$headerBorderC3 : '#e9e9e9'),
height: config.tableHeaderHeight + (showWeekNumber ? weekNumberRowHeight : 0)
};
var schedulerHeadScrollStyle = {
overflowX: 'scroll',
overflowY: 'hidden',
margin: "0px 0px -".concat(contentScrollbarHeight, "px")
};
var schedulerHeadInnerStyle = {
paddingRight: "".concat(contentScrollbarWidth, "px"),
width: schedulerWidth + contentScrollbarWidth
};
tbodyContent = /*#__PURE__*/(0, _jsxRuntime.jsxs)("tr", {
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
style: resourceColumnStyle,
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
className: "resource-view",
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
style: resourceHeaderStyle,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
style: resourceHeaderScrollStyle,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("table", {
className: "resource-table",
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("thead", {
children: [showWeekNumber && /*#__PURE__*/(0, _jsxRuntime.jsx)("tr", {
style: weekNumberRowStyle,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("th", {
style: weekNumberThStyle,
children: (_config$weekNumberLab = config.weekNumberLabel) !== null && _config$weekNumberLab !== void 0 ? _config$weekNumberLab : 'Week No.'
})
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("tr", {
style: {
height: config.tableHeaderHeight
},
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("th", {
className: "header3-text",
children: CustomResourceHeader ? /*#__PURE__*/(0, _jsxRuntime.jsx)(CustomResourceHeader, {}) : resourceName
})
})]
})
})
})
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
style: resourceContentStyle,
ref: schedulerResourceRef,
onMouseOver: onSchedulerResourceMouseOver,
onFocus: onSchedulerResourceMouseOver,
onMouseOut: onSchedulerResourceMouseOut,
onBlur: onSchedulerResourceMouseOut,
onScroll: onSchedulerResourceScroll,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_ResourceView["default"], {
schedulerData: schedulerData,
schedulerDataVersion: schedulerDataVersion,
contentScrollbarHeight: resourcePaddingBottom,
slotClickedFunc: props.slotClickedFunc,
slotItemTemplateResolver: props.slotItemTemplateResolver,
toggleExpandFunc: props.toggleExpandFunc,
CustomResourceCell: props.CustomResourceCell,
isSelecting: selectionState.isSelecting,
selectedResourceIds: selectionState.selectedResourceIds
})
})]
})
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
className: "scheduler-view",
style: schedulerViewStyle,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
style: schedulerHeadWrapperStyle,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
style: schedulerHeadScrollStyle,
ref: schedulerHeadRef,
onMouseOver: onSchedulerHeadMouseOver,
onFocus: onSchedulerHeadMouseOver,
onMouseOut: onSchedulerHeadMouseOut,
onBlur: onSchedulerHeadMouseOut,
onScroll: onSchedulerHeadScroll,
"aria-label": "Scheduler Header",
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
style: schedulerHeadInnerStyle,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("table", {
className: "scheduler-bg-table",
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_HeaderView["default"], {
schedulerData: schedulerData,
schedulerDataVersion: schedulerDataVersion,
nonAgendaCellHeaderTemplateResolver: props.nonAgendaCellHeaderTemplateResolver
})
})
})
})
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
style: schedulerContentStyle,
ref: schedulerContentRef,
onMouseOver: onSchedulerContentMouseOver,
onFocus: onSchedulerContentMouseOver,
onMouseOut: onSchedulerContentMouseOut,
onBlur: onSchedulerContentMouseOut,
onScroll: onSchedulerContentScroll,
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
style: schedulerInnerStyle,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
className: "scheduler-content",
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("table", {
className: "scheduler-content-table",
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("tbody", {
children: resourceEventsList
})
})
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
className: "scheduler-bg",
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("table", {
className: "scheduler-bg-table",
style: schedulerInnerStyle,
ref: schedulerContentBgTableRef,
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_BodyView["default"], {
schedulerData: schedulerData,
schedulerDataVersion: schedulerDataVersion
})
})
})]
})
})]
})
})]
});
}
var schedulerHeaderStyle = (0, _react.useMemo)(function () {
return {
display: config.headerEnabled ? undefined : 'none',
marginBottom: config.headerEnabled ? '24px' : undefined
};
}, [config.headerEnabled]);
var schedulerHeader = (0, _react.useMemo)(function () {
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_SchedulerHeader["default"], {
ref: setSchedulerHeaderRef,
style: schedulerHeaderStyle,
onViewChange: handleViewChange,
schedulerData: schedulerData,
onSelectDate: onSelect,
goNext: goNext,
goBack: goBack,
rightCustomHeader: rightCustomHeader,
leftCustomHeader: leftCustomHeader
});
}, [schedulerHeaderStyle, handleViewChange, schedulerData, onSelect, goNext, goBack, rightCustomHeader, leftCustomHeader]);
var rootTableStyle = (0, _react.useMemo)(function () {
return {
width: "".concat(width, "px")
};
}, [width]);
return /*#__PURE__*/(0, _jsxRuntime.jsxs)("table", {
id: "rbs-root",
className: "rbs",
style: rootTableStyle,
ref: schedulerRootRef,
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("thead", {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("tr", {
children: /*#__PURE__*/(0, _jsxRuntime.jsx)("td", {
colSpan: "2",
children: schedulerHeader
})
})
}), /*#__PURE__*/(0, _jsxRuntime.jsx)("tbody", {
children: tbodyContent
})]
});
}
Scheduler.propTypes = {
parentRef: _propTypes["default"].object,
schedulerData: _propTypes["default"].object.isRequired,
prevClick: _propTypes["default"].func.isRequired,
nextClick: _propTypes["default"].func.isRequired,
onViewChange: _propTypes["default"].func.isRequired,
onSelectDate: _propTypes["default"].func.isRequired,
onSetAddMoreState: _propTypes["default"].func,
updateEventStart: _propTypes["default"].func,
updateEventEnd: _propTypes["default"].func,
moveEvent: _propTypes["default"].func,
movingEvent: _propTypes["default"].func,
leftCustomHeader: _propTypes["default"].object,
rightCustomHeader: _propTypes["default"].object,
newEvent: _propTypes["default"].func,
subtitleGetter: _propTypes["default"].func,
eventItemClick: _propTypes["default"].func,
viewEventClick: _propTypes["default"].func,
viewEventText: _propTypes["default"].string,
viewEvent2Click: _propTypes["default"].func,
viewEvent2Text: _propTypes["default"].string,
conflictOccurred: _propTypes["default"].func,
eventItemTemplateResolver: _propTypes["default"].func,
dndSources: _propTypes["default"].array,
slotClickedFunc: _propTypes["default"].func,
toggleExpandFunc: _propTypes["default"].func,
slotItemTemplateResolver: _propTypes["default"].func,
nonAgendaCellHeaderTemplateResolver: _propTypes["default"].func,
onScrollLeft: _propTypes["default"].func,
onScrollRight: _propTypes["default"].func,
onScrollTop: _propTypes["default"].func,
onScrollBottom: _propTypes["default"].func,
CustomResourceHeader: _propTypes["default"].func,
CustomResourceCell: _propTypes["default"].func,
configTableHeaderStyle: _propTypes["default"].object
};