芝麻web文件管理V1.00
编辑当前文件:/home/pulsehostuk9/www/cloud.pulsehost.co.uk/modules/CalendarWebclient/js/views/CalendarView.js
'use strict' const _ = require('underscore'), $ = require('jquery'), ko = require('knockout'), moment = require('moment-timezone') const DateUtils = require('%PathToCoreWebclientModule%/js/utils/Date.js'), TextUtils = require('%PathToCoreWebclientModule%/js/utils/Text.js'), Types = require('%PathToCoreWebclientModule%/js/utils/Types.js'), Api = require('%PathToCoreWebclientModule%/js/Api.js'), App = require('%PathToCoreWebclientModule%/js/App.js'), Browser = require('%PathToCoreWebclientModule%/js/Browser.js'), CJua = require('%PathToCoreWebclientModule%/js/CJua.js'), Screens = require('%PathToCoreWebclientModule%/js/Screens.js'), UserSettings = require('%PathToCoreWebclientModule%/js/Settings.js'), Pulse = require('%PathToCoreWebclientModule%/js/Pulse.js'), CAbstractScreenView = require('%PathToCoreWebclientModule%/js/views/CAbstractScreenView.js'), Popups = require('%PathToCoreWebclientModule%/js/Popups.js'), ConfirmPopup = require('%PathToCoreWebclientModule%/js/popups/ConfirmPopup.js'), Utils = require('%PathToCoreWebclientModule%/js/utils/Common.js') const EditCalendarPopup = require('modules/%ModuleName%/js/popups/EditCalendarPopup.js'), EditEventPopup = require('modules/%ModuleName%/js/popups/EditEventPopup.js'), EditEventRecurrencePopup = require('modules/%ModuleName%/js/popups/EditEventRecurrencePopup.js'), GetCalendarLinkPopup = require('modules/%ModuleName%/js/popups/GetCalendarLinkPopup.js'), ImportCalendarPopup = require('modules/%ModuleName%/js/popups/ImportCalendarPopup.js'), SelectCalendarPopup = require('modules/%ModuleName%/js/popups/SelectCalendarPopup.js'), CalendarSharePopup = require('modules/%ModuleName%/js/popups/CalendarSharePopup.js'), FullCalendarUtils = require('modules/%ModuleName%/js/utils/FullCalendar.js'), Ajax = require('modules/%ModuleName%/js/Ajax.js'), CalendarCache = require('modules/%ModuleName%/js/Cache.js'), Settings = require('modules/%ModuleName%/js/Settings.js'), CCalendarListModel = require('modules/%ModuleName%/js/models/CCalendarListModel.js'), CCalendarModel = require('modules/%ModuleName%/js/models/CCalendarModel.js') const bMobileDevice = false require('jquery-ui/ui/widgets/datepicker') /** * @constructor */ function CCalendarView() { CAbstractScreenView.call(this, '%ModuleName%') this.browserTitle = ko.observable(TextUtils.i18n('%MODULENAME%/HEADING_BROWSER_TAB')) var self = this this.initialized = ko.observable(false) this.isPublic = App.isPublic() this.uploaderArea = ko.observable(null) this.bDragActive = ko.observable(false) this.bDragActiveComp = ko.computed(function () { return this.bDragActive() }, this) this.aDayNames = TextUtils.i18n('COREWEBCLIENT/LIST_DAY_NAMES').split(' ') this.popUpStatus = false this.linkRow = 0 this.linkColumn = 0 this.sTimeFormat = UserSettings.timeFormat() === Enums.TimeFormat.F24 ? 'HH:mm' : 'hh:mm A' this.dateFormatForMoment = Utils.getDateFormatForMoment(UserSettings.dateFormat()) this.topPositionToday = ko.observable('.fc-widget-content.fc-today') this.loadOnce = false this.scrollModel = ko.observable(null) this.scrollHeight = 0 this.dateTitle = ko.observable('') this.aMonthNames = DateUtils.getMonthNamesArray() this.selectedView = ko.observable('') this.visibleWeekdayHeader = ko.computed(function () { return this.selectedView() === 'month' }, this) this.selectedView.subscribe(function () { this.resize() }, this) this.$calendarGrid = null this.calendarGridDom = ko.observable(null) this.$datePicker = null this.datePickerDom = ko.observable(null) this.calendars = new CCalendarListModel({ onCalendarCollectionChange: function () { self.refreshView() }, onCalendarActiveChange: function () { self.refreshView() }, }) this.colors = Settings.CalendarColors this.busyDays = ko.observableArray([]) this.$inlineEditedEvent = null this.inlineEditedEventText = null this.checkStarted = ko.observable(false) this.loaded = false this.startDateTime = 0 this.endDateTime = 0 this.needsToReload = false this.bTimezoneChanged = false UserSettings.timezone.subscribe(function () { this.startDateTime = 0 this.endDateTime = 0 this.needsToReload = true this.bTimezoneChanged = true this.getCalendars() }, this) this.calendarListClick = function (oItem) { oItem.active(!oItem.active()) } this.currentCalendarDropdown = ko.observable(false) this.currentCalendarDropdownOffset = ko.observable(0) this.calendarDropdownToggle = function (bValue, oElement) { if (oElement && bValue) { var position = oElement.position(), height = oElement.outerHeight() self.currentCalendarDropdownOffset(Types.pInt(position.top) + height) } self.currentCalendarDropdown(bValue) } this.calendarDropdownHide = _.throttle( _.bind(function () { this.calendarDropdownToggle(false) }, this), 500 ) this.dayNamesResizeBinding = _.throttle(_.bind(this.resize, this), 50) this.customscrollTop = ko.observable(0) this.fullcalendarOptions = { handleWindowResize: true, eventLimit: 10, header: false, editable: !this.isPublic, selectable: !this.isPublic, allDayText: TextUtils.i18n('%MODULENAME%/LABEL_ALL_DAY'), dayNames: this.aDayNames, monthNames: this.aMonthNames, isRTL: UserSettings.IsRTL, scrollTime: moment.duration(8, 'hours'), forceEventDuration: true, defaultTimedEventDuration: '00:00:01', views: { month: { columnFormat: 'dddd', // Monday }, week: { columnFormat: 'dddd D', // Monday 7 }, day: { columnFormat: 'dddd D', // Monday 7 }, listMonth: { listDayFormat: this.dateFormatForMoment } }, displayEventEnd: { month: true, basicWeek: true, default: true, }, select: _.bind(this.createEventFromGrid, this), eventClick: _.bind(this.eventClickCallback, this), eventDragStart: _.bind(this.onEventDragStart, this), eventDragStop: _.bind(this.onEventDragStop, this), eventResizeStart: _.bind(this.onEventResizeStart, this), eventResizeStop: _.bind(this.onEventResizeStop, this), eventDrop: _.bind(this.moveEvent, this), eventResize: _.bind(this.resizeEvent, this), eventRender: function (oEv, oEl) { if (Settings.AddDescriptionToTitle) { var oTitle = oEl.find('.fc-title') oTitle.html( '
' + $.trim(oEv.subject.replace(/[\n\r]/g, ' ')) + '
' + '
' + $.trim(oEv.description.replace(/[\n\r]/g, ' ')) + '
' + '
' + $.trim(oEv.location.replace(/[\n\r]/g, ' ')) + '
' ) } if (oEv.isCalendarShared && oEv.isPrivate && Settings.AllowPrivateEvents) { oEl.css('cursor', 'default') // var oTitle = oEl.find('.fc-title'); // oTitle.html('
[' + TextUtils.i18n('%MODULENAME%/LABEL_NO_EVENT_INFORMATION') + ']
'); } if (oEv.type === 'VTODO') { var content = oEl.find('.fc-content'), title = content.find('.fc-title'), completed = $( '
' ) // fcTime = content.find('.fc-time') if (oEv.status) { completed.addClass('checked') title.css('text-decoration-line', 'line-through') } else { completed.removeClass('checked') title.css('text-decoration-line', 'unset') } oEl.addClass('fc-custom-task') title.prepend(completed) if (oEv.isCalendarShared && oEv.isPrivate && Settings.AllowPrivateEvents) { completed.attr('readonly', true) completed.css('cursor', 'default') } else { completed.on(function (event) { if (oEv.status) { oEv.status = false completed.removeClass('checked') title.css('text-decoration-line', 'unset') } else { oEv.status = true completed.addClass('checked') title.css('text-decoration-line', 'line-through') } oEv.modified = true if (oEv.rrule) { oEv.allEvents = Enums.CalendarEditRecurrenceEvent.OnlyThisInstance } self.updateEvent(oEv) event.preventDefault() event.stopPropagation() }) } } }, eventAfterRender: _.bind(function (oEv, oEl) {}, this), eventAfterAllRender: _.bind(this.updateAllEvents, this), viewRender: _.bind(this.viewRenderCallback, this), events: _.bind(this.eventsSource, this), } this.revertFunction = null this.bAllowShare = Settings.AllowShare this.bAllowTasks = Settings.AllowTasks this.defaultViewName = ko.computed(function () { switch (Settings.DefaultTab) { case Enums.CalendarDefaultTab.List: return 'listWeek' case Enums.CalendarDefaultTab.Day: return 'agendaDay' case Enums.CalendarDefaultTab.Week: return 'agendaWeek' case Enums.CalendarDefaultTab.Month: default: return 'month' } }, this) this.iAutoReloadTimer = -1 this.dragEventTrigger = false this.delayOnEventResult = false this.delayOnEventResultData = [] this.refreshView = _.throttle(_.bind(this.refreshViewSingle, this), 100) this.uploadCalendarId = ko.observable('') this.changeFullCalendarDate = true this.domScrollWrapper = null this.hotKeysBind() this.viewEventRoute = null App.broadcastEvent('%ModuleName%::ConstructView::after', { Name: this.ViewConstructorName, View: this }) } _.extendOwn(CCalendarView.prototype, CAbstractScreenView.prototype) CCalendarView.prototype.ViewTemplate = '%ModuleName%_CalendarView' CCalendarView.prototype.ViewConstructorName = 'CCalendarView' /** * Hot keys events */ CCalendarView.prototype.hotKeysBind = function () { var self = this $(document).on('keyup', function (ev) { var iKey = ev.keyCode /* Close popup "more events" if click Esc button */ if (self.calendars.getEvents().length > 0 && self.selectedView() === 'month') { if (iKey === Enums.Key.Esc && self.popUpStatus) { /* two triggers for correct plugin working */ $('body').trigger('click') /* popUpStatus has just been changed */ if (!self.popUpStatus) { $('body').trigger('mousedown') } } } }) } CCalendarView.prototype.getDateFromCurrentView = function (sDateType) { var oView = this.$calendarGrid.fullCalendar('getView'), oDate = oView && oView[sDateType] ? oView[sDateType] : null if (oDate && sDateType === 'end' && oView.name === 'agendaDay') { oDate.add(1, 'd') } return oDate && oDate['unix'] ? oView[sDateType]['unix']() : 0 } /** * @param {Object} oStart * @param {Object} oEnd * @param {*} mTimezone * @param {Function} fCallback */ CCalendarView.prototype.eventsSource = function (oStart, oEnd, mTimezone, fCallback) { fCallback(this.calendars.getEvents(oStart, oEnd)) } CCalendarView.prototype.changeView = function (viewName) { this.selectedView(viewName) if (viewName === 'month') { this.loadOnce = false } this.$calendarGrid.fullCalendar('changeView', viewName) } CCalendarView.prototype.recreateFullCalendar = function (viewName) { this.$calendarGrid.fullCalendar('destroy') this.$calendarGrid.fullCalendar(this.fullcalendarOptions) this.changeView(viewName) } CCalendarView.prototype.applyCalendarSettings = function () { this.sTimeFormat = UserSettings.timeFormat() === Enums.TimeFormat.F24 ? 'HH:mm' : 'hh:mm A' this.dateFormatForMoment = Utils.getDateFormatForMoment(UserSettings.dateFormat()) this.calendarGridDom().removeClass('fc-show-weekends') if (Settings.HighlightWorkingDays) { this.calendarGridDom().addClass('fc-show-weekends') } this.fullcalendarOptions.timeFormat = this.sTimeFormat this.fullcalendarOptions.views.listMonth.listDayFormat = this.dateFormatForMoment this.fullcalendarOptions.slotLabelFormat = this.sTimeFormat this.fullcalendarOptions.defaultView = this.defaultViewName() this.fullcalendarOptions.lang = moment.locale() this.applyFirstDay() const showWeekNumbers = Settings.ShowWeekNumbers && Settings.WeekStartsOn == 1; this.$datePicker.datepicker('option', 'showWeek', showWeekNumbers); this.fullcalendarOptions.weekNumbers = showWeekNumbers; this.fullcalendarOptions.weekNumberTitle = TextUtils.i18n('%MODULENAME%/LABEL_WEEK_SHORT') + ' '; this.fullcalendarOptions.weekNumberCalculation = 'ISO'; this.recreateFullCalendar(this.defaultViewName()) } CCalendarView.prototype.applyFirstDay = function () { var aDayNames = [], sFirstDay = '', sLastDay = '' if (App.getUserRole() !== Enums.UserRole.Anonymous) { this.fullcalendarOptions.firstDay = Settings.WeekStartsOn } _.each(this.aDayNames, function (sDayName) { aDayNames.push(sDayName) }) switch (Settings.WeekStartsOn) { case 1: sLastDay = aDayNames.shift() aDayNames.push(sLastDay) break case 6: sFirstDay = aDayNames.pop() aDayNames.unshift(sFirstDay) break } this.$datePicker.datepicker('option', 'firstDay', Settings.WeekStartsOn) } CCalendarView.prototype.initDatePicker = function () { this.$datePicker.datepicker({ showOtherMonths: true, selectOtherMonths: true, monthNames: this.aMonthNames, dayNamesMin: TextUtils.i18n('COREWEBCLIENT/LIST_DAY_NAMES_MIN').split(' '), showWeek: false, weekHeader: TextUtils.i18n('CALENDARWEBCLIENT/LABEL_WEEK_SHORT'), nextText: '', prevText: '', onChangeMonthYear: _.bind(this.changeMonthYearFromDatePicker, this), onSelect: _.bind(this.selectDateFromDatePicker, this), beforeShowDay: _.bind(this.getDayDescription, this), }) } CCalendarView.prototype.onBind = function () { var self = this this.$calendarGrid = $(this.calendarGridDom()) this.$datePicker = $(this.datePickerDom()) if (!this.isPublic) { this.initUploader() } /* Click more links */ $('body').on('click', function (e) { if (self.calendars.getEvents().length > 0 && self.selectedView() === 'month') { if ($(e.target).hasClass('fc-more')) { var $this = $(e.target) $('.fc-more-cell.active').removeClass('active') $('.fc-row.fc-week.active').removeClass('active') $this.closest('.fc-more-cell').addClass('active') $this.closest('.fc-row.fc-week').addClass('active') var $popup = $('body').find('.fc-popover.fc-more-popover'), $parent = $this.closest('tr'), $superParent = $this.closest('.fc-day-grid'), indexColumn = Types.pInt($parent.find('.fc-more-cell.active').index('.fc-more-cell')), indexRow = Types.pInt($superParent.find('.fc-row.fc-week.active').index('.fc-row.fc-week')) if ($popup.length > 0) { self.linkRow = indexRow self.linkColumn = indexColumn self.popUpStatus = true } else { self.popUpStatus = false self.linkRow = 0 self.linkColumn = 0 } } else if ($(e.target).hasClass('checkstate') || $(e.target).parent().hasClass('checkstate')) { e.preventDefault() } else { self.popUpStatus = false self.linkRow = 0 self.linkColumn = 0 } } }) } CCalendarView.prototype.onShow = function () { var bInitialized = this.initialized() if (!bInitialized) { this.initDatePicker() var oParent = this.$calendarGrid.parent() if (oParent) { this.fullcalendarOptions.height = oParent.height() } this.applyCalendarSettings() this.highlightWeekInDayPicker() this.initialized(true) } var sTimeFormat = UserSettings.timeFormat() === Enums.TimeFormat.F24 ? 'HH:mm' : 'hh:mm A' const dateFormatForMoment = Utils.getDateFormatForMoment(UserSettings.dateFormat()) if (CalendarCache.calendarSettingsChanged() || this.sTimeFormat !== sTimeFormat || CalendarCache.calendarChanged() || this.dateFormatForMoment !== dateFormatForMoment) { if (CalendarCache.calendarSettingsChanged() || this.sTimeFormat !== sTimeFormat || this.dateFormatForMoment !== dateFormatForMoment) { this.applyCalendarSettings() } CalendarCache.calendarSettingsChanged(false) CalendarCache.calendarChanged(false) } else if (this.isPublic) { this.$calendarGrid.fullCalendar('render') this.applyDateTime() } this.$calendarGrid.fullCalendar() if (bInitialized) { this.getCalendars() } this.refetchEvents() } /** * @param {Array} aParams */ CCalendarView.prototype.onRoute = function (aParams) { var sCalendarId = aParams[0], sEventId = aParams[1], start = aParams[2], oEvent = null this.$calendarGrid.fullCalendar('gotoDate', moment(start)) oEvent = this.getClientEvent(sCalendarId, sEventId) if (oEvent !== null) { this.eventClickCallback(oEvent) } else { this.viewEventRoute = { CalendarId: sCalendarId, EventId: sEventId, } } } CCalendarView.prototype.getClientEvent = function (sCalendarId, sEventId) { var oCalendar = null, oEvent = null, oEventResult = null, aEvents = [] aEvents = this.$calendarGrid.fullCalendar('clientEvents', sEventId) if (Array.isArray(aEvents) && aEvents.length > 0) { oCalendar = this.calendars.getCalendarById(sCalendarId) if (oCalendar !== undefined) { oEvent = _.find( aEvents, function (oEvent) { return oEvent.calendarId === sCalendarId }, this ) if (oEvent !== undefined) { oEventResult = oEvent } } } return oEventResult } CCalendarView.prototype.applyDateTime = function () { FullCalendarUtils.recreateIfDateChanged(this.$calendarGrid, this.recreateFullCalendar.bind(this)) FullCalendarUtils.setTimeline() } /** * When all event's rendered */ CCalendarView.prototype.updateAllEvents = function () { if (this.calendars.getEvents().length > 0 && this.selectedView() === 'month') { if (!this.loadOnce) { this.topPositionToday.valueHasMutated() this.loadOnce = true } else { this.scrollModel()['vertical'].set(this.scrollHeight) } /* open current more link */ if (this.popUpStatus) { $('body') .find('.fc-row.fc-week') .eq(this.linkRow) .find('.fc-more-cell') .eq(this.linkColumn) .find('a.fc-more') .click() } } } /** * @param {Object} oView * @param {Object} oElement */ CCalendarView.prototype.viewRenderCallback = function (oView, oElement) { var prevDate = null, constDate = '01/01/1971 ' this.changeDate() if (!this.loaded) { this.initResizing() } if (oView.name !== 'month' && Settings.HighlightWorkingHours) { $('.fc-slats tr').each(function () { $('tr .fc-time span').each(function () { var theValue = $(this).eq(0).text(), theDate = theValue !== '' ? Date.parse(constDate + theValue) : prevDate, rangeTimeFrom = Date.parse(constDate + Settings.WorkdayStarts + ':00'), rangeTimeTo = Date.parse(constDate + Settings.WorkdayEnds + ':00') prevDate = theDate if (theDate < rangeTimeFrom || theDate >= rangeTimeTo) { $(this).parent().parent().addClass('fc-non-working-time') $(this).parent().parent().next().addClass('fc-non-working-time') } }) }) } this.activateCustomScrollInDayAndWeekView() } CCalendarView.prototype.collectBusyDays = function () { var aBusyDays = [], oStart = null, oEnd = null, iDaysDiff = 0, iIndex = 0 _.each( this.calendars.getEvents(), function (oEvent) { oStart = moment(oEvent.start) oEnd = oEvent.end ? moment(oEvent.end) : null if (oEvent.allDay && oEnd) { oEnd.subtract(1, 'days') } iDaysDiff = oEnd ? oEnd.diff(oStart, 'days') : 0 iIndex = 0 for (; iIndex <= iDaysDiff; iIndex++) { aBusyDays.push(oStart.clone().add(iIndex, 'days').toDate()) } }, this ) this.busyDays(aBusyDays) } CCalendarView.prototype.refreshDatePicker = function () { var self = this _.defer(function () { self.collectBusyDays() self.$datePicker.datepicker('refresh') self.highlightWeekInDayPicker() }) } /** * @param {Object} oDate */ CCalendarView.prototype.getDayDescription = function (oDate) { var bSelectable = true, oFoundBusyDay = _.find( this.busyDays(), function (oBusyDay) { return ( oBusyDay.getDate() === oDate.getDate() && oBusyDay.getMonth() === oDate.getMonth() && oBusyDay.getYear() === oDate.getYear() ) }, this ), sDayClass = oFoundBusyDay ? 'day_with_events' : '', sDayTitle = '' return [bSelectable, sDayClass, sDayTitle] } CCalendarView.prototype.initResizing = function () { var fResize = _.throttle(_.bind(this.resize, this), 50) $(window).bind('resize', function (e) { if (e.target !== this && !Browser.ie8AndBelow) { return } fResize() }) fResize() } CCalendarView.prototype.resize = function () { var oParent = this.$calendarGrid.parent() if (oParent) { this.$calendarGrid.fullCalendar('option', 'height', oParent.height()) } this.dayNamesResize() } CCalendarView.prototype.dayNamesResize = function () { if (this.selectedView() === 'month') { var oDayNamesHeaderItem = $('div.weekday-header-item'), oFirstWeek = $('tr.fc-first td.fc-day'), oFirstWeekWidth = $(oFirstWeek[0]).width(), iIndex = 0 if (oDayNamesHeaderItem.length === 7 && oFirstWeek.length === 7 && oFirstWeekWidth !== 0) { for (; iIndex < 7; iIndex++) { $(oDayNamesHeaderItem[iIndex]).width(oFirstWeekWidth) } } } } /** * @param {number} iYear * @param {number} iMonth * @param {Object} oInst */ CCalendarView.prototype.changeMonthYearFromDatePicker = function (iYear, iMonth, oInst) { if (this.changeFullCalendarDate) { var oDate = this.$calendarGrid.fullCalendar('getDate') // Date object in javascript and fullcalendar use numbers 0,1,2...11 for monthes // datepiker uses numbers 1,2,3...12 for monthes oDate.month(iMonth - 1).year(iYear) this.$calendarGrid.fullCalendar('gotoDate', oDate) } } /** * @param {string} sDate * @param {Object} oInst */ CCalendarView.prototype.selectDateFromDatePicker = function (sDate, oInst) { var oDate = moment(sDate, 'MM/DD/YYYY') this.$calendarGrid.fullCalendar('gotoDate', oDate) _.defer(_.bind(this.highlightWeekInDayPicker, this)) } CCalendarView.prototype.highlightWeekInDayPicker = function () { var $currentDay = this.$datePicker.find('td.ui-datepicker-current-day'), $currentWeek = $currentDay.parent(), $currentMonth = this.$datePicker.find('table.ui-datepicker-calendar'), oView = this.$calendarGrid.fullCalendar('getView') switch (oView.name) { case 'agendaDay': $currentMonth.addClass('highlight_day').removeClass('highlight_week') break case 'agendaWeek': $currentMonth.removeClass('highlight_day').addClass('highlight_week') break default: $currentMonth.removeClass('highlight_day').removeClass('highlight_week') break } $currentWeek.addClass('current_week') } CCalendarView.prototype.changeDateTitle = function () { var oDate = this.$calendarGrid.fullCalendar('getDate').clone().locale(moment.locale()), oView = this.$calendarGrid.fullCalendar('getView'), sTitle = oDate.format('MMMM YYYY'), oStart = oView.intervalStart.clone().locale(moment.locale()), oEnd = oView.intervalEnd ? oView.intervalEnd.clone().add(-1, 'days').locale(moment.locale()) : null switch (oView.name) { case 'agendaDay': sTitle = oDate.format('MMMM D, YYYY') break case 'agendaWeek': if (oStart && oEnd) { sTitle = oStart.format('MMMM D, YYYY') + ' - ' + oEnd.format('MMMM D, YYYY') } break } this.dateTitle(sTitle) } CCalendarView.prototype.changeDate = function () { this.changeDateInDatePicker() this.changeDateTitle() this.getTimeLimits() this.getCalendars() } CCalendarView.prototype.changeDateInDatePicker = function () { var oDateMoment = this.$calendarGrid.fullCalendar('getDate') this.changeFullCalendarDate = false this.$datePicker.datepicker('setDate', oDateMoment.local().toDate()) this.changeFullCalendarDate = true this.highlightWeekInDayPicker() } CCalendarView.prototype.activateCustomScrollInDayAndWeekView = function () { if (bMobileDevice) { return } var oView = this.$calendarGrid.fullCalendar('getView'), sGridType = oView.name === 'month' ? 'day' : 'time', oGridContainer = $('.fc-' + sGridType + '-grid-container') if (!oGridContainer.hasClass('scroll-inner')) { var oScrollWrapper = $('
') oGridContainer.parent().append(oScrollWrapper) oGridContainer.appendTo(oScrollWrapper) if (!oScrollWrapper.hasClass('scroll-wrap')) { oScrollWrapper.attr( 'data-bind', 'customScrollbar: {x: false, y: true, top: 0, scrollTo: topPositionToday, oScroll: scrollModel}' ) oGridContainer.css({ overflow: 'hidden' }).addClass('scroll-inner') ko.applyBindings(this, oScrollWrapper[0]) } this.domScrollWrapper = oScrollWrapper } } CCalendarView.prototype.displayToday = function () { this.$calendarGrid.fullCalendar('today') } CCalendarView.prototype.displayPrev = function () { this.$calendarGrid.fullCalendar('prev') } CCalendarView.prototype.displayNext = function () { this.$calendarGrid.fullCalendar('next') } CCalendarView.prototype.setAutoReloadTimer = function () { var self = this clearTimeout(this.iAutoReloadTimer) if (UserSettings.AutoRefreshIntervalMinutes > 0) { this.iAutoReloadTimer = setTimeout(function () { self.getCalendars() }, UserSettings.AutoRefreshIntervalMinutes * 60 * 1000) } } CCalendarView.prototype.getTimeLimits = function () { var iStart = this.getDateFromCurrentView('start'), iEnd = this.getDateFromCurrentView('end') if (this.startDateTime === 0 && this.endDateTime === 0) { this.startDateTime = iStart this.endDateTime = iEnd this.needsToReload = true } else if (iStart < this.startDateTime && iEnd > this.endDateTime) { this.startDateTime = iStart this.endDateTime = iEnd this.needsToReload = true } else if (iStart < this.startDateTime) { iEnd = this.startDateTime this.startDateTime = iStart this.needsToReload = true } else if (iEnd > this.endDateTime) { iStart = this.endDateTime this.endDateTime = iEnd this.needsToReload = true } } CCalendarView.prototype.getCalendars = function () { this.checkStarted(true) this.setCalendarGridVisibility() if (this.isPublic) { Ajax.send('GetPublicCalendar', { CalendarId: Settings.PublicCalendarId }, this.onGetCalendarsResponse, this) } else { Ajax.send('GetCalendars', null, this.onGetCalendarsResponse, this) } } /** * @param {Object} oResponse * @param {Object} oParameters */ CCalendarView.prototype.onGetCalendarsResponse = function (oResponse, oParameters) { var aCalendarIds = [], aNewCalendarIds = [], oCalendar = null, oClientCalendar = null if (this.loadOnce && this.selectedView() === 'month') { this.scrollHeight = this.scrollModel()['vertical'].get() } else { this.scrollHeight = 0 } if (oResponse.Result) { this.loaded = true _.each( oResponse.Result.Calendars, function (oCalendarData) { if (!_.isEmpty(oCalendarData)) { oCalendar = this.calendars.parseCalendar(oCalendarData) aCalendarIds.push(oCalendar.id) oClientCalendar = this.calendars.getCalendarById(oCalendar.id) if ( this.needsToReload || (oClientCalendar && oClientCalendar.isSharedToAll) || (oClientCalendar && oClientCalendar.sSyncToken) !== (oCalendar && oCalendar.sSyncToken) ) { oCalendar = this.calendars.parseAndAddCalendar(oCalendarData) if (oCalendar) { oCalendar.davUrl(Types.pString(oResponse.Result.ServerUrl)) if (this.isPublic) { var oPublicHeaderItem = require('modules/%ModuleName%/js/views/PublicHeaderItem.js') oPublicHeaderItem.linkText(oCalendar.name()) this.browserTitle(oCalendar.name()) } aNewCalendarIds.push(oCalendar.id) } } } }, this ) if (this.calendars.count() === 0 && this.isPublic && this.needsToReload) { this.browserTitle(TextUtils.i18n('%MODULENAME%/INFO_NO_CALENDAR_FOUND')) Api.showErrorByCode(0, TextUtils.i18n('%MODULENAME%/INFO_NO_CALENDAR_FOUND'), true) } this.needsToReload = false this.calendars.expunge(aCalendarIds) _.each( aCalendarIds, function (sCalendarId) { oCalendar = this.calendars.getCalendarById(sCalendarId) if (oCalendar && oCalendar.eventsCount() > 0) { oCalendar.reloadEvents() } }, this ) this.requestEvents(aNewCalendarIds) } else { this.setCalendarGridVisibility() this.checkStarted(false) } } /** * @param {Array} aCalendarIds */ CCalendarView.prototype.requestEvents = function (aCalendarIds) { var oOptions = { CalendarIds: aCalendarIds, Start: this.startDateTime, End: this.endDateTime, IsPublic: this.isPublic, } if (this.isPublic && !App.getUserId()) { oOptions.DefaultTimeZone = moment.tz.guess() } if (aCalendarIds.length > 0) { Ajax.send('GetEvents', oOptions, this.onGetEventsResponse, this) } else { this.setAutoReloadTimer() this.checkStarted(false) } } /** * @param {Object} oResponse * @param {Object} oRequest */ CCalendarView.prototype.onGetEventsResponse = function (oResponse, oRequest) { if (oResponse.Result) { var oCalendar = null, oParameters = oRequest.Parameters, aCalendarIds = _.isArray(oParameters.CalendarIds) ? oParameters.CalendarIds : [], aEvents = [] _.each( oResponse.Result, function (oEventData) { oCalendar = this.calendars.getCalendarById(oEventData.calendarId) if (oCalendar) { oEventData.isCalendarShared = oCalendar.isShared() aEvents.push(oEventData.id) var oEvent = oCalendar.getEvent(oEventData.id) if (!oEvent) { oCalendar.addEvent(oEventData) } else if (this.bTimezoneChanged || oEvent.lastModified !== oEventData.lastModified) { oCalendar.updateEvent(oEventData) } } }, this ) this.bTimezoneChanged = false _.each( aCalendarIds, function (sCalendarId) { oCalendar = this.calendars.getCalendarById(sCalendarId) if (oCalendar && oCalendar.eventsCount() > 0 && oCalendar.active()) { oCalendar.expungeEvents(aEvents, this.startDateTime, this.endDateTime, 'VEVENT') } }, this ) this.refreshView() if (this.viewEventRoute) { var oEvent = this.getClientEvent(this.viewEventRoute.CalendarId, this.viewEventRoute.EventId) this.viewEventRoute = false if (oEvent !== null) { this.eventClickCallback(oEvent) } } } this.setAutoReloadTimer() this.checkStarted(false) this.getTasks(aCalendarIds) } /** * @param {Array} aCalendarIds */ CCalendarView.prototype.getTasks = function (aCalendarIds) { if (this.bAllowTasks) { if (Types.isNonEmptyArray(aCalendarIds)) { Ajax.send( 'GetTasks', { CalendarIds: aCalendarIds, Start: this.startDateTime, End: this.endDateTime, IsPublic: this.isPublic, }, this.onGetTasksResponse, this ) } else { this.setAutoReloadTimer() this.checkStarted(false) } } } /** * @param {Object} oResponse * @param {Object} oRequest */ CCalendarView.prototype.onGetTasksResponse = function (oResponse, oRequest) { if (oResponse.Result) { var oCalendar = null, oParameters = oRequest.Parameters, aCalendarIds = _.isArray(oParameters.CalendarIds) ? oParameters.CalendarIds : [], aTasks = [] _.each( oResponse.Result, function (oTaskData) { oCalendar = this.calendars.getCalendarById(oTaskData.calendarId) if (oCalendar) { oTaskData.isCalendarShared = oCalendar.isShared() aTasks.push(oTaskData.id) var oEvent = oCalendar.getEvent(oTaskData.id) if (!oEvent) { oCalendar.addEvent(oTaskData) } else if (oEvent.lastModified !== oTaskData.lastModified) { oCalendar.updateEvent(oTaskData) } } }, this ) _.each( aCalendarIds, function (sCalendarId) { oCalendar = this.calendars.getCalendarById(sCalendarId) if (oCalendar && oCalendar.eventsCount() > 0 && oCalendar.active()) { oCalendar.expungeEvents(aTasks, this.startDateTime, this.endDateTime, 'VTODO') } }, this ) this.refreshView() } this.setAutoReloadTimer() this.checkStarted(false) } CCalendarView.prototype.setCalendarGridVisibility = function () { this.$calendarGrid.css('visibility', '').find('.fc-view div').first().css('visibility', '') } CCalendarView.prototype.getUnusedColor = function () { var colors = _.difference(this.colors, this.calendars.getColors()) return colors.length > 0 ? colors[0] : this.colors[0] } CCalendarView.prototype.openCreateCalendarForm = function () { if (!this.isPublic) { var oCalendar = new CCalendarModel() oCalendar.color(this.getUnusedColor()) Popups.showPopup(EditCalendarPopup, [_.bind(this.createCalendarCallback, this), this.colors, oCalendar]) } } CCalendarView.prototype.createCalendarCallback = function (aCalendar) { if (aCalendar) { this.calendars.parseAndAddCalendar(aCalendar) } } /** * @param {Object} oCalendar */ CCalendarView.prototype.openImportCalendarForm = function (oCalendar) { if (!this.isPublic) { Popups.showPopup(ImportCalendarPopup, [_.bind(this.getCalendars, this), oCalendar]) } } /** * @param {Object} oCalendar */ CCalendarView.prototype.openShareCalendarForm = function (oCalendar) { Popups.showPopup(CalendarSharePopup, [_.bind(this.shareCalendar, this), oCalendar]) } /** * @param {string} sId * @param {boolean} bIsPublic * @param {Array} aShares * @param {boolean} bShareToAll * @param {number} iShareToAllAccess */ CCalendarView.prototype.shareCalendar = function (sId, bIsPublic, aShares, bShareToAll, iShareToAllAccess) { if (!this.isPublic) { Ajax.send( 'UpdateCalendarShare', { Id: sId, IsPublic: bIsPublic ? 1 : 0, Shares: JSON.stringify(aShares), ShareToAll: bShareToAll ? 1 : 0, ShareToAllAccess: iShareToAllAccess, }, this.onUpdateShareResponse, this ) } } /** * @param {Object} oResponse * @param {Object} oRequest */ CCalendarView.prototype.onUpdateShareResponse = function (oResponse, oRequest) { if (oResponse.Result) { this.getCalendars() /* TODO: var oCalendar = this.calendars.getCalendarById(oRequest.Parameters.Id); if (oCalendar) { oCalendar.shares(JSON.parse(oRequest.Parameters.Shares)); if (oRequest.Parameters.ShareToAll === 1) { oCalendar.isShared(true); oCalendar.isSharedToAll(true); oCalendar.sharedToAllAccess = oRequest.Parameters.ShareToAllAccess; } else { oCalendar.isSharedToAll(false); } } */ } else { Screens.showError(TextUtils.i18n('%MODULENAME%/ERROR_SHARE_NOT_UPDATED')) } } /** * @param {Object} oCalendar */ CCalendarView.prototype.openUpdateCalendarForm = function (oCalendar) { if (!this.isPublic) { Popups.showPopup(EditCalendarPopup, [_.bind(this.updateCalendarCallback, this), this.colors, oCalendar]) } } CCalendarView.prototype.updateCalendarCallback = function (oParameters) { if (oParameters) { var oCalendar = this.calendars.getCalendarById(oParameters.Id) if (oCalendar) { oCalendar.name(oParameters.Name) oCalendar.description(oParameters.Description) oCalendar.color(oParameters.Color) this.refetchEvents() } } } /** * @param {string} sColor * @param {string} sId */ CCalendarView.prototype.updateCalendarColor = function (sColor, sId) { if (!this.isPublic) { Ajax.send( 'UpdateCalendarColor', { Color: sColor, Id: sId, }, this.onUpdateCalendarColorResponse, this ) } } /** * @param {Object} oResponse * @param {Object} oRequest */ CCalendarView.prototype.onUpdateCalendarColorResponse = function (oResponse, oRequest) { if (oResponse.Result) { var oParameters = oRequest.Parameters, oCalendar = this.calendars.getCalendarById(oParameters.Id) if (oCalendar) { oCalendar.color(oParameters.Color) this.refetchEvents() } } } /** * @param {Object} oCalendar */ CCalendarView.prototype.openGetLinkCalendarForm = function (oCalendar) { if (!this.isPublic) { Popups.showPopup(GetCalendarLinkPopup, [_.bind(this.publicCalendar, this), oCalendar]) } } /** * @param {string} sId * @param {boolean} bIsPublic */ CCalendarView.prototype.publicCalendar = function (sId, bIsPublic) { if (!this.isPublic) { Ajax.send( 'UpdateCalendarPublic', { Id: sId, IsPublic: bIsPublic, }, this.onUpdateCalendarPublicResponse, this ) } } /** * @param {Object} oResponse * @param {Object} oRequest */ CCalendarView.prototype.onUpdateCalendarPublicResponse = function (oResponse, oRequest) { if (oResponse.Result) { var oParameters = oRequest.Parameters, oCalendar = this.calendars.getCalendarById(oParameters.Id) if (oCalendar) { oCalendar.isPublic(oParameters.IsPublic) } } } /** * @param {string} sId * @param {boolean} bIsUnsubscribe */ CCalendarView.prototype.deleteCalendar = function (sId, bIsUnsubscribe) { var oCalendar = this.calendars.getCalendarById(sId), sConfirm = oCalendar ? bIsUnsubscribe ? TextUtils.i18n('%MODULENAME%/CONFIRM_UNSUBSCRIBE_CALENDAR', { CALENDARNAME: TextUtils.encodeHtml(oCalendar.name()), }) : TextUtils.i18n('%MODULENAME%/CONFIRM_REMOVE_CALENDAR', { CALENDARNAME: TextUtils.encodeHtml(oCalendar.name()), }) : '', fRemove = _.bind(function (bRemove) { if (bRemove) { Ajax.send('DeleteCalendar', { Id: sId }, this.onDeleteCalendarResponse, this) } }, this) if (!this.isPublic && oCalendar) { Popups.showPopup(ConfirmPopup, [sConfirm, fRemove]) } } /** * @param {Object} oResponse * @param {Object} oRequest */ CCalendarView.prototype.onDeleteCalendarResponse = function (oResponse, oRequest) { if (oResponse.Result) { var oParameters = oRequest.Parameters, oCalendar = this.calendars.getCalendarById(oParameters.Id) if (oCalendar && !oCalendar.isDefault) { if (this.calendars.currentCal().id === oCalendar.id) { this.calendars.pickCurrentCalendar() } this.calendars.removeCalendar(oCalendar.id) this.refetchEvents() } } } CCalendarView.prototype.onEventDragStart = function () { this.dragEventTrigger = true this.refreshDatePicker() } CCalendarView.prototype.onEventDragStop = function (oEvent) { var self = this this.dragEventTrigger = false if (this.delayOnEventResult && this.delayOnEventResultData && 0 < this.delayOnEventResultData.length) { this.delayOnEventResult = false _.each(this.delayOnEventResultData, function (aData) { self.onEventActionResponse(aData[0], aData[1], false) }) this.delayOnEventResultData = [] this.refreshView() } else { this.refreshDatePicker() } } CCalendarView.prototype.onEventResizeStart = function () { this.dragEventTrigger = true } CCalendarView.prototype.onEventResizeStop = function () { var self = this this.dragEventTrigger = false if (this.delayOnEventResult && this.delayOnEventResultData && 0 < this.delayOnEventResultData.length) { this.delayOnEventResult = false _.each(this.delayOnEventResultData, function (aData) { self.onEventActionResponse(aData[0], aData[1], false) }) this.delayOnEventResultData = [] this.refreshView() } else { this.refreshDatePicker() } } CCalendarView.prototype.createEventInCurrentCalendar = function () { this.calendars.pickCurrentCalendar() this.createEventToday(this.calendars.currentCal()) } /** * @param {Object} oCalendar */ CCalendarView.prototype.createEventToday = function (oCalendar) { var oToday = moment() if (oToday.minutes() > 30) { oToday.add(60 - oToday.minutes(), 'minutes') } else { oToday.minutes(30) } oToday.seconds(0).milliseconds(0) this.openEventPopup(oCalendar, oToday, oToday.clone().add(30, 'minutes'), false) } /** * @param {Object} oEventData */ CCalendarView.prototype.getParamsFromEventData = function (oEventData) { var sBrowserTimezone = moment.tz.guess(), sServerTimezone = UserSettings.timezone(), oStart = moment.tz(oEventData.start.format('YYYY-MM-DD HH:mm:ss'), sServerTimezone || sBrowserTimezone), oEnd = moment.tz(oEventData.end.format('YYYY-MM-DD HH:mm:ss'), sServerTimezone || sBrowserTimezone), rrule = null if (oEventData.rrule) { rrule = { byDays: oEventData.rrule.byDays, count: oEventData.rrule.count, end: Types.pInt(oEventData.rrule.end), interval: Types.pInt(oEventData.rrule.interval), period: Types.pInt(oEventData.rrule.period), until: Types.pInt(oEventData.rrule.until), weekNum: oEventData.rrule.weekNum, } } return { id: oEventData.id, uid: oEventData.uid, calendarId: oEventData.calendarId, newCalendarId: oEventData.newCalendarId || oEventData.calendarId, subject: oEventData.subject, allDay: oEventData.allDay ? 1 : 0, location: oEventData.location, description: oEventData.description, alarms: oEventData.alarms ? JSON.stringify(oEventData.alarms) : '[]', attendees: oEventData.attendees ? JSON.stringify(oEventData.attendees) : '[]', owner: oEventData.owner, recurrenceId: oEventData.recurrenceId, excluded: oEventData.excluded, allEvents: oEventData.allEvents, modified: oEventData.modified ? 1 : 0, start: oStart.format(), end: oEnd.format(), startTS: oStart.unix(), endTS: oEnd.unix(), rrule: rrule ? JSON.stringify(rrule) : null, type: oEventData.type, status: oEventData.status, withDate: oEventData.withDate, isPrivate: oEventData.isPrivate, } } /** * @param {Array} aParameters */ CCalendarView.prototype.getEventDataFromParams = function (aParameters) { var oEventData = aParameters oEventData.alarms = aParameters.alarms || [] oEventData.attendees = aParameters.attendees || [] if (aParameters.rrule) { oEventData.rrule = aParameters.rrule } return oEventData } /** * @param {Object} oStart * @param {Object} oEnd */ CCalendarView.prototype.createEventFromGrid = function (oStart, oEnd) { var bAllDay = !oStart.hasTime() this.calendars.pickCurrentCalendar() this.openEventPopup(this.calendars.currentCal(), oStart.local(), oEnd.local(), bAllDay) } /** * @param {Object} oCalendar * @param {Object} oStart * @param {Object} oEnd * @param {boolean} bAllDay */ CCalendarView.prototype.openEventPopup = function (oCalendar, oStart, oEnd, bAllDay) { if (!this.isPublic && oCalendar) { Popups.showPopup(EditEventPopup, [ { CallbackSave: _.bind(this.createEvent, this), CallbackDelete: _.bind(this.deleteEvent, this), Calendars: this.calendars, SelectedCalendar: oCalendar ? oCalendar.id : 0, Start: oStart, End: oEnd, AllDay: bAllDay, TimeFormat: this.sTimeFormat, DateFormat: UserSettings.dateFormat(), CallbackAttendeeActionDecline: _.bind(this.attendeeActionDecline, this), }, ]) } } /** * @param {Object} oEventData */ CCalendarView.prototype.createEvent = function (oEventData) { var aParameters = this.getParamsFromEventData(oEventData) if (!this.isPublic) { aParameters.calendarId = oEventData.newCalendarId aParameters.selectStart = this.getDateFromCurrentView('start') aParameters.selectEnd = this.getDateFromCurrentView('end') Ajax.send('CreateEvent', aParameters, this.onEventActionResponseWithSubThrottle, this) } } /** * @param {Object} oEventData */ CCalendarView.prototype.eventClickCallback = function (oEventData) { if (oEventData.isCalendarShared && oEventData.isPrivate && Settings.AllowPrivateEvents) { return // reject editing } var /** * @param {number} iResult */ fCallback = _.bind(function (iResult) { var oParams = { ID: oEventData.id, Uid: oEventData.uid, RecurrenceId: oEventData.recurrenceId, Calendars: this.calendars, SelectedCalendar: oEventData.calendarId, AllDay: oEventData.allDay, Location: oEventData.location, Description: oEventData.description, Subject: oEventData.subject, Alarms: oEventData.alarms, Attendees: oEventData.attendees, RRule: oEventData.rrule ? oEventData.rrule : null, Excluded: oEventData.excluded ? oEventData.excluded : false, Owner: oEventData.owner, Organizer: oEventData.organizer, Appointment: oEventData.appointment, OwnerName: oEventData.ownerName, TimeFormat: this.sTimeFormat, DateFormat: UserSettings.dateFormat(), AllEvents: iResult, CallbackSave: _.bind(this.updateEvent, this), CallbackDelete: _.bind(this.deleteEvent, this), CallbackAttendeeActionDecline: _.bind(this.attendeeActionDecline, this), Type: oEventData.type, Status: oEventData.status, IsPrivate: oEventData.isPrivate, } if (iResult !== Enums.CalendarEditRecurrenceEvent.None) { if (iResult === Enums.CalendarEditRecurrenceEvent.AllEvents && oEventData.rrule) { oParams.Start = moment.unix(oEventData.rrule.startBase) oParams.End = moment.unix(oEventData.rrule.endBase) } else { oParams.Start = oEventData.start.clone() oParams.Start = oParams.Start.local() oParams.End = oEventData.end.clone() oParams.End = oParams.End.local() } Popups.showPopup(EditEventPopup, [oParams]) } }, this), oCalendar = this.calendars.getCalendarById(oEventData.calendarId) if (oEventData.rrule && !oCalendar.subscribed()) { if (oEventData.excluded) { fCallback(Enums.CalendarEditRecurrenceEvent.OnlyThisInstance) } else { Popups.showPopup(EditEventRecurrencePopup, [fCallback, oEventData.type]) } } else { fCallback(Enums.CalendarEditRecurrenceEvent.AllEvents) } } /** * @param {string} sMethod * @param {Object} oParameters * @param {Function=} fRevertFunc = undefined */ CCalendarView.prototype.eventAction = function (sMethod, oParameters, fRevertFunc) { var oCalendar = this.calendars.getCalendarById(oParameters.calendarId) if (!oCalendar.isEditable()) { if (fRevertFunc) { fRevertFunc() } } else { if (!this.isPublic) { if (fRevertFunc) { this.revertFunction = fRevertFunc } Ajax.send(sMethod, oParameters, this.onEventActionResponseWithSubThrottle, this) } } } /** * @param {Object} oEventData */ CCalendarView.prototype.updateEvent = function (oEventData) { var oParameters = this.getParamsFromEventData(oEventData) oParameters.selectStart = this.getDateFromCurrentView('start') oParameters.selectEnd = this.getDateFromCurrentView('end') if (oEventData.modified) { this.calendars.setDefault(oEventData.newCalendarId) this.eventAction('UpdateEvent', oParameters) } } /** * @param {Object} oEventData * @param {number} delta * @param {Function} revertFunc */ CCalendarView.prototype.moveEvent = function (oEventData, delta, revertFunc) { var oParameters = this.getParamsFromEventData(oEventData) oParameters.selectStart = this.getDateFromCurrentView('start') oParameters.selectEnd = this.getDateFromCurrentView('end') if (!this.isPublic) { if (oParameters.rrule) { revertFunc(false) } else { oParameters.allEvents = Enums.CalendarEditRecurrenceEvent.AllEvents this.eventAction('UpdateEvent', oParameters, revertFunc) } } } /** * @param {Object} oEventData * @param {number} delta * @param {Function} revertFunc */ CCalendarView.prototype.resizeEvent = function (oEventData, delta, revertFunc) { if (oEventData?.rrule?.until) { var localUntill = new Date(oEventData.rrule.until * 1000), utcUntil = new Date( localUntill.getUTCFullYear(), localUntill.getUTCMonth(), localUntill.getUTCDate(), localUntill.getUTCHours(), localUntill.getUTCMinutes(), localUntill.getUTCSeconds() ) oEventData.rrule.until = moment(utcUntil).unix() } var oParameters = this.getParamsFromEventData(oEventData), /** * @param {number} iResult */ fCallback = _.bind(function (iResult) { if (iResult !== Enums.CalendarEditRecurrenceEvent.None) { oParameters.allEvents = iResult this.eventAction('UpdateEvent', oParameters, revertFunc) } else { revertFunc() } }, this) oParameters.selectStart = this.getDateFromCurrentView('start') oParameters.selectEnd = this.getDateFromCurrentView('end') if (oEventData.rrule) { if (oParameters.excluded) { fCallback(Enums.CalendarEditRecurrenceEvent.OnlyThisInstance) } else { Popups.showPopup(EditEventRecurrencePopup, [fCallback, oEventData.type]) } } else { fCallback(Enums.CalendarEditRecurrenceEvent.AllEvents) } } /** * @param {Object} oEventData */ CCalendarView.prototype.deleteEvent = function (oEventData) { this.eventAction('DeleteEvent', this.getParamsFromEventData(oEventData)) CalendarCache.markIcalNotSaved(oEventData.uid) } /** * @param {Object} oData * @param {Object} oParameters */ CCalendarView.prototype.onEventActionResponseWithSubThrottle = function (oData, oParameters) { if (this.dragEventTrigger) { this.delayOnEventResult = true this.delayOnEventResultData.push([oData, oParameters]) } else { this.onEventActionResponse(oData, oParameters, true) } } /** * @param {Object} oResponse * @param {Object} oRequest * @param {boolean} bDoRefresh */ CCalendarView.prototype.onEventActionResponse = function (oResponse, oRequest, bDoRefresh) { var oParameters = oRequest.Parameters, oCalendar = this.calendars.getCalendarById(oParameters && oParameters.calendarId), oEvent = null, iScrollTop = 0 if (oResponse && oResponse.Result && oCalendar) { iScrollTop = $('.calendar .fc-widget-content .scroll-inner').scrollTop() if (oRequest.Method === 'CreateEvent' || oRequest.Method === 'UpdateEvent') { oEvent = oCalendar.getEvent(oParameters.id) if ( ((oEvent && oEvent.rrule) || oParameters.rrule) && oParameters.allEvents === Enums.CalendarEditRecurrenceEvent.AllEvents ) { oCalendar.removeEventByUid(oParameters.uid) } else { oCalendar.removeEvent(oParameters.id) } if (oParameters.newCalendarId && oParameters.newCalendarId !== oParameters.calendarId) { oCalendar = this.calendars.getCalendarById(oParameters.newCalendarId) } _.each( oResponse.Result.Events, function (oEventData) { oCalendar.addEvent(oEventData) }, this ) oCalendar.sSyncToken = oResponse.Result.SyncToken if (!oCalendar.active()) { oCalendar.active(true) } if (bDoRefresh) { this.refreshView() } this.restoreScroll(iScrollTop) this.calendars.pickCurrentCalendar() } else if (oRequest.Method === 'DeleteEvent') { oCalendar.sSyncToken = oResponse.Result if (oParameters.allEvents === Enums.CalendarEditRecurrenceEvent.OnlyThisInstance) { oCalendar.removeEvent(oParameters.id) } else { oCalendar.removeEventByUid(oParameters.uid) } if (bDoRefresh) { this.refreshView() } this.restoreScroll(iScrollTop) } } else if ( oRequest.Method === 'UpdateEvent' && !oResponse.Result && Enums.Errors.NotDisplayedError === Types.pInt(oResponse.ErrorCode) ) { this.revertFunction = null } else { Api.showErrorByCode(oResponse, TextUtils.i18n('%MODULENAME%/ERROR_EVENT_NOT_UPDATED')) if (this.revertFunction) { this.revertFunction() } } this.revertFunction = null } /** * @param {Object} oCalendar * @param {string} sId */ CCalendarView.prototype.attendeeActionDecline = function (oCalendar, sId) { oCalendar.removeEvent(sId) this.refreshView() } CCalendarView.prototype.refetchEvents = function () { this.$calendarGrid.fullCalendar('refetchEvents') } CCalendarView.prototype.refreshViewSingle = function () { this.refetchEvents() this.refreshDatePicker() } CCalendarView.prototype.refreshView = function () {} /** * Initializes file uploader. */ CCalendarView.prototype.initUploader = function () { var self = this if (this.uploaderArea()) { this.oJua = new CJua({ action: '?/Api/', name: 'jua-uploader', queueSize: 2, dragAndDropElement: this.uploaderArea(), disableAjaxUpload: false, disableFolderDragAndDrop: false, disableDragAndDrop: false, disableAutoUploadOnDrop: true, hidden: _.extendOwn( { Module: Settings.ServerModuleName, Method: 'UploadCalendar', Parameters: function () { return JSON.stringify({ CalendarID: self.uploadCalendarId(), }) }, }, App.getCommonRequestParameters() ), }) this.oJua .on('onDrop', _.bind(this.onFileDrop, this)) .on('onComplete', _.bind(this.onFileUploadComplete, this)) .on('onBodyDragEnter', _.bind(this.bDragActive, this, true)) .on('onBodyDragLeave', _.bind(this.bDragActive, this, false)) } } CCalendarView.prototype.onFileDrop = function (oFile, oEvent, fProceedUploading) { const editableCalendars = this.calendars.collection().filter((calendar) => calendar.isEditable()) const calendarToSelect = editableCalendars.find((calendar) => calendar.isDefault) || editableCalendars[0] if (!calendarToSelect) { Screens.showError(TextUtils.i18n('%MODULENAME%/ERROR_NO_EDITABLE_CALENDAR')) return } if (editableCalendars.length > 1) { Popups.showPopup(SelectCalendarPopup, [ { CallbackSave: _.bind(this.uploadToSelectedCalendar, this), ProceedUploading: fProceedUploading, Calendars: this.calendars, EditableCalendars: editableCalendars, DefaultCalendarId: calendarToSelect.id, }, ]) } else { this.uploadToSelectedCalendar(calendarToSelect.id, fProceedUploading) } } CCalendarView.prototype.onFileUploadComplete = function (sFileUid, bResponseReceived, oResponse) { var bError = !bResponseReceived || !oResponse || !oResponse.Result if (!bError) { this.getCalendars() } else { if (oResponse && oResponse.ErrorCode && oResponse.ErrorCode === Enums.Errors.IncorrectFileExtension) { Screens.showError(TextUtils.i18n('%MODULENAME%/ERROR_FILE_NOT_ICS')) } else { Screens.showError(TextUtils.i18n('COREWEBCLIENT/ERROR_UPLOAD_FILE')) } } } CCalendarView.prototype.uploadToSelectedCalendar = function (selectedCalendarId, fProceedUploading) { this.uploadCalendarId(selectedCalendarId) this.checkStarted(true) fProceedUploading() } /** * @param {number} iScrollTop */ CCalendarView.prototype.restoreScroll = function (iScrollTop) { if ( Types.isPositiveNumber(iScrollTop) && this.domScrollWrapper && this.domScrollWrapper.data('customscroll') && this.domScrollWrapper.data('customscroll')['vertical'] ) { this.domScrollWrapper.data('customscroll')['vertical'].set(iScrollTop) } } const calendarView = new CCalendarView() Pulse.registerEveryMinuteFunction(() => { calendarView.applyDateTime() }) module.exports = calendarView