TextAction.js 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406
  1. 'use strict';
  2. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. /**
  4. * Licensed Materials - Property of IBM
  5. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2019, 2020
  6. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  7. */
  8. define(['underscore', 'dashboard-analytics/visualizations/vipr/VIPRUtils', '../../../../widgets/livewidget/nls/StringResources', 'dashboard-analytics/util/FontFamilyOptions', '../../../../lib/@waca/dashboard-common/dist/core/APIFactory', '../../../content/slotActions/api/SlotActionsProviderAPI', '../../../../util/ContentUtil'], function (_, VIPRUtils, stringResources, FontFamilyOptions, APIFactory, SlotActionsProviderAPI, ContentUtil) {
  9. var TextAction = function () {
  10. function TextAction(options) {
  11. _classCallCheck(this, TextAction);
  12. this.initialState = {
  13. fontSize: null,
  14. font: null,
  15. bold: false,
  16. italic: false,
  17. underline: false,
  18. justifyLeft: false,
  19. justifyCenter: false,
  20. justifyRight: false,
  21. color: null,
  22. textAlign: '',
  23. textWrap: false
  24. };
  25. this.localVisSuffix = {
  26. color: 'Color',
  27. fontSize: 'FontSize',
  28. font: 'FontFace',
  29. bold: 'FontBold',
  30. italic: 'FontItalic',
  31. underline: 'FontUnderline',
  32. textAlign: 'FontAlign',
  33. textWrap: 'TextWrap'
  34. };
  35. this.vidaVisSuffix = {
  36. color: '.color',
  37. fontSize: 'size',
  38. font: 'family',
  39. bold: 'weight',
  40. italic: 'style'
  41. };
  42. this.booleanProperty = ['weight', 'style'];
  43. this.selectedAreaPrefix = 'selectedArea';
  44. this.dashboard = options.dashboardAPI;
  45. this.content = options.content;
  46. this.icons = options.features['Dashboard.Icons'];
  47. this.colorsService = this.dashboard.getFeature('Colors');
  48. this.content.getFeature('DataPointActions').registerProvider('TextAction', this);
  49. this.content.getFeature('SlotActions').registerProvider('TextAction', this.getAPI());
  50. }
  51. //vida based visulization does not support text decoration and text alignment yet, widget.legend has the same naming pattern
  52. TextAction.prototype.getDataPointActionList = function getDataPointActionList(selections, options) {
  53. if (this._supportDataPointAction()) {
  54. if (options.isAreaSelected) {
  55. this.selectedArea = ContentUtil.getContextFromSelection(this.content, this.dashboard);
  56. // if the selection is not valid, disable the textAction
  57. if (!this.selectedArea.length) {
  58. return [];
  59. }
  60. this.isAreaSelected = true;
  61. } else {
  62. this.isAreaSelected = false;
  63. this.selectedArea = null;
  64. }
  65. return this.getContribution(null, selections.area);
  66. }
  67. return [];
  68. };
  69. TextAction.prototype._supportDataPointAction = function _supportDataPointAction() {
  70. if (this.dashboard.getMode() !== this.dashboard.MODES.EDIT) {
  71. return false;
  72. }
  73. return true;
  74. };
  75. TextAction.prototype.getSlotActionList = function getSlotActionList(slotId, index, options) {
  76. if (this._supportSlotAction(index)) {
  77. if (options && options.isAreaSelected) {
  78. // textAction is not actually a slot action, should only have measure title selection here
  79. this.selectedArea = this._getContextFromSlot(slotId, index);
  80. // if the selection is not valid, disable the textAction
  81. if (!this.selectedArea.length) {
  82. return [];
  83. }
  84. this.isAreaSelected = true;
  85. } else {
  86. this.isAreaSelected = false;
  87. this.selectedArea = null;
  88. }
  89. return this.getContribution(slotId, options && options.area);
  90. }
  91. return [];
  92. };
  93. TextAction.prototype._getContextFromSlot = function _getContextFromSlot(slotId, index) {
  94. var slot = this.content.getFeature('Visualization').getSlots().getSlot(slotId);
  95. var dataItemList = slot && slot.getDataItemList();
  96. var dataItemLabel = dataItemList && dataItemList[index] && dataItemList[index].getLabel();
  97. if (dataItemLabel) {
  98. return [dataItemLabel];
  99. }
  100. };
  101. TextAction.prototype._supportSlotAction = function _supportSlotAction(index) {
  102. if (this.content.getFeature('Visualization').getDefinition().getId() === 'summary') {
  103. return false;
  104. }
  105. if (this.dashboard.getMode() !== this.dashboard.MODES.EDIT) {
  106. return false;
  107. }
  108. if (Array.isArray(index) && index.length == 1) {
  109. return true;
  110. }
  111. if (index !== undefined) {
  112. return false;
  113. }
  114. return true;
  115. };
  116. TextAction.prototype._supportsTextWrap = function _supportsTextWrap(slotId, area) {
  117. var supportsTextWrapAreaList = this.content.getFeature('Visualization').getDefinition().getProperty('supportsTextWrap');
  118. return supportsTextWrapAreaList ? supportsTextWrapAreaList[area] || supportsTextWrapAreaList[slotId] : false;
  119. };
  120. TextAction.prototype.getContribution = function getContribution(slotId, area) {
  121. var _this = this;
  122. this.propertyPrefix = this.isAreaSelected ? this.selectedAreaPrefix : this.constructPropertyPrefix(slotId, area);
  123. this.groupedProperty = this.content.getFeature('Visualization').getDefinition().getProperty('groupedProperty');
  124. if (this.propertyPrefix) {
  125. this.currentProps = this.content.getPropertyNameList().map(function (prop) {
  126. return { id: prop, value: _this.content.getPropertyValue(prop) };
  127. });
  128. var currentState = {};
  129. this.isLocalVis = this._isLocalVis(this.content.getFeature('Visualization').getDefinition().getId());
  130. this.propertySuffix = this.isLocalVis ? this.localVisSuffix : this.vidaVisSuffix;
  131. _.each(this.propertySuffix, function (value, prop) {
  132. currentState[prop] = _this.findCurrentProperties(_this.currentProps, value);
  133. });
  134. var elementListType = this.content.getFeature('Visualization').getDefinition().getProperty('supportsAdvancedProperties') ? 'default' : 'simpleTextEdit';
  135. var colorOptions = this._getTextColorOptions();
  136. var fontSizeOptions = this._getAppropriateFontSizes(area);
  137. var supportsTextWrap = this._supportsTextWrap(slotId, area);
  138. var viewOptions = {
  139. height: 140,
  140. width: 140,
  141. initialState: this.initialState,
  142. currentState: currentState,
  143. properties: {
  144. colors: colorOptions,
  145. fontSizes: fontSizeOptions,
  146. fonts: FontFamilyOptions
  147. },
  148. elementListType: elementListType,
  149. supportsTextWrap: supportsTextWrap
  150. };
  151. var commonTextEdit = this.icons.getIcon('common-text-edit');
  152. return [{
  153. name: 'text',
  154. text: stringResources.get('toolbarTextActionText'),
  155. label: stringResources.get('toolbarTextActionText'),
  156. icon: commonTextEdit.id,
  157. type: 'NextView',
  158. view: {
  159. module: 'dashboard-analytics/lib/@waca/dashboard-common/dist/ui/dialogs/TextToolbarCompactDialog',
  160. state: viewOptions
  161. },
  162. actions: {
  163. apply: this.onStateChange.bind(this)
  164. },
  165. showCaption: false
  166. }];
  167. }
  168. };
  169. /**
  170. * This method returns the appropriate font sizes that need to be shown. For the area type legend we are going to show 3 options and for the rest, 4 options.
  171. * @param {string} area
  172. * returns the Font Size object
  173. */
  174. TextAction.prototype._getAppropriateFontSizes = function _getAppropriateFontSizes(area) {
  175. var FONT_SIZE_OPTIONS = [{ value: '12px', label: '12px' }, { value: '14px', label: '14px' }, { value: '16px', label: '16px' }, { value: '24px', label: '24px' }];
  176. var LEGEND_FONT_SIZE_OPTIONS = [{ value: '11px', label: '11px' }, { value: '14px', label: '14px' }, { value: '16px', label: '16px' }];
  177. return area === 'legend' ? LEGEND_FONT_SIZE_OPTIONS : FONT_SIZE_OPTIONS;
  178. };
  179. TextAction.prototype.constructPropertyPrefix = function constructPropertyPrefix(currentSlotId, area) {
  180. var propertyPrefixesForWidget = this.content.getFeature('Visualization').getDefinition().getProperty('propertyPrefixes');
  181. var result = void 0;
  182. if (propertyPrefixesForWidget) {
  183. result = propertyPrefixesForWidget[area];
  184. if (result) {
  185. return result;
  186. } else {
  187. if (!currentSlotId && area === 'visualization') {
  188. return propertyPrefixesForWidget['dataPoint'];
  189. } else if (currentSlotId) {
  190. return propertyPrefixesForWidget[currentSlotId];
  191. }
  192. }
  193. }
  194. };
  195. TextAction.prototype._isLocalVis = function _isLocalVis(visId) {
  196. var localVis = ['summary', 'list', 'crosstab', 'JQGrid'];
  197. return _.contains(localVis, visId);
  198. };
  199. TextAction.prototype.findCurrentProperties = function findCurrentProperties(currentProps, propertyToFind) {
  200. var isFontProp = this.isLocalVis === false && propertyToFind !== '.color';
  201. var isColorProp = propertyToFind === '.color' || propertyToFind === 'Color';
  202. if (propertyToFind) {
  203. var findValue = this.propertyPrefix + (isFontProp ? '.font' : propertyToFind);
  204. } else {
  205. return undefined;
  206. }
  207. var propertyFound = this.findPropertyById(currentProps, findValue);
  208. if (currentProps === undefined || propertyFound === undefined) {
  209. var prefix = _.invert(this.propertySuffix)[propertyToFind];
  210. return this.initialState[prefix];
  211. } else if (propertyFound) {
  212. if (!isFontProp) {
  213. if (this.isAreaSelected) {
  214. // if multiple selections are made, show the first selection's value
  215. propertyFound.value = propertyFound.value && propertyFound.value[this.selectedArea[0]] && propertyFound.value[this.selectedArea[0]].value;
  216. }
  217. // if the property is a color property, we need to transform the color class value into hex value
  218. if (isColorProp && propertyFound.value !== null && typeof propertyFound.value === 'string' && !this._isHexColor(propertyFound.value)) {
  219. return this.colorsService.getHexColorFromDashboardColorSet(propertyFound.value);
  220. }
  221. return propertyFound.value;
  222. } else {
  223. return VIPRUtils.getVidaFontPropertiesPart(propertyToFind, propertyFound.value);
  224. }
  225. }
  226. };
  227. TextAction.prototype._isHexColor = function _isHexColor(val) {
  228. return val.indexOf('#') === 0 && val.length === 7;
  229. };
  230. TextAction.prototype.findPropertyById = function findPropertyById(properties, id) {
  231. var foundProperty = _.find(properties, function (property) {
  232. return property.id === id;
  233. });
  234. return foundProperty;
  235. };
  236. TextAction.prototype._getTextColorOptions = function _getTextColorOptions() {
  237. var colorPalette = this.colorsService.getDashboardColorSet().filter(function (item) {
  238. return item.id !== 'transparent';
  239. });
  240. var colorOptions = [];
  241. _.each(colorPalette, function (color) {
  242. colorOptions.push(color.hexValue);
  243. });
  244. return colorOptions;
  245. };
  246. TextAction.prototype.onStateChange = function onStateChange(stateChanges) {
  247. var propertyList = [];
  248. if (this.propertyPrefix) {
  249. if (this.isLocalVis) {
  250. propertyList = this._buildLocalVisPropertyList(stateChanges, propertyList);
  251. } else {
  252. propertyList = this._buildVidaVisPropertyList(stateChanges, propertyList);
  253. }
  254. }
  255. this.editProperties(propertyList);
  256. };
  257. TextAction.prototype._buildLocalVisPropertyList = function _buildLocalVisPropertyList(stateChanges, propertyList) {
  258. var _this2 = this;
  259. var changedStates = Object.keys(stateChanges);
  260. _.each(changedStates, function (changedState) {
  261. if (_this2.propertySuffix[changedState]) {
  262. var propertyName = _this2.propertyPrefix + _this2.propertySuffix[changedState];
  263. var isColorProp = changedState === 'color';
  264. // the text toolbar will set the hex color value, we need to transform the value into color class value before saved in the model
  265. var newPropertyVal = isColorProp && stateChanges[changedState] !== null ? _this2._findColorIdFromHex(stateChanges[changedState]) : stateChanges[changedState];
  266. if (_this2.isAreaSelected) {
  267. var currentPropertyValue = JSON.parse(JSON.stringify(_this2.content.getPropertyValue(propertyName) || {}));
  268. _.each(_this2.selectedArea, function (selectedArea) {
  269. // the text formatting for selection need to be applied in order, whichever comes last should win, use timestamp as the weight to sort the order here
  270. currentPropertyValue[selectedArea] = {
  271. value: newPropertyVal,
  272. weight: Date.now()
  273. };
  274. });
  275. newPropertyVal = currentPropertyValue;
  276. }
  277. propertyList.push({ 'id': propertyName, 'value': newPropertyVal });
  278. if (_this2.groupedProperty && _.has(_this2.groupedProperty, propertyName)) {
  279. _.each(_this2.groupedProperty[propertyName], function (prop) {
  280. propertyList.push({ 'id': prop, 'value': newPropertyVal });
  281. });
  282. }
  283. }
  284. });
  285. return propertyList;
  286. };
  287. TextAction.prototype._buildVidaVisPropertyList = function _buildVidaVisPropertyList(stateChanges, propertyList) {
  288. var _this3 = this;
  289. var vidaPropertyList = [];
  290. var fontParts = _.pick(stateChanges, 'font', 'fontSize');
  291. var colorPart = _.pick(stateChanges, 'color');
  292. if (!_.isEmpty(fontParts)) {
  293. var fontPropName = this.propertyPrefix + '.font';
  294. var currentPropertyValue = this.content.getPropertyValue(fontPropName);
  295. var fontProperty = VIPRUtils.buildVidaFontPropertiesFromParts(fontParts, currentPropertyValue);
  296. vidaPropertyList.push({ id: fontPropName, value: fontProperty });
  297. }
  298. if (!_.isEmpty(colorPart)) {
  299. //build color property
  300. var colorPropName = this.propertyPrefix + '.color';
  301. // the text toolbar will set the hex color value, we need to transform the value into color class value before saved in the model
  302. var colorPropValue = colorPart['color'] !== null ? this._findColorIdFromHex(colorPart['color']) : colorPart['color'];
  303. vidaPropertyList.push({ id: colorPropName, value: colorPropValue });
  304. }
  305. vidaPropertyList.forEach(function (vidaProperty) {
  306. if (_this3.groupedProperty && _.has(_this3.groupedProperty, vidaProperty.id)) {
  307. _.each(_this3.groupedProperty[vidaProperty.id], function (id) {
  308. return vidaPropertyList.push({ 'id': id, 'value': vidaProperty.value });
  309. });
  310. }
  311. });
  312. return propertyList.concat(vidaPropertyList);
  313. };
  314. TextAction.prototype._findColorIdFromHex = function _findColorIdFromHex(colorValue) {
  315. var colorPalette = this.colorsService.getDashboardColorSet().filter(function (item) {
  316. return item.id !== 'transparent';
  317. });
  318. var found = _.find(colorPalette, function (color) {
  319. return color.hexValue.toUpperCase() === colorValue.toUpperCase();
  320. });
  321. if (!found) {
  322. return this.colorsService.getColorClassName(colorValue);
  323. } else {
  324. return found.id;
  325. }
  326. };
  327. /**
  328. * This method sets the vis properties to the value given
  329. * @param propertyList - the propertyList that trigerred the state change
  330. */
  331. TextAction.prototype.editProperties = function editProperties(propertyList) {
  332. var _this4 = this;
  333. var transactionToken = this.dashboard.getFeature('Transaction').startTransaction();
  334. propertyList.forEach(function (prop) {
  335. _this4.content.setPropertyValue(prop.id, prop.value, transactionToken);
  336. });
  337. this.dashboard.getFeature('Transaction').endTransaction(transactionToken);
  338. };
  339. TextAction.prototype.getAPI = function getAPI() {
  340. if (!this._api) {
  341. this._api = APIFactory.createAPI(this, [SlotActionsProviderAPI]);
  342. }
  343. return this._api;
  344. };
  345. return TextAction;
  346. }();
  347. return TextAction;
  348. });
  349. //# sourceMappingURL=TextAction.js.map