UNPKG

tui-calendar

Version:
372 lines (327 loc) 12.6 kB
/** * @fileoverview Factory module for WeekView * @author NHN FE Development Lab <dl_javascript@nhn.com> */ 'use strict'; var util = require('tui-code-snippet'); var config = require('../config'); var domutil = require('../common/domutil'); var common = require('../common/common'); var VLayout = require('../common/vlayout'); var reqAnimFrame = require('../common/reqAnimFrame'); var Schedule = require('../model/schedule'); // Parent views var Week = require('../view/week/week'); // Sub views var DayName = require('../view/week/dayname'); var DayGrid = require('../view/week/dayGrid'); var TimeGrid = require('../view/week/timeGrid'); var ScheduleCreationPopup = require('../view/popup/scheduleCreationPopup'); var ScheduleDetailPopup = require('../view/popup/scheduleDetailPopup'); // Handlers var DayNameClick = require('../handler/time/clickDayname'); var DayGridClick = require('../handler/daygrid/click'); var DayGridCreation = require('../handler/daygrid/creation'); var DayGridMove = require('../handler/daygrid/move'); var DayGridResize = require('../handler/daygrid/resize'); var TimeClick = require('../handler/time/click'); var TimeCreation = require('../handler/time/creation'); var TimeMove = require('../handler/time/move'); var TimeResize = require('../handler/time/resize'); var DAYGRID_HANDLDERS = { 'click': DayGridClick, 'creation': DayGridCreation, 'move': DayGridMove, 'resize': DayGridResize }; var TIMEGRID_HANDLERS = { 'click': TimeClick, 'creation': TimeCreation, 'move': TimeMove, 'resize': TimeResize }; var DEFAULT_PANELS = [ { name: 'milestone', type: 'daygrid', minHeight: 20, maxHeight: 80, showExpandableButton: true, maxExpandableHeight: 210, handlers: ['click'], show: true }, { name: 'task', type: 'daygrid', minHeight: 40, maxHeight: 120, showExpandableButton: true, maxExpandableHeight: 210, handlers: ['click', 'move'], show: true }, { name: 'allday', type: 'daygrid', minHeight: 30, maxHeight: 80, showExpandableButton: true, maxExpandableHeight: 210, handlers: ['click', 'creation', 'move', 'resize'], show: true }, { name: 'time', type: 'timegrid', autoHeight: true, handlers: ['click', 'creation', 'move', 'resize'], show: true } ]; /* eslint-disable complexity*/ module.exports = function(baseController, layoutContainer, dragHandler, options, viewName) { var panels = [], vpanels = []; var weekView, dayNameContainer, dayNameView, vLayoutContainer, vLayout; var createView, onSaveNewSchedule, onSetCalendars, lastVPanel; var detailView, onShowDetailPopup, onDeleteSchedule, onShowEditPopup, onEditSchedule; var taskView = options.taskView; var scheduleView = options.scheduleView; var viewVisibilities = { 'milestone': util.isArray(taskView) ? util.inArray('milestone', taskView) >= 0 : taskView, 'task': util.isArray(taskView) ? util.inArray('task', taskView) >= 0 : taskView, 'allday': util.isArray(scheduleView) ? util.inArray('allday', scheduleView) >= 0 : scheduleView, 'time': util.isArray(scheduleView) ? util.inArray('time', scheduleView) >= 0 : scheduleView }; // Make panels by view sequence and visibilities util.forEach(DEFAULT_PANELS, function(panel) { var name = panel.name; panel = util.extend({}, panel); panels.push(panel); // Change visibilities panel.show = viewVisibilities[name]; if (panel.show) { if (vpanels.length) { vpanels.push({ isSplitter: true }); } vpanels.push(util.extend({}, panel)); } }); if (vpanels.length) { lastVPanel = vpanels[vpanels.length - 1]; lastVPanel.autoHeight = true; lastVPanel.maxHeight = null; lastVPanel.showExpandableButton = false; util.forEach(panels, function(panel) { if (panel.name === lastVPanel.name) { panel.showExpandableButton = false; return false; } return true; }); } util.extend(options.week, {panels: panels}); weekView = new Week(null, options.week, layoutContainer, panels, viewName); weekView.handler = { click: {}, dayname: {}, creation: {}, move: {}, resize: {} }; dayNameContainer = domutil.appendHTMLElement('div', weekView.container, config.classname('dayname-layout')); /********** * Day name (top row(Mon, Tue, Wed...)) **********/ dayNameView = new DayName(options, dayNameContainer, baseController.theme); weekView.handler.dayname.date = new DayNameClick(dragHandler, dayNameView, baseController); weekView.addChild(dayNameView); /********** * Initialize vertical layout module **********/ vLayoutContainer = domutil.appendHTMLElement('div', weekView.container, config.classname('vlayout-area')); vLayoutContainer.style.height = (domutil.getSize(weekView.container)[1] - dayNameView.container.offsetHeight) + 'px'; vLayout = new VLayout({ panels: vpanels, panelHeights: options.week.panelHeights || [] }, vLayoutContainer, baseController.theme); weekView.vLayout = vLayout; util.forEach(panels, function(panel) { var name = panel.name; var handlers = panel.handlers; var view; if (!panel.show) { return; } if (panel.type === 'daygrid') { /********** * Schedule panel by Grid **********/ view = new DayGrid(name, options, vLayout.getPanelByName(panel.name).container, baseController.theme); view.on('afterRender', function(viewModel) { vLayout.getPanelByName(name).setHeight(null, viewModel.height); }); weekView.addChild(view); util.forEach(handlers, function(type) { if (!options.isReadOnly || type === 'click') { weekView.handler[type][name] = new DAYGRID_HANDLDERS[type](dragHandler, view, baseController, options); view.addHandler(type, weekView.handler[type][name], vLayout.getPanelByName(name)); } }); } else if (panel.type === 'timegrid') { /********** * Schedule panel by TimeGrid **********/ view = new TimeGrid(name, options, vLayout.getPanelByName(name).container); weekView.addChild(view); util.forEach(handlers, function(type) { if (!options.isReadOnly || type === 'click') { weekView.handler[type][name] = new TIMEGRID_HANDLERS[type](dragHandler, view, baseController, options); } }); view.on('clickTimezonesCollapsedBtn', function() { var timezonesCollapsed = !weekView.state.timezonesCollapsed; weekView.setState({ timezonesCollapsed: timezonesCollapsed }); reqAnimFrame.requestAnimFrame(function() { if (!weekView.invoke('clickTimezonesCollapseBtn', timezonesCollapsed)) { weekView.render(); } }); }); } }); vLayout.on('resize', function() { reqAnimFrame.requestAnimFrame(function() { weekView.render(); }); }); // binding create schedules event if (options.useCreationPopup) { createView = new ScheduleCreationPopup(layoutContainer, baseController.calendars, options.usageStatistics); onSaveNewSchedule = function(scheduleData) { util.extend(scheduleData, { useCreationPopup: true }); if (scheduleData.isAllDay) { weekView.handler.creation.allday.fire('beforeCreateSchedule', scheduleData); } else { weekView.handler.creation.time.fire('beforeCreateSchedule', scheduleData); } }; createView.on('beforeCreateSchedule', onSaveNewSchedule); } onSetCalendars = function(calendars) { if (createView) { createView.setCalendars(calendars); } }; baseController.on('setCalendars', onSetCalendars); // binding popup for schedule detail if (options.useDetailPopup) { detailView = new ScheduleDetailPopup(layoutContainer); onShowDetailPopup = function(eventData) { var scheduleId = eventData.schedule.calendarId; eventData.calendar = common.find(baseController.calendars, function(calendar) { return calendar.id === scheduleId; }); if (options.isReadOnly) { eventData.schedule = util.extend({}, eventData.schedule, {isReadOnly: true}); } detailView.render(eventData); }; onDeleteSchedule = function(eventData) { if (eventData.isAllDay) { weekView.handler.creation.allday.fire('beforeDeleteSchedule', eventData); } else { weekView.handler.creation.time.fire('beforeDeleteSchedule', eventData); } }; onEditSchedule = function(eventData) { if (eventData.isAllDay) { weekView.handler.move.allday.fire('beforeUpdateSchedule', eventData); } else { weekView.handler.move.time.fire('beforeUpdateSchedule', eventData); } }; util.forEach(weekView.handler.click, function(panel) { panel.on('clickSchedule', onShowDetailPopup); }); if (options.useCreationPopup) { onShowEditPopup = function(eventData) { var calendars = baseController.calendars; eventData.isEditMode = true; createView.setCalendars(calendars); createView.render(eventData); }; createView.on('beforeUpdateSchedule', onEditSchedule); detailView.on('beforeUpdateSchedule', onShowEditPopup); } else { detailView.on('beforeUpdateSchedule', onEditSchedule); } detailView.on('beforeDeleteSchedule', onDeleteSchedule); } weekView.on('afterRender', function() { vLayout.refresh(); }); // add controller weekView.controller = baseController.Week; // add destroy weekView._beforeDestroy = function() { util.forEach(weekView.handler, function(type) { util.forEach(type, function(handler) { handler.off(); handler.destroy(); }); }); if (options.useCreationPopup && createView) { createView.off('beforeCreateSchedule', onSaveNewSchedule); createView.destroy(); } if (options.useDetailPopup && detailView) { detailView.off('beforeDeleteSchedule', onDeleteSchedule); detailView.destroy(); } weekView.off(); }; return { view: weekView, refresh: function() { var weekViewHeight = weekView.getViewBound().height, daynameViewHeight = domutil.getBCRect( dayNameView.container ).height; vLayout.container.style.height = weekViewHeight - daynameViewHeight + 'px'; vLayout.refresh(); }, scrollToNow: function() { weekView.children.each(function(childView) { if (childView.scrollToNow) { childView.scrollToNow(); } }); }, openCreationPopup: function(schedule) { if (createView) { if (schedule.isAllDay) { weekView.handler.creation.allday.invokeCreationClick(Schedule.create(schedule)); } else { weekView.handler.creation.time.invokeCreationClick(Schedule.create(schedule)); } } }, showCreationPopup: function(eventData) { if (createView) { createView.setCalendars(baseController.calendars); createView.render(eventData); } } }; };