WRMCB=function(e){var c=console;if(c&&c.log&&c.error){c.log('Error running batched script.');c.error(e);}} ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-roadmap-plugin:roadmap-editor-view-resources', location = 'view/roadmap-editor/templates.soy' */ // This file was automatically generated from templates.soy. // Please don't edit this file by hand. /** * @fileoverview Templates in namespace Confluence.Templates.Roadmap. */ if (typeof Confluence == 'undefined') { var Confluence = {}; } if (typeof Confluence.Templates == 'undefined') { Confluence.Templates = {}; } if (typeof Confluence.Templates.Roadmap == 'undefined') { Confluence.Templates.Roadmap = {}; } Confluence.Templates.Roadmap.roadmapPopupPanel = function(opt_data, opt_ignored) { return '
'; }; if (goog.DEBUG) { Confluence.Templates.Roadmap.roadmapPopupPanel.soyTemplateName = 'Confluence.Templates.Roadmap.roadmapPopupPanel'; } Confluence.Templates.Roadmap.roadmapEditor = function(opt_data, opt_ignored) { return '
'; }; if (goog.DEBUG) { Confluence.Templates.Roadmap.roadmapEditor.soyTemplateName = 'Confluence.Templates.Roadmap.roadmapEditor'; } Confluence.Templates.Roadmap.lane = function(opt_data, opt_ignored) { return '
' + soy.$$escapeHtml(opt_data.title) + '
 
'; }; if (goog.DEBUG) { Confluence.Templates.Roadmap.lane.soyTemplateName = 'Confluence.Templates.Roadmap.lane'; } Confluence.Templates.Roadmap.marker = function(opt_data, opt_ignored) { return '
' + soy.$$escapeHtml(opt_data.title) + '
'; }; if (goog.DEBUG) { Confluence.Templates.Roadmap.marker.soyTemplateName = 'Confluence.Templates.Roadmap.marker'; } Confluence.Templates.Roadmap.bar = function(opt_data, opt_ignored) { return '

' + soy.$$escapeHtml(opt_data.title) + '

'; }; if (goog.DEBUG) { Confluence.Templates.Roadmap.bar.soyTemplateName = 'Confluence.Templates.Roadmap.bar'; } Confluence.Templates.Roadmap.newRowLine = function(opt_data, opt_ignored) { return '
'; }; if (goog.DEBUG) { Confluence.Templates.Roadmap.newRowLine.soyTemplateName = 'Confluence.Templates.Roadmap.newRowLine'; } Confluence.Templates.Roadmap.deprecationDialog = function(opt_data, opt_ignored) { return ''; }; if (goog.DEBUG) { Confluence.Templates.Roadmap.deprecationDialog.soyTemplateName = 'Confluence.Templates.Roadmap.deprecationDialog'; } Confluence.Templates.Roadmap.newRowPlaceholder = function(opt_data, opt_ignored) { return '
'; }; if (goog.DEBUG) { Confluence.Templates.Roadmap.newRowPlaceholder.soyTemplateName = 'Confluence.Templates.Roadmap.newRowPlaceholder'; } Confluence.Templates.Roadmap.laneDialog = function(opt_data, opt_ignored) { return '' + aui.buttons.button({id: 'add-bar-button', type: 'subtle', iconType: 'aui', extraClasses: 'aui-button-compact', text: '', extraAttributes: {title: 'Add bar'}, iconClass: 'aui-icon-small aui-iconfont-add'}) + aui.buttons.button({id: 'rename-button', type: 'subtle', iconType: 'aui', extraClasses: 'aui-button-compact', text: '', extraAttributes: {title: 'Rename lane'}, iconClass: 'aui-icon-small aui-iconfont-edit'}) + Confluence.Templates.Roadmap.laneColorSelect(opt_data) + ((opt_data.canDelete) ? aui.buttons.button({id: 'delete-button', type: 'subtle', iconType: 'aui', extraClasses: 'aui-button-compact', text: '', extraAttributes: {title: 'Delete lane'}, iconClass: 'aui-icon aui-icon-small aui-iconfont-delete'}) : ''); }; if (goog.DEBUG) { Confluence.Templates.Roadmap.laneDialog.soyTemplateName = 'Confluence.Templates.Roadmap.laneDialog'; } Confluence.Templates.Roadmap.markerDialog = function(opt_data, opt_ignored) { return '' + aui.buttons.button({id: 'rename-button', type: 'subtle', iconType: 'aui', extraClasses: 'aui-button-compact', text: '', extraAttributes: {title: 'Rename marker'}, iconClass: 'aui-icon-small aui-iconfont-edit'}) + aui.buttons.button({id: 'delete-button', type: 'subtle', iconType: 'aui', extraClasses: 'aui-button-compact', text: '', extraAttributes: {title: 'Delete marker'}, iconClass: 'aui-icon aui-icon-small aui-iconfont-delete'}); }; if (goog.DEBUG) { Confluence.Templates.Roadmap.markerDialog.soyTemplateName = 'Confluence.Templates.Roadmap.markerDialog'; } Confluence.Templates.Roadmap.markerRenameDialog = function(opt_data, opt_ignored) { return '' + aui.form.form({action: '', content: '' + aui.form.input({extraClasses: 'marker-title', name: 'marker-title', type: 'text', value: opt_data.markerTitle}) + aui.buttons.button({extraClasses: 'rename-button', text: 'Save'})}); }; if (goog.DEBUG) { Confluence.Templates.Roadmap.markerRenameDialog.soyTemplateName = 'Confluence.Templates.Roadmap.markerRenameDialog'; } Confluence.Templates.Roadmap.laneRenameDialog = function(opt_data, opt_ignored) { return '' + aui.form.form({action: '', content: '' + aui.form.input({extraClasses: 'lane-title', name: 'lane-title', type: 'text', value: opt_data.laneTitle}) + aui.buttons.button({extraClasses: 'rename-button', text: 'Save'})}); }; if (goog.DEBUG) { Confluence.Templates.Roadmap.laneRenameDialog.soyTemplateName = 'Confluence.Templates.Roadmap.laneRenameDialog'; } Confluence.Templates.Roadmap.laneColorSelect = function(opt_data, opt_ignored) { var output = ' 
'; return output; }; if (goog.DEBUG) { Confluence.Templates.Roadmap.laneColorSelect.soyTemplateName = 'Confluence.Templates.Roadmap.laneColorSelect'; } Confluence.Templates.Roadmap.linkPageTitle = function(opt_data, opt_ignored) { return ''; }; if (goog.DEBUG) { Confluence.Templates.Roadmap.linkPageTitle.soyTemplateName = 'Confluence.Templates.Roadmap.linkPageTitle'; } Confluence.Templates.Roadmap.footerActionContent = function(opt_data, opt_ignored) { return '' + ((opt_data.roadmapShouldAutoSave) ? '' + soy.$$escapeHtml('This roadmap planner autosaves every 15 seconds.') + '' : '') + aui.buttons.button({text: 'Insert', id: 'roadmapInsertBtn'}) + ((opt_data.roadmapShouldAutoSave) ? aui.buttons.button({text: 'Close', type: 'link', id: 'roadmapCloseBtn'}) : aui.buttons.button({text: 'Cancel', type: 'link', id: 'roadmapCancelBtn'})); }; if (goog.DEBUG) { Confluence.Templates.Roadmap.footerActionContent.soyTemplateName = 'Confluence.Templates.Roadmap.footerActionContent'; } }catch(e){WRMCB(e)}; ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-roadmap-plugin:roadmap-editor-view-resources', location = 'view/roadmap-editor/bar/bar.js' */ /** * Currently InlineDialog doesn't support left/right orientation ( will support from version AUI 5.5.1 https://ecosystem.atlassian.net/browse/AUI-2197 ) * SideInlineDialog has been already implemented and support left/right orientation * https://bitbucket.org/atlassianlabs/confluence-roadmap-plugin/src/f7c94dfb23007aa7fd0458af5e6128cdeacc6338/src/main/resources/js/SideInlineDialog.js?at=master * Temporary copied getDimensions & calculatePositions, getArrowPath functions to here with names_getSideDimensions & _calculateSidePositions, _getSideArrowPath * TODO update Roadmap InlineDialog use left/right option https://jira.atlassian.com/browse/CONFDEV-25613 */ (function ($, _) { Roadmap.BarView = Backbone.View.extend({ className: 'roadmap-bar', events: { 'click': '_showDialog', 'dragstart': '_onDragstart', 'dragstop': '_onDragStop', 'dropover': '_onDropOver', 'dropout': '_onDropOut' }, attributes: function () { return { cid: this.cid }; }, initialize: function () { _.bindAll(this, 'render', '_updateBar', '_beforeResize', 'updateMaxWidth', '_deleteBar', '_updateTitle'); this._addEvents(); }, _addEvents: function () { var me = this; this.$el.draggable({ opacity: 0.3, cursor: "move", appendTo: '.roadmap-drag-area', snap: '.roadmap-bar-row, .new-bar-row', snapMode: 'inner', snapTolerance: 17, scroll: true, zIndex: 4020, // this will prevent the cursor change to resize when drag over two borders left/right helper: function () { return me.$el.clone().addClass('roadmap-bar-clone').data('View', me); } }); this.$el.droppable({ accept: '.roadmap-bar', tolerance: 'touch', hoverClass: 'bar-hover-bar' }); this.$el.data('View', this); }, render: function () { this.updateColor(this.options.color); var barPosition = this.options.timelineView.getBarPosition(this.model.attributes); this.$el.css({ left: barPosition.left + 'px', width: barPosition.width + 'px' }); this.$el.attr('title', this.model.get('title')); this.$el.append( Confluence.Templates.Roadmap.bar({ title: this.model.get('title') }) ); this.$el.resizable({ handles: 'e, w', minWidth: Roadmap.barMinWidth, start: this._beforeResize, stop: this._updateBar }); return this; }, updateMaxWidth: function (maxWidth) { this.$el.resizable('option', 'maxWidth', maxWidth); // min width is always smaller or equal max width var minWidth = this.$el.resizable('option', 'minWidth'); if (maxWidth < minWidth) { this.$el.resizable('option', 'minWidth', maxWidth); } }, _beforeResize: function (event, barUI) { this._barDialog && this._barDialog.remove(); // remove bar dialog before resize this.trigger('beforeResize', this, this._checkHandleDirection(event)); }, _checkHandleDirection: function (event) { var direction = $(event.toElement ? event.toElement : event.originalEvent.target); //we only support resize on left and right so don't need to check more if (direction.hasClass('ui-resizable-w')) { return 'left'; } else if (direction.hasClass('ui-resizable-e')) { return 'right'; } throw "Unsupport resize direction handling = " + direction; }, _updateBar: function (event, barUI) { if (barUI.originalPosition.left != barUI.position.left) { this.model.set({ startDate: this.options.timelineView.getBarStartDate(barUI.position.left), duration: this.options.timelineView.getBarDuration(barUI.element.outerWidth()) }); } else if (barUI.originalSize.width != barUI.size.width) { this.model.set('duration', this.options.timelineView.getBarDuration(barUI.element.outerWidth())); } }, appendTo: function ($container) { this.$el.appendTo($container); }, updateColor: function (color) { this.$el.css({ 'background-color': color.bar, 'border-color': color.lane, color: color.text }); }, updatePositionLeft: function (left) { this.$el.css('left', left); }, _onDragStop: function (e, ui) { this.options.lane.cleanLaneAfterDrop(); this.$el.trigger('BarView.dragstop'); }, /** * Update delete function from lane, called when bar is dropped into another lane. */ updateDeleteBar: function (deleteBar) { this.options.deleteBar = deleteBar; }, /** * Open the 'Bar' dialog. * Called when the 'bar' is clicked. */ _showDialog: function (event) { if (!$(event.target).is('.ui-resizable-handle')) { // do not show dialog when resize this._barDialog && this._barDialog.remove(); // remove existing object if there is any this._barDialog = this._createDialog(); this._barDialog.show(); Confluence.Roadmap.Analytics.openBarDialogInEdit(); } }, _createDialog: function () { return new Roadmap.BarDialogView({ trigger: this.$el, model: this.model, timelineWidth: this.options.timelineView.$el.width(), renderOption: { isEditMode: true, editInplace: { title: true, pageLink: true, description: true } }, linkPageEditable: true, // user of course has edit page permission in edit mode deleteBar: this._deleteBar, updateTitle: this._updateTitle, updateDescription: this._updateDescription, updatePageLink: this._updatePageLink, createLinkPageCallback: this._goToCreateLinkPage }); }, _deleteBar: function () { this.options.deleteBar(this); }, _updateTitle: function (newTitle) { this.model.set('title', newTitle); this.$el.attr('title', newTitle); this.$el.find('.roadmap-bar-title').html(AJS.escapeHtml(newTitle)); }, _updateDescription: function (newDescription) { this.model.set('description', newDescription); }, _updatePageLink: function (pageLink) { this.model.set('pageLink', pageLink); }, _onDragstart: function (e, ui) { Roadmap.DragDrop.barDraggingOver = {}; this.$el.trigger('BarView.dragstart', [ui]); }, _onDropOver: function (e, ui) { Roadmap.DragDrop.barDraggingOver[this.cid] = this.cid; if (Roadmap.DragDrop.barDraggingOver && ui.helper.data('isAddingNewRow') !== true) { ui.helper.addClass('roadmap-bar-overlapped'); } }, _onDropOut: function (e, ui) { var me = this; delete Roadmap.DragDrop.barDraggingOver[me.cid]; ui.helper.removeClass('roadmap-bar-overlapped'); _.each(Roadmap.DragDrop.barDraggingOver, function (item) { var isNotAddingNewRow = ui.helper.data('isAddingNewRow') !== true; if (isNotAddingNewRow) { if (typeof item === 'string') { // still over on a bar ui.helper.addClass('roadmap-bar-overlapped'); } else if (item.className === 'roadmap-bar-row') { // still in a bar-row item.$el.addClass('roadmap-bar-drag-hover'); } } }); }, _goToCreateLinkPage: function (event) { event.preventDefault(); var me = this.me; var currentPageId = parseInt(AJS.Meta.get('page-id')); var pageId = currentPageId > 0 ? currentPageId : AJS.Meta.get('parent-page-id'); var linkParam = { roadmapBarId: me.model.id, roadmapContentId: pageId, updateRoadmap: false } Confluence.RoadmapLink.addCreateLinkPageListener(linkParam, function (barDetail) { var $pageLink = me._updatePageLink(barDetail.pageLink); me.fields.$pageLink.html($pageLink); }); } }); })(AJS.$, window._); }catch(e){WRMCB(e)}; ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-roadmap-plugin:roadmap-editor-view-resources', location = 'view/roadmap-editor/bar/bar-row.js' */ (function ($, _) { Roadmap.BarRowView = Backbone.View.extend({ className: 'roadmap-bar-row', initialize: function () { _.bindAll(this, '_addEvents'); this._addEvents(); return this; }, attributes: function () { return { cid: this.cid }; }, _addEvents: function () { var me = this; this.$el.droppable({ greedy: true, tolerance: 'pointer', hoverClass: 'roadmap-bar-drag-hover', activeClass: 'roadmap-bar-drag-active', accept: '.roadmap-bar', over: function (e, ui) { Roadmap.DragDrop.barDraggingOver[me.cid] = me; if (ui.helper.data('isAddingNewRow') !== true) { var $barRow = $(this); $barRow.closest('.roadmap-content').find('.new-row-placeholder').remove(); } else { me.$el.removeClass('roadmap-bar-drag-hover'); } }, out: function () { var $barRow = $(this); delete Roadmap.DragDrop.barDraggingOver[me.cid]; $barRow.closest('.roadmap-content').find('.new-row-placeholder').remove(); }, drop: function (e, ui) { var isBarOverlapped = _.reject(Roadmap.DragDrop.barDraggingOver, function (item) { return (typeof item === 'object'); }).length > 0; if (!ui.helper.hasClass('roadmap-bar-overlapped') && !isBarOverlapped) { $(this).trigger('BarView.drop', [ { $barViewHelper: ui.helper, $barViewOriginal: ui.draggable, $barRow: $(this) }, ui ]); } } }); }, isEmptyRow: function () { return this.$el.is(':empty'); } }); })(AJS.$, window._); }catch(e){WRMCB(e)}; ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-roadmap-plugin:roadmap-editor-view-resources', location = 'view/roadmap-editor/bar/bar-row-new.js' */ (function ($, _) { Roadmap.BarRowNewView = Backbone.View.extend({ className: 'new-bar-row', overlayTop: 3, // number of pixel that will overlay on bar margin: 5, // margin between two bar-rows events: { drop: '_onDrop', dropover: '_onDropOver', dropout: '_onDropOut' }, initialize: function () { _.bindAll(this, 'render', '_addEvent'); return this; }, render: function () { this.$el.append(Confluence.Templates.Roadmap.newRowLine()); this._addEvent(); this._setSizePosition(); return this; }, _addEvent: function () { this.$el.droppable({ accept: '.roadmap-bar', tolerance: 'pointer', hoverClass: 'new-bar-row-hover' }); }, _setSizePosition: function () { var $barRow = this.options.$barRow; var barRowHeight = this.options.renderBottom === false ? (this.margin * -1) : $barRow.height(); var isFirstRow = $barRow.index() === 0; var overlay = (isFirstRow) ? this.overlayTop + this.margin : this.overlayTop; this.$el.css({ top: $barRow.position().top + barRowHeight - overlay, width: $barRow.width() }); }, _onDrop: function (e, ui) { this.$el.trigger('BarView.drop', [{ barRowNewView: this }, ui]); }, _onDropOver: function (e, ui) { this.$el.trigger('BarRowNew.dropover', [this, ui]); }, _onDropOut: function (e, ui) { this.$el.trigger('BarRowNew.dropout', [this, ui]); } }); })(AJS.$, window._); }catch(e){WRMCB(e)}; ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-roadmap-plugin:roadmap-editor-view-resources', location = 'view/roadmap-editor/lane-dialog/lane-dialog.js' */ (function ($, _) { var InlineDialogView = Roadmap.InlineDialogView; Roadmap.LaneDialogView = InlineDialogView.extend({ events: { 'click #delete-button': '_onDeleteClick', 'click #rename-button': '_onRenameClick', 'click #add-bar-button': '_onAddBarClick' }, initialize: function () { _.bindAll(this, '_onHide'); this.options.dialogOptions = { width: this._getDialogWidth(), hideCallback: this._onHide }; $('.roadmap-editor-popup, .roadmap-macro-view').scroll(function () { $('#lane-color-picker').hide(); }); InlineDialogView.prototype.initialize.call(this, this.options); }, /** * Get Lane dialog content * @param {element} element The inline dialog element. * @param {function} showDialog A function that shows the inline dialog. */ _getContent: function (element) { var laneColor = this.options.lane.model.get('color').lane; element.html(Confluence.Templates.Roadmap.laneDialog({ canDelete: this.options.canDelete, colors: Roadmap.COLORS, laneColor: laneColor })); this.$el.find('.aui-button').tooltip({gravity: 's'}); var me = this; var $colorItems = this.$el.find('#lane-color-picker .color-item'); $colorItems.click(function (event) { event.preventDefault(); var newColor = Roadmap.COLORS[$colorItems.index(this)]; if (newColor.lane != laneColor) { me.options.changeColor(newColor); } $('#lane-color-picker').hide(); // remove lane dialog after color is selected to match // UX of other buttons in the dialog. me.remove(); }) }, _getDialogWidth: function () { var iconButtonWidth = 29; var colorSelectWidth = 51; var buttonCount = 2; // currently only has 2 buttons: Add Bar & Rename lane if (this.options.canDelete) { // only display delete button when lane can delete buttonCount++; } return buttonCount * iconButtonWidth + colorSelectWidth; }, _onDeleteClick: function () { this.options.deleteLane(); this.remove(); }, _onRenameClick: function () { if (!this._laneRenameDialog) { this._laneRenameDialog = new Roadmap.LaneRenameDialogView({ trigger: this.options.trigger, lane: this.options.lane }); } this._laneRenameDialog.show(); this.hide(); }, _onAddBarClick: function () { this.options.addBar(); this.remove(); }, _onHide: function () { $('#lane-color-picker').hide(); InlineDialogView.prototype._onHide.call(this); } }); })(AJS.$, window._); }catch(e){WRMCB(e)}; ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-roadmap-plugin:roadmap-editor-view-resources', location = 'view/roadmap-editor/lane-dialog/lane-rename-dialog.js' */ (function ($, _) { var InlineDialogView = Roadmap.InlineDialogView; Roadmap.LaneRenameDialogView = InlineDialogView.extend({ events: { 'click .rename-button': '_onRenameButtonClick', 'keyup .lane-title': '_onChangeLaneTitle' }, initialize: function () { this.options.dialogOptions = { width: this._getDialogWidth() }; InlineDialogView.prototype.initialize.call(this, this.options); }, _getContent: function (element) { element.html(Confluence.Templates.Roadmap.laneRenameDialog({laneTitle: this.options.trigger.text()})); this.controls = { $renameButton: this.$el.find('.rename-button'), $laneTitle: this.$el.find('.lane-title') }; }, _getDialogWidth: function () { return 315; }, _onChangeLaneTitle: function (e) { var changedTitle = $.trim(this.controls.$laneTitle.val()); if (!changedTitle) { this.controls.$renameButton.disable(); } else { this.controls.$renameButton.enable(); if (e.which == AJS.$.ui.keyCode.ENTER) { this.controls.$renameButton.click(); //bug in IE only (submit with enter) } } }, _onShow: function (e) { this.controls.$laneTitle.select(); }, _onRenameButtonClick: function (event) { event.preventDefault(); this.hide(); var changedTitle = this.controls.$laneTitle.val(); this.options.lane.renameTitle(changedTitle); } }); })(AJS.$, window._); }catch(e){WRMCB(e)}; ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-roadmap-plugin:roadmap-editor-view-resources', location = 'view/roadmap-editor/marker-dialog/marker-dialog.js' */ (function ($, _) { var InlineDialogView = Roadmap.InlineDialogView; Roadmap.MarkerDialogView = InlineDialogView.extend({ events: { 'click #rename-button': '_onRenameButtonClick', 'click #delete-button': '_onDeleteButtonClick' }, initialize: function () { this.options.dialogOptions = { width: 60 }; InlineDialogView.prototype.initialize.call(this, this.options); }, _getContent: function (element) { element.html(Confluence.Templates.Roadmap.markerDialog()); this.$el.find('.aui-button.aui-button-compact').tooltip({gravity: 's'}); }, _onRenameButtonClick: function () { if (!this._markerRenameDialog) { this._markerRenameDialog = new Roadmap.MarkerRenameDialogView({ trigger: this.options.trigger, marker: this.options.marker }); } this._markerRenameDialog.show(); this.hide(); }, _onDeleteButtonClick: function () { this.options.marker.removeMarker(); this.hide(); } }); })(AJS.$, window._); }catch(e){WRMCB(e)}; ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-roadmap-plugin:roadmap-editor-view-resources', location = 'view/roadmap-editor/marker-dialog/marker-rename-dialog.js' */ (function ($, _) { var InlineDialogView = Roadmap.InlineDialogView; Roadmap.MarkerRenameDialogView = InlineDialogView.extend({ events: { 'click .rename-button': '_onSaveButtonClick', 'keyup .marker-title': '_onChangeMarkerTitle' }, initialize: function () { this.options.dialogOptions = { width: 315 }; InlineDialogView.prototype.initialize.call(this, this.options); }, _getContent: function (element) { element.html(Confluence.Templates.Roadmap.markerRenameDialog({markerTitle: this.options.marker.model.get('title')})); this.controls = { $renameButton: this.$el.find('.rename-button'), $title: this.$el.find('.marker-title') }; }, _onChangeMarkerTitle: function (e) { var changedTitle = $.trim(this.controls.$title.val()); if (!changedTitle) { this.controls.$renameButton.disable(); } else { this.controls.$renameButton.enable(); if (e.which == AJS.$.ui.keyCode.ENTER) { this.controls.$renameButton.click(); } } }, _onShow: function (e) { this.controls.$title.select(); }, _onSaveButtonClick: function (e) { e.preventDefault(); this.hide(); this.options.marker.renameTitle(this.controls.$title.val()); } }); })(AJS.$, window._); }catch(e){WRMCB(e)}; ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-roadmap-plugin:roadmap-editor-view-resources', location = 'view/roadmap-editor/lane.js' */ (function ($, _) { window.Roadmap = window.Roadmap || {}; Roadmap.LaneView = Backbone.View.extend({ tagName: 'div', className: 'roadmap-lane', events: { "click .roadmap-lane-title": '_showDialog', 'BarView.drop': '_onBarDropped', 'BarRowNew.dropover': '_onBarRowNewDropover', 'BarRowNew.dropout': '_onBarRowNewDropout' }, attributes: function () { return { cid: this.cid }; }, initialize: function () { _.bindAll(this, 'render', 'renameTitle', 'updateRowIndex', 'removeEmptyRow', 'cleanLaneAfterDrop', '_deleteLane', '_updateLaneHeight', '_renderComplete', '_deleteBar', '_addBar', '_changeColor', 'addDefaultBarRow'); this._barViews = []; this._barRowViews = []; this.listenTo(this.model.get('bars'), 'add', function (barModel) { // New Bar Row var rowView = this._newBarRowView(); // Add Bar to new Row var barView = this._newBarView(barModel); rowView.$el.append(barView.render().$el); this._$laneContent.append(rowView.$el); this._barViews.push(barView); this.$el.trigger('BarView.add', barView); _.defer(this._updateLaneHeight); }); }, render: function () { var me = this; this.$el.append( Confluence.Templates.Roadmap.lane({ title: this.model.get('title'), color: this.model.get('color') }) ); Confluence.Roadmap.ColorHelper.adjustColorCount(this.model.get('color'), 1); var barModels = this.model.get('bars').models; barModels = _.sortBy(barModels, function (barModel) { return barModel.attributes.rowIndex; }); _.each(barModels, function (barModel) { var barView = me._newBarView(barModel); me._barViews.push(barView); }); this._renderBars(); _.defer(this._renderComplete); return this; }, _renderComplete: function () { this._updateLaneHeight(); }, renameTitle: function (newTitle) { this.model.set('title', newTitle); this.$el.find('.roadmap-lane-title').attr('title', newTitle); this.$el.find('.title-inner').html(AJS.escapeHtml(newTitle)); this._updateLaneHeight(); }, _updateLaneHeight: function () { //lane-title must be calculated base on 'roadmap-lane-content' //To do that: hide title -> get 'roadmap-lane-content' height ->show var $titleElement = this.$el.find('.title-inner'); $titleElement.hide(); var laneHeight = this._$laneContent.outerHeight(); $titleElement.width(laneHeight - 2 * Roadmap.LANE_PADDING); $titleElement.show(); }, _barBeforeResize: function (barViewObj, direction) { var barView = barViewObj.$el; var paddingBarValue = Math.ceil(barView.outerWidth() - barView.width()); //Control margin/padding value var barResizeMaxWidth; if (direction == 'left') { var barViewLeft = this._getNearestBarView(barViewObj, direction); var barViewLeftRightX = barViewLeft == null ? 0 : barViewLeft.position().left + barViewLeft.width() + paddingBarValue; var distance = barView.position().left - barViewLeftRightX; barResizeMaxWidth = barView.width() + distance; } else { //right var barViewRight = this._getNearestBarView(barViewObj, direction); var barViewRightLeftX = barViewRight == null ? this._getLaneContentWidth() - paddingBarValue : barViewRight.position().left - paddingBarValue; barResizeMaxWidth = barViewRightLeftX - barView.position().left; } barViewObj.updateMaxWidth(barResizeMaxWidth - Roadmap.BAR_MARGIN); }, _renderBars: function () { var me = this; this._$laneContent = this.$el.find('.roadmap-lane-content'); var rowViews = {}; _.each(this._barViews, function (barView) { // New Bar Row var rowViewKey = 'row-' + barView.model.get('rowIndex'); var rowView = rowViews[rowViewKey]; if (!rowView) { rowView = me._newBarRowView(barView.model.get("rowIndex")); rowViews[rowViewKey] = rowView; } rowView.$el.append(barView.render().$el); me._$laneContent.append(rowView.$el); }); }, _newBarRowView: function () { var rowView = new Roadmap.BarRowView(); this._barRowViews.push(rowView); return rowView; }, _newBarView: function (barModel) { var barView = new Roadmap.BarView({ model: barModel, lane: this, color: this.model.get('color'), timelineView: this.options.timelineView, deleteBar: this._deleteBar }); barView.on('beforeResize', _.bind(this._barBeforeResize, this)); //listen 'beforeResize' event on Bar return barView; }, _getNearestBarView: function (barView, direction) { var barViewsInSameRow = _.filter(barView.options.lane._barViews, function (bv) { return bv.model.get('rowIndex') === barView.model.get('rowIndex'); }); var nearBar = null; if (direction == 'left') { _.each(barViewsInSameRow, function (bar) { if (bar.$el.position().left < barView.$el.position().left && (nearBar == null || bar.$el.position().left > nearBar.$el.position().left)) { nearBar = bar; } }); } else { _.each(barViewsInSameRow, function (bar) { if (bar.$el.position().left > barView.$el.position().left && (nearBar == null || bar.$el.position().left < nearBar.$el.position().left)) { nearBar = bar; } }); } return nearBar != null ? nearBar.$el : null; }, _getLaneContentWidth: function () { return this.$el.find('.roadmap-lane-content').width(); }, /** * Open the 'Lane' dialog. * * Called when the 'Lane title' is clicked. * */ _showDialog: function () { this._laneDialog && this._laneDialog.remove(); // remove existing object if there is any this._laneDialog = this._createLaneDialog(); this._laneDialog.show(); }, _createLaneDialog: function () { return new Roadmap.LaneDialogView({ trigger: this.$el.find('.title-outer'), canDelete: this.options.canDelete, // provide delete status for lane dialog deleteLane: this._deleteLane, addBar: this._addBar, changeColor: this._changeColor, lane: this }); }, _onBarDropped: function (e, dropInfo, ui) { var isAddingNewRow = !!dropInfo.barRowNewView; var draggedBarView = ui.draggable.data('View'); var draggedBarModel = draggedBarView.model; var oldLane = draggedBarView.options.lane; var inSameLane = (oldLane.cid === this.cid); var barCollectionDropped = this.model.get('bars'); var newLeftPosition = ui.position.left; var newStartDate = this.options.timelineView.getBarStartDate(newLeftPosition); // don't allow to drop on new row if lane has only one bar if (inSameLane && barCollectionDropped.models.length === 1 && isAddingNewRow) { return; } // Update model after drop draggedBarView.updatePositionLeft(newLeftPosition); draggedBarView.updateColor(this.model.get('color')); draggedBarModel.attributes.startDate = newStartDate; // Add New Row if (isAddingNewRow) { var $rowView = this._newBarRowView(); dropInfo.barRowNewView.$el.replaceWith($rowView.$el); draggedBarView.appendTo($rowView.$el); } // Drag on an existing row else { draggedBarView.appendTo(dropInfo.$barRow); } // By default, ui.helper will be removed by jQuery, but we need to remove it manually to get removeEmptyRow() works properly ui.helper.remove(); if (!inSameLane) { draggedBarView.options.lane.removeEmptyRow(); barCollectionDropped._byId[draggedBarModel.id] = draggedBarModel; this._barViews.push(draggedBarView); // when bar was dragged into new lane need update delete function for new lane can control delete it's bar. draggedBarView.updateDeleteBar(this._deleteBar); oldLane.model.get('bars').remove(draggedBarModel); barCollectionDropped.models.push(draggedBarModel); oldLane._barViews.splice(_.indexOf(oldLane._barViews, draggedBarView), 1); //remove draggedBarView from old lane this.updateRowIndex(oldLane.$el); // Update the default options draggedBarView.options = _.extend(draggedBarView.options, { color: this.model.get('color'), lane: this }); oldLane._updateLaneHeight(); } this.removeEmptyRow(); // Update rowIndex for current lane this.updateRowIndex(this.$el); this._updateLaneHeight(); }, updateRowIndex: function ($lane) { $lane.find('.roadmap-bar-row').each(function (rowIndex, rowEl) { $(rowEl).find('.roadmap-bar:not(".roadmap-bar-clone")').each(function (barIndex, barEl) { var barModel = $(barEl).data('View'); if (barModel) { barModel.model.attributes.rowIndex = rowIndex; } }); }); }, /** * Find and remove empty rows * * @params {laneView} the lane view is use for find and remove empty rows ** @return boolean - true if has empty row is removed */ removeEmptyRow: function () { var barRowDeleted = 0; _.each(this._barRowViews, function (barRow) { if (barRow.isEmptyRow()) { barRow.remove(); barRowDeleted++; } }); return !!barRowDeleted; }, // this function will clear all stuff that generated by D&D and should be call when dragging a bar was stopped. cleanLaneAfterDrop: function () { this._$laneContent.find('.roadmap-bar-drag-active').removeClass('roadmap-bar-drag-active'); this._$laneContent.find('.new-row-placeholder').remove(); }, _deleteLane: function () { Confluence.Roadmap.ColorHelper.adjustColorCount(this.model.get('color'), -1); this.$el.trigger('Lane.delete', this); }, /** * Update delete status show/hide delete button for this lane when open lane dialog * * @param {canDelete} true show delete button */ updateDeleteStatus: function (canDelete) { if (this._laneDialog) { this._laneDialog.remove(); // remove previous dialog delete this._laneDialog; } this.options.canDelete = canDelete; }, _deleteBar: function (barView) { this.model.get('bars').remove(barView.model); this._barViews.splice(_.indexOf(this._barViews, barView), 1); barView.remove(); if (this.removeEmptyRow()) { this.updateRowIndex(this.$el); this._updateLaneHeight(); this.$el.trigger('BarRowView.remove'); } }, _addBar: function () { var bars = this.model.get('bars'); var timeline = this.options.timelineView.model; var mStartDateTimeline = moment(timeline.get('startDate')); var mStartDateToRender = timeline.get('displayOption') === Roadmap.TIMELINE_DISPLAY_OPTION.MONTH ? mStartDateTimeline.startOf('month') : mStartDateTimeline.startOf('isoWeek'); bars.add(new Roadmap.Bar({ rowIndex: this.model.getNumberOfRows(), startDate: mStartDateToRender.toDate() })); }, _changeColor: function (newColor) { Confluence.Roadmap.ColorHelper.adjustColorCount(this.model.get('color'), -1); this.model.set('color', newColor); Confluence.Roadmap.ColorHelper.adjustColorCount(newColor, 1); this.$el.find('.roadmap-lane-title').css({ 'background-color': newColor.lane, color: newColor.text }); _.each(this._barViews, function (barView) { barView.updateColor(newColor); }); }, addNewBarRow: function ($draggingBar) { var $barRows = this._$laneContent.find('.roadmap-bar-row'); var barRowNewViewList = []; var add = function () { $barRows.each(function () { var $barRow = $(this); var isFirstRow = $barRow.index() === 0; if (isFirstRow) { var barRowNewViewBefore = new Roadmap.BarRowNewView({ $barRow: $barRow, renderBottom: false }); $barRow.before(barRowNewViewBefore.render().$el); barRowNewViewList.push(barRowNewViewBefore); } var barRowNewViewAfter = new Roadmap.BarRowNewView({ $barRow: $barRow }); $barRow.after(barRowNewViewAfter.render().$el); barRowNewViewList.push(barRowNewViewAfter); }); }; if ($barRows.length == 0) { // Empty lane this.addDefaultBarRow(); } else { var $bars = $barRows.find('.roadmap-bar'); if ($bars.length > 0) { // this is empty lane with default bar-row var selfDropped = ($bars.length > 0) && ($bars.length == 1) && ($bars.attr('cid') === $draggingBar.attr('cid')); // Drop the bar into itself if (!selfDropped) { add(); } } } return barRowNewViewList; }, /** * Add a empty row as default if lane is empty */ addDefaultBarRow: function () { var rowView = this._newBarRowView(); this._$laneContent.append(rowView.$el); }, _onBarRowNewDropover: function (e, barRowNew, ui) { if (!_.isEmpty(Roadmap.DragDrop.barDraggingOver)) { // Make sure there is only one bar-row-new activated at a time _.each(Roadmap.DragDrop.barDraggingOver, function (item) { item.$el && item.$el.removeClass('new-bar-row-hover roadmap-bar-drag-hover'); }); } Roadmap.DragDrop.barDraggingOver[barRowNew.cid] = barRowNew; ui.helper.removeClass('roadmap-bar-overlapped'); ui.helper.data('isAddingNewRow', true); }, _onBarRowNewDropout: function (e, barRowNew, ui) { ui.helper.data('isAddingNewRow', false); delete Roadmap.DragDrop.barDraggingOver[barRowNew.cid]; _.each(Roadmap.DragDrop.barDraggingOver, function (item) { if (typeof item === 'string') { // still over on a bar ui.helper.addClass('roadmap-bar-overlapped'); } else if (item.className === 'roadmap-bar-row' && ui.helper.data('isAddingNewRow') !== true) { // still in a bar-row item.$el.addClass('roadmap-bar-drag-hover'); } }); } }); })(AJS.$, window._); }catch(e){WRMCB(e)}; ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-roadmap-plugin:roadmap-editor-view-resources', location = 'view/roadmap-editor/marker.js' */ (function ($, _) { window.Roadmap = window.Roadmap || {}; Roadmap.MarkerView = Backbone.View.extend({ className: 'vertical-line', events: { dragstop: '_onDragStop', dragstart: '_onDragStart' }, initialize: function () { _.bindAll(this, 'render', 'updateHeight', 'renameTitle', '_renderComplete', '_onMarkerClick'); }, render: function () { var timeline = this.options.roadmap._timelineView.model; var markerPosition; if (timeline.get('displayOption') === Roadmap.TIMELINE_DISPLAY_OPTION.MONTH) { markerPosition = Confluence.Roadmap.Helper.getPosXOnMonthTimeline(timeline.attributes, this.model.get('markerDate')); } else { markerPosition = Confluence.Roadmap.Helper.getPosXOnWeekTimeline(timeline.attributes, this.model.get('markerDate')); } if (markerPosition < 0 || markerPosition > this.options.roadmap._timelineView.$el.width()) { return false; } this.$el.css({ left: (markerPosition + Roadmap.LANE_TITLE_WIDTH) + 'px' }); this.$el.append( Confluence.Templates.Roadmap.marker({title: this.model.get('title')}) ); this.updateHeight(this.options.roadmap._getLaneHeight()); _.defer(this._renderComplete); return this; }, _renderComplete: function () { this._setupMarkerDragging(); this.$el.click(this._onMarkerClick); this.$el.find('.marker-title').ellipsis({row: Roadmap.MARKER_TITLE_LINE}); }, _setupMarkerDragging: function () { this.$el.draggable({ axis: 'x', zIndex: 4013, containment: '.roadmap-frame-content', cursor: 'move' }); }, _onDragStop: function (e, ui) { var posx = ui.position.left - Roadmap.LANE_TITLE_WIDTH; var timeline = this.options.roadmap._timelineView.model.attributes; var markerDate; if (timeline.displayOption === Roadmap.TIMELINE_DISPLAY_OPTION.MONTH) { markerDate = Confluence.Roadmap.Helper.getMonthStartDateByPosition(timeline, posx); } else { markerDate = Confluence.Roadmap.Helper.getWeekStartDateByPosition(timeline, posx); } this.model.set('markerDate', markerDate); }, _onDragStart: function (e, ui) { this.options.roadmap.hideDialog(); }, _onMarkerClick: function (e) { if (!$(e.target).hasClass('marker-title')) { return; } this._markerDialog && this._markerDialog.remove(); this._markerDialog = this._createMarkerDialog(); this._markerDialog.show(); }, _createMarkerDialog: function () { return new Roadmap.MarkerDialogView({ trigger: this.$el.find(".marker-title"), marker: this }); }, updateHeight: function (timelineHeight) { this.$el.height(timelineHeight + Roadmap.MARKER_HEIGHT_PADDING); }, renameTitle: function (newTitle) { this.model.set('title', newTitle); var $markerTitle = this.$el.find('.marker-title'); $markerTitle.attr('title', newTitle); $markerTitle.html(AJS.escapeHtml(newTitle)).ellipsis({row: Roadmap.MARKER_TITLE_LINE}); }, removeMarker: function () { this.model.collection.remove(this.model); this.remove(); } }); })(AJS.$, window._); }catch(e){WRMCB(e)}; ; try { /* module-key = 'com.atlassian.confluence.plugins.confluence-roadmap-plugin:roadmap-editor-view-resources', location = 'view/roadmap-editor/roadmap.js' */ (function ($, _) { window.Roadmap = window.Roadmap || {}; Roadmap.RoadmapEditorView = Backbone.View.extend({ className: 'roadmap-editor-container', events: { 'BarView.add': '_onAddBar', 'BarView.dragstart': '_onBarDragstart', 'BarView.dragstop': '_onBarDragstop', 'BarView.drop': '_onBarDropped', 'LaneView.drop': '_onBarDropped', 'Lane.delete': '_onDeleteLane', 'BarRowView.remove': '_onBarRowViewRemove', 'sortstart .roadmap-content': '_onSortStart', 'sortstop .roadmap-content': '_onSortStop', 'remove': '_onRemove' }, initialize: function () { _.bindAll(this, 'render'); this.listenTo(this.model.get('lanes'), 'add', function (laneModel) { var laneView = new Roadmap.LaneView({ model: laneModel, timelineView: this._timelineView, canDelete: true }); if (this._laneViews.length === 1) { this._laneViews[0].updateDeleteStatus(true); // when has more than 2 lanes, lanes can be delete } this._laneViews.push(laneView); this.$roadmapContent.append(laneView.render().$el); this._updateTimelineColumnHeight(); this._scrollToBottom(); }); this.listenTo(this.model.get('markers'), 'add', function (markerModel) { var markerView = new Roadmap.MarkerView({model: markerModel, roadmap: this}); this.$roadmapMarker.append(markerView.render().$el); this._markerViews.push(markerView); }); this.listenTo(this.model.get('timeline'), 'change', function () { if (this._isTimelineChanged()) { this._calculateMinWidthOfABar(); this._timelineView.update(); this._timelineColumnView.update(); this.$roadmapContent.empty(); _.each(this._laneViews, function (laneView) { laneView.remove(); }); this._laneViews = []; this._renderLanes(); this.$roadmapMarker.empty(); this._markerViews = []; this._renderMarkers(); this._updateDragArea(); } }); }, render: function () { this.$el.html(Confluence.Templates.Roadmap.roadmapEditor()); this._calculateMinWidthOfABar(); this._initVariables(); this._renderToolbar(); this._renderTimeline(); this._renderLanes(); this._renderMarkers(); this._renderTimelineColumn(); this._updateDragArea(); return this; }, _calculateMinWidthOfABar: function () { Roadmap.barMinWidth = this.model.get('timeline').get('displayOption') === Roadmap.TIMELINE_DISPLAY_OPTION.MONTH ? Roadmap.MONTH_BAR_MIN_WIDTH : Roadmap.WEEK_BAR_MIN_WIDTH; }, _initVariables: function () { this.$roadmapContainer = this.$el.find('#roadmap-container'); this.$roadmapTimeline = this.$roadmapContainer.find('.roadmap-frame'); this.$roadmapContent = this.$roadmapContainer.find('.roadmap-content'); this.$roadmapMarker = this.$roadmapContainer.find('.roadmap-marker'); this._timelineView = new Roadmap.TimelineView({model: this.model.get('timeline')}); this._timelineColumnView = new Roadmap.TimelineColumnView({model: this.model.get('timeline')}); this._laneViews = []; this._markerViews = []; }, _renderTimeline: function () { this.$roadmapTimeline.prepend(this._timelineView.render().$el); }, _renderTimelineColumn: function () { this._updateTimelineColumnHeight(); this.$roadmapTimeline.append(this._timelineColumnView.render().$el); }, _renderMarkers: function () { var me = this; this.model.get('markers').each(function (markerModel) { var markerView = new Roadmap.MarkerView({model: markerModel, roadmap: me}); me.$roadmapMarker.append(markerView.render().$el); me._markerViews.push(markerView); }); }, _renderLanes: function () { Confluence.Roadmap.ColorHelper.resetColorCounts(); var me = this; this._updateLaneWidth(); var canDelete = this.model.get('lanes').models.length > 1; // can not delete the last lane this.model.get('lanes').each(function (laneModel) { var laneView = new Roadmap.LaneView({ model: laneModel, timelineView: me._timelineView, canDelete: canDelete }); me._laneViews.push(laneView); me.$roadmapContent.append(laneView.render().$el); }); // Setup Lanes Re-ordering this._setupLaneReordering(); }, _onAddBar: function (event, barView) { this._updateTimelineColumnHeight(); var $barEl = barView.$el; if (!this._isInViewScreen($barEl)) { this._scrollToBar($barEl); } }, _renderToolbar: function () { var $dialogBody = $('#' + this.options.dialogId + ' .aui-dialog2-content'); $dialogBody.find('.roadmap-toolbar').remove(); var toolbarView = new Roadmap.ToolbarView({ model: this.model, timelineView: this._timelineView }); $dialogBody.prepend(toolbarView.render().$el); }, _getTimelineWidth: function () { return this.$roadmapTimeline.find('.roadmap-frame-title').width(); }, _getLaneHeight: function () { return this.$roadmapContent.height(); }, _updateLaneWidth: function () { this.$roadmapContent.width(this._getTimelineWidth() + Roadmap.LANE_TITLE_WIDTH); }, _scrollToBottom: function () { this.options.roadmapEditorPopup.scrollTop(this._getLaneHeight()); }, _isInViewScreen: function ($elem) { return $.inviewport($elem, {threshold: -200}); }, _scrollToBar: function ($bar) { this.options.roadmapEditorPopup.scrollTop($bar.parent().position().top); this.options.roadmapEditorPopup.scrollLeft(0); }, _onBarDropped: function () { this._updateTimelineColumnHeight(); }, _onDeleteLane: function (event, laneView) { this.model.get('lanes').remove(laneView.model); this._laneViews.splice(_.indexOf(this._laneViews, laneView), 1); laneView.remove(); this._updateTimelineColumnHeight(); if (this._laneViews.length === 1) { // update delete status for can not delete the last lane this._laneViews[0].updateDeleteStatus(false); } }, _onBarRowViewRemove: function () { this._updateTimelineColumnHeight(); }, _updateTimelineColumnHeight: function () { var laneHeight = this._getLaneHeight(); this._timelineColumnView.updateHeight(laneHeight); _.each(this._markerViews, function (markerView) { markerView.updateHeight(laneHeight); }); }, hideDialog: function () { $('#inline-dialog-roadmap-dialog, #inline-dialog-timeline-options').hide(); }, removeDialog: function () { $('#inline-dialog-roadmap-dialog, #inline-dialog-timeline-options').remove(); }, _onBarDragstart: function (e, ui) { var me = this; this.hideDialog(); this._updateDragArea(); this._barRowNewViewList = []; _.each(this._laneViews, function (laneView) { me._barRowNewViewList.push(laneView.addNewBarRow(ui.helper)); }); }, _updateDragArea: function () { // Create a drag-area that draggable element will be rendered to. var $dragZone = this.$roadmapContainer.find('.roadmap-drag-area'); $dragZone.css(this._timelineColumnView.getSizeAndPosition()); }, _onBarDragstop: function () { // Remove Roadmap.BarRowNewView _.each(_.flatten(this._barRowNewViewList), function (barRowNew) { barRowNew.remove(); }); delete this._barRowNewViewList; _.each(this._laneViews, function (laneView) { laneView.removeEmptyRow(); }); }, /* Lanes re-ordering */ _setupLaneReordering: function () { this.$roadmapContent.sortable({ axis: 'y', cursor: 'move', handle: '.roadmap-lane-title', opacity: 0.3, placeholder: 'roadmap-lane lane-sorting-placeholder', helper: function (e, el) { return $(el).clone().addClass('lane-sorting-hepler'); } }); }, _onSortStart: function (e, ui) { this.hideDialog(); // Hide the vertical line, we will show it up again in _onSortStop function // Reason for this is decrease the effort to update height for them. this._timelineColumnView.$el.hide(); // Format the placeholder ui.placeholder.css({ height: Math.min(ui.helper.height(), 100), width: ui.helper.width() }).html(Confluence.Templates.Roadmap.lane(Roadmap.TRANSPARENT_LANE)); // Set a specific width for roadmap-lane-content, because of limitation of display is table-cell. ui.helper.find('.roadmap-lane-content').css({ width: ui.helper.width() - (ui.helper.find('.roadmap-lane-title').outerWidth() + ui.helper.find('.roadmap-separate-content').outerWidth()) }); }, _onSortStop: function (e, ui) { // Re-show the timeline column which was hidden in _onSortStart this._timelineColumnView.$el.show(); // lookup for lane which is reordered var laneViewId = ui.item.attr('cid'); var laneView = _.find(this._laneViews, function (lane) { return lane.cid === laneViewId; }); var laneModel = laneView.model; var laneCollection = this.model.get('lanes'); // Remove from current collection laneCollection.remove(laneModel); // Insert model to new position laneCollection.models.splice(ui.item.index(), 0, laneModel); laneCollection._byId[laneModel.cid] = laneModel; }, _onRemove: function () { this.$roadmapTimeline.remove(); }, /* End lanes re-ordering */ _isMonthYearChanged: function () { var isDifferentMonthYear = function (date1, date2) { if (date1.getMonth() !== date2.getMonth() || date1.getYear() !== date2.getYear()) { return true; } return false; }; var timeline = this.model.get('timeline'); return isDifferentMonthYear(timeline._previousAttributes.startDate, timeline.attributes.startDate) || isDifferentMonthYear(timeline._previousAttributes.endDate, timeline.attributes.endDate); }, _isWeekChanged: function () { var isSameWeek = function (date1, date2) { var mDate1 = moment(date1); var mDate2 = moment(date2); return mDate1.get('year') === mDate2.get('year') && mDate1.isoWeek() === mDate2.isoWeek(); }; var timeline = this.model.get('timeline'); var oldStartDate = timeline._previousAttributes.startDate; var currentStartDate = timeline.attributes.startDate; var oldEndDate = timeline._previousAttributes.endDate; var currentEndDate = timeline.attributes.endDate; return !(isSameWeek(oldStartDate, currentStartDate) && isSameWeek(oldEndDate, currentEndDate)); }, _isTimelineChanged: function () { var timeline = this.model.get('timeline'); var isChanged = timeline.changed.displayOption; if (isChanged) { this.model.updateDurationUnit(timeline.get('displayOption')); } else { isChanged = timeline.get('displayOption') === Roadmap.TIMELINE_DISPLAY_OPTION.MONTH ? this._isMonthYearChanged() : this._isWeekChanged(); } return isChanged; }, resize: function () { this._updateLaneWidth(); this._updateTimelineColumnHeight(); this.$roadmapContent.css({ top: this.$roadmapTimeline.find('.roadmap-column-title:first').innerHeight() }); } }); })(AJS.$, window._); }catch(e){WRMCB(e)};