'use strict'; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; /** * Licensed Materials - Property of IBM * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2013, 2020 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ define(['./PageCollectionView', 'jquery', '../../../../lib/@waca/core-client/js/core-client/utils/BidiUtil', '../../../../app/nls/StringResources', '../../../../lib/@waca/core-client/js/core-client/utils/dom-utils', '../../../../lib/@waca/core-client/js/core-client/utils/Deferred', '../../../../app/ui/dnd/DnDHelper', '../../../../app/ui/dialogs/GenericViewDialog', '../../../views/LayoutPickerView', '../../../../lib/@waca/core-client/js/core-client/utils/EventHelper'], function (BaseClass, $, BidiUtil, stringResources, utils, Deferred, DnDHelper, Dialog, TemplatePickerView) { var Tab = null; Tab = BaseClass.extend({ init: function init(options) { var _this = this; Tab.inherited('init', this, arguments); options = options || {}; this._getLabelId = this.consumeView._getLabelId.bind(this.consumeView); this.specializeConsumeView(['showView', 'renderContent', '_attachView', 'onAddClick', 'onReorder', '_handleKeydown', 'showToolbar', 'deleteView', 'updateViewLabel', 'editViewTitle']); this.services = options.services; this.config = options.config; this.layoutsPath = options.layoutsPath; this.templateListing = options.templateListing; this.whenIsReadyDfd = new Deferred(); this.backgroundChangeHandle = this.model.on('change:css', function () { return _this.consumeView.tabWidget.updateTheme(); }); this.dashboardApi = options.dashboardApi; this._attachedHandles = {}; this._icons = this.dashboardApi.getFeature('Icons'); }, renderContent: function renderContent() { var _this2 = this; return this.overridden.renderContent().then(function () { _this2.consumeView.tabWidget.setState({ addable: true, deleteable: _this2.allowTabDeletion(), draggable: true }); if (_this2.model.items && _this2.model.items.length) { _this2.model.items.forEach(function (item) { return _this2._attachView(item); }); } _this2._initializeDnd(); }); }, whenIsReady: function whenIsReady() { return this.whenIsReadyDfd.promise; }, destroy: function destroy() { // Remove the registered dropZonez if (this._tabStripDropZone) { this._tabStripDropZone.remove(); } if (this._tabDropHandler) { this._tabDropHandler.deregister(); this._tabDropHandler = null; } if (this.backgroundChangeHandle) { this.backgroundChangeHandle.remove(); } if (this.toolbar && this.toolbar.remove) { this.toolbar.remove(); } this.toolbar = null; this.model.items.forEach(this._detachView.bind(this)); this.consumeView.updateState({ addable: false, deleteable: false, draggable: false }); Tab.inherited('destroy', this, arguments); }, _initializeDnd: function _initializeDnd() { this._dndManager = this.dashboardApi.getFeature('DashboardDnd.internal'); this.setupGlobalDropZone(); this.whenIsReadyDfd.resolve(); }, _attachView: function _attachView(pageModel) { var _this3 = this; this.services.getSvcSync('TranslationService').registerView({ view: this, model: pageModel }); this._attachedHandles[pageModel.id] = pageModel.on('change:title', this.onTabLabelChange.bind(this, pageModel), this); this._attachedHandles[pageModel.id] = pageModel.on('change:tabTextColor', function (options) { return _this3.consumeView.tabWidget.updateTheme(options); }); this._attachedHandles[pageModel.id] = pageModel.on('change:tabSelectedLineColor', function (options) { return _this3.consumeView.tabWidget.updateTheme(options); }); this._attachedHandles[pageModel.id] = pageModel.on('change:tabBackgroundColor', function (options) { return _this3.consumeView.tabWidget.updateTheme(options); }); this._attachedHandles[pageModel.id] = pageModel.on('change:tabIconColor', function (options) { return _this3.consumeView.tabWidget.updateTheme(options); }); this._attachedHandles[pageModel.id] = pageModel.on('change:tabIcon', function (options) { return _this3.onTabIconChange(pageModel, options); }); }, _detachView: function _detachView(pageModel) { if (this._attachedHandles[pageModel.id]) { this._attachedHandles[pageModel.id].remove(); delete this._attachedHandles[pageModel.id]; } }, addTranslationIcon: function addTranslationIcon(multilingualAttributesInfo) { var pageModel = multilingualAttributesInfo && multilingualAttributesInfo[0].propertyParentModel; if (this.model.get('hideTab')) { return 0; } else { return this.consumeView.tabWidget.updateTranslationIcon(pageModel, true); } }, removeTranslationIcon: function removeTranslationIcon(multilingualAttributesInfo) { var pageModel = multilingualAttributesInfo && multilingualAttributesInfo[0].propertyParentModel; return this.consumeView.tabWidget.updateTranslationIcon(pageModel, false); }, _handleKeydown: function _handleKeydown(pageModel, evt, node) { var keyCode = evt.keyCode; if (this._shouldShowToolbar(evt, keyCode)) { this.showToolbar(pageModel, node); evt.preventDefault(); return false; //Signal to the browser that it should prevent the default behavior of opening the context menu } else { this.overridden._handleKeydown(pageModel, evt, node); } }, // Shift + F10 key - show contextual toolbar _shouldShowToolbar: function _shouldShowToolbar(evt, keyCode) { return evt.shiftKey && keyCode === 121; }, /** * Move the view to the location before the provided id. * @param pageModel * @param beforeId */ moveViewBefore: function moveViewBefore(pageModel, beforeId) { // Avoid a model update when it is not needed if (pageModel.id !== beforeId && pageModel.getNextSiblingId() !== beforeId) { pageModel.updateModel({ updateArray: [{ id: pageModel.id, parentId: pageModel.getParent().id, insertBefore: beforeId }] }); } }, showView: function showView(viewModel) { if (this.isToolbarShown) { this.hideToolbar(); } //call consume view's showView this.overridden.showView(viewModel); }, showToolbar: function showToolbar(viewModel, node) { if (!this.isToolbarShown) { this.isToolbarShown = true; this.toolbar.clearItems(); var items = this._toolbarItems(viewModel); this.toolbar.addItems(items); this.toolbar.setSelectionContext($(node)); this.toolbar.show(); } else { this.hideToolbar(); } }, hideToolbar: function hideToolbar() { this.isToolbarShown = false; return this.toolbar.hide(); }, _toolbarItems: function _toolbarItems(viewModel) { var items = []; /* * By UX design order of icons matters: * 1. edit * 2. duplicate * 3. delete (if more then one tab exists) * 4. change template */ items.push({ icon: this._icons.getIcon('edit').id, label: stringResources.get('toolbarActionEditTitle'), name: 'rename', type: 'Button', action: this.editViewTitle.bind(this, viewModel) }); items.push({ icon: this._icons.getIcon('dashboard-duplicate').id, label: stringResources.get('duplicate'), name: 'duplicate', type: 'Button', action: this.duplicateTab.bind(this, viewModel.id) }); if (this.config.changeTabTemplate !== 'disabled') { items.push({ icon: this._icons.getIcon('template').id, label: stringResources.get('changeTemplate'), name: 'changeTemplate', type: 'Button', disabled: viewModel.templateName === 'NoTemplate', action: this.selectTemplate.bind(this, viewModel.id) }); } return items; }, /** * Called when a new tab is added. * * @param n - tab content node * @param insertBefore - content node to insert before, null if we're creating a new tab, and a string when we're dragging tabs around * @param model - model of the page being added */ add: function add(layoutView, insertBefore) { var _this4 = this; var model = layoutView.model; var tabs = this.consumeView.tabWidget.state.tabs; var layoutIndex = void 0, isNew = true; for (var i = 0; i < tabs.length; i++) { if (this.consumeView._getModelIdFromPanel(tabs[i].props.id) === model.id) { isNew = false; layoutIndex = i; break; } } if (!isNew) { // This is a re-order. See if we need to update the state. if (!(insertBefore === null && layoutIndex === tabs.length - 1 || tabs[layoutIndex + 1] && this.consumeView._getModelIdFromPanel(tabs[layoutIndex + 1].props.id) === insertBefore)) { var updatedTabs = []; tabs.forEach(function (tab) { if (_this4.consumeView._getModelIdFromPanel(tab.props.id) === insertBefore) { updatedTabs.push(tabs[layoutIndex]); updatedTabs.push(tab); } else if (_this4.consumeView._getModelIdFromPanel(tab.props.id) !== model.id) { updatedTabs.push(tab); } }); if (insertBefore === null) { updatedTabs.push(tabs[layoutIndex]); } this.consumeView.tabWidget.setState({ tabs: updatedTabs }); } var $tabContent = this.$el.find('#' + this._getViewId(model)); $tabContent.append(layoutView.domNode); } else { var _$tabContent = $(this.htmlTemplate.replaceLayoutValues(this.htmlTemplate.getItemTemplate('tab', '', model), this.model)); _$tabContent.append(layoutView.domNode); this.$el.find('.tabPageHolder').append(_$tabContent); var _updatedTabs = []; var newTab = this.consumeView._createTabPanel(model, _$tabContent, this.consumeView._getColorProperties()); if (insertBefore) { tabs.forEach(function (tab) { if (_this4.consumeView._getModelIdFromPanel(tab.props.id) === insertBefore) { _updatedTabs.push(newTab); } _updatedTabs.push(tab); }); } else { _updatedTabs = tabs.slice(); _updatedTabs.push(newTab); } this.consumeView.tabWidget.setState({ tabs: _updatedTabs }); this.consumeView.canvas.selectContent([model.id]); // Attach the tab behavior (e.g. events) this.overridden._attachView(model); this._attachView(model); } if (this.consumeView.tabWidget.state.deleteable === false && this.allowTabDeletion()) { this.consumeView.tabWidget.setState({ deleteable: true }); } }, allowTabDeletion: function allowTabDeletion() { return this.model.items.length > 1; }, _getDefaultViewLabel: function _getDefaultViewLabel() { var tabLength = this.model.items.length; for (var i = 1; i < tabLength + 1; i++) { var isAvailable = true; for (var j = 0; j < tabLength; j++) { if (this.model.items[j].get('title') === stringResources.get('defaultTabTitle', { index: i })) { isAvailable = false; break; } } if (isAvailable) { return stringResources.get('defaultTabTitle', { index: i }); } } return stringResources.get('defaultTabTitle', { index: tabLength + 1 }); }, onAddClick: function onAddClick() { return this._invokeLifeCycleHandlers('tabs.onPressNew', { $el: this.$el }).then(function () { //default behavior goes in here. this._openTemplateSelectDialog(); //TODO this needs to be triggered via a lifecycle handler! }.bind(this)); }, onReorder: function onReorder(tabsList, newIndex, tabId) { var beforeId = null; if (newIndex + 1 < tabsList.length) { beforeId = this.consumeView._getModelIdFromPanel(tabsList[newIndex + 1].props.id); } var movedId = this.consumeView._getModelIdFromPanel(tabId); this.moveViewBefore(this.model.findModel(movedId), beforeId); this.consumeView.eventRouter.trigger('properties:refreshPane'); }, onTabLabelChange: function onTabLabelChange(pageModel) { this.consumeView.tabWidget.updateTabLabel(pageModel); var pageIndex = this.model.items.findIndex(function (item) { return item.id === pageModel.id; }); var propertyName = 'tabIndividualStylingLink' + pageIndex; var updatePayload = { propertyName: propertyName, subPropertyName: 'r_' + propertyName + '0', value: pageModel.get('title') }; this.consumeView.eventRouter.trigger('properties:setValue', updatePayload); this.consumeView.eventRouter.trigger('properties:setChildValue', { propertyName: 'title', value: pageModel.get('title'), contentId: pageModel.id }); }, onTabIconChange: function onTabIconChange(pageModel, options) { this.consumeView.tabWidget.updateTabIcon(pageModel); if (options && options.sender === 'UndoRedoController') { var content = this.consumeView.canvas.getContent(pageModel.id); this.consumeView.eventRouter.trigger('properties:refreshChild', { content: content }); this.consumeView.eventRouter.trigger('properties:refreshPane'); } }, setupGlobalDropZone: function setupGlobalDropZone() { var _this5 = this; if (this._tabStripDropZone) { this._tabStripDropZone.remove(); } this._tabStripDropZone = this._dndManager.addDropTarget($(this.consumeView.tabWidget.tabListNode), '[role=tab]', { accepts: function accepts(dragObject) { if (dragObject.type === 'widget') { return true; } return false; }, onDragEnter: function onDragEnter(dragObject, node) { var tabPanel = _this5.consumeView._getPanelFromNode(node); var hoverColor = tabPanel.props.hoverColor; $(node).css('background-color', hoverColor); }, onDragLeave: function onDragLeave(dragObject, node) { var tabPanel = _this5.consumeView._getPanelFromNode(node); var backgroundColor = tabPanel.props.backgroundColor; $(node).css('background-color', backgroundColor); }, onDrop: function onDrop(dragObject, node) { var tabPanel = _this5.consumeView._getPanelFromNode(node); if (dragObject.type === 'widget' && tabPanel) { var id = _this5.consumeView._getModelIdFromPanel(tabPanel.props.id); DnDHelper.handleWidgetDrop(_this5.consumeView.canvas, id, dragObject); } }, info: function info(node) { var tabPanel = _this5.consumeView._getPanelFromNode(node); if (tabPanel) { return { containerId: _this5.consumeView._getModelIdFromPanel(tabPanel.props.id) }; } return {}; }, type: 'dropOnTab' }); if (!this._tabDropHandler) { this._tabDropHandler = this._dndManager.registerDropHandler({ accepts: function accepts(dragPayload, dropPayload) { return dragPayload.type.match(/content\..*/) && dropPayload.type === 'dropOnTab'; }, onDrop: function onDrop(dragPayload, dropPayload) { if (dropPayload.info.containerId) { var content = _extends({}, dragPayload.data, { containerId: dropPayload.info.containerId }); _this5.consumeView.canvas.addContent(content); } } }); } }, updateViewLabel: function updateViewLabel(pageModel, sText) { var content = this.consumeView.canvas.getContent(pageModel.id); content.setPropertyValue('title', sText); }, duplicateTab: function duplicateTab(sViewId) { this.model.boardModel.duplicateLayout(sViewId); }, deleteView: function deleteView(sViewId) { this.consumeView.canvas.removeContent(sViewId); this.services.getSvcSync('TranslationService').deregisterView(sViewId); }, selectTemplate: function selectTemplate(sViewId) { this._openTemplateSelectDialog(sViewId, true); }, /** * Private method that creates the template selection dialog options * It gets the excluded tab templates list from the perspective collection and adds the default exclusion NoTemplate to the list * Returns template selection dialog options */ _templateSelectDialogViewOptions: function _templateSelectDialogViewOptions() { var excludedTabTemplates = this.dashboardApi.getCanvas().getPropertyValue('excludedTemplates'); excludedTabTemplates.push('NoTemplate'); var dialogElement = document.createElement('div'); dialogElement.classList.add('templatePickerDialog'); return { el: dialogElement, templateListing: this.templateListing, layoutsPath: this.layoutsPath, disableHeaderSection: true, action: function action() {}, // Freeform no longer is diplayed as an template option - replaced by the 'absolute' dashboard property excludeTemplates: excludedTabTemplates }; }, /** * @param viewId string a model id for the view (of the tab) to update * @param forEdit boolean true if opening the template select dialog for editing; undefined/false for new */ _openTemplateSelectDialog: function _openTemplateSelectDialog(viewId, forEdit) { var _this6 = this; var templateSelectDialog = void 0; var templateView = void 0; var action = void 0; var viewOptions = this._templateSelectDialogViewOptions(); if (!forEdit) { action = function action(_ref) { var layout = _ref.layout; _this6._addBoardLayout(layout); _this6._setDefaultLayoutPositioning(); _this6.lastSelectedTemplate = layout.templateName; templateSelectDialog.hide(); }; } else if (forEdit === true) { /* * When we are editing we need to use a slightly different action */ action = function action(_ref2) { var layout = _ref2.layout; _this6._updateTemplateDropZones(viewId, layout); _this6.lastSelectedTemplate = layout.templateName; templateSelectDialog.hide(); }; } viewOptions.action = function () { return templateView.getSelectedLayoutSpec().then(action); }; templateSelectDialog = new Dialog({ title: stringResources.get('selectTemplateLabel'), viewClass: TemplatePickerView, viewOptions: viewOptions, okCallback: viewOptions.action, buttons: [{ text: stringResources.get('dlg_create'), handler: viewOptions.action, type: 'primary' }, 'cancel'], showCloseX: true, width: '850px' }); templateView = templateSelectDialog.view; templateView.setNavigationTemplate('tab'); var selectedTemplate = this.lastSelectedTemplate || this.model.items.length > 0 && this.model.items[0].templateName || 'NoTemplate'; templateView.selectLayout(selectedTemplate); templateSelectDialog.open(); }, _setDefaultLayoutPositioning: function _setDefaultLayoutPositioning() { var defaultLayoutPositioning = this.model.getValueFromSelfOrParent('layoutPositioning') || 'relative'; var layouts = this.model.findDescendantsWithType('genericPage'); for (var _iterator = layouts, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) { var _ref3; if (_isArray) { if (_i >= _iterator.length) break; _ref3 = _iterator[_i++]; } else { _i = _iterator.next(); if (_i.done) break; _ref3 = _i.value; } var layout = _ref3; layout.layoutPositioning = defaultLayoutPositioning; } }, editViewTitle: function editViewTitle(viewModel) { var _this7 = this; this.hideToolbar().then(function () { _this7.consumeView.tabWidget.editTabLabel(true, viewModel); }); }, _addBoardLayout: function _addBoardLayout(layout) { layout = layout || { type: 'absolute' }; layout.title = this._getDefaultViewLabel(); layout.localizedProps = ['title']; var content = { spec: layout, containerId: this.model.id }; this.consumeView.canvas.addContent(content); }, /** * Private method to handle updating the drop zones in dashboards * After the user selects a template we update the layout drop zones * * @param viewId string The model id of the dashboard tab the user is updating * @param layout object The user selected layout to update/change the template to */ _updateTemplateDropZones: function _updateTemplateDropZones(viewId, layout) { this.model.boardModel.updateLayoutDropZones({ id: viewId, model: layout }); }, /** * Called when a view is removed * * @param node */ removeChild: function removeChild(layoutView) { var _this8 = this; if (!layoutView) { return; } // detach model event listener added by the current parent layoutView.model.off('change:title'); var model = layoutView.model; var tabs = this.consumeView.tabWidget.state.tabs; var isPresent = false; var updatedTabs = [], index = void 0; tabs.forEach(function (tab, i) { if (_this8.consumeView._getModelIdFromPanel(tab.props.id) === model.id) { isPresent = true; index = i; } else { updatedTabs.push(tab); } }); if (isPresent) { var stateUpdate = { tabs: updatedTabs }; if (this.consumeView._getViewId(model) === this.consumeView._currentViewId) { //We are deleting the selected tab. We need to select a new one. var selectedIndex = Math.max(index - 1, 0); stateUpdate.selectedTab = this.consumeView._getPanelId(this.model.items[selectedIndex].id); } this.consumeView.tabWidget.setState(stateUpdate); } //Remove the dom node var parentSelector = '#' + layoutView.domNode.parentNode.id; $(parentSelector).remove(); Tab.inherited('removeChild', this, arguments); if (this.consumeView.tabWidget.state.deleteable === true && !this.allowTabDeletion()) { this.consumeView.tabWidget.setState({ deleteable: false }); } }, _invokeLifeCycleHandlers: function _invokeLifeCycleHandlers(name, payload) { return this.services.getSvc('.LifeCycleManager').then(function (LifeCycleManager) { return LifeCycleManager.invokeLifeCycleHandlers(name, payload); }); } }); return Tab; }); //# sourceMappingURL=Tab.js.map