'use strict'; /** * Licensed Materials - Property of IBM * IBM Cognos Products: Storytelling * (C) Copyright IBM Corp. 2014, 2020 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ define(['baglass/core-client/js/core-client/ui/core/View', '../nls/StringResources', './TimelineSliderContentView', './TimelineHighlightIndicatorView', 'storytelling-ui/storytelling-ui.min', 'react', 'react-dom'], function (View, stringResources, Slider, TimelineIndicator, StorytellingUI, React, ReactDOM) { var PROVIDER_ID = 'PropertiesPane'; var TimelineSliderView = View.extend({ init: function init(options) { TimelineSliderView.inherited('init', this, arguments); this.id = options.id; this.model = options.model; this.label = options.label; this.scaleManager = options.scaleManager; this.timelineController = options.timelineController; this.glassContext = options.glassContext; this.dndManager = options.dndManager; this.dashboardApi = options.dashboardApi; this.services = options.services; this._dashboardState = this.dashboardApi.getFeature('DashboardState'); this._flyoutHolder = document.createElement('div'); this._flyoutHolder.classList.add('flyout-holder'); this.extraCssClassForHighlight = 'timelineHighlight'; this._timelineIndicators = []; this._highlightActModelListeners = []; }, render: function render() { this.el.id = 'timelineWidgetSlider' + this.id; this.el.classList.add('sliderContent'); this._renderDragSlider(); this._renderTimelineHighlightIndicators(); this._addDropZone(); this.scaleManager.on('scale:change', this.onScaleChanged, this); this.timelineController.on('slider:addHighlight', this.onAddTimelineHighlight, this); this.timelineController.on('slider:closeFlyouts', this._closeFlyouts, this); this.timelineController.on('slider:deselect', this.onHideSliderSelection, this); this.timelineController.on('slider:removeHighlight', this.onRemoveTimelineHighlight, this); this.timelineController.on('slider:select', this.onShowSliderSelection, this); this.timelineController.on('slider:showHighlightSummary', this.onShowHighlightSummary, this); }, remove: function remove() { if (this._dropZone) { this._dropZone.remove(); } this._removeActModelListeners(); this._removeTimelineIndicators(); if (this._rangeSlider) { this._rangeSlider.remove(); } this.scaleManager.off('scale:change', this.onScaleChanged, this); this.timelineController.off('slider:addHighlight', this.onAddTimelineHighlight, this); this.timelineController.off('slider:closeFlyouts', this._closeFlyouts, this); this.timelineController.off('slider:deselect', this.onHideSliderSelection, this); this.timelineController.off('slider:removeHighlight', this.onRemoveTimelineHighlight, this); this.timelineController.off('slider:select', this.onShowSliderSelection, this); this.timelineController.off('slider:showHighlightSummary', this.onShowHighlightSummary, this); TimelineSliderView.inherited('remove', this, arguments); }, _removeActModelListeners: function _removeActModelListeners() { this._highlightActModelListeners.forEach(function (listener) { listener.remove(); }); this._highlightActModelListeners = []; }, _removeTimelineIndicators: function _removeTimelineIndicators() { this._timelineIndicators.forEach(function (indicator) { indicator.remove(); }); this._timelineIndicators = []; }, onScaleChanged: function onScaleChanged() { this._timelineIndicators.forEach(function (indicator) { indicator.onScaleChange(); }); }, onAddTimelineHighlight: function onAddTimelineHighlight() { this._refreshTimelineHighlightIndicators(); }, onShowHighlightSummary: function onShowHighlightSummary(event) { var highlight = this._timelineIndicators.find(function (indicator) { return indicator.id === event.actModel.id; }); if (highlight) { highlight.launchHighlightSummaryDialog(); } }, _closeFlyouts: function _closeFlyouts(targetElement) { if (this._flyout) { ReactDOM.unmountComponentAtNode(this._flyoutHolder); this._flyout = null; this.el.removeChild(this._flyoutHolder); } this._timelineIndicators.forEach(function (indicator) { return indicator.closeFlyout(); }); // There is an event triggered in TimelineView that passes an object with a // widgetId and this method is the one listening on that event but we // don't seem to be using that widgetId. It is used in a few different places // though and now we need to check that the parameter (targetElement) is one // that has a "focus" method on it. UGH! if (targetElement && targetElement.setActive) { // A workaround using setActive in IE which will set focus without scrolling targetElement.setActive(); } else if (targetElement && targetElement.focus) { targetElement.focus(); } }, onRemoveTimelineHighlight: function onRemoveTimelineHighlight(event) { var highlightListener = this._highlightActModelListeners.find(function (listener) { return listener.id === event.actModel.id; }); if (highlightListener) { highlightListener.remove(); this._highlightActModelListeners = this._highlightActModelListeners.filter(function (listener) { return listener.id !== event.actModel.id; }); } var highlight = this._timelineIndicators.find(function (indicator) { return indicator.id === event.actModel.id; }); if (highlight) { highlight.remove(); this._timelineIndicators = this._timelineIndicators.filter(function (indicator) { return indicator.id !== event.actModel.id; }); } }, onShowSliderSelection: function onShowSliderSelection(event) { if (event.widgetId === this.id) { this.toggleSelected(true); var $timelineController = this.$el.parent('.timelineContent'); // FIXME: Reaching out of scope this.$el.toggleClass('bringToFront', $timelineController.scrollTop() === 0); } }, onHideSliderSelection: function onHideSliderSelection(event) { if (event.widgetId === this.id) { this.toggleSelected(false); this._closeFlyouts(); // Update the previously selected slider. this.$el.removeClass('bringToFront'); } }, setLabel: function setLabel(label) { this.label = label; this._rangeSlider.middleShortenTitle(this.label); }, getLabel: function getLabel() { return this.label; }, setScale: function setScale(scale) { var scaleUpdated = this.model.scale !== scale; this.model.scale = scale; this._rangeSlider.setScale(scale); // setScale can be called multiple times with the same value. Since // middleShortenString() is considered expensive, only call it if necessary. if (scaleUpdated) { this._rangeSlider.middleShortenTitle(this.label); } }, setValue: function setValue(value, preventNotify) { this._rangeSlider.setValue(value, preventNotify); this._timelineIndicators.forEach(function (indicator) { indicator.onSliderChange(); }); this._rangeSlider.middleShortenTitle(this.label); }, getValue: function getValue() { return this._rangeSlider.getValue(); }, getDragValue: function getDragValue() { return this._rangeSlider.dragValue; }, getDraggingElement: function getDraggingElement() { return this._rangeSlider.draggingElement; }, toggleSelected: function toggleSelected(toggle) { this._rangeSlider.toggleSelected(toggle); }, onScroll: function onScroll(event) { this._rangeSlider.onScroll(event); }, onSliderSelect: function onSliderSelect(event) { var _this = this; event.stopPropagation(); event.preventDefault(); this.timelineController.trigger('timeline:select', { widgetId: this.id, pageX: event && event.pageX ? event.pageX : 0, originalEvent: event }); this.timelineController.selectWidgetAndSlider(this.id).then(function () { // don't toggle flyout on drag end (which triggers a mouseup or touchend on mobile) if (!(event.type === 'mouseup' || event.type === 'touchend')) { _this._toggleFlyout(event); } }); }, addTimelineHighlight: function addTimelineHighlight(pageX) { // pageX is from the event that clicks on timeline slider var timer = this.scaleManager.convertPositionToTime(pageX - this.$el.offset().left); this.timelineController.addTimelineHighlight(this.id, timer); }, isHighlightSupported: function isHighlightSupported() { return this.timelineController.isHighlightSupported(this.id); }, _toggleFlyout: function _toggleFlyout(event) { if (this._flyout) { this._closeFlyouts(event.currentTarget); return; } var $timelineContent = this.$el.closest('.timelineContent'); var scrollBarOffset = $timelineContent[0].scrollLeft; var timelineOffset = this.$el.children().first()[0].offsetLeft; var triggerPosition = this.el.querySelector('.slider-selection').getBoundingClientRect().left; if (event.pageX) { triggerPosition = event.pageX; } var position = triggerPosition - this.el.getBoundingClientRect().left; this._flyoutHolder.style.left = (event.pageX ? position : Math.max(scrollBarOffset, timelineOffset)) + 'px'; this.$el.append(this._flyoutHolder); this._flyout = React.createElement(StorytellingUI.SliderFlyout, { isHighlightSupported: this.isHighlightSupported.bind(this), anchorElement: this._flyoutHolder, pageX: event.pageX || 0, closeFlyout: this._closeFlyouts.bind(this, event.currentTarget), openAnimationProperties: this.openAnimationProperties.bind(this), addTimelineHighlight: this.addTimelineHighlight.bind(this) }); ReactDOM.render(this._flyout, this._flyoutHolder); }, openAnimationProperties: function openAnimationProperties() { var state = this._dashboardState.getUiState(); if (!state.fullScreen) { this._dashboardState.setSelectionProperties(true); this._dashboardState.setSidePanelCurrentView(this._getProviderId()); this._dashboardState.setSidePanelOpen(true); } }, _getProviderId: function _getProviderId() { return PROVIDER_ID; }, onSliderWillChange: function onSliderWillChange() { this.timelineController.trigger('timeline:willChange', { widgetId: this.id, getDragValue: this.getDragValue.bind(this), getDraggingElement: this.getDraggingElement.bind(this) }); }, onSliderChange: function onSliderChange(event) { this._updateWidgetTimeline(this.id, event.value, event.payloadData); this._rangeSlider.middleShortenTitle(this.label); this._timelineIndicators.forEach(function (indicator) { indicator.onSliderChange(); }); this.timelineController.trigger('timeline:change', { widgetId: this.id }); }, onSliderDrop: function onSliderDrop(event) { this.timelineController.trigger('timeline:doneMoving', event); }, onSliderMoveUp: function onSliderMoveUp(event) { this.timelineController.trigger('timeline:movingUp', event); }, onSliderMoveDown: function onSliderMoveDown(event) { this.timelineController.trigger('timeline:movingDown', event); }, onSliderDragStarted: function onSliderDragStarted(event) { this.timelineController.trigger('timeline:sliderDragStarted', event); }, _addDropZone: function _addDropZone() { var _this2 = this; this._dropZone = this.dndManager.addDropTarget(this.$el[0], { accepts: function accepts(dragObject) { // we only accept the slider, not the 'handles' return dragObject.type === 'dragSliderContent'; }, onDragLeave: function onDragLeave(dragObject) { if (!dragObject || dragObject.type !== 'dragSliderContent' || !dragObject.data || !dragObject.data.slider) { return; } if (_this2._rangeSlider.id === dragObject.data.slider.id) { // us return; } if (!dragObject.lastPosition) { dragObject.lastPosition = dragObject.startPosition; } if (dragObject.position.y < dragObject.lastPosition.y) { _this2.timelineController.trigger('timeline:movingUp', { id: dragObject.data.slider.id, to: _this2.id }); } else { _this2.timelineController.trigger('timeline:movingDown', { id: dragObject.data.slider.id, to: _this2.id }); } dragObject.lastPosition = dragObject.position; } }); }, _renderDragSlider: function _renderDragSlider() { this._rangeSlider = new Slider({ id: this.id, el: this.$el, value: this.model.value, scale: this.model.scale, title: this.label, cssClassSelector: this.extraCssClassForHighlight, dndManager: this.dndManager, services: this.services, timelineController: this.timelineController }); this._rangeSlider.on('value:changed', this.onSliderChange.bind(this)); this._rangeSlider.on('value:willChange', this.onSliderWillChange.bind(this)); this._rangeSlider.on('dragSlider:select', this.onSliderSelect.bind(this)); this._rangeSlider.on('dragSlider:isDropped', this.onSliderDrop.bind(this)); this._rangeSlider.on('dragSlider:movingUp', this.onSliderMoveUp.bind(this)); this._rangeSlider.on('dragSlider:movingDown', this.onSliderMoveDown.bind(this)); this._rangeSlider.on('dragSlider:dragStarted', this.onSliderDragStarted.bind(this)); this._rangeSlider.render(); this._rangeSlider.middleShortenTitle(this.label); }, /* Set the time range info of the widgets in selected page.*/ _updateWidgetTimeline: function _updateWidgetTimeline(id, value, payloadData) { var defaultPixelsPerSecond = this.scaleManager.getScaleToPixelRatio(); this.timelineController.updateTimelineDuration(id, value[0] / defaultPixelsPerSecond * 1000, value[1] / defaultPixelsPerSecond * 1000, { payloadData: payloadData }); }, _renderTimelineHighlightIndicators: function _renderTimelineHighlightIndicators() { var _this3 = this; var episodeModel = this.timelineController.getTimelineEpisodeById(this.id); var highlightActModels = episodeModel.acts.filter(function (value) { return value.get('action') === 'highlight'; }); highlightActModels.sort(function (item1, item2) { return item1.get('timer') - item2.get('timer'); }); highlightActModels.forEach(function (highlightActModel) { _this3._renderTimelineHighlightIndicator(episodeModel, highlightActModel); }); episodeModel.acts.on('change:payload', this.onTimelineHighlightPayloadChange, this); }, _renderTimelineHighlightIndicator: function _renderTimelineHighlightIndicator(episodeModel, highlightActModel) { if (episodeModel.id === this.id) { // Rendering highlight indicators should be done within the TimelineContentSliderView (_rangeSlider) // instead of this class because the indicators are placed within a div that comes from _rangeSlider var highlightEl = document.createElement('div'); this._rangeSlider.$highlightsEl.append(highlightEl); var timelineIndicator = new TimelineIndicator({ el: highlightEl, widgetId: this.id, controller: this.timelineController, scaleManager: this.scaleManager, episodeModel: episodeModel, highlightAct: highlightActModel, extraCssClass: this.extraCssClassForHighlight, services: this.services, dashboardApi: this.dashboardApi }); timelineIndicator.render(); this._timelineIndicators.push(timelineIndicator); var _highlightActModel$on = highlightActModel.on('change:timer', this.onTimelineHighlightTimerChange, this), remove = _highlightActModel$on.remove; this._highlightActModelListeners.push({ id: highlightActModel.id, remove: remove }); } }, _refreshTimelineHighlightIndicators: function _refreshTimelineHighlightIndicators() { this._removeActModelListeners(); this._removeTimelineIndicators(); this._renderTimelineHighlightIndicators(); }, onTimelineHighlightTimerChange: function onTimelineHighlightTimerChange() { var reFocusHighlight = false; var activeElId = document.activeElement.id; if (document.activeElement.classList.contains('timelineHighlight')) { reFocusHighlight = true; } this._refreshTimelineHighlightIndicators(); if (reFocusHighlight) { document.getElementById(activeElId).focus(); } }, onTimelineHighlightPayloadChange: function onTimelineHighlightPayloadChange() { // one or more highlight changed.... this._timelineIndicators.forEach(function (indicator) { return indicator.onPayloadChange(); }); } }); return TimelineSliderView; }); //# sourceMappingURL=TimelineSliderView.js.map