123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029 |
- 'use strict';
- var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; };
- /**
- * Licensed Materials - Property of IBM
- * IBM Cognos Products: dashboard
- * (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(['../../lib/@waca/core-client/js/core-client/ui/core/Class', '../../view/features/content/contentViewDom/api/impl/ContentViewDomImpl', 'underscore', 'jquery', '../../app/util/EventChainLocal', './LayoutHelper', '../../lib/@waca/dashboard-common/dist/core/APIFactory', '../../api/deprecated/CanvasAPI', '../../canvas/DeprecatedCanvas', './authoring/interaction/Controller', './authoring/interaction/strategy/Common', '../../lib/@waca/core-client/js/core-client/utils/Deferred', '../../lib/@waca/core-client/js/core-client/utils/ClassFactory'], function (Class, ContentViewDomImpl, _, $, EventChainLocal, LayoutHelper, APIFactory, DeprecatedCanvasAPI, DeprecatedCanvas, Controller, CommonInteraction, Deferred, ClassFactory) {
- var LayoutController = null; // declaration
- LayoutController = Class.extend([], {
- init: function init(options) {
- LayoutController.inherited('init', this, arguments);
- this.contentFeatureLoader = options.contentFeatureLoader;
- //TODO - to be remove after refactoring
- this.services = options.services;
- this.appSettings = options.appSettings || {};
- if (this.appSettings.options && this.appSettings.options.config) {
- this.config = this.appSettings.options.config;
- } else {
- this.config = {};
- }
- // TODO - end
- this.dashboardApi = options.dashboardApi;
- this.canvas = options.canvas;
- this.glassContext = options.glassContext;
- this.transaction = this.dashboardApi.getFeature('Transaction');
- this.contentTypeRegistry = this.dashboardApi.getFeature('ContentTypeRegistry');
- this.isAuthoring = this.dashboardApi.getMode() === 'authoring';
- this.id = _.uniqueId('layoutController');
- this.$el = options.$el;
- this.viewsMap = {};
- this.boardModel = options.boardModel;
- this.boardModuleFactory = options.boardModuleFactory;
- this.interactionControllerDfd = new Deferred();
- this.widgetLoader = options.widgetLoader;
- this.canvasController = options.canvasController;
- this.logger = this.dashboardApi.getGlassCoreSvc('.Logger');
- this.colorsService = this.dashboardApi.getFeature('Colors');
- if (this.colorsService) {
- this.colorsService.on('theme:changed', this.onThemeChange, this);
- this.colorsService.on('colorSet:changed', this.onColorSetChanged, this);
- }
- this.topLayoutModel = this.boardModel.layout;
- this.topLayoutModel.on('change:layoutPositioning', this._onLayoutPositioning, this);
- this._setupViewModules(options.layoutExtensions || {});
- this.canvasNotifier = options.canvasNotifier;
- this.interactionController = null;
- this.eventRouter = options.eventRouter;
- if (this.eventRouter) {
- this.eventRouter.on('canvas:selectWidget', this.selectWidget, this);
- this.eventRouter.on('canvas:deselectWidget', this.deselectWidget, this);
- this.eventRouter.on('scene:select', this.deselectAllWidgets, this);
- this.eventRouter.on('scene:next', this.deselectAllWidgets, this);
- this.eventRouter.on('scene:previous', this.deselectAllWidgets, this);
- }
- this.gatewayUrl = options.gatewayUrl;
- this.cdnUrl = options.cdnUrl;
- this._init();
- // Create the deprecated canvas
- // This is the canvas implementation for all the deprecated APIs
- // It is is created in here because the deprecated APIs depend on the layout controller and the layout and widget views
- // The non deprecated canvas API is created earlier in the boardLoader.
- this.deprecatedCanvas = new DeprecatedCanvas(this.dashboardApi, this.boardModel, this.canvasController, this, this.widgetLoader);
- },
- initialize: function initialize() {
- return this.pageReady;
- },
- getDeprecatedCanvas: function getDeprecatedCanvas() {
- // Merge the public canvas api with the deprecated one
- // Eventually , the layout controller will stop creating the deprecated one onces all deprecated method are no longer used
- if (!this.mergedCanvasAPI) {
- this.mergedCanvasAPI = _.extend(this.deprecatedCanvas.getAPI(), this.canvas);
- }
- return this.mergedCanvasAPI;
- },
- _setupViewModules: function _setupViewModules(layoutExtensions) {
- this.consumeViews = layoutExtensions.consumeViews || {};
- this.authoringViews = layoutExtensions.authoringViews || {};
- },
- /** If the layout has 'subviews' (ie. tabs or scenes), return the id of the current one. */
- getCurrentSubViewId: function getCurrentSubViewId() {
- var topView = this.getView(this.topLayoutModel.id).view;
- return topView.getSelectedSubViewId();
- },
- /** If the layout has 'subviews' (ie. tabs or scenes), return the title of the current one. */
- getCurrentSubViewTitle: function getCurrentSubViewTitle() {
- var topView = this.getView(this.topLayoutModel.id).view;
- return topView.getSelectedSubViewTitle();
- },
- _animationHelper: function _animationHelper(el, property, value, duration) {
- return new Promise(function (resolve) {
- var transitionEndCallback = function transitionEndCallback() {
- el.style.transition = 'none';
- el.removeEventListener('transitionend', transitionEndCallback);
- resolve();
- };
- el.addEventListener('transitionend', transitionEndCallback);
- el.style.transition = property + ' ' + duration + 'ms';
- el.style[property] = value;
- // fail safe
- Promise.delay(duration + 100).then(transitionEndCallback);
- });
- },
- _init: function _init() {
- this._interactionControllerCreationPromise = this._createInteractionController().then(function () {
- var topView = this._getTopViewElement()[0];
- if (topView) {
- $(topView).toggleClass('authoringMode', this.isAuthoring);
- }
- }.bind(this));
- $(window).on('resize.layoutController' + this.id, this.onResize.bind(this));
- // set global right-click context menu suppression
- this.fnOnContextMenu = this.onContextMenu.bind(this);
- window.oncontextmenu = this.fnOnContextMenu;
- },
- createLayoutModules: function createLayoutModules() {
- var _this = this;
- this.pageReady = Promise.all([this._interactionControllerCreationPromise, this.createLayoutModule(this.topLayoutModel.id).then(function (layout) {
- if (layout) {
- return layout.renderContent();
- }
- })]);
- // Mark the page when the render is complete for the top layout and all widget underneath it.
- this.onPageRenderComplete = this.whenPageRenderComplete();
- this.onPageRenderComplete.then(function () {
- var topLayoutView = _this.getTopLayoutView();
- if (topLayoutView) {
- topLayoutView.$el.attr('data-render', 'renderComplete');
- }
- });
- },
- _getInteractionControllerInteractionModules: function _getInteractionControllerInteractionModules() {
- var paths = void 0;
- if (this.isAuthoring && !this.isEventGroupMode) {
- paths = ['dashboard-core/js/dashboard/layout/authoring/interaction/strategy/Authoring'];
- } else {
- paths = [];
- }
- return Promise.all(paths.map(function (path) {
- return ClassFactory.loadModule(path);
- }));
- },
- _shouldEnableInteractions: function _shouldEnableInteractions() {
- return !(this.dashboardApi.getAppConfig('enableInteractions') === false);
- },
- _createInteractionController: function _createInteractionController() {
- var _this2 = this;
- if (!this._shouldEnableInteractions() || this.interactionController) {
- return Promise.resolve();
- }
- return this._loadInteractionControllerConfig().then(function (selectionOptions) {
- var interactionController = new Controller({
- // TODO - to be removed after refactoring
- services: _this2.services,
- glassContext: _this2.glassContext,
- appSettings: _this2.appSettings,
- // TODO - end to be removed
- dashboardAPI: _this2.dashboardApi,
- toolbarConfig: _this2.dashboardApi.getAppConfig('toolbar'),
- transaction: _this2.transaction,
- canvas: _this2.canvas,
- boardModel: _this2.boardModel,
- layoutController: _this2,
- eventRouter: _this2.eventRouter,
- $el: _this2.$el,
- gatewayUrl: _this2.gatewayUrl,
- cdnUrl: _this2.cdnUrl,
- selectionOptions: selectionOptions
- });
- // TODO temporary code to register interaction controller needed by the widget action features, e.g. GroupAction
- _this2.dashboardApi.getFeature('internal').registerDashboardSvc('InteractionController.internal', interactionController);
- _this2.defaultInteractions = [new CommonInteraction(_this2.logger, _this2.dashboardApi)];
- _this2._setInteractionController(interactionController);
- return _this2._updateInteractionControllerInteractions();
- });
- },
- _setInteractionController: function _setInteractionController(controller) {
- this.interactionController = controller;
- this.interactionControllerDfd.resolve(controller);
- },
- getInteractionController: function getInteractionController() {
- return this.interactionControllerDfd.promise;
- },
- _loadInteractionControllerConfig: function _loadInteractionControllerConfig() {
- var _ref = this.dashboardApi.getAppConfig('selection') || {},
- deselectionSelector = _ref.deselectionSelector;
- if (deselectionSelector) {
- return new Promise(function (resolve, reject) {
- require([deselectionSelector], resolve, reject);
- }).then(function (module) {
- return {
- deselectionSelector: module
- };
- });
- }
- return Promise.resolve();
- },
- /**
- * Set the interaction controller strategy (authoring, consumption, event group).
- *
- * @return {Promise} Promise to be resolved when the strategy has been set
- */
- _updateInteractionControllerInteractions: function _updateInteractionControllerInteractions() {
- var _this3 = this;
- if (!this.interactionController) {
- return Promise.resolve();
- }
- return this._getInteractionControllerInteractionModules().then(function (Interactions) {
- var interactions = Interactions.map(function (Interaction) {
- return new Interaction(_this3.logger);
- });
- var allInteractions = _this3.defaultInteractions.concat(interactions);
- return _this3.interactionController.applyInteractions(allInteractions).then(function () {
- _this3.dashboardApi.getFeature('.LifeCycleManager').invokeLifeCycleHandlers('dashboard.layout.interactions.ready');
- });
- });
- },
- /**
- * Moves to consume mode
- *
- * Removes authoring functionality that was added to the all consume views.
- * Views associated with static widgets remain (they are not deleted)
- */
- changeToConsumeMode: function changeToConsumeMode() {
- var _this4 = this;
- this.isAuthoring = false;
- this.isEventGroupMode = false;
- return this._updateInteractionControllerInteractions().then(function () {
- _this4.removeAuthorModeFromLayout(_this4.topLayoutModel.id);
- _this4._getTopViewElement().removeClass('authoringMode').removeClass('eventGroupMode');
- });
- },
- /**
- * Removes author behavior to specified view
- *
- * @param id - layout identifier
- */
- removeAuthorModeFromLayout: function removeAuthorModeFromLayout(id) {
- var layoutModel = this.topLayoutModel.findModel(id);
- var view = $('#' + layoutModel.id, this.$el)[0];
- if (view && view._layout && view._layout.authorHelper) {
- view._layout.authorHelper.destroy();
- view._layout.authorHelper = undefined;
- if (view._layout.authorViewManager) {
- view._layout.authorViewManager.destroy();
- view._layout.authorViewManager = undefined;
- }
- }
- if (layoutModel.items) {
- for (var i = 0, iLen = layoutModel.items.length; i < iLen; i++) {
- this.removeAuthorModeFromLayout(layoutModel.items[i].id);
- }
- }
- },
- /**
- * Attaches author behavior
- *
- * @param options - {canvasNotifier: notifier obj}
- * @return promise to indicate when move to authoring is complete
- */
- changeToAuthorMode: function changeToAuthorMode(options) {
- var _this5 = this;
- this.isAuthoring = true;
- this.isEventGroupMode = false;
- this.canvasNotifier = options.canvasNotifier;
- //start with top layout
- return this.addAuthorModetoLayout(this.topLayoutModel.id, null).then(function () {
- _this5._getTopViewElement().addClass('authoringMode').removeClass('eventGroupMode');
- // initialize interaction controller strategy
- return _this5._updateInteractionControllerInteractions();
- });
- },
- changeToEventGroupMode: function changeToEventGroupMode() {
- var _this6 = this;
- this.isAuthoring = true;
- this.isEventGroupMode = true;
- return this._updateInteractionControllerInteractions().then(function () {
- _this6.removeAuthorModeFromLayout(_this6.topLayoutModel.id);
- _this6._getTopViewElement().removeClass('authoringMode').addClass('eventGroupMode');
- });
- },
- _getTopViewElement: function _getTopViewElement() {
- return this.$el.find('#' + this.topLayoutModel.id);
- },
- /**
- * Attaches author behavior to specified view
- *
- * @param id - layout identifier
- * @param parentLayout - parent view for layout being moved to author
- * @return promise to indicate when move to authoring is complete
- */
- addAuthorModetoLayout: function addAuthorModetoLayout(id, parentLayout) {
- var _this7 = this;
- var layoutModel = this.topLayoutModel.findModel(id);
- var node = $('#' + this.modelIdToNodeId(id), this.$el)[0];
- var pageLayoutView = node && node._layout;
- if (!pageLayoutView) {
- // the layout view does not exist. This is the case for static widget and layouts like group layout.
- // Create layout module will take care of create the layout view and the author helper.
- return this.createLayoutModule(id, parentLayout).then(function (layout) {
- return layout.renderContent();
- });
- }
- if (pageLayoutView.authorHelper) {
- // Authoring has already been enabled for this view.
- return Promise.resolve();
- }
- var options = {
- //TODO - remove after refactoring
- services: this.services,
- config: this.config,
- appSettings: this.appSettings,
- // TODO - end remove
- canvas: this.canvas,
- dashboardApi: this.dashboardApi,
- model: layoutModel,
- parentLayout: parentLayout,
- layoutController: this,
- canvasNotifier: this.canvasNotifier,
- consumeView: pageLayoutView,
- widgetChromeEventRouter: pageLayoutView.widgetChromeEventRouter,
- eventRouter: this.eventRouter
- };
- var modules = this._getLayoutModule(layoutModel, options);
- return ClassFactory.loadModule(modules.sAuthorHelper).then(function (PageLayoutAuthor) {
- // The authoring view will set the authorHelper reference of the consumeView to itself
- new PageLayoutAuthor(options);
- pageLayoutView.renderContent();
- //process children layouts
- var layoutModels = layoutModel.items;
- if (layoutModels && !pageLayoutView.preventAuthoringForChildren) {
- var promises = [];
- for (var i = 0, iLen = layoutModels.length; i < iLen; i++) {
- promises.push(_this7.addAuthorModetoLayout(layoutModels[i].id, pageLayoutView));
- }
- return Promise.all(promises);
- }
- });
- },
- getView: function getView(modelId) {
- return this.viewsMap[modelId];
- },
- markViewAsReady: function markViewAsReady(view) {
- if (this.viewsMap[view.id]) {
- this.viewsMap[view.id].viewReadyDeferred.resolve(view);
- }
- },
- /**
- * Create an instance of the layout module
- *
- * @param {string} pageId - layout page id
- * @param {View} parentLayout - parent view for layout being moved to author
- * @param {any} [additionalWidgetData] - data to be passed to the widget when the layout is created.
- *
- * @return {Promise} Promise to indicate when the creation is complete
- */
- createLayoutModule: function createLayoutModule(pageId, parentLayout, additionalWidgetData) {
- var existingView = this.viewsMap[pageId] && this.viewsMap[pageId].view;
- if (existingView) {
- /* No need to create the view. We have an existing view associated with the layout id that is being created.
- This might happen after the following scenario:
- - Create layout model A
- - Create layout model B
- - Move layout model A to be child of B.
- The view creation is asynchronous. This means that the process of the creation of A & B will start
- but the move operation will happen before the view are created so the changes will not be reflected in the views.
- so we end up with creating the view A and the view B with another instance of View A.
- The scenario that will cause this is the following:
- - group 2 objects.
- - delete 1 of the grouped objects.
- - This will delete the object and remove the group
- - undo the change.
- */
- var _promise = this.viewsMap[pageId].viewReady;
- _promise.then(function () {
- var nodeId = this.modelIdToNodeId(pageId);
- this.viewsMap[pageId].view.parentLayout = parentLayout;
- $(parentLayout.domNode).find('#' + nodeId).replaceWith(this.viewsMap[pageId].view.domNode);
- }.bind(this));
- return _promise;
- }
- var deferred = new Deferred();
- var page = this.topLayoutModel.findModel(pageId);
- var options = {
- // TODO - remove after refactoring
- services: this.services,
- config: this.config,
- appSettings: this.appSettings,
- // TODO - end remove
- canvas: this.canvas,
- content: this.canvas.getContent(pageId),
- dashboardApi: this.dashboardApi,
- eventRouter: this.eventRouter,
- model: page,
- layoutController: this,
- canvasNotifier: this.canvasNotifier,
- parentLayout: parentLayout,
- additionalWidgetData: additionalWidgetData,
- contentFeatureLoader: this.contentFeatureLoader
- };
- var layoutModules = this._getLayoutModule(page, options);
- var sPageLayout = layoutModules.sPageLayout;
- var sAuthorHelper = layoutModules.sAuthorHelper;
- this.viewsMap[pageId] = {
- viewReadyDeferred: deferred,
- viewReady: deferred.promise
- };
- var promise = void 0;
- if (sPageLayout) {
- var modules = ['dashboard-core/js/app/EventRouter'];
- if (sAuthorHelper) {
- modules.push(sAuthorHelper);
- }
- var pageLayout = void 0;
- if ((typeof sPageLayout === 'undefined' ? 'undefined' : _typeof(sPageLayout)) === 'object') {
- pageLayout = sPageLayout;
- } else {
- pageLayout = {
- path: sPageLayout,
- type: this.boardModuleFactory.getDefaultModuleType()
- };
- }
- promise = Promise.all([this.loadLayout(pageLayout), Promise.all(modules.map(function (module) {
- return ClassFactory.loadModule(module);
- }))]).then(function (Modules) {
- // update the parent layout in the options
- // there is a case where by the time we load the module, the parent has changed
- // Today, this is the case of undo a delete of an object that belongs to a group.
- // the operation will create the object with the page as a parent, then move it to the group object
- var parentModel = options.model.getParent();
- if (parentModel) {
- options.parentLayout = this.getLayoutView(parentModel.id);
- }
- var PageLayout = Modules[0];
- var EventRouter = Modules[1][0];
- var AuthorHelper = Modules[1][1];
- if (page.type === 'widget' || this.contentTypeRegistry.isTypeRegistered(page.type)) {
- options.widgetChromeEventRouter = new EventRouter();
- }
- var pageLayout = new PageLayout(options);
- if (AuthorHelper) {
- options.consumeView = pageLayout;
- // The authoring view will set the authorHelper reference of the consumeView to itself
- new AuthorHelper(options);
- }
- this.viewsMap[pageId].view = pageLayout;
- return pageLayout;
- }.bind(this));
- } else {
- promise = Promise.resolve();
- }
- return promise;
- },
- loadLayout: function loadLayout(module) {
- return this.boardModuleFactory.make(module.type || this.boardModuleFactory.getDefaultModuleType()).then(function (boardModule) {
- return boardModule.load(module).then(function (moduleInstance) {
- return moduleInstance.module;
- });
- });
- },
- removeView: function removeView(view) {
- if (this.viewsMap) {
- delete this.viewsMap[view.model.id];
- }
- },
- _getLayoutModule: function _getLayoutModule(layoutSpec, options) {
- var sPageLayout = void 0;
- var sPageLayoutAuthor = void 0;
- var modules = null;
- if (layoutSpec.type === 'widget' || layoutSpec.type === 'appwidget') {
- modules = this._getWidgetLayoutModule(layoutSpec, options);
- } else {
- sPageLayout = this.consumeViews[layoutSpec.type];
- if (!sPageLayout) {
- // layout views like group do not have consumption views.
- // Use the base view for them in authoring mode
- sPageLayout = 'dashboard-core/js/dashboard/layout/views/LayoutBaseView';
- }
- // else {
- // TODO: what do we do if we don't have a page layout?
- // }
- sPageLayoutAuthor = this.isAuthoring ? this.authoringViews[layoutSpec.type] || 'dashboard-core/js/dashboard/layout/authoring/views/LayoutBaseView' : undefined;
- modules = {
- sPageLayout: sPageLayout,
- sAuthorHelper: sPageLayoutAuthor
- };
- }
- return modules;
- },
- _getWidgetLayoutModule: function _getWidgetLayoutModule(layoutSpec, options) {
- var widgetModel = this.boardModel.getWidgetModel(layoutSpec.id);
- options.widgetModel = widgetModel;
- var type = widgetModel && widgetModel.type;
- options.widgetRegistry = this.widgetLoader.widgetRegistry[type];
- var sPageLayout = options.widgetRegistry && options.widgetRegistry.layoutConsumeView;
- var sPageLayoutAuthor = null;
- if (this.isAuthoring) {
- if (!sPageLayout) {
- //static widgets don't have a view associated in consume mode
- //use base widget view for them
- sPageLayout = 'dashboard-core/js/dashboard/layout/views/Widget';
- }
- if (options.widgetRegistry) {
- sPageLayoutAuthor = options.widgetRegistry.layoutAuthoringView;
- }
- }
- return {
- sPageLayout: sPageLayout,
- sAuthorHelper: sPageLayoutAuthor
- };
- },
- onThemeChange: function onThemeChange(payload) {
- if (payload.value !== payload.prevValue) {
- this.onResize({ reRender: true });
- }
- this.eventRouter.trigger('properties:refreshPane', {
- focusSelector: '.dropDowntheme'
- });
- },
- _onLayoutPositioning: function _onLayoutPositioning(payload) {
- if (payload.sender === 'UndoRedoController') {
- this.eventRouter.trigger('properties:refreshPane');
- } else {
- var layoutModels = this.topLayoutModel.findDescendantsWithType('genericPage');
- for (var _iterator = layoutModels, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
- var _ref2;
- if (_isArray) {
- if (_i >= _iterator.length) break;
- _ref2 = _iterator[_i++];
- } else {
- _i = _iterator.next();
- if (_i.done) break;
- _ref2 = _i.value;
- }
- var layoutModel = _ref2;
- layoutModel.set({
- layoutPositioning: payload.value
- }, {
- payloadData: payload.data,
- sender: this.id
- });
- }
- }
- },
- onColorSetChanged: function onColorSetChanged() {
- this.colorsService.makeSureColorIsValidInModel({
- model: this.topLayoutModel,
- propertyName: 'css',
- offset: 2,
- valuePrefix: 'fill-'
- });
- this.colorsService.makeSureColorIsValidInModel({
- model: this.topLayoutModel,
- propertyName: 'fillColor',
- offset: 2
- });
- // Don't use the same offset as the fillColor or our tab text color will end up being the same color as the background
- this.colorsService.makeSureColorIsValidInModel({
- model: this.topLayoutModel,
- propertyName: 'tabTextColor',
- offset: 1
- });
- this.colorsService.makeSureColorIsValidInModel({
- model: this.topLayoutModel,
- propertyName: 'tabSelectedLineColor',
- offset: 1
- });
- this.colorsService.makeSureColorIsValidInModel({
- model: this.topLayoutModel,
- propertyName: 'tabBackgroundColor',
- offset: 1
- });
- },
- onResize: function onResize(renderOptions) {
- if (this.$el.is(':visible')) {
- // We only resize if the view is visible.
- var topLayoutView = this.getTopLayoutView();
- if (topLayoutView && topLayoutView.onResize) {
- topLayoutView.onResize(renderOptions);
- }
- }
- },
- getTopLayoutView: function getTopLayoutView() {
- return this.getLayoutView(this.topLayoutModel.id);
- },
- getTopLayoutViewWhenReady: function getTopLayoutViewWhenReady() {
- return this.getLayoutViewWhenReady(this.topLayoutModel.id);
- },
- getSelectedNodes: function getSelectedNodes() {
- return this.interactionController.getSelectedNodes();
- },
- getSelectedWidgets: function getSelectedWidgets() {
- var selectedLayout = this.boardModel.getSelectedLayout();
- var layout = this.topLayoutModel.findModel(selectedLayout);
- return layout ? layout.getSelectedWidgets() : [];
- },
- getLayoutContentContainer: function getLayoutContentContainer() {
- return LayoutHelper.getLayoutContentContainer(this.topLayoutModel.id, null, this.dashboardApi);
- },
- getLayoutContentContainerForDropTarget: function getLayoutContentContainerForDropTarget(dropTargetNode) {
- return LayoutHelper.getLayoutContentContainerForDropTarget(dropTargetNode, this.topLayoutModel, this.dashboardApi);
- },
- /**
- * Find the last visible page to insert. For example, if you have this hierarchy of pages: Block/Tab/Absolute.
- * It will return the Absolute of the selected tab.
- * Will return the first availabe drop zone if a template.
- */
- getLastVisiblePage: function getLastVisiblePage() {
- return LayoutHelper.getLastVisiblePage(this.topLayoutModel.id, null, this.dashboardApi);
- },
- setPreferredAddOptions: function setPreferredAddOptions(addOptions) {
- return LayoutHelper.setPreferredAddOptions(addOptions, this.topLayoutModel, this.dashboardApi);
- },
- setPreferredLocation: function setPreferredLocation(addOptions) {
- return LayoutHelper.setPreferredLocation(addOptions);
- },
- destroy: function destroy(event) {
- // Ensure we are not removing the context menu if has been set by some other class.
- if (this.fnOnContextMenu && window.oncontextmenu === this.fnOnContextMenu) {
- this.fnOnContextMenu = null;
- window.oncontextmenu = null;
- }
- $(window).off('resize.layoutController' + this.id);
- if (this.colorsService) {
- this.colorsService.off('theme:changed', this.onThemeChange, this);
- }
- if (this.topLayoutModel) {
- this.topLayoutModel.off('change:layoutPositioning', this._onLayoutPositioning, this);
- // destroy the top layout view.
- this.destroyLayoutView(this.topLayoutModel.id, event);
- }
- if (this.interactionController) {
- this.interactionController.destroy();
- }
- if (this.deprecatedCanvas) {
- this.deprecatedCanvas.destroy();
- }
- for (var prop in this) {
- // clear everything referenced by this object in case someone is still holding on to it.
- if (Object.prototype.hasOwnProperty.call(this, prop)) {
- delete this[prop];
- }
- }
- this._isDestroyed = true;
- },
- destroyLayoutView: function destroyLayoutView(layoutId, event) {
- var viewEntry = this.viewsMap[layoutId];
- viewEntry && viewEntry.view && viewEntry.view.destroy(event);
- },
- /**
- * Return the node id that maps to the given model id
- * @param modelId
- * @returns
- */
- modelIdToNodeId: function modelIdToNodeId(modelId) {
- return LayoutHelper.modelIdToNodeId(modelId);
- },
- /**
- * Return the model id for a given node id
- * @param nodeId
- * @returns
- */
- nodeIdToModelId: function nodeIdToModelId(nodeId) {
- return LayoutHelper.nodeIdToModelId(nodeId);
- },
- /**
- * Return a promise that will be resolved when the layout view is created and ready
- * At this point, the widget module (if available) might not be loaded and ready yet.
- *
- * @param modelId - id or array of ids
- *
- * @returns {Promise} promise to be fulfilled when the layout is ready
- */
- layoutReady: function layoutReady(modelId) {
- if (this._isDestroyed) {
- return Promise.reject('Layout Controller destroyed');
- }
- var idArray = modelId;
- if (!_.isArray(idArray)) {
- idArray = [modelId];
- }
- var views = _.pick.apply(_, [this.viewsMap].concat(idArray));
- return Promise.all(_.pluck(views, 'viewReady')).then(function () {
- var layout = void 0;
- if (_.isArray(modelId)) {
- layout = _.pluck(views, 'view');
- } else {
- layout = views[modelId] && views[modelId].view;
- }
- return layout;
- });
- },
- /**
- * Selects all layouts (groups, widgets, etc...) in the array of ids
- * @param layoutIds Array of ids
- * @param event The original event
- */
- selectLayouts: function selectLayouts(layoutIds, event) {
- var promises = [];
- var selectionHandler = this.interactionController.selectionHandler;
- _.each(layoutIds, function (layoutId) {
- var promise = this.whenWidgetRenderComplete(layoutId).then(function (layout) {
- selectionHandler.selectNode(layout.domNode, event);
- });
- promises.push(promise);
- }.bind(this));
- return Promise.all(promises);
- },
- /**
- * Return a promise that will be resolved when the widget module is created and ready
- *
- * @param modelId - id
- *
- */
- widgetReady: function widgetReady(modelId) {
- return this.layoutReady(modelId).then(function (layout) {
- if (this.viewsMap[modelId] && this.viewsMap[modelId].view && this.viewsMap[modelId].view.widgetReady) {
- return this.viewsMap[modelId].view.widgetReady().then(function () /* widgetAPI */{
- return layout;
- });
- } else {
- // Some widget in consume mode do not have modules.
- return layout;
- }
- }.bind(this));
- },
- /**
- * Return a promise that will be resolved when the widget is rendered
- *
- * @param modelId - id
- *
- */
- whenWidgetRenderComplete: function whenWidgetRenderComplete(modelId) {
- return this.layoutReady(modelId).then(function (layout) {
- if (this.viewsMap[modelId] && this.viewsMap[modelId].view && this.viewsMap[modelId].view.whenRenderComplete) {
- return this.viewsMap[modelId].view.whenRenderComplete().then(function () {
- return layout;
- });
- } else {
- // Some widget in consume mode do not have modules.
- return layout;
- }
- }.bind(this));
- },
- /**
- * Wait until page render is complete
- *
- * @param {Layout} pageLayout - page layout
- * @return {Promise} promise resolved when the page render is complete
- */
- whenPageRenderComplete: function whenPageRenderComplete(pageLayout) {
- return this.layoutReady(this.topLayoutModel.id).then(function () {
- var widgets = (pageLayout || this.topLayoutModel).findDescendantsWithType('widget');
- var promises = [];
- _.each(widgets, function (widget) {
- promises.push(this.whenWidgetRenderComplete(widget.id));
- }, this);
- return Promise.all(promises);
- }.bind(this));
- },
- /**
- * Return a promise that will be resolved when the widget is rendered
- *
- * @param modelId - identifier of widget the message is sent on behalf of
- * @param multiselect - flag indicating whether the selection is for multiple widgets
- * @param showContextBar - flag indicating whether to show the default context bar
- *
- */
- selectWidget: function selectWidget(event) {
- var modelId = event.modelId;
- var multiselect = event.multiselect;
- var showContextBar = event.showContextBar;
- return this.widgetReady(modelId).then(function (layout) {
- //widget param in widgetReady function is also passed in (can be used at a later time)
- if (!multiselect) {
- this.deselectAllWidgets();
- }
- var selectionHandler = this.interactionController.selectionHandler;
- //this prevents the context bar from appearing
- var eventChainLocal = new EventChainLocal(event);
- if (!showContextBar) {
- eventChainLocal.setProperty('preventDefaultContextBar', true);
- }
- if (selectionHandler) {
- selectionHandler.selectNode(layout.domNode, event);
- }
- }.bind(this));
- },
- deselectAllWidgets: function deselectAllWidgets() {
- if (this.interactionController) {
- this.interactionController.selectionHandler.deselectAll();
- }
- },
- deselectWidget: function deselectWidget(event) {
- var modelId = event.modelId;
- var layoutView = this.viewsMap[modelId] && this.viewsMap[modelId].view;
- var selectionHandler = this.interactionController.selectionHandler;
- if (!selectionHandler) {
- return Promise.resolve();
- }
- if (layoutView && layoutView.domNode) {
- return Promise.resolve(selectionHandler.deselectNode(layoutView.domNode));
- } else {
- return this.widgetReady(modelId).then(function (layout) {
- selectionHandler.deselectNode(layout.domNode);
- }.bind(this));
- }
- },
- moveLayout: function moveLayout(updateArray) {
- var _this8 = this;
- var transactionToken = this.transaction.startTransaction();
- updateArray.forEach(function (info) {
- _this8.canvas.moveContent(info.parentId, [info.id], transactionToken);
- });
- this.transaction.endTransaction(transactionToken);
- },
- // NOTE:
- // getLayoutView and getLayoutViewWhenReady should be combined into one.
- // `getLayoutViewWhenReady` - was created as part of the conversion to bluebird and the operation became async instead of sync.
- //
- // We can't guarantee that the view is ready so to be safe, one should always call getLayoutViewWhenReady.
- // Should be fixed as part of a bigger revamp
- //
- getLayoutViewWhenReady: function getLayoutViewWhenReady(modelId) {
- var viewEntry = this.viewsMap[modelId];
- if (!viewEntry) {
- return Promise.resolve(null);
- }
- return viewEntry.viewReady;
- },
- getLayoutView: function getLayoutView(modelId) {
- var viewEntry = this.viewsMap[modelId];
- return viewEntry && viewEntry.view;
- },
- onContextMenu: function onContextMenu(event) {
- var nodeName = event.target.nodeName;
- var $target = $(event.target);
- return nodeName === 'INPUT' || nodeName === 'TEXTAREA' || $target.attr('contenteditable') === 'true' || $target.closest('[contenteditable="true"]').length ? true : false;
- },
- getInteractionProperties: function getInteractionProperties() {
- return this.interactionController.getInteractionProperties();
- },
- hasMaximizedWidget: function hasMaximizedWidget() {
- var viewIds = Object.keys(this.viewsMap);
- for (var i = 0; i < viewIds.length; i++) {
- var view = this.getLayoutView(viewIds[i]);
- if (view && view.widgetAPI && view.widgetAPI.isWidgetMaximized && view.widgetAPI.isWidgetMaximized()) {
- return true;
- }
- }
- return false;
- },
- /**
- * @param layoutWidgetId The layout id for the widget being processed.
- * @param {boolean} noPageContextMerge if <tt>true</tt> the pageContext will not be merged into the Widget Model
- * @returns the widgetModel which is attached to the pin for this layoutWidgetId.
- * The widgetModel for pinning can be overridden (or returned) by a widget
- * if it implements the 'getWidgetModelForPinning' API. Otherwise, the model is returned from the board spec.
- */
- getLayoutWidgetModel: function getLayoutWidgetModel(layoutWidgetId, noPageContextMerge) {
- var widgetObj = this.widgetLoader.getWidget(layoutWidgetId);
- return widgetObj && widgetObj.getWidgetModelForPinning && !noPageContextMerge ? widgetObj.getWidgetModelForPinning() : this.boardModel.getWidgetModel(layoutWidgetId);
- }
- });
- return LayoutController;
- });
- //# sourceMappingURL=LayoutController.js.map
|