'use strict'; function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } /** * Licensed Materials - Property of IBM * IBM Cognos Products: Dashboard * (C) Copyright IBM Corp. 2019, 2020 * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */ define(['../../../app/nls/StringResources', '../../../dashboard/layout/LayoutHelper', '../../../lib/@waca/dashboard-common/dist/core/APIFactory', '../../../lib/@waca/dashboard-common/dist/ui/interaction/Utils', '../../../lib/@waca/baglass/js/baglass/utils/Utils', '../../../lib/@waca/core-client/js/core-client/ui/dialogs/ConfirmationDialog', '../../../lib/@waca/dashboard-common/dist/api/PropertiesProviderAPI', 'underscore', '../../../dashboard/widgets/PropertyListUtil', '../../../dashboard/util/ContentRegistryUtil'], function (StringResources, LayoutHelper, APIFactory, CommonUtils, Utils, ConfirmationDialog, PropertiesProviderAPI, _, PropertyListUtil, ContentRegistryUtil) { var WIDGET_SIZES = { 'widget.text': { min: { width: 100, height: 40 } }, default: { min: { width: 25, height: 25 } } }; var LayoutProperties = function () { function LayoutProperties(options) { _classCallCheck(this, LayoutProperties); this.dashboard = options.dashboardApi || options.dashboardAPI; this._canvas = options.features['Canvas']; this.content = options.content; this.content.getFeature('Properties').registerProvider(this.getAPI()); } LayoutProperties.prototype.getLayoutModel = function getLayoutModel() { var boardModel = this.dashboard.getFeature('internal').getBoardModel(); return boardModel.layout.findModel(this.content.getId()); }; LayoutProperties.prototype.getAPI = function getAPI() { return APIFactory.createAPI(this, [PropertiesProviderAPI]); }; LayoutProperties.prototype._getCommonType = function _getCommonType(contentType) { return contentType && contentType.split('.')[0]; }; LayoutProperties.prototype._getSubType = function _getSubType(contentType) { if (contentType && contentType.indexOf('.') !== -1) { return contentType.split('.')[1]; } else { return null; } }; LayoutProperties.prototype.getPropertyList = function getPropertyList() { var _this = this; var propertyList = []; var contentType = this.content.getType(); var commonType = this._getCommonType(contentType); var subType = this._getSubType(contentType); if (commonType === 'widget' || commonType === 'group' || this._isTypeRegistered(commonType)) { propertyList.push.apply(propertyList, this._getWidgetPropertyList(subType)); } // Default the setPropertyValue and getPropertyValue for any property that doesn't define those methods //propertyList.forEach((property) => { if (propertyList) { var _loop = function _loop(i) { var property = propertyList[i]; if (!property.setPropertyValue) { property.setPropertyValue = function (value) { return _this._setPropertyValueInModel(property.id, value); }; } if (!property.getPropertyValue) { property.getPropertyValue = function () { return _this._getPropertyValueFromModel(property.id); }; } }; for (var i = 0; i < propertyList.length; i++) { _loop(i); } } //}); return propertyList; }; LayoutProperties.prototype._isTypeRegistered = function _isTypeRegistered(type) { var contentTypeRegistry = this.dashboard.getFeature('ContentTypeRegistry'); return contentTypeRegistry.isTypeRegistered(type); }; LayoutProperties.prototype.getPropertyLayoutList = function getPropertyLayoutList() { var propertiesLayoutSpec = []; if (!this._isTopLevelPage()) { propertiesLayoutSpec.push({ 'value': StringResources.get('settings'), 'id': 'banner', 'type': 'Banner', 'editable': false, 'override': false // a flag means if we already have the banner defined by other property provider, then do not override }); } var commonType = this._getCommonType(this.content.getType()); if (this._isTypeRegistered(commonType) || commonType === 'widget' || commonType === 'group') { propertiesLayoutSpec.push({ id: 'general', type: 'Group', label: StringResources.get('tabName_general') }, { id: 'appearance', type: 'Section', open: false, label: StringResources.get('sectionName_appearance'), position: 1 }, { id: 'layout', type: 'Section', open: true, label: StringResources.get('sectionName_layout'), position: 2 }, { id: 'widgetPosition', type: 'Section', collapsible: false, label: StringResources.get('propPositionLabel'), position: 2 }, { id: 'moveWidgetSplit', type: 'Split', items: [{ id: 'left', align: 'left', items: [] }, { id: 'right', align: 'right', items: [] }] }, { id: 'resizeWidget', type: 'Section', collapsible: false, label: StringResources.get('propResizeLabel'), position: 3 }, { id: 'rotate', type: 'Section', collapsible: false, label: StringResources.get('propRotateLabel'), position: 4 }, { id: 'resizeWidgetSplit', type: 'Split', items: [{ id: 'left', align: 'left', items: [] }, { id: 'right', align: 'right', items: [] }] }); } return propertiesLayoutSpec; }; LayoutProperties.prototype.getUnit = function getUnit() { return this._canvas.getPropertyValue('layoutPositioning') === 'absolute' ? 'px' : '%'; }; LayoutProperties.prototype._getMaxValueForConstraint = function _getMaxValueForConstraint(constrainedBy) { if (this._canvas.getPropertyValue('layoutPositioning') === 'relative') { return 100; } else { if (constrainedBy === 'width' || constrainedBy === 'left') { return parseFloat(this._canvas.getPropertyValue('pageSizeWidth')); } else { return parseFloat(this._canvas.getPropertyValue('pageSizeHeight')); } } }; LayoutProperties.prototype._getNumericValueWithConstraint = function _getNumericValueWithConstraint(constrainedBy, propertyValue, minimum) { var numericValue = parseFloat(propertyValue); if (isNaN(numericValue)) { numericValue = 0; } var constraint = this.content.getPropertyValue(constrainedBy) || 0; var maxValue = this._getMaxValueForConstraint(constrainedBy); numericValue = Math.max(Math.min(maxValue, numericValue), minimum || 0); constraint = parseFloat(constraint); if (constraint + numericValue > maxValue) { numericValue = maxValue - constraint; } return numericValue; }; LayoutProperties.prototype._onChangePercentOrPixelProperty = function _onChangePercentOrPixelProperty(constrainedBy, propertyName, propertyValue, options) { var units = this.getUnit(); var minimum = WIDGET_SIZES[this.content.getType()] ? WIDGET_SIZES[this.content.getType()].min[propertyName] : WIDGET_SIZES.default.min[propertyName]; if (minimum && units === '%') { // get the minimum value to percent var domFeature = this.content.getContainer().getFeature('ContentViewDOM'); if (domFeature) { var node = domFeature.getNode(); var size = propertyName === 'height' ? node.clientHeight : node.clientWidth; minimum = 100 * minimum / size; } else { // without a dom we can't figure out the minimum percent.. so we use 0 minimum = 0; } } var numericValue = this._getNumericValueWithConstraint(constrainedBy, propertyValue, minimum); var formattedValue = PropertyListUtil.getPropertyDisplayString(numericValue, units); this.content.setPropertyValue(propertyName, formattedValue, options); }; LayoutProperties.prototype._onChangeAngle = function _onChangeAngle(propertyName, propertyValue) { this.content.setPropertyValue(propertyName, propertyValue); }; LayoutProperties.prototype._getWidgetPropertyList = function _getWidgetPropertyList() { var _this2 = this; var model = this.getLayoutModel(); var isInGroup = false; var selection = this._canvas.getSelectedContentList(); if (selection && selection.length) { var selectionParent = selection[0].getContainer(); if (selectionParent) { isInGroup = selectionParent.getType() === 'group'; } } var propertyList = [{ getPropertyValue: function getPropertyValue() { if (model.style && (model.style.opacity || model.style.opacity === 0)) { return model.style.opacity; } else { return 1; } }, setPropertyValue: function setPropertyValue(value, options) { _this2._updateStyleValueInModel('opacity', value, options); }, id: 'opacity', editor: { sectionId: 'general.appearance', position: 4, uiControl: { label: StringResources.get('propOpacity'), description: StringResources.get('propOpacityDescription'), module: '../ui/UiSlider', sliderType: 'percentage', connect: [true, false], noInputView: true, step: 1, start: [100], startLabels: [StringResources.get('propOpacityDescription')], range: { 'min': 0, 'max': 100 }, format: { 'decimals': 0, 'postfix': '%' } } } }]; var leftProperty = { id: 'left', getPropertyValue: function getPropertyValue() { if (model.style) { return model.style.left; } }, setPropertyValue: function setPropertyValue(value, options) { _this2._updateStyleValueInModel('left', value, options); }, editor: { sectionId: 'general.layout.widgetPosition.moveWidgetSplit.left', uiControl: { type: 'InputLabel', label: StringResources.get('propPositionXAxis'), multiline: true, handleReturnKey: true, decimalPlaces: 2, onChange: this._onChangePercentOrPixelProperty.bind(this, 'width') } }, onPropertyChange: { refresh: { propertiesPane: true } } }; if (isInGroup) { delete leftProperty.editor; } propertyList.push(leftProperty); var topProperty = { id: 'top', getPropertyValue: function getPropertyValue() { if (model.style) { return model.style.top; } }, setPropertyValue: function setPropertyValue(value, options) { _this2._updateStyleValueInModel('top', value, options); }, editor: { sectionId: 'general.layout.widgetPosition.moveWidgetSplit.right', uiControl: { type: 'InputLabel', label: StringResources.get('propPositionYAxis'), multiline: true, handleReturnKey: true, decimalPlaces: 2, onChange: this._onChangePercentOrPixelProperty.bind(this, 'height') } }, onPropertyChange: { refresh: { propertiesPane: true } } }; if (isInGroup) { delete topProperty.editor; } propertyList.push(topProperty); var widthProperty = { id: 'width', getPropertyValue: function getPropertyValue() { if (model.style) { return model.style.width; } }, setPropertyValue: function setPropertyValue(value, options) { _this2._updateStyleValueInModel('width', value, options); }, editor: { sectionId: 'general.layout.resizeWidget.resizeWidgetSplit.left', uiControl: { type: 'InputLabel', label: StringResources.get('propResizeWidth'), multiline: true, handleReturnKey: true, decimalPlaces: 2, onChange: this._onChangePercentOrPixelProperty.bind(this, 'left') } }, onPropertyChange: { refresh: { propertiesPane: true } } }; if (isInGroup) { delete widthProperty.editor; } propertyList.push(widthProperty); var heightProperty = { id: 'height', getPropertyValue: function getPropertyValue() { if (model.style) { return model.style.height; } }, setPropertyValue: function setPropertyValue(value, options) { _this2._updateStyleValueInModel('height', value, options); }, editor: { sectionId: 'general.layout.resizeWidget.resizeWidgetSplit.right', uiControl: { type: 'InputLabel', label: StringResources.get('propResizeHeight'), multiline: true, handleReturnKey: true, decimalPlaces: 2, onChange: this._onChangePercentOrPixelProperty.bind(this, 'top') } }, onPropertyChange: { refresh: { propertiesPane: true } } }; if (isInGroup) { delete heightProperty.editor; } propertyList.push(heightProperty); var rotationSupported = this._isCapabilityEnabled('rotation'); propertyList.push({ id: 'canRotate', getPropertyValue: function getPropertyValue() { return rotationSupported; }, setPropertyValue: function setPropertyValue() { throw new Error('not supported'); } }); if (rotationSupported) { var rotationProperty = { id: 'rotateAngle', getPropertyValue: function getPropertyValue() { var transform = model.style && model.style.transform; if (transform) { var deg = /-?\d*\.?\d*deg/.exec(transform); if (deg) { var str = deg[0]; var value = str.substr(0, str.length - 3); return parseFloat(value) || 0; } else { return CommonUtils.getAngleFromMatrix(transform); } } else { return 0; } }, setPropertyValue: function setPropertyValue(value, options) { value = parseFloat(value); var sanitizedValue = (value % 360 + 360) % 360; if (!isNaN(sanitizedValue)) { _this2._updateStyleValueInModel('-webkit-transform', 'rotate( ' + sanitizedValue + 'deg )', options); _this2._updateStyleValueInModel('transform', 'rotate( ' + sanitizedValue + 'deg )', options); } }, editor: { sectionId: 'general.layout.rotate', uiControl: { type: 'InputLabel', label: StringResources.get('propRotateAngle'), handleReturnKey: true, onChange: this._onChangeAngle.bind(this) } } }; if (isInGroup) { delete rotationProperty.editor; } propertyList.push(rotationProperty); } return propertyList; }; LayoutProperties.prototype._isCapabilityEnabled = function _isCapabilityEnabled(capability) { var capabilitiesFeature = ContentRegistryUtil.getCapabilities(this.content); return this.content.getType() !== 'widget.live' && (capabilitiesFeature ? capabilitiesFeature.getCapabilities()[capability] : true); }; LayoutProperties.prototype._getPropertyValueFromModel = function _getPropertyValueFromModel(propName) { var model = this.getLayoutModel(); // In case of livewidget previews, we have a content but it is not attached to the layout, which causes the model to be null. return model && model.get(propName); }; LayoutProperties.prototype._setPropertyValueInModel = function _setPropertyValueInModel(propName, propValue, options) { var payload = {}; var model = this.getLayoutModel(); payload[propName] = propValue; model.set(payload, options); }; LayoutProperties.prototype._updateStyleValueInModel = function _updateStyleValueInModel(styleName, value) { var styleValue = value; var model = this.getLayoutModel(); var newStyle = _.extend({}, model.style); newStyle[styleName] = styleValue; // Todo: we can stop using the topLayoutModel once the undo/redo uses // the API events, but for now using the model directly doesn't add to the stack // if the widget is not on the same tab that it was initally added on. model.getTopLayoutModel().updateModel({ updateArray: [{ id: model.id, style: newStyle }] }, this, { skipUndoRedo: true }); return styleValue; }; LayoutProperties.prototype._isTopLevelPage = function _isTopLevelPage() { return !this.content.getContainer(); }; return LayoutProperties; }(); return LayoutProperties; }); //# sourceMappingURL=LayoutPropertiesProvider.js.map