UNPKG

@progress/kendo-react-scheduler

Version:

React Scheduler brings the functionality of Outlook's Calendar to a single UI component. KendoReact Scheduler package

370 lines (369 loc) 13.6 kB
/** * @license *------------------------------------------------------------------------------------------- * Copyright © 2025 Progress Software Corporation. All rights reserved. * Licensed under commercial license. See LICENSE.md in the package root for more information *------------------------------------------------------------------------------------------- */ import * as a from "react"; import n from "prop-types"; import { getModelFields as Oe, toSchedulerGroups as Ne, findMaster as y, setField as d, getField as c } from "./utils/index.mjs"; import { validatePackage as We, getLicenseMessage as Pe, useRtl as He, clone as w, classNames as ze, WatermarkOverlay as _e } from "@progress/kendo-react-common"; import { SchedulerContext as Be } from "./context/SchedulerContext.mjs"; import { useControlledState as N } from "./hooks/useControlledState.mjs"; import { useInternationalization as Ue, useLocalization as Ge } from "@progress/kendo-react-intl"; import { SchedulerHeader as Ke } from "./components/header/SchedulerHeader.mjs"; import { SchedulerNavigation as ce } from "./components/header/navigation/SchedulerNavigation.mjs"; import { SchedulerViewSelector as Ze } from "./components/header/view-selector/SchedulerViewSelector.mjs"; import { addMonths as Y, addDays as $, ZonedDate as je } from "@progress/kendo-date-math"; import { SchedulerFooter as qe } from "./components/footer/SchedulerFooter.mjs"; import { ButtonGroup as Je, Button as R, ToolbarSpacer as Qe } from "@progress/kendo-react-buttons"; import { today as ee, messages as T, previousTitle as te, nextTitle as re, showFullDay as ae, showWorkDay as ne } from "./messages/index.mjs"; import { NavigationDatePicker as Xe } from "./components/header/navigation/NavigationDatePicker.mjs"; import { ViewSelectorList as Ye } from "./components/header/view-selector/ViewSelectorList.mjs"; import { BusinessHours as $e } from "./components/footer/bussiness-hours/BussinessHours.mjs"; import { DayView as P, dayViewDefaultProps as et } from "./views/day/DayView.mjs"; import { packageMetadata as oe } from "./package-metadata.mjs"; import { caretAltRightIcon as le, caretAltLeftIcon as se, clockIcon as tt } from "@progress/kendo-svg-icons"; import { DATA_ACTION as W } from "./constants/index.mjs"; import { AgendaView as rt, agendaViewDefaultProps as at } from "./views/agenda/AgendaView.mjs"; import { MonthView as nt, monthViewDefaultProps as ot } from "./views/month/MonthView.mjs"; import { WeekView as lt, weekViewDefaultProps as st } from "./views/week/WeekView.mjs"; import { WorkWeekView as ct, workWeekDefaultProps as it } from "./views/week/WorkWeekView.mjs"; import { TimelineView as ut, timeLineViewDefaultProps as dt } from "./views/time/TimelineView.mjs"; const mt = "{0:D}", gt = "{0:d}", ft = "application", k = /* @__PURE__ */ new Map(); k.set(rt, at); k.set(P, et); k.set(nt, ot); k.set(lt, st); k.set(ct, it); k.set(ut, dt); const ie = a.forwardRef((r, ue) => { var J, Q, X; const de = !We(oe, { component: "Scheduler" }), me = Pe(oe), { timezone: V, onDataChange: A } = r, g = a.useRef(null), b = a.useRef(null); a.useImperativeHandle(b, () => ({ props: r, element: g.current })), a.useImperativeHandle(ue, () => b.current); const I = He(g), F = Ue(), C = Ge(), { fields: t } = a.useMemo(() => Oe(r.modelFields), [r.modelFields]), [p, f] = N( r.defaultDate || h.defaultDate, r.date, r.onDateChange ), x = a.Children.toArray(r.children || []).map( (e) => { var l; return a.isValidElement(e) ? a.cloneElement(e, { ...k.get(e.type), ...(l = e.props) != null ? l : {} }) : e; } ), ge = a.cloneElement(/* @__PURE__ */ a.createElement(P, null), k.get(P)), [H, z] = N( r.defaultView || x[0] && x[0].props.name || "day", r.view, r.onViewChange ), [S, _] = N(!0), i = x.find((e) => e.props.name === H) || x[0] || ge, D = ((J = r.data) != null ? J : h.data) || h.data, fe = Ne(r.group, r.resources), he = r.group && r.group.orientation ? r.group.orientation : "horizontal", pe = i.props.selectedDateFormat || mt, De = i.props.selectedShortDateFormat || gt, B = i.props.slotDuration, we = i.props.dateRange !== void 0 ? typeof i.props.dateRange == "function" ? i.props.dateRange.call(void 0, { intl: F, date: p, timezone: V, numberOfDays: i.props.numberOfDays, workWeekStart: i.props.workWeekStart || F.firstDay(), workWeekEnd: i.props.workWeekEnd || (F.firstDay() + i.props.numberOfDays) % 6 }) : i.props.dateRange : { start: h.defaultDate, end: h.defaultDate }, v = a.useCallback( ({ created: e = [], updated: l = [], deleted: m = [] }) => { if (A) { const o = { created: e, updated: l, deleted: m }; A.call(void 0, o); } }, [A] ), U = a.useCallback( (e) => { const l = [e.dataItem]; v({ created: l }); }, [v] ), G = a.useCallback( (e) => { const l = [], m = []; if (e.series) if (Array.isArray(e.dataItem)) e.dataItem.forEach((o) => { const s = w(y(e.dataItem, t, D)), u = w(o); d(u, t.originalStart, c(s, t.originalStart)), d(u, t.recurrenceId, c(s, t.recurrenceId)), d( u, t.recurrenceExceptions, c(s, t.recurrenceExceptions) ), m.push(u); }); else { const o = w(y(e.dataItem, t, D)), s = w(e.dataItem); d(s, t.originalStart, c(o, t.originalStart)), d(s, t.recurrenceId, c(o, t.recurrenceId)), d( s, t.recurrenceExceptions, c(o, t.recurrenceExceptions) ), m.push(s); } else if (Array.isArray(e.dataItem)) e.dataItem.forEach((o) => { const s = c(o, t.recurrenceRule) !== null && c(o, t.recurrenceRule) !== void 0; if (c(o, t.recurrenceId) !== null && c(o, t.recurrenceId) !== void 0 && s) { const E = w(y(o, t, D)), O = c(o, t.originalStart), Le = c(E, t.recurrenceExceptions) || []; d(E, t.recurrenceExceptions, [...Le, O]), d(o, t.recurrenceRule, null), m.push(E), l.push(o); } else m.push(o); }); else { const o = c(e.dataItem, t.recurrenceRule) !== null && c(e.dataItem, t.recurrenceRule) !== void 0; if (c(e.dataItem, t.recurrenceId) !== null && c(e.dataItem, t.recurrenceId) !== void 0 && o) { const u = w(y(e.dataItem, t, D)), E = c(e.dataItem, t.originalStart), O = c(u, t.recurrenceExceptions) || []; d(u, t.recurrenceExceptions, [...O, E]), d(e.dataItem, t.recurrenceRule, null), m.push(u), l.push(e.dataItem); } else m.push(e.dataItem); } v({ updated: m, created: l }); }, [v, t, D] ), K = a.useCallback( (e) => { const l = [], m = []; if (e.series) { const o = w(y(e.dataItem, t, D)), s = w(e.dataItem); d(s, t.originalStart, c(o, t.originalStart)), d(s, t.recurrenceId, c(o, t.recurrenceId)), d(s, t.recurrenceRule, c(o, t.recurrenceRule)), d(s, t.recurrenceExceptions, c(o, t.recurrenceExceptions)), m.push(s); } else if (!(c(e.dataItem, t.recurrenceRule) !== null && c(e.dataItem, t.recurrenceRule) !== void 0)) m.push(e.dataItem); else { const s = w(y(e.dataItem, t, D)), u = c(e.dataItem, t.originalStart), E = c(s, t.recurrenceExceptions) || []; d(s, t.recurrenceExceptions, [...E, u]), d(e.dataItem, t.recurrenceRule, null), l.push(s); } v({ updated: l, deleted: m }); }, [v, t, D] ), Z = a.useCallback( (e) => { switch (e.type) { case W.create: U(e); break; case W.update: G(e); break; case W.remove: K(e); break; } }, [U, K, G] ), be = a.useCallback( (e, l) => { z(e, { ...l, target: b.current }); }, [z, b] ), ke = a.useCallback( (e, l) => { f(e, { ...l, target: b.current }); }, [f, b] ), Ie = a.useCallback( (e) => { e.value && f(e.value, { ...e, target: b.current, nativeEvent: e.nativeEvent }); }, [f, b] ), Ee = a.useCallback( (e) => { var s, u; e.preventDefault(); const l = (u = (s = i.props.step) != null ? s : i.props.numberOfDays) != null ? u : 1, o = l > 27 ? Y(p, Math.round(l / 27)) : $(p, l); f(o, e); }, [p, f, i.props.numberOfDays, i.props.step] ), ve = a.useCallback( (e) => { var s, u; e.preventDefault(); const l = (u = (s = i.props.step) != null ? s : i.props.numberOfDays) != null ? u : 1, o = l > 27 ? Y(p, -Math.round(l / 27)) : $(p, -l); f(o, e); }, [p, f, i.props.numberOfDays, i.props.step] ), ye = a.useCallback( (e) => { e.preventDefault(); const l = je.fromLocalDate(/* @__PURE__ */ new Date(), V); f(new Date(l.getTime()), e); }, [f, V] ), xe = a.useCallback(() => { _(!S); }, [_, S]), Se = a.useCallback(() => { g.current && (g.current.style.boxShadow = "0 0.5px 0.5px 0.5px rgba(0, 0, 0, .12)"); }, [g]), Ce = a.useCallback(() => { g.current && (g.current.style.boxShadow = ""); }, [g]), Re = a.useMemo( () => { var e; return { ...r.style, height: (e = r.height) != null ? e : h.height }; }, [r.height, r.style] ), Te = a.useMemo( () => ze( { "k-rtl": r.rtl !== void 0 ? r.rtl : I === "rtl" }, "k-scheduler", r.className ), [r.className, r.rtl, I] ), M = C.toLanguageString(ee, T[ee]), j = C.toLanguageString(te, T[te]), q = C.toLanguageString(re, T[re]), Ve = i.props.header || r.header || h.header, Ae = i.props.footer || r.footer || h.footer, Fe = ce, [L, Me] = a.useState(null); return /* @__PURE__ */ a.createElement( Be, { element: g, props: r, views: x, fields: t, groups: fe, dateRange: we, orientation: he, dateFormat: { dateFormat: pe, shortDateFormat: De }, date: [p, ke], activeView: [H, be], selection: [L, Me], data: [D, Z] }, /* @__PURE__ */ a.createElement( "div", { ref: g, id: r.id, style: Re, className: Te, tabIndex: (Q = r.tabIndex) != null ? Q : h.tabIndex, dir: I, role: r.role || ft, "aria-label": r.ariaLabel, "aria-labelledby": r.ariaLabelledby, "aria-activedescendant": L && L.props.id || void 0, onFocus: Se, onBlur: Ce }, /* @__PURE__ */ a.createElement(Ve, null, /* @__PURE__ */ a.createElement(Fe, null, /* @__PURE__ */ a.createElement(Je, { className: "k-scheduler-navigation" }, /* @__PURE__ */ a.createElement( R, { role: "button", tabIndex: -1, title: M, "aria-label": M, onClick: ye }, M ), /* @__PURE__ */ a.createElement( R, { role: "button", tabIndex: -1, icon: I === "rtl" ? "caret-alt-right" : "caret-alt-left", svgIcon: I === "rtl" ? le : se, title: j, "aria-label": j, onClick: ve } ), /* @__PURE__ */ a.createElement( R, { role: "button", tabIndex: -1, icon: I === "rtl" ? "caret-alt-left" : "caret-alt-right", svgIcon: I === "rtl" ? se : le, title: q, "aria-label": q, onClick: Ee } ))), /* @__PURE__ */ a.createElement(Xe, { value: p, onChange: Ie }), /* @__PURE__ */ a.createElement(Qe, null), /* @__PURE__ */ a.createElement(Ye, null)), i && /* @__PURE__ */ a.createElement( i.type, { editable: (X = r.editable) != null ? X : h.editable, key: i.props.name, item: r.item, viewItem: r.viewItem, editItem: r.editItem, task: r.task, viewTask: r.viewTask, editTask: r.viewTask, slot: r.slot, viewSlot: r.viewSlot, editSlot: r.editSlot, form: r.form, onDataAction: Z, showWorkHours: S, ...i.props } ), /* @__PURE__ */ a.createElement(Ae, null, B && B < 24 * 60 && /* @__PURE__ */ a.createElement($e, null, /* @__PURE__ */ a.createElement(R, { tabIndex: -1, onClick: xe, icon: "clock", svgIcon: tt }, C.toLanguageString( S ? ae : ne, T[S ? ae : ne] )))), de && /* @__PURE__ */ a.createElement(_e, { message: me }) ) ); }), h = { data: [], height: 600, tabIndex: -1, editable: !1, defaultDate: /* @__PURE__ */ new Date(), header: Ke, footer: qe, navigation: ce, viewSelector: Ze }; ie.propTypes = { data: n.array, editable: n.oneOfType([ n.bool, n.shape({ add: n.bool, drag: n.bool, edit: n.bool, remove: n.bool, resize: n.bool }) ]), view: n.string, defaultView: n.string, date: n.any, defaultDate: n.any, rtl: n.bool, height: n.oneOfType([n.number, n.string]), children: n.any, timezone: n.string, group: n.any, resources: n.any, modelFields: n.shape({ id: n.string, start: n.string, startTimezone: n.string, end: n.string, endTimezone: n.string, isAllDay: n.string, title: n.string, description: n.string, recurrenceRule: n.string, recurrenceId: n.string, recurrenceException: n.string }) }; ie.displayName = "KendoReactScheduler"; export { ie as Scheduler, h as schedulerDefaultProps };