UNPKG

devextreme

Version:

JavaScript/TypeScript Component Suite for Responsive Web Development

170 lines (169 loc) • 7.34 kB
/** * DevExtreme (esm/__internal/scheduler/m_compact_appointments_helper.js) * Version: 25.2.5 * Build date: Fri Feb 20 2026 * * Copyright (c) 2012 - 2026 Developer Express Inc. ALL RIGHTS RESERVED * Read about DevExtreme licensing here: https://js.devexpress.com/Licensing/ */ import { locate, move } from "../../common/core/animation/translator"; import dateLocalization from "../../common/core/localization/date"; import messageLocalization from "../../common/core/localization/message"; import $ from "../../core/renderer"; import { FunctionTemplate } from "../../core/templates/function_template"; import Button from "../../ui/button"; import { APPOINTMENT_SETTINGS_KEY, LIST_ITEM_CLASS, LIST_ITEM_DATA_KEY } from "./constants"; const APPOINTMENT_COLLECTOR_CLASS = "dx-scheduler-appointment-collector"; const COMPACT_APPOINTMENT_COLLECTOR_CLASS = `${APPOINTMENT_COLLECTOR_CLASS}-compact`; const APPOINTMENT_COLLECTOR_CONTENT_CLASS = `${APPOINTMENT_COLLECTOR_CLASS}-content`; export class CompactAppointmentsHelper { constructor(instance) { this.elements = []; this.instance = instance } render(options) { const { isCompact: isCompact, items: items } = options; const template = this._createTemplate(items.length, isCompact); const button = this._createCompactButton(template, options); const $button = button.$element(); this.elements.push($button); $button.data("items", items); return $button } clear() { this.elements.forEach((button => { button.detach(); button.remove() })); this.elements = [] } _onButtonClick(e, options) { const $button = $(e.element); this.instance.showAppointmentTooltipCore($button, $button.data("items"), this._getExtraOptionsForTooltip(options, $button)) } _getExtraOptionsForTooltip(options, $appointmentCollector) { return { clickEvent: this._clickEvent(options.onAppointmentClick).bind(this), dragBehavior: options.allowDrag && this._createTooltipDragBehavior($appointmentCollector).bind(this), isButtonClick: true, _loopFocus: true } } _clickEvent(onAppointmentClick) { return e => { const clickEventArgs = this.instance._createEventArgs(e); onAppointmentClick(clickEventArgs) } } _createTooltipDragBehavior($appointmentCollector) { return e => { const $element = $(e.element); const $schedulerElement = $(this.instance.element()); const workSpace = this.instance.getWorkSpace(); const initialPosition = locate($appointmentCollector); const options = { filter: `.${LIST_ITEM_CLASS}`, isSetCursorOffset: true, initialPosition: initialPosition, getItemData: itemElement => { var _$$data; return null === (_$$data = $(itemElement).data(LIST_ITEM_DATA_KEY)) || void 0 === _$$data ? void 0 : _$$data.appointment }, getItemSettings: (_, event) => event.itemSettings }; workSpace._createDragBehaviorBase($element, $schedulerElement, options) } } _setPosition(element, position) { move(element, { top: position.top, left: position.left }) } _createCompactButton(template, options) { const $button = this._createCompactButtonElement(options); return this.instance._createComponent($button, Button, { type: "default", width: options.width, height: options.height, onClick: e => this._onButtonClick(e, options), template: this._renderTemplate(template, options.items, options.isCompact) }) } static measureCollectorDimensions($container, isCompact) { const $collector = $("<div>").addClass(APPOINTMENT_COLLECTOR_CLASS).toggleClass(COMPACT_APPOINTMENT_COLLECTOR_CLASS, isCompact).appendTo($container); const styles = getComputedStyle($collector.get(0)); const geometry = { width: styles.width, height: styles.height, marginLeft: styles.marginLeft, marginRight: styles.marginRight, marginTop: styles.marginTop, marginBottom: styles.marginBottom }; $collector.detach(); $collector.remove(); return geometry } _createCompactButtonElement(_ref) { let { isCompact: isCompact, $container: $container, coordinates: coordinates, sortedIndex: sortedIndex, items: items } = _ref; const appointmentDate = this._getDateText(items[0].appointment, items[0].targetedAppointment); const result = $("<div>").addClass(APPOINTMENT_COLLECTOR_CLASS).attr("aria-roledescription", appointmentDate).toggleClass(COMPACT_APPOINTMENT_COLLECTOR_CLASS, isCompact).appendTo($container); result.data(APPOINTMENT_SETTINGS_KEY, { sortedIndex: sortedIndex }); this._setPosition(result, coordinates); return result } _renderTemplate(template, items, isCompact) { return new FunctionTemplate((options => template.render({ model: { appointmentCount: items.length, items: items.map((item => item.appointment)), isCompact: isCompact }, container: options.container }))) } _createTemplate(count, isCompact) { this._initButtonTemplate(count, isCompact); return this.instance._getAppointmentTemplate("appointmentCollectorTemplate") } _initButtonTemplate(count, isCompact) { this.instance._templateManager.addDefaultTemplates({ appointmentCollector: new FunctionTemplate((options => this._createButtonTemplate(count, $(options.container), isCompact))) }) } _createButtonTemplate(appointmentCount, element, isCompact) { const text = isCompact ? appointmentCount : messageLocalization.getFormatter("dxScheduler-moreAppointments")(appointmentCount); return element.append($("<span>").text(text)).addClass(APPOINTMENT_COLLECTOR_CONTENT_CLASS) } _localizeDate(date) { return `${dateLocalization.format(date,"monthAndDay")}, ${dateLocalization.format(date,"year")}` } _getDateText(appointment, targetedAppointment) { const startDate = (null === targetedAppointment || void 0 === targetedAppointment ? void 0 : targetedAppointment.displayStartDate) ?? appointment.startDate; const endDate = (null === targetedAppointment || void 0 === targetedAppointment ? void 0 : targetedAppointment.displayEndDate) ?? appointment.endDate; const startDateText = this._localizeDate(startDate); const endDateText = this._localizeDate(endDate); return startDateText === endDateText ? startDateText : `${startDateText} - ${endDateText}` } }