You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DayColumn.js 16 KiB

3 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462
  1. "use strict";
  2. var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard");
  3. var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
  4. exports.__esModule = true;
  5. exports.default = void 0;
  6. var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose"));
  7. var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
  8. var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized"));
  9. var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose"));
  10. var _propTypes = _interopRequireDefault(require("prop-types"));
  11. var _react = _interopRequireDefault(require("react"));
  12. var _reactDom = require("react-dom");
  13. var _clsx = _interopRequireDefault(require("clsx"));
  14. var _Selection = _interopRequireWildcard(require("./Selection"));
  15. var dates = _interopRequireWildcard(require("./utils/dates"));
  16. var TimeSlotUtils = _interopRequireWildcard(require("./utils/TimeSlots"));
  17. var _selection = require("./utils/selection");
  18. var _helpers = require("./utils/helpers");
  19. var DayEventLayout = _interopRequireWildcard(require("./utils/DayEventLayout"));
  20. var _TimeSlotGroup = _interopRequireDefault(require("./TimeSlotGroup"));
  21. var _TimeGridEvent = _interopRequireDefault(require("./TimeGridEvent"));
  22. var DayColumn =
  23. /*#__PURE__*/
  24. function (_React$Component) {
  25. (0, _inheritsLoose2.default)(DayColumn, _React$Component);
  26. function DayColumn() {
  27. var _this;
  28. for (var _len = arguments.length, _args = new Array(_len), _key = 0; _key < _len; _key++) {
  29. _args[_key] = arguments[_key];
  30. }
  31. _this = _React$Component.call.apply(_React$Component, [this].concat(_args)) || this;
  32. _this.state = {
  33. selecting: false,
  34. timeIndicatorPosition: null
  35. };
  36. _this.intervalTriggered = false;
  37. _this.renderEvents = function () {
  38. var _this$props = _this.props,
  39. events = _this$props.events,
  40. rtl = _this$props.rtl,
  41. selected = _this$props.selected,
  42. accessors = _this$props.accessors,
  43. localizer = _this$props.localizer,
  44. getters = _this$props.getters,
  45. components = _this$props.components,
  46. step = _this$props.step,
  47. timeslots = _this$props.timeslots;
  48. var _assertThisInitialize = (0, _assertThisInitialized2.default)(_this),
  49. slotMetrics = _assertThisInitialize.slotMetrics;
  50. var messages = localizer.messages;
  51. var styledEvents = DayEventLayout.getStyledEvents({
  52. events: events,
  53. accessors: accessors,
  54. slotMetrics: slotMetrics,
  55. minimumStartDifference: Math.ceil(step * timeslots / 2)
  56. });
  57. return styledEvents.map(function (_ref, idx) {
  58. var event = _ref.event,
  59. style = _ref.style;
  60. var end = accessors.end(event);
  61. var start = accessors.start(event);
  62. var format = 'eventTimeRangeFormat';
  63. var label;
  64. var startsBeforeDay = slotMetrics.startsBeforeDay(start);
  65. var startsAfterDay = slotMetrics.startsAfterDay(end);
  66. if (startsBeforeDay) format = 'eventTimeRangeEndFormat';else if (startsAfterDay) format = 'eventTimeRangeStartFormat';
  67. if (startsBeforeDay && startsAfterDay) label = messages.allDay;else label = localizer.format({
  68. start: start,
  69. end: end
  70. }, format);
  71. var continuesEarlier = startsBeforeDay || slotMetrics.startsBefore(start);
  72. var continuesLater = startsAfterDay || slotMetrics.startsAfter(end);
  73. return _react.default.createElement(_TimeGridEvent.default, {
  74. style: style,
  75. event: event,
  76. label: label,
  77. key: 'evt_' + idx,
  78. getters: getters,
  79. rtl: rtl,
  80. components: components,
  81. continuesEarlier: continuesEarlier,
  82. continuesLater: continuesLater,
  83. accessors: accessors,
  84. selected: (0, _selection.isSelected)(event, selected),
  85. onClick: function onClick(e) {
  86. return _this._select(event, e);
  87. },
  88. onDoubleClick: function onDoubleClick(e) {
  89. return _this._doubleClick(event, e);
  90. }
  91. });
  92. });
  93. };
  94. _this._selectable = function () {
  95. var node = (0, _reactDom.findDOMNode)((0, _assertThisInitialized2.default)(_this));
  96. var selector = _this._selector = new _Selection.default(function () {
  97. return (0, _reactDom.findDOMNode)((0, _assertThisInitialized2.default)(_this));
  98. }, {
  99. longPressThreshold: _this.props.longPressThreshold
  100. });
  101. var maybeSelect = function maybeSelect(box) {
  102. var onSelecting = _this.props.onSelecting;
  103. var current = _this.state || {};
  104. var state = selectionState(box);
  105. var start = state.startDate,
  106. end = state.endDate;
  107. if (onSelecting) {
  108. if (dates.eq(current.startDate, start, 'minutes') && dates.eq(current.endDate, end, 'minutes') || onSelecting({
  109. start: start,
  110. end: end
  111. }) === false) return;
  112. }
  113. if (_this.state.start !== state.start || _this.state.end !== state.end || _this.state.selecting !== state.selecting) {
  114. _this.setState(state);
  115. }
  116. };
  117. var selectionState = function selectionState(point) {
  118. var currentSlot = _this.slotMetrics.closestSlotFromPoint(point, (0, _Selection.getBoundsForNode)(node));
  119. if (!_this.state.selecting) {
  120. _this._initialSlot = currentSlot;
  121. }
  122. var initialSlot = _this._initialSlot;
  123. if (dates.lte(initialSlot, currentSlot)) {
  124. currentSlot = _this.slotMetrics.nextSlot(currentSlot);
  125. } else if (dates.gt(initialSlot, currentSlot)) {
  126. initialSlot = _this.slotMetrics.nextSlot(initialSlot);
  127. }
  128. var selectRange = _this.slotMetrics.getRange(dates.min(initialSlot, currentSlot), dates.max(initialSlot, currentSlot));
  129. return (0, _extends2.default)({}, selectRange, {
  130. selecting: true,
  131. top: selectRange.top + "%",
  132. height: selectRange.height + "%"
  133. });
  134. };
  135. var selectorClicksHandler = function selectorClicksHandler(box, actionType) {
  136. if (!(0, _Selection.isEvent)((0, _reactDom.findDOMNode)((0, _assertThisInitialized2.default)(_this)), box)) {
  137. var _selectionState = selectionState(box),
  138. startDate = _selectionState.startDate,
  139. endDate = _selectionState.endDate;
  140. _this._selectSlot({
  141. startDate: startDate,
  142. endDate: endDate,
  143. action: actionType,
  144. box: box
  145. });
  146. }
  147. _this.setState({
  148. selecting: false
  149. });
  150. };
  151. selector.on('selecting', maybeSelect);
  152. selector.on('selectStart', maybeSelect);
  153. selector.on('beforeSelect', function (box) {
  154. if (_this.props.selectable !== 'ignoreEvents') return;
  155. return !(0, _Selection.isEvent)((0, _reactDom.findDOMNode)((0, _assertThisInitialized2.default)(_this)), box);
  156. });
  157. selector.on('click', function (box) {
  158. return selectorClicksHandler(box, 'click');
  159. });
  160. selector.on('doubleClick', function (box) {
  161. return selectorClicksHandler(box, 'doubleClick');
  162. });
  163. selector.on('select', function (bounds) {
  164. if (_this.state.selecting) {
  165. _this._selectSlot((0, _extends2.default)({}, _this.state, {
  166. action: 'select',
  167. bounds: bounds
  168. }));
  169. _this.setState({
  170. selecting: false
  171. });
  172. }
  173. });
  174. selector.on('reset', function () {
  175. if (_this.state.selecting) {
  176. _this.setState({
  177. selecting: false
  178. });
  179. }
  180. });
  181. };
  182. _this._teardownSelectable = function () {
  183. if (!_this._selector) return;
  184. _this._selector.teardown();
  185. _this._selector = null;
  186. };
  187. _this._selectSlot = function (_ref2) {
  188. var startDate = _ref2.startDate,
  189. endDate = _ref2.endDate,
  190. action = _ref2.action,
  191. bounds = _ref2.bounds,
  192. box = _ref2.box;
  193. var current = startDate,
  194. slots = [];
  195. while (dates.lte(current, endDate)) {
  196. slots.push(current);
  197. current = dates.add(current, _this.props.step, 'minutes');
  198. }
  199. (0, _helpers.notify)(_this.props.onSelectSlot, {
  200. slots: slots,
  201. start: startDate,
  202. end: endDate,
  203. resourceId: _this.props.resource,
  204. action: action,
  205. bounds: bounds,
  206. box: box
  207. });
  208. };
  209. _this._select = function () {
  210. for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  211. args[_key2] = arguments[_key2];
  212. }
  213. (0, _helpers.notify)(_this.props.onSelectEvent, args);
  214. };
  215. _this._doubleClick = function () {
  216. for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
  217. args[_key3] = arguments[_key3];
  218. }
  219. (0, _helpers.notify)(_this.props.onDoubleClickEvent, args);
  220. };
  221. _this.slotMetrics = TimeSlotUtils.getSlotMetrics(_this.props);
  222. return _this;
  223. }
  224. var _proto = DayColumn.prototype;
  225. _proto.componentDidMount = function componentDidMount() {
  226. this.props.selectable && this._selectable();
  227. if (this.props.isNow) {
  228. this.setTimeIndicatorPositionUpdateInterval();
  229. }
  230. };
  231. _proto.componentWillUnmount = function componentWillUnmount() {
  232. this._teardownSelectable();
  233. this.clearTimeIndicatorInterval();
  234. };
  235. _proto.componentWillReceiveProps = function componentWillReceiveProps(nextProps) {
  236. if (nextProps.selectable && !this.props.selectable) this._selectable();
  237. if (!nextProps.selectable && this.props.selectable) this._teardownSelectable();
  238. this.slotMetrics = this.slotMetrics.update(nextProps);
  239. };
  240. _proto.componentDidUpdate = function componentDidUpdate(prevProps, prevState) {
  241. var getNowChanged = !dates.eq(prevProps.getNow(), this.props.getNow(), 'minutes');
  242. if (prevProps.isNow !== this.props.isNow || getNowChanged) {
  243. this.clearTimeIndicatorInterval();
  244. if (this.props.isNow) {
  245. var tail = !getNowChanged && dates.eq(prevProps.date, this.props.date, 'minutes') && prevState.timeIndicatorPosition === this.state.timeIndicatorPosition;
  246. this.setTimeIndicatorPositionUpdateInterval(tail);
  247. }
  248. } else if (this.props.isNow && (!dates.eq(prevProps.min, this.props.min, 'minutes') || !dates.eq(prevProps.max, this.props.max, 'minutes'))) {
  249. this.positionTimeIndicator();
  250. }
  251. };
  252. /**
  253. * @param tail {Boolean} - whether `positionTimeIndicator` call should be
  254. * deferred or called upon setting interval (`true` - if deferred);
  255. */
  256. _proto.setTimeIndicatorPositionUpdateInterval = function setTimeIndicatorPositionUpdateInterval(tail) {
  257. var _this2 = this;
  258. if (tail === void 0) {
  259. tail = false;
  260. }
  261. if (!this.intervalTriggered && !tail) {
  262. this.positionTimeIndicator();
  263. }
  264. this._timeIndicatorTimeout = window.setTimeout(function () {
  265. _this2.intervalTriggered = true;
  266. _this2.positionTimeIndicator();
  267. _this2.setTimeIndicatorPositionUpdateInterval();
  268. }, 60000);
  269. };
  270. _proto.clearTimeIndicatorInterval = function clearTimeIndicatorInterval() {
  271. this.intervalTriggered = false;
  272. window.clearTimeout(this._timeIndicatorTimeout);
  273. };
  274. _proto.positionTimeIndicator = function positionTimeIndicator() {
  275. var _this$props2 = this.props,
  276. min = _this$props2.min,
  277. max = _this$props2.max,
  278. getNow = _this$props2.getNow;
  279. var current = getNow();
  280. if (current >= min && current <= max) {
  281. var top = this.slotMetrics.getCurrentTimePosition(current);
  282. this.setState({
  283. timeIndicatorPosition: top
  284. });
  285. } else {
  286. this.clearTimeIndicatorInterval();
  287. }
  288. };
  289. _proto.render = function render() {
  290. var _this$props3 = this.props,
  291. max = _this$props3.max,
  292. rtl = _this$props3.rtl,
  293. isNow = _this$props3.isNow,
  294. resource = _this$props3.resource,
  295. accessors = _this$props3.accessors,
  296. localizer = _this$props3.localizer,
  297. _this$props3$getters = _this$props3.getters,
  298. dayProp = _this$props3$getters.dayProp,
  299. getters = (0, _objectWithoutPropertiesLoose2.default)(_this$props3$getters, ["dayProp"]),
  300. _this$props3$componen = _this$props3.components,
  301. EventContainer = _this$props3$componen.eventContainerWrapper,
  302. components = (0, _objectWithoutPropertiesLoose2.default)(_this$props3$componen, ["eventContainerWrapper"]);
  303. var slotMetrics = this.slotMetrics;
  304. var _this$state = this.state,
  305. selecting = _this$state.selecting,
  306. top = _this$state.top,
  307. height = _this$state.height,
  308. startDate = _this$state.startDate,
  309. endDate = _this$state.endDate;
  310. var selectDates = {
  311. start: startDate,
  312. end: endDate
  313. };
  314. var _dayProp = dayProp(max),
  315. className = _dayProp.className,
  316. style = _dayProp.style;
  317. return _react.default.createElement("div", {
  318. style: style,
  319. className: (0, _clsx.default)(className, 'rbc-day-slot', 'rbc-time-column', isNow && 'rbc-now', isNow && 'rbc-today', // WHY
  320. selecting && 'rbc-slot-selecting')
  321. }, slotMetrics.groups.map(function (grp, idx) {
  322. return _react.default.createElement(_TimeSlotGroup.default, {
  323. key: idx,
  324. group: grp,
  325. resource: resource,
  326. getters: getters,
  327. components: components
  328. });
  329. }), _react.default.createElement(EventContainer, {
  330. localizer: localizer,
  331. resource: resource,
  332. accessors: accessors,
  333. getters: getters,
  334. components: components,
  335. slotMetrics: slotMetrics
  336. }, _react.default.createElement("div", {
  337. className: (0, _clsx.default)('rbc-events-container', rtl && 'rtl')
  338. }, this.renderEvents())), selecting && _react.default.createElement("div", {
  339. className: "rbc-slot-selection",
  340. style: {
  341. top: top,
  342. height: height
  343. }
  344. }, _react.default.createElement("span", null, localizer.format(selectDates, 'selectRangeFormat'))), isNow && _react.default.createElement("div", {
  345. className: "rbc-current-time-indicator",
  346. style: {
  347. top: this.state.timeIndicatorPosition + "%"
  348. }
  349. }));
  350. };
  351. return DayColumn;
  352. }(_react.default.Component);
  353. DayColumn.propTypes = process.env.NODE_ENV !== "production" ? {
  354. events: _propTypes.default.array.isRequired,
  355. step: _propTypes.default.number.isRequired,
  356. date: _propTypes.default.instanceOf(Date).isRequired,
  357. min: _propTypes.default.instanceOf(Date).isRequired,
  358. max: _propTypes.default.instanceOf(Date).isRequired,
  359. getNow: _propTypes.default.func.isRequired,
  360. isNow: _propTypes.default.bool,
  361. rtl: _propTypes.default.bool,
  362. accessors: _propTypes.default.object.isRequired,
  363. components: _propTypes.default.object.isRequired,
  364. getters: _propTypes.default.object.isRequired,
  365. localizer: _propTypes.default.object.isRequired,
  366. showMultiDayTimes: _propTypes.default.bool,
  367. culture: _propTypes.default.string,
  368. timeslots: _propTypes.default.number,
  369. selected: _propTypes.default.object,
  370. selectable: _propTypes.default.oneOf([true, false, 'ignoreEvents']),
  371. eventOffset: _propTypes.default.number,
  372. longPressThreshold: _propTypes.default.number,
  373. onSelecting: _propTypes.default.func,
  374. onSelectSlot: _propTypes.default.func.isRequired,
  375. onSelectEvent: _propTypes.default.func.isRequired,
  376. onDoubleClickEvent: _propTypes.default.func.isRequired,
  377. className: _propTypes.default.string,
  378. dragThroughEvents: _propTypes.default.bool,
  379. resource: _propTypes.default.any
  380. } : {};
  381. DayColumn.defaultProps = {
  382. dragThroughEvents: true,
  383. timeslots: 2
  384. };
  385. var _default = DayColumn;
  386. exports.default = _default;
  387. module.exports = exports["default"];