123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869 |
- '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: 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(['./LayoutBaseView', 'jquery', 'underscore', './WidgetTitleView', '../../model/LayoutModel', '../../widgets/PropertiesUtil', '../../../app/nls/StringResources', '../../../lib/@waca/core-client/js/core-client/utils/Deferred', '../../../lib/@waca/core-client/js/core-client/ui/KeyCodes', '../../../lib/@waca/core-client/js/core-client/ui/core/Events', '../../../app/util/EventChainLocal'], function (BaseView, $, _, WidgetTitleView, LayoutModel, PropertiesUtil, StringResources, Deferred, KeyCodes, Events, EventChainLocal) {
- // NOSONAR
- var Widget = BaseView.extend({
- init: function init(options) {
- Widget.inherited('init', this, arguments);
- this._layoutEvents = new Events();
- this._widgetReady = new Deferred();
- this._widgetRenderComplete = new Deferred();
- this.canvasNotifier = options.canvasNotifier;
- this.widgetModel = options.widgetModel;
- this.widgetRegistry = options.widgetRegistry;
- this.visPreferredSize = null;
- this.icons = {};
- this._savedTransform = null;
- this.$widgetContentWrapper = this.$el.find('.widgetContentWrapper');
- this._registerWidgetChromeEvents();
- this._createHeader();
- this._createAttachedView();
- this._createFilterGroupOverlay();
- this.isTouchDevice = 'ontouchstart' in document.documentElement;
- this.additionalWidgetData = options.additionalWidgetData;
- // Add appcues-data-id attribute to widget
- this.$el.attr('appcues-data-id', 'widget');
- // attach keydown event handler (done here to ensure dom is ready)
- $(this.domNode).on('keydown.widgetKeydown', this.onKeyDown.bind(this));
- },
- renderContent: function renderContent() {
- var _this = this;
- // todo lifecycle_cleanup -- the widget creation/rendering is too complex. It needs to be simplified
- // The widget can be created here instead of using the widget loader to do that
- // Also make sure we render once.
- // Render is called as we switch between consume/authoring mode by the layout controller
- // we don't want to render the widget multiple times
- if (!this._isRendered && this.widgetModel) {
- this._isRendered = true;
- this.registerViewFeatures().then(function () {
- // Notify the widget loader, create and render the widget
- if (_this.canvasNotifier) {
- _this._establishCanvasConnection(_this.additionalWidgetData);
- }
- _this.renderWidget();
- });
- }
- this.layoutController.markViewAsReady(this);
- return Promise.resolve();
- // Can't wait for the widget render compelete because the glass wait for the layout render to be resolved before showing
- // the view.. and as long as the view is hidden, the widget will not render (because they are invisible)
- // return this.whenRenderComplete().then(() => {
- // });
- },
- renderWidget: function renderWidget() {
- var _this2 = this;
- return new Promise(function (resolve, reject) {
- if (!_this2.layoutController.widgetLoader.isLoaded(_this2.id)) {
- var transactionId = _this2.additionalWidgetData && _this2.additionalWidgetData.addPayloadData && _this2.additionalWidgetData.addPayloadData.undoRedoTransactionId;
- _this2.layoutController.widgetLoader.loadWidget(_this2.id, _this2.widgetModel.toJSON(), _this2.domNode, _this2._prepareAsyncCallback(function (loadInfo) {
- if (loadInfo && loadInfo.widget) {
- if (loadInfo.widget.onContainerReady) {
- loadInfo.widget.onContainerReady({
- model: _this2.widgetModel,
- widgetChromeEventRouter: _this2.widgetChromeEventRouter,
- isAuthoringMode: _this2.layoutController.isAuthoring,
- additionalWidgetData: _this2.additionalWidgetData,
- layoutAPI: _this2.getAPI()
- });
- }
- _this2._triggerChromeEvents(loadInfo.widget, _this2.widgetChromeEventRouter);
- }
- }), _this2._prepareAsyncCallback(function (error) {
- if (error.errorCode === (_this2.layoutController.widgetLoader && _this2.layoutController.widgetLoader.ERROR.WIDGET_ALREADY_LOADED)) {
- //We've hit a rare timing issue where the two loads ended up being requested before one finished. Trigger the onLoad behavior.
- _this2._widgetAlreadyLoadedCallback();
- resolve();
- } else if (error.exception) {
- reject(error.exception);
- } else {
- reject(new Error(error.errorCode));
- }
- }), transactionId).then(function () {
- resolve();
- });
- } else {
- _this2._widgetAlreadyLoadedCallback();
- resolve();
- }
- });
- },
- _widgetAlreadyLoadedCallback: function _widgetAlreadyLoadedCallback() {
- var widget = this.layoutController.widgetLoader.getWidget(this.id);
- if (widget) {
- if (widget.onContainerReady) {
- widget.onContainerReady({
- model: this.widgetModel,
- widgetChromeEventRouter: this.widgetChromeEventRouter,
- isAuthoringMode: this.layoutController.isAuthoring,
- layoutAPI: this.getAPI()
- });
- }
- this._triggerChromeEvents(widget);
- }
- },
- _triggerChromeEvents: function _triggerChromeEvents(widget) {
- if (this.widgetChromeEventRouter) {
- // Notify the chrome that the widget is ready
- this.widgetChromeEventRouter.trigger('widget:ready', {
- // TODO -- to be removed after refactoring
- widget: widget,
- //TODO - end to be removeDone
- widgetAPI: widget.getAPI()
- });
- this._triggerRenderComplete(widget);
- }
- },
- _triggerRenderComplete: function _triggerRenderComplete(widget) {
- if (widget.whenRenderComplete) {
- widget.whenRenderComplete().then(this._prepareAsyncCallback(function () {
- // Notify the chrome that the widget has finished rendering
- this.widgetChromeEventRouter.trigger('widget:renderComplete', {
- widget: widget
- });
- this.eventRouter.trigger('widget:renderComplete', {
- widget: widget
- });
- }.bind(this)));
- } else {
- this.widgetChromeEventRouter.trigger('widget:renderComplete', {
- widget: widget
- });
- this.eventRouter.trigger('widget:renderComplete', {
- widget: widget
- });
- }
- },
- /**
- * Execute a callback. The method will only execute the callback if the object is not destroyed
- * Typpically used in a promise callback because we might have destroyed the object before the promise was resolved.
- * @param {Function} callback
- */
- _prepareAsyncCallback: function _prepareAsyncCallback(callback) {
- return function () {
- if (!this._destroyed) {
- return callback.apply(undefined, arguments);
- }
- return Promise.reject('The live widget object was destroyed');
- }.bind(this);
- },
- getAPI: function getAPI() {
- var api = Widget.inherited('getAPI', this, arguments);
- if (this.widgetTitleView) {
- api.updateTitle = this.widgetTitleView.updateTitle.bind(this.widgetTitleView);
- api.setTitleBadge = this.setTitleBadge.bind(this);
- api.onTitleBadgeClick = this.onTitleBadgeClick.bind(this);
- api.offTitleBadgeClick = this.offTitleBadgeClick.bind(this);
- api.offFocus = this.widgetTitleView.onChromeOffFocus.bind(this.widgetTitleView);
- }
- return api;
- },
- setTitleBadge: function setTitleBadge(value, label) {
- var _this3 = this;
- this.$badgeContainer.empty();
- if (value) {
- var $badge = $('<div>', {
- 'tabindex': 0,
- 'class': 'titleBadge',
- 'aria-label': label,
- 'appcues-data-id': 'titleBadge'
- });
- $badge.text(value);
- this.$badgeContainer.append($badge);
- $badge.on('clicktap keydown', function (event) {
- if (event.type !== 'keydown' || event.which === 13) {
- _this3._layoutEvents.trigger('titlebadge:click', { event: event });
- }
- });
- }
- },
- onTitleBadgeClick: function onTitleBadgeClick(handler, scope) {
- this._layoutEvents.on('titlebadge:click', handler, scope);
- },
- offTitleBadgeClick: function offTitleBadgeClick(handler, scope) {
- this._layoutEvents.off('titlebadge:click', handler, scope);
- },
- /**
- * Detect a focus out so that we can invoke the onExistContainer event.
- * This method detect lossing focus either by tabbing or clicking outside of the container
- *
- */
- onFocusOut: function onFocusOut() /*event*/{
- var isFocusIn = false;
- var focusIn = function (evt) {
- if (evt.target !== this.domNode) {
- isFocusIn = true;
- }
- }.bind(this);
- $(this.domNode).on('focusin.widgetFocus', focusIn);
- setTimeout(function () {
- if (!isFocusIn) {
- this._exitContainer();
- }
- }.bind(this), 10);
- },
- onKeyDown: function onKeyDown(event) {
- // F10 or (Ctrl key + X) will maximize the selected widget
- // Only data widget support maximize mode..
- if (event.keyCode === KeyCodes.F10 || event.ctrlKey && event.keyCode === KeyCodes.X) {
- this.onMaximize();
- return false;
- }
- if (event.keyCode === KeyCodes.F12 && !event.shiftKey || event.ctrlKey && event.keyCode === KeyCodes.NUM1) {
- // Press F12 Key + Without Shift Key or (Ctrl + 1) to enter into the widget container
- this.isEnterContainer = true;
- this.widgetChromeEventRouter.trigger('widget:onEnterContainer');
- $(this.domNode).on('focusout.widgetFocus', this.onFocusOut.bind(this));
- event.stopPropagation();
- event.preventDefault();
- return false;
- }
- if (event.keyCode === KeyCodes.F12 && event.shiftKey || event.ctrlKey && event.keyCode === KeyCodes.NUM0) {
- // Press F12 Key + Shift or (Ctrl+0) to exit from the widget container
- this._exitContainer();
- // just dump focus back on the widget
- $(this.domNode).focus();
- event.stopPropagation();
- event.preventDefault();
- return false;
- }
- if ((event.keyCode === KeyCodes.SPACE || event.keyCode === KeyCodes.ENTER) && $.contains(this.domNode, event.target)) {
- var eventChainLocal = new EventChainLocal(event);
- eventChainLocal.setProperty('preventWidgetSelection', true);
- return true;
- }
- var isArrowKey = event.keyCode === KeyCodes.LEFT_ARROW || event.keyCode === KeyCodes.RIGHT_ARROW || event.keyCode === KeyCodes.UP_ARROW || event.keyCode === KeyCodes.DOWN_ARROW;
- if (isArrowKey && $.contains(this.domNode, event.target)) {
- var _eventChainLocal = new EventChainLocal(event);
- _eventChainLocal.setProperty('preventMoveAction', true);
- return true;
- }
- },
- _exitContainer: function _exitContainer() {
- if (this.isEnterContainer) {
- this.widgetChromeEventRouter.trigger('widget:onExitContainer');
- this.isEnterContainer = false;
- $(this.domNode).off('focusout');
- }
- },
- /**
- * Trigger an event using the chrome event router
- * @param eventName - Event name
- * @param paylad - Event payload
- */
- notifyWidget: function notifyWidget(eventName, payload) {
- this.widgetChromeEventRouter.trigger(eventName, payload);
- },
- widgetReady: function widgetReady() {
- return this._widgetReady.promise;
- },
- whenRenderComplete: function whenRenderComplete() {
- return this._widgetRenderComplete.promise;
- },
- _registerWidgetChromeEvents: function _registerWidgetChromeEvents() {
- this.widgetChromeEventRouter_disposeEvents.push(this.widgetChromeEventRouter.on('widget:updateLayout', this.updateModel, this), this.widgetChromeEventRouter.on('layout:getPageFillColor', this.getPageFillColor, this), this.widgetChromeEventRouter.on('widget:setPreferredSize', this.setPreferredSize, this), this.widgetChromeEventRouter.on('widget:getSize', this.getSize, this), this.widgetChromeEventRouter.on('widget:showError', this.sizeToErrorContainer, this), this.widgetChromeEventRouter.on('widget:clearError', this.resizeToModel, this), this.widgetChromeEventRouter.on('widget:clearMoreDataIndicator', this.clearMoreDataIndicator, this), this.widgetChromeEventRouter.on('widget:updateDescription', this.updateDescription, this), this.widgetChromeEventRouter.on('widget:addIcon', this.addIcon, this), this.widgetChromeEventRouter.on('widget:onShowAttachedView', this.onShowAttachedView, this), this.widgetChromeEventRouter.on('widget:onHideAttachedView', this.onHideAttachedView, this), this.widgetChromeEventRouter.on('widget:setLayoutProperties', this.setLayoutProperties, this), this.widgetChromeEventRouter.on('title:resizeViz', this.onResize, this), this.widgetChromeEventRouter.on('title:resetTitle', this.recreateHeader, this), this.widgetChromeEventRouter.on('widget:ready', this.onWidgetReady, this), this.widgetChromeEventRouter.on('widget:renderComplete', this.onWidgetRenderComplete, this));
- },
- onWidgetReady: function onWidgetReady(info) {
- this.widget = info.widget;
- this.widgetAPI = info.widgetAPI;
- this._widgetReady.resolve(info.widgetAPI);
- },
- onWidgetRenderComplete: function onWidgetRenderComplete() {
- this._widgetRenderComplete.resolve();
- },
- getPageFillColor: function getPageFillColor(payload) {
- var parent = this.model.getParent();
- var fillColor = null;
- while (parent && !fillColor) {
- if (parent.fillColor && parent.fillColor !== 'transparent') {
- fillColor = parent.fillColor;
- }
- parent = parent.getParent();
- }
- payload.fillColor = fillColor;
- },
- /**
- * This is an event handler for sizing the widget dom node to fit the error container properly;
- * But doing so without storing the size in the model.
- * @param payload - An object containing the height and width of the error container
- */
- sizeToErrorContainer: function sizeToErrorContainer(payload) {
- var _this4 = this;
- if (_.isUndefined(this._errorStyle)) {
- this._errorStyle = {};
- }
- _.each(payload, function (value, key) {
- _this4._errorStyle[key] = value;
- });
- if (_.isEmpty(this._errorStyle)) {
- this.logger.warn('no error style to apply');
- } else {
- this.$el.css(this._errorStyle);
- }
- },
- /**
- * Resizes the widget layout DOM node to the size stored in the model
- */
- resizeToModel: function resizeToModel() {
- var style = this.model.style;
- var styleToApply = {};
- if (this._errorStyle) {
- styleToApply = _.clone(this._errorStyle);
- _.each(styleToApply, function (value, key) {
- styleToApply[key] = '';
- });
- delete this._errorStyle;
- }
- if (style) {
- styleToApply.height = style.height;
- styleToApply.width = style.width;
- if (this.model.style.opacity) {
- styleToApply.opacity = this.model.style.opacity;
- }
- }
- if (!_.isEmpty(styleToApply)) {
- this.$el.css(styleToApply);
- }
- },
- /**
- * Update the layout view model with the given preferred size
- * @param payload - event payload.
- */
- setPreferredSize: function setPreferredSize(payload) {
- var iPreferredHeight = payload.preferredSize.height + 'px';
- var iPreferredWidth = payload.preferredSize.width + 'px';
- var bPreferredSizeChanged = this.visPreferredSize && !_.isEqual(this.visPreferredSize, payload.preferredSize);
- var style = this.model.style;
- var bHasSizeInModel = !!(style && style.height && style.width);
- if (!bHasSizeInModel || bPreferredSizeChanged && !this._isWidgetInDropZone()) {
- if (payload.options.undoRedoTransactionId) {
- this._updateModel({
- undoRedoTransactionId: payload.options.undoRedoTransactionId,
- transactionToken: payload.options && payload.options.transactionToken,
- triggerResize: false
- }, this, {
- height: iPreferredHeight,
- width: iPreferredWidth
- });
- } else {
- this._updateModel({
- triggerResize: false
- }, null, {
- height: iPreferredHeight,
- width: iPreferredWidth
- });
- }
- } else {
- // Update DOM node with saved style. Useful when loading a board.
- this.$el.css({
- height: this.model.style.height,
- width: this.model.style.width
- });
- }
- this.visPreferredSize = payload.preferredSize;
- },
- /**
- * Return the bounds of the visualization within the widget layout view DOM node
- * This is an asynchronous function and it returns the bounds by resolving the deferred object
- * in the payload argument
- *
- * @param payload - Contains the deferred object that is resolved with the bounds
- * @return undefined
- */
- getSize: function getSize(payload) {
- var $widgetContent = this.$el.find('.widgetContent');
- var iWidth;
- var iHeight;
- var oModelStyle = this.model.style;
- //when the parent of an element is hidden, children without dimensions explicitly set are returned as 0.
- if (this._getHiddenLayoutParents().length > 0) {
- // element has a hidden parent, get the dims from the model
- // possible values stored on the model that will still work:
- // - percentage (ends in %)
- // - pixels (ends in px)
- // - no ending (pixels assumed)
- iWidth = oModelStyle.width;
- iHeight = oModelStyle.height;
- } else {
- iWidth = $widgetContent.innerWidth();
- iHeight = $widgetContent.innerHeight();
- }
- // The payload should contain a deferred object that will be resolved with the size
- if (payload.deferred) {
- payload.deferred.resolve({
- top: oModelStyle.top || 0,
- left: oModelStyle.left || 0,
- width: iWidth,
- height: iHeight
- });
- }
- },
- /*
- * Checks whether the widget has a parent which is hidden via display:none.
- * @return collection of jquery selectors
- */
- _getHiddenLayoutParents: function _getHiddenLayoutParents() {
- return this.$el.parents().filter(function () {
- return $(this).css('display') === 'none';
- });
- },
- /**
- * Checks whether the widget is snapped in a template drop zone or not.
- * @return boolean - true if widget is snapped and false otherwise.
- */
- _isWidgetInDropZone: function _isWidgetInDropZone() {
- var current = this.model;
- var parent = this.model.getParent();
- var bIsInDropZone = false;
- while (parent && parent.type !== 'genericPage') {
- current = parent;
- parent = parent.getParent();
- }
- if (parent && current.relatedLayouts) {
- var relatedLayout = parent.findChildItem(parent.items, current.relatedLayouts);
- if (relatedLayout.type === 'templateDropZone') {
- bIsInDropZone = true;
- }
- }
- return bIsInDropZone;
- },
- // This allows us to pass in a transaction id so that there isn't more than one frame added to the undo/redo stack
- updateModel: function updateModel(payload) {
- this.model.updateModel({
- updateArray: [{
- id: this.id,
- style: {
- height: $(this.domNode).outerHeight() + 'px',
- width: $(this.domNode).outerWidth() + 'px'
- }
- }]
- }, this, payload.payloadData);
- },
- /**
- * TODO: Combine this with updateModel function
- * @param payload The event payload
- * @param sender The event's sender
- * @param style object with at least height and width
- */
- _updateModel: function _updateModel(payload, sender, style) {
- if (style) {
- var newStyle = {
- height: style.height,
- width: style.width
- };
- if (style.opacity !== undefined) {
- newStyle.opacity = style.opacity;
- }
- this.model.updateModel({
- updateArray: [{
- id: this.model.id,
- style: newStyle
- }]
- }, sender, payload);
- }
- },
- /**
- * Tell the widget module that the the layout container is ready.
- *
- * @param additionalWidgetData - additional data to be passed to the widget module.
- */
- _establishCanvasConnection: function _establishCanvasConnection(additionalWidgetData) {
- this.widgetOwnsTitle = this.widgetRegistry ? this.widgetRegistry.ownTitle : true;
- this.canvasNotifier.trigger('widget:addDone', {
- id: this.id,
- widgetChromeEventRouter: this.widgetChromeEventRouter,
- isAuthoringMode: this.isAuthoringMode,
- domNode: this.domNode,
- additionalWidgetData: additionalWidgetData,
- layoutAPI: this.getAPI(),
- // TODO: should be removed.
- // nobody should be calling the widget layout instance directly.
- // Consumers should be consuming the layoutAPI instead.
- //
- // for now we'll keep it in because storytelling still references it
- widget: this
- });
- },
- updateDescription: function updateDescription(payload) {
- if (this._nWidgetDescription) {
- this._nWidgetDescription.text(payload.value);
- } else {
- this.$el.attr('aria-label', payload.value);
- }
- },
- _getDescriptionDomNodeId: function _getDescriptionDomNodeId() {
- return this.domNode.id + 'Description';
- },
- recreateHeader: function recreateHeader(ev) {
- // Check and recreate the header
- this._createHeader(ev.widgetTitleView);
- },
- _createHeader: function _createHeader(widgetTitleViewInstance) {
- if (this.widgetRegistry) {
- this.createContentNode = this.widgetRegistry.createContentNode;
- this.supportsTitle = this.createContentNode && !this.widgetRegistry.disableTitle;
- this.createDescriptionNode = this.createContentNode || !!this.widgetRegistry.createDescriptionNode;
- } else {
- this.createContentNode = this.supportsTitle = this.createDescriptionNode = true;
- }
- var ariaLabelledBy = void 0;
- if (this.createDescriptionNode) {
- this._nWidgetDescription = $('<div>', {
- 'id': this._getDescriptionDomNodeId(),
- 'class': 'ariaLabelNode hidden'
- });
- this.$el.append(this._nWidgetDescription);
- ariaLabelledBy = this._getDescriptionDomNodeId();
- }
- if (this.createContentNode) {
- var nContainer = $('<div>', {
- 'class': 'widgetHeader'
- });
- if (this.supportsTitle) {
- var interactions = this.dashboardApi.getAppConfig('interactions') || {};
- var canEditTitle = interactions.editTitle === undefined || interactions.editTitle === true || interactions.editTitle === 'true';
- if (widgetTitleViewInstance) {
- this.widgetTitleView = widgetTitleViewInstance;
- } else {
- this.widgetTitleView = new WidgetTitleView({
- id: this.domNode.id,
- header: nContainer,
- canEditTitle: canEditTitle,
- widgetModel: this.widgetModel,
- widgetChromeEventRouter: this.widgetChromeEventRouter,
- dashboardApi: this.dashboardApi
- });
- var hidden = !!(this.widgetModel && !this.widgetModel.showTitle);
- this.widgetTitleView.render(hidden);
- }
- this.$el.addClass('titleSupported');
- ariaLabelledBy += ' ' + this.widgetTitleView.titleId;
- nContainer.prepend(this.widgetTitleView.getStyleNode());
- var nIcons = $('<div>', {
- 'class': 'widgetIcons'
- });
- this.$badgeContainer = $('<div>', {
- 'class': 'badgeContainer'
- });
- nContainer.append(this.$badgeContainer);
- nContainer.append(nIcons);
- }
- this.$widgetContentWrapper.prepend(nContainer);
- }
- if (ariaLabelledBy) {
- this.$el.attr('aria-labelledby', ariaLabelledBy);
- }
- },
- _createAttachedView: function _createAttachedView() {
- var viewId = this.domNode.id + '_attachedView';
- var nContainer = $('<div>', {
- id: viewId,
- 'class': 'attachedView'
- });
- this.$widgetContentWrapper.append(nContainer);
- this.$attachedView = nContainer;
- },
- _createFilterGroupOverlay: function _createFilterGroupOverlay() {
- var viewId = this.domNode.id + '_eventGroupOverlay';
- var nContainer = $('<div>', {
- id: viewId,
- 'class': 'eventGroupOverlay'
- });
- var nContent = $('<div>', {
- 'class': 'eventGroupOverlayContent'
- });
- nContainer.append(nContent);
- this.$widgetContentWrapper.append(nContainer);
- },
- onShowAttachedView: function onShowAttachedView(view) {
- this.$attachedView.html(view.$el).addClass('expanded');
- },
- onHideAttachedView: function onHideAttachedView() /*$html*/{
- this.$attachedView.removeClass('expanded').empty();
- },
- destroy: function destroy(event) {
- // clean up keydown event handler
- $(this.domNode).off('keydown.widgetKeydown');
- $(this.domNode).off('.widgetFocus');
- this._destroyAuthoringHelper();
- this.nHandle = null;
- // Notify the canvas to unload/destroy the widget module
- if (this.canvasNotifier) {
- this.canvasNotifier.trigger('widget:removeDone', _.extend(event || {}, {
- id: this.model.id,
- widget: this
- }));
- }
- if (this.widgetTitleView) {
- this.widgetTitleView.remove();
- this.widgetTitleView = null;
- }
- this._destroyed = true;
- Widget.inherited('destroy', this, arguments);
- },
- // Notify the widget
- _triggerWidgetChromeEvent: function _triggerWidgetChromeEvent(sMsg, options) {
- if (this.widgetChromeEventRouter) {
- this.widgetChromeEventRouter.trigger(sMsg, options);
- }
- },
- onResize: function onResize() {
- Widget.inherited('onResize', this, arguments);
- this._triggerWidgetChromeEvent('widget:onResize', _typeof(arguments[0]) === 'object' ? arguments[0] : {});
- },
- onSelect: function onSelect() {
- this._triggerWidgetChromeEvent('widgetchrome:selected');
- },
- onDeselect: function onDeselect() {
- this._triggerWidgetChromeEvent('widgetchrome:deselected');
- },
- /**
- * @param options - options to be passed and sent in the eventRouter payload.
- */
- onShow: function onShow(options) {
- Widget.inherited('onShow', this, arguments);
- this._triggerWidgetChromeEvent('widget:onShow', options);
- },
- onHide: function onHide() {
- Widget.inherited('onHide', this, arguments);
- this._triggerWidgetChromeEvent('widget:onHide');
- },
- onMaximize: function onMaximize() {
- this._triggerWidgetChromeEvent('widget:onMaximize');
- },
- setLayoutProperties: function setLayoutProperties(payload) {
- this.$el.toggleClass('noRotate', !!payload.noRotate);
- this.$el.toggleClass('mobilePannable', !!payload.mobilePannable);
- this.$el.toggleClass('pannable', !!payload.pannable);
- this.$el.toggleClass('maximizable', !!payload.maximizable);
- },
- addIcon: function addIcon(payload) {
- if (this.icons[payload.name]) {
- this.icons[payload.name].widgetIcon.detach();
- }
- //We can specify a location in the payload where we put the icon.
- if (payload.location) {
- payload.location.append(payload.widgetIcon);
- } else {
- this.$el.find('.widgetIcons').append(payload.widgetIcon);
- }
- this.icons[payload.name] = payload;
- },
- getContextToolbarItems: function getContextToolbarItems() /*hideFn*/{
- var toolbarItems = [];
- if (this.widgetAPI && !this.widgetAPI.getError()) {
- var consumeItems = this.widgetAPI.getContextToolbarItems();
- toolbarItems = toolbarItems.concat(consumeItems);
- }
- return {
- items: toolbarItems
- };
- },
- /**
- * Get the propertyUIControl spec for this layout & widget
- *
- * @returns {Promise} - Promise that will resolve with the property UI control spec
- */
- getProperties: function getProperties() {
- var _this5 = this;
- return this.widgetReady() //Ensure that the widget is present before we try to get the properties.
- .then(function () {
- return _this5.widgetAPI.getProperties();
- }).then(function (items) {
- return _this5._getLayoutProperties().then(function (layoutProperties) {
- return $.merge(items, layoutProperties);
- });
- });
- },
- _getLayoutProperties: function _getLayoutProperties() {
- var _this6 = this;
- var properties = this._getStyleProperties();
- return PropertiesUtil.processProperties(properties, this.model.style, this.dashboardApi).then(function () {
- if (_this6.supportsTitle) {
- properties = _this6.widgetTitleView.getProperties(properties);
- }
- return properties;
- });
- },
- _getLayoutOpacity: function _getLayoutOpacity() {
- if (this.model.style.opacity || this.model.style.opacity === 0) {
- return this.model.style.opacity;
- } else {
- return '1';
- }
- },
- _getStyleProperties: function _getStyleProperties() {
- this._registerOnPropertyChangeStyle();
- var props = [];
- props.push(this._getOpacityProperty());
- return props;
- },
- _getOpacityProperty: function _getOpacityProperty() {
- return {
- name: 'opacity',
- label: StringResources.get('propOpacity'),
- module: '../ui/UiSlider',
- sliderType: 'percentage',
- description: StringResources.get('propOpacityDescription'),
- connect: [true, false],
- defaultValue: 100,
- range: {
- 'min': 0,
- 'max': 100
- },
- step: 1,
- format: {
- 'decimals': 0,
- 'postfix': '%'
- },
- tabName: StringResources.get('tabName_general'),
- sectionName: StringResources.get('sectionName_appearance'),
- noInputView: true
- };
- },
- _registerOnPropertyChangeStyle: function _registerOnPropertyChangeStyle() {
- this.model.style.onPropertyChange = function (name, value) {
- var style = $.extend(true, {}, this.model.style);
- style[name] = value;
- this._updateModel({
- undoRedoTransactionId: _.uniqueId('changeLayoutStyle_' + name),
- triggerResize: false
- }, this, style);
- }.bind(this);
- },
- clearMoreDataIndicator: function clearMoreDataIndicator() {
- //Consume Mode View case
- var $moredataNode = this.$el.find('.widgetHeader .dataWidgetHasMoreData');
- if ($moredataNode && $moredataNode.length > 0) {
- $moredataNode.remove();
- } else {
- //DataSlots View case, in which the 'has more data message' is showing outside of the widget header
- //and it's in a dialogBlocker instead
- var $pageViewContent = this.$el.closest('.pageViewContent');
- if ($pageViewContent && $pageViewContent.length > 0) {
- $moredataNode = $pageViewContent.find('.dialogBlocker .dataWidgetHasMoreData');
- if ($moredataNode && $moredataNode.length > 0) {
- $moredataNode.remove();
- }
- }
- }
- },
- getWidgetAPI: function getWidgetAPI() {
- return this.widgetAPI;
- }
- });
- return Widget;
- });
- //# sourceMappingURL=Widget.js.map
|