123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381 |
- '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. 2015, 2020
- * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
- */
- define(['jquery', 'underscore', '../../app/util/DeepClone'], function ($, _) {
- var LayoutHelper = function () {
- function LayoutHelper() {
- _classCallCheck(this, LayoutHelper);
- }
- LayoutHelper.setPreferredAddOptions = function setPreferredAddOptions(addOptions, topLayoutModel, dashboardApi) {
- // if we have no parent Id, we will add to the last visible page
- if (!addOptions.parentId) {
- var lastPage = LayoutHelper.getLastVisiblePage(topLayoutModel.id, null, dashboardApi);
- if (lastPage) {
- addOptions.parentId = LayoutHelper.nodeIdToModelId(lastPage.id);
- }
- }
- var sourceModel = addOptions.model;
- LayoutHelper.setPreferredLocation(addOptions);
- if (addOptions.copyPaste) {
- LayoutHelper._setCopyPasteLayout(addOptions, sourceModel, topLayoutModel, dashboardApi);
- }
- };
- LayoutHelper.setPreferredLocation = function setPreferredLocation(addOptions) {
- // Ask the layout to update the layout properties with preferred options (e.g. position)
- if (addOptions.parentId) {
- // find the layout object
- var nLayout = $('#' + LayoutHelper.modelIdToNodeId(addOptions.parentId), this.$el)[0];
- if (nLayout && nLayout._layout && nLayout._layout.setPreferredLocation) {
- if (!addOptions.layoutProperties) {
- addOptions.layoutProperties = {};
- }
- nLayout._layout.setPreferredLocation(addOptions);
- }
- }
- };
- /**
- * Paste a widget to current page via using the copy-paste functionality
- * the pasted widget into the current page will be the same size as the source widget
- * Its position will be slightly offset from the source widget
- * the insertBefore id is null (because we want it pasted in front of the source widget).
- * @addOptions
- * @sourceModel the copied model
- */
- LayoutHelper._setCopyPasteLayout = function _setCopyPasteLayout(addOptions, sourceModel, topLayoutModel, dashboardApi) {
- var currentPage = LayoutHelper.getLayoutContentContainer(topLayoutModel.id, null, dashboardApi);
- var currentPageId = LayoutHelper.nodeIdToModelId(currentPage.id);
- var topItem = topLayoutModel.findModel(currentPageId);
- if (!currentPage || !topItem || !(sourceModel.layout && sourceModel.layout.style || sourceModel.style)) {
- return;
- }
- addOptions.insertBefore = null;
- addOptions.parentId = topItem.id;
- var properties = addOptions.layoutProperties;
- if (!properties.style) {
- properties.style = {};
- }
- // Convert top, left, width and height to pixel values so that they can be used in the out of bounds calculations
- var sourceStyle = sourceModel.layout && sourceModel.layout.style ? sourceModel.layout.style : sourceModel.style;
- var startingTop = sourceStyle.top;
- var startingLeft = sourceStyle.left;
- if (LayoutHelper._isOffsetAdjustmentRequired(currentPageId, topLayoutModel, dashboardApi)) {
- // Start from the source widget location, increment top and left offset in a loop until you find a location
- // with no widget. Then place that widget there. Set to a maximum of 30 so there is no possiblility of an inifnite lo
- var styles = topItem.items.map(function (x) {
- return x.style;
- });
- var counter = 0,
- newStartingTop = 0,
- newStartingLeft = 0;
- while (counter < 30) {
- var array = styles.filter(function (style) {
- return style.top === startingTop && style.left === startingLeft;
- });
- if (array && array.length === 0) {
- break;
- }
- newStartingTop = LayoutHelper._incrementStyleValue(startingTop);
- newStartingLeft = LayoutHelper._incrementStyleValue(startingLeft);
- if (LayoutHelper._isOutOfBounds(newStartingTop, sourceStyle.height, currentPage.clientHeight) === true || LayoutHelper._isOutOfBounds(newStartingLeft, sourceStyle.width, currentPage.clientWidth) === true) {
- break;
- }
- startingTop = newStartingTop;
- startingLeft = newStartingLeft;
- counter++;
- }
- }
- properties.style.top = startingTop;
- properties.style.left = startingLeft;
- properties.style.width = sourceStyle.width;
- properties.style.height = sourceStyle.height;
- };
- // Check if the current page has any existed widgets or registered content types
- // @currentPageId current page Id
- // @return true if currentPage has any widget or registered content types
- // false otherwise
- LayoutHelper._isOffsetAdjustmentRequired = function _isOffsetAdjustmentRequired(currentPageId, topLayoutModel, dashboardApi) {
- var currentPage = topLayoutModel.findModel(currentPageId);
- var types = ['widget'];
- var contentTypeRegistry = dashboardApi.getFeature('ContentTypeRegistry');
- types = types.concat(contentTypeRegistry.getRegisteredTypes());
- var layouts = currentPage.findDescendantsWithType(types);
- if (layouts.length > 0) {
- return true;
- } else {
- return false;
- }
- };
- LayoutHelper._incrementStyleValue = function _incrementStyleValue(value) {
- var val = value.match(/[0-9\\.]+/g),
- unit = value.match(/[^0-9\\.]+/g);
- if (val == null || unit == null || val.isEmpty || unit.isEmpty) {
- return value;
- }
- var newValue = parseFloat(val[0]);
- if (unit[0] === '%') {
- newValue = newValue + 5;
- } else {
- newValue = newValue + 25;
- }
- return newValue + unit[0];
- };
- /**
- * Given an origin and a dimension (height or width), calculates if the origin+dimension is out of bounds (above max)
- */
- LayoutHelper._isOutOfBounds = function _isOutOfBounds(origin, dimension, max) {
- var newOrigin = LayoutHelper._getPixelValue(origin, max);
- var newDimension = LayoutHelper._getPixelValue(dimension, max);
- return newOrigin > max - newDimension;
- };
- LayoutHelper._getPixelValue = function _getPixelValue(value, maxValue) {
- if (value[value.length - 1] === '%') {
- return parseFloat(value) / 100 * parseFloat(maxValue);
- } else {
- return parseFloat(value);
- }
- };
- /**
- * Return the model id for a given node id
- * @param nodeId
- * @returns
- */
- LayoutHelper.nodeIdToModelId = function nodeIdToModelId(nodeId) {
- return nodeId;
- };
- /**
- * Return the node id for a given model id
- * @param modelId
- * @returns
- */
- LayoutHelper.modelIdToNodeId = function modelIdToNodeId(modelId) {
- return modelId;
- };
- /**
- * Find the last selected page to insert. If not found, find the last visible page. For example, if you have this hierarchy of pages: Block/Tab/Absolute.
- * It will return the Absolute of the selected tab.
- * @param id of topLayoutModel
- */
- LayoutHelper.getLayoutContentContainer = function getLayoutContentContainer(topLayoutModelId, id, dashboardApi) {
- var findDropPage = function findDropPage(nTopPage) {
- var isMultiTab = false;
- var nSelectedPage = $('.pageTabContent .page:not(.pagegroup):not(.pagetemplateDropZone):not(.pagetemplateIndicator)', $(nTopPage)).filter(function (i, page) {
- isMultiTab = true;
- if (id) {
- return $('#' + id, page).length > 0;
- }
- // filter out the pages whose parent container is selected
- return $(this).closest('.pageTabContent').hasClass('selected');
- }).last();
- if (!isMultiTab) {
- var nLastPage = $('.page:not(.pagegroup):not(.pagetemplateDropZone):not(.pagetemplateIndicator)', $(nTopPage)).filter(function (i, page) {
- isMultiTab = true;
- if (id) {
- return $('#' + id, page).length > 0;
- }
- // filter out the hidden pages
- return $(this).is(':visible');
- }).last();
- return nLastPage && nLastPage[0] || nTopPage;
- } else {
- if (nSelectedPage && nSelectedPage[0]) {
- return nSelectedPage[0];
- } else if (dashboardApi) {
- var stringResources = dashboardApi.getDashboardCoreSvc('.StringResources');
- var translation = stringResources.get('pageSelectWarning');
- dashboardApi.showToast(translation, { type: 'info' });
- }
- }
- };
- var nPage = findDropPage(document.getElementById(topLayoutModelId));
- return nPage;
- };
- /**
- * Find the genericPage for the dropTarget, and if found, return the dropTargetNode as the content container node.
- * If not found, find the last visible page. It will return the Absolute of this page as the content container node.
- * @param {node} dropTargetNode
- * @param {modelObject} topLayoutModel
- * @param {apiInstance} dashboardApi
- */
- LayoutHelper.getLayoutContentContainerForDropTarget = function getLayoutContentContainerForDropTarget(dropTargetNode, topLayoutModel, dashboardApi) {
- if (dropTargetNode) {
- var layoutModelId = $(dropTargetNode).attr('id');
- var layoutModel = topLayoutModel && topLayoutModel.findModel(layoutModelId);
- if (layoutModel && layoutModel.type === 'genericPage') {
- return dropTargetNode;
- }
- }
- return LayoutHelper.getLayoutContentContainer(topLayoutModel.id, null, dashboardApi);
- };
- /**
- * Find the last selected page to insert. If not found, find the last visible dropzone. For example, if you have this hierarchy of pages: Block/Tab/Relative/templateDropZone.
- * It will return the the templateDropZone of the selected tab that the widget is apart of.
- * @param id of topLayoutModel
- */
- LayoutHelper.getLastVisiblePage = function getLastVisiblePage(topLayoutModelId, id, dashboardApi) {
- var nPage = LayoutHelper.getLayoutContentContainer(topLayoutModelId, id, dashboardApi);
- // Now check if we have an empty drop zone. If yes, we will use it
- var emptyDropZones = $(nPage).find('.pagetemplateDropZone.empty');
- return emptyDropZones.length > 0 ? emptyDropZones[0] : nPage;
- };
- /**
- * @returns container Page id containing the layout id
- * @param topLayoutModel
- */
- LayoutHelper.getContainerPageId = function getContainerPageId(topLayoutModel, id) {
- var topParent = topLayoutModel.findTopLevelParentItem(id);
- if (topParent) {
- return topParent.id;
- }
- return undefined;
- };
- /**
- * Calculates the minimum bounding page size to contain its widgets on absolute layout pages
- * @param layoutModel The layout model to start calculating the minimum bounding page size
- * @param minimumPageSize The minimum page size (optional)
- * @returns (object { width: xxx, height: xxx }) The smallest page size (pixels) that can contain all widgets in the given model
- */
- LayoutHelper.getBoundingPageSize = function getBoundingPageSize(layoutModel, minimumPageSize) {
- if (!layoutModel) {
- return undefined;
- }
- var boundingPageSize = { width: 0, height: 0 };
- var pageModels = void 0;
- // Get the starting point pages
- if (layoutModel.type === 'genericPage') {
- pageModels = [layoutModel];
- } else {
- pageModels = layoutModel.findDescendantsWithType('genericPage');
- }
- if (minimumPageSize) {
- boundingPageSize = _.deepClone(minimumPageSize);
- }
- for (var _iterator = pageModels, _isArray = Array.isArray(_iterator), _i = 0, _iterator = _isArray ? _iterator : _iterator[Symbol.iterator]();;) {
- var _ref;
- if (_isArray) {
- if (_i >= _iterator.length) break;
- _ref = _iterator[_i++];
- } else {
- _i = _iterator.next();
- if (_i.done) break;
- _ref = _i.value;
- }
- var pageModel = _ref;
- if (pageModel.layoutPositioning === 'absolute') {
- var itemLayoutModels = pageModel.findDescendantsWithType(['widget', 'group']);
- for (var _iterator2 = itemLayoutModels, _isArray2 = Array.isArray(_iterator2), _i2 = 0, _iterator2 = _isArray2 ? _iterator2 : _iterator2[Symbol.iterator]();;) {
- var _ref2;
- if (_isArray2) {
- if (_i2 >= _iterator2.length) break;
- _ref2 = _iterator2[_i2++];
- } else {
- _i2 = _iterator2.next();
- if (_i2.done) break;
- _ref2 = _i2.value;
- }
- var itemLayoutModel = _ref2;
- var rawStyle = LayoutHelper._getRawStyle(itemLayoutModel.style, 'px');
- if (rawStyle) {
- var right = rawStyle.left + rawStyle.width;
- if (right > boundingPageSize.width) {
- boundingPageSize.width = right;
- }
- var bottom = rawStyle.top + rawStyle.height;
- if (bottom > boundingPageSize.height) {
- boundingPageSize.height = bottom;
- }
- }
- }
- }
- }
- return boundingPageSize && boundingPageSize.width ? boundingPageSize : undefined;
- };
- LayoutHelper._getRawStyle = function _getRawStyle(style, units) {
- // Validate style units
- if (style.left.indexOf(units) !== -1 && style.top.indexOf(units) !== -1 && style.width.indexOf(units) !== -1 && style.height.indexOf(units) !== -1) {
- return {
- left: parseInt(style.left, 10),
- top: parseInt(style.top, 10),
- width: parseInt(style.width, 10),
- height: parseInt(style.height, 10)
- };
- }
- return undefined;
- };
- LayoutHelper.styleIntToPx = function styleIntToPx(style) {
- style.top = style.top + 'px';
- style.left = style.left + 'px';
- style.width = style.width + 'px';
- style.height = style.height + 'px';
- };
- return LayoutHelper;
- }();
- return LayoutHelper;
- });
- //# sourceMappingURL=LayoutHelper.js.map
|