TranslationService.js 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874
  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. 2018, 2020
  6. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  7. */
  8. define(['jquery', 'underscore', '../../app/nls/StringResources', 'doT', 'text!../../common/templates/TranslationOverlayTemplate.html', '../../app/ui/dialogs/ConfirmationDialog', '../util/ButtonHideHelper', '../../lib/@waca/core-client/js/core-client/utils/Utils'], function ($, _, StringResources, dot, TranslationOverlay, ConfirmationDialog, ButtonHideHelper, Utils) {
  9. 'use strict';
  10. var TranslationService = function () {
  11. /**
  12. * @param options.glassContext - glass context
  13. * @param options.eventRouter - event router
  14. */
  15. function TranslationService(options) {
  16. _classCallCheck(this, TranslationService);
  17. _.extend(this, options);
  18. this.blacklistCSVAttributes = ['titleHtml'];
  19. this.propsStoredAsHTML = ['content'];
  20. this.localizedItems = {};
  21. this.dashboardApi.getFeature('Properties').registerProvider(this);
  22. this._icons = this.dashboardApi.getFeature('Icons');
  23. this.registeredHandlers = [];
  24. }
  25. /**
  26. * @param options.view
  27. * @param options.model
  28. */
  29. TranslationService.prototype.registerView = function registerView(options) {
  30. this.localizedItems[options.model.id] = options;
  31. if (this.isInTranslationMode()) {
  32. this._startModelTranslationMode(options.model, options.view, this._getTranslationModeLocale());
  33. }
  34. };
  35. /**
  36. * @param options.model
  37. */
  38. TranslationService.prototype.deregisterView = function deregisterView(id) {
  39. if (this.isInTranslationMode()) {
  40. this._endModelTranslationMode(this.localizedItems[id].model, this.localizedItems[id].view, true);
  41. }
  42. delete this.localizedItems[id];
  43. };
  44. /**
  45. * @param options.defaultLocale
  46. */
  47. TranslationService.prototype.initialize = function initialize(options) {
  48. var _this = this;
  49. this.$el = options.view;
  50. this.boardModel = options.boardModel;
  51. this.defaultLocale = options.boardModel.properties.defaultLocale;
  52. options.boardModel.properties.on('change:translationModeLocale', this._onChangeTranslationMode, this);
  53. options.boardModel.properties.on('change:defaultLocale', this._onChangeDefaultLocale, this);
  54. options.boardModel.properties.on('change:switchLanguageInfo', this._onChangeToLocale, this);
  55. this._contentLocalesPromise = this.dashboardApi.getFeature('UserProfile').getAvailableContentLocales().then(function (locales) {
  56. _this._contentLocales = locales;
  57. });
  58. // [perf] we started this in the ctor...
  59. return this._contentLocalesPromise;
  60. };
  61. /**
  62. * Returns an array of radio button property specs to show in the select a language slideout
  63. */
  64. TranslationService.prototype.getLanguageRadioItems = function getLanguageRadioItems() {
  65. var languageList = [];
  66. var selectedLanguages = this.getSelectedLanguages();
  67. if (this.getDefaultLanguage() === 'Default') {
  68. // If a defaultLocale hasn't been chosen, 'Default' will be one of the selected languages
  69. // we need to remove any selected languages so any default may be chosen
  70. selectedLanguages = [];
  71. }
  72. _.each(this._contentLocales, function (label, value) {
  73. if (selectedLanguages.indexOf(value) === -1) {
  74. languageList.push({
  75. value: value,
  76. label: label
  77. });
  78. }
  79. });
  80. return languageList;
  81. };
  82. TranslationService.prototype.getContentLocales = function getContentLocales() {
  83. return this._contentLocales;
  84. };
  85. TranslationService.prototype.getLanguageName = function getLanguageName(languageId) {
  86. return this._contentLocales[languageId];
  87. };
  88. TranslationService.prototype._onChangeTranslationMode = function _onChangeTranslationMode() {
  89. var translationModeLocale = this._getTranslationModeLocale();
  90. if (!translationModeLocale) {
  91. this._endTranslationMode();
  92. } else {
  93. this._startTranslationMode(translationModeLocale);
  94. }
  95. };
  96. TranslationService.prototype._getTranslationModeLocale = function _getTranslationModeLocale() {
  97. return this.boardModel.properties.get('translationModeLocale');
  98. };
  99. TranslationService.prototype.isInTranslationMode = function isInTranslationMode() {
  100. return this.translationModeOn;
  101. };
  102. /**
  103. * Use a property in the model to trigger the translation mode so that
  104. * we can take advantage of the undo/redo stack
  105. */
  106. TranslationService.prototype.startTranslationMode = function startTranslationMode(selectedLanguage) {
  107. this.boardModel.setTranslationLocale(selectedLanguage);
  108. };
  109. TranslationService.prototype.endTranslationMode = function endTranslationMode() {
  110. this.boardModel.setTranslationLocale(null);
  111. };
  112. TranslationService.prototype._startTranslationMode = function _startTranslationMode(selectedLanguage) {
  113. var translationOverlay = dot.template(TranslationOverlay)({
  114. 'text': StringResources.get('multilingualDashboardTranslationMode', {
  115. currentLanguage: this.getLanguageName(selectedLanguage)
  116. }),
  117. 'buttonText': StringResources.get('multilingualDashboardTranslationDone')
  118. });
  119. this.$el.append(translationOverlay);
  120. this.$el.find('.translate-button').click(this.endTranslationMode.bind(this));
  121. this.translationModeOn = true;
  122. this.translationModeLanguage = selectedLanguage;
  123. this.eventRouter.trigger('properties:refreshPane');
  124. ButtonHideHelper.changeMode(this.glassContext, 'translation');
  125. this.numTranslationsLeft = 0;
  126. this.showingMissingTranslationCount = false;
  127. for (var itemId in this.localizedItems) {
  128. var _localizedItems$itemI = this.localizedItems[itemId],
  129. model = _localizedItems$itemI.model,
  130. view = _localizedItems$itemI.view;
  131. this._startModelTranslationMode(model, view, selectedLanguage);
  132. }
  133. };
  134. TranslationService.prototype._startModelTranslationMode = function _startModelTranslationMode(model, view, selectedLanguage) {
  135. var _this2 = this;
  136. var multilingualAttributesInfo = model.getMultilingualAttributes();
  137. var missingTranslationMultilingualAttributesInfo = [];
  138. var localizedItem = this.localizedItems[model.id];
  139. if (localizedItem.enterTranslationMode) {
  140. localizedItem.enterTranslationMode();
  141. }
  142. multilingualAttributesInfo.forEach(function (multilingualAttributeInfo) {
  143. var propertyName = multilingualAttributeInfo.propertyName,
  144. propertyParentModel = multilingualAttributeInfo.propertyParentModel,
  145. multilingualProperty = multilingualAttributeInfo.multilingualProperty;
  146. multilingualProperty.startTranslation(selectedLanguage);
  147. if (_this2.dashboardApi && propertyParentModel.multilingual) {
  148. var content = _this2.dashboardApi.getCanvas().getContent(model.id);
  149. content.on('change:property:' + multilingualAttributeInfo.propertyParentModel.name, _this2._onPropertyChange.bind(_this2, model.id, model, multilingualAttributeInfo.propertyParentModel.name));
  150. } else {
  151. var handler = propertyParentModel.on('change:' + propertyName, _this2._onPropertyChange.bind(_this2, model.id, propertyParentModel, propertyName));
  152. _this2.registeredHandlers.push(handler);
  153. }
  154. if (Object.keys(multilingualProperty.translationTable).length === 0) {
  155. return;
  156. }
  157. if (multilingualProperty.needsTranslation()) {
  158. missingTranslationMultilingualAttributesInfo.push(multilingualAttributeInfo);
  159. } else {
  160. _this2._updateView(propertyParentModel, propertyName, _this2.localizedItems[model.id]);
  161. }
  162. });
  163. if (missingTranslationMultilingualAttributesInfo.length > 0) {
  164. this._appendTranslationIcon(view, missingTranslationMultilingualAttributesInfo);
  165. }
  166. };
  167. TranslationService.prototype._onPropertyChange = function _onPropertyChange(modelId, parentModel, propertyName) {
  168. var multilingualAttributeInfo = parentModel.getMultilingualAttribute(propertyName);
  169. if (!multilingualAttributeInfo) {
  170. return;
  171. }
  172. var multilingualProperty = multilingualAttributeInfo.multilingualProperty;
  173. var view = this.localizedItems[modelId].view;
  174. if (multilingualProperty.needsTranslation()) {
  175. this._appendTranslationIcon(view, [multilingualAttributeInfo]);
  176. } else {
  177. this._removeTranslationIcon(view, [multilingualAttributeInfo]);
  178. }
  179. };
  180. TranslationService.prototype._endTranslationMode = function _endTranslationMode() {
  181. this.$el.find('div.translate-overlay').remove();
  182. this.translationModeOn = false;
  183. this.showingMissingTranslationCount = false;
  184. for (var itemId in this.localizedItems) {
  185. var item = this.localizedItems[itemId];
  186. this._endModelTranslationMode(item.model, item.view, false);
  187. }
  188. this.eventRouter.trigger('properties:refreshPane', {
  189. focusSelector: '.clickablelanguage_' + this.translationModeLanguage
  190. });
  191. ButtonHideHelper.changeMode(this.glassContext, 'authoring');
  192. };
  193. TranslationService.prototype._endModelTranslationMode = function _endModelTranslationMode(model, view, deregisteringView) {
  194. var _this3 = this;
  195. var localizedItem = this.localizedItems[model.id];
  196. if (localizedItem.leaveTranslationMode) {
  197. localizedItem.leaveTranslationMode();
  198. }
  199. this.registeredHandlers.forEach(function (handler) {
  200. handler.remove();
  201. });
  202. this.registeredHandlers = [];
  203. var multilingualAttributesInfo = model.getMultilingualAttributes();
  204. multilingualAttributesInfo.forEach(function (multilingualAttributeInfo) {
  205. var propertyName = multilingualAttributeInfo.propertyName,
  206. propertyParentModel = multilingualAttributeInfo.propertyParentModel,
  207. multilingualProperty = multilingualAttributeInfo.multilingualProperty;
  208. multilingualProperty.stopTranslation();
  209. if (!deregisteringView) {
  210. _this3._updateView(propertyParentModel, propertyName, _this3.localizedItems[model.id]);
  211. }
  212. if (_this3.dashboardApi && propertyParentModel.multilingual) {
  213. var content = _this3.dashboardApi.getCanvas().getContent(model.id);
  214. content.off('change:property:' + multilingualAttributeInfo.propertyParentModel.name, _this3._onPropertyChange.bind(_this3, model.id, model, multilingualAttributeInfo.propertyParentModel.name));
  215. }
  216. });
  217. this._removeTranslationIcon(view, multilingualAttributesInfo);
  218. };
  219. /**
  220. * Will cause the view/text to get updated so the correct string (locale) is shown
  221. */
  222. TranslationService.prototype._updateView = function _updateView(mode, propertyName, localizedItem) {
  223. if (localizedItem.reRender) {
  224. localizedItem.reRender();
  225. } else {
  226. this._triggerTextUpdate(mode, propertyName);
  227. }
  228. };
  229. TranslationService.prototype._triggerTextUpdate = function _triggerTextUpdate(model, propertyName) {
  230. var obj = {};
  231. obj[propertyName] = model.get(propertyName); //TODO fix this in Endor with ES6
  232. model.set(obj, {
  233. payloadData: {
  234. forceEvent: true,
  235. skipUndoRedo: true
  236. },
  237. sender: 'TranslationService'
  238. });
  239. };
  240. /**
  241. * Adds the translation icon
  242. * @param {Object} view - the view that was registered with the translation service
  243. * @param {Array} multilingualAttributesInfo - All the information about the multilingual attributes in the model that are missing translations
  244. */
  245. TranslationService.prototype._appendTranslationIcon = function _appendTranslationIcon(view, multilingualAttributesInfo) {
  246. // We should never append translation icons if we're not in translation mode
  247. if (!this.isInTranslationMode()) {
  248. return;
  249. }
  250. if (view.addTranslationIcon) {
  251. this.numTranslationsLeft += view.addTranslationIcon(multilingualAttributesInfo);
  252. } else {
  253. this.appendTranslationIcon(view.$el);
  254. this.numTranslationsLeft++;
  255. }
  256. this._displayRemainingMessage();
  257. };
  258. TranslationService.prototype.appendTranslationIcon = function appendTranslationIcon($el) {
  259. if (this.isInTranslationMode()) {
  260. var $iconContainer = $('<div class="translateIcon"></div>');
  261. Utils.setIcon($iconContainer, this._icons.getIcon('warning').id, StringResources.get('multilingualDashboardIconTranslatableArea'));
  262. $el.append($iconContainer);
  263. }
  264. };
  265. TranslationService.prototype.updateRemainingCount = function updateRemainingCount(delta) {
  266. if (delta !== 0) {
  267. this.showingMissingTranslationCount = true;
  268. }
  269. this.numTranslationsLeft += delta;
  270. this._displayRemainingMessage();
  271. };
  272. /**
  273. * Adds the translation icon
  274. * @param {Object} view - the view that was registered with the translation service
  275. * @param {Array} multilingualAttributesInfo - All the information about the multilingual attributes in the model for which we want the icon to be removed
  276. */
  277. TranslationService.prototype._removeTranslationIcon = function _removeTranslationIcon(view, multilingualAttributesInfo) {
  278. var el = view.$el;
  279. if (view.removeTranslationIcon) {
  280. var numRemoved = view.removeTranslationIcon(multilingualAttributesInfo);
  281. if (numRemoved) {
  282. this.updateRemainingCount(-numRemoved);
  283. }
  284. } else {
  285. if (this.hasTranslationIcon(el)) {
  286. this.updateRemainingCount(-1);
  287. this.removeTranslationIcon(el);
  288. }
  289. }
  290. };
  291. TranslationService.prototype.hasTranslationIcon = function hasTranslationIcon($el) {
  292. return $el.find('.translateIcon').length > 0;
  293. };
  294. TranslationService.prototype.removeTranslationIcon = function removeTranslationIcon($el) {
  295. $el.find('.translateIcon').remove();
  296. };
  297. TranslationService.prototype._displayRemainingMessage = function _displayRemainingMessage() {
  298. if (this.numTranslationsLeft >= 0 && this.showingMissingTranslationCount) {
  299. var remainingTranslations;
  300. if (this.numTranslationsLeft === 1) {
  301. remainingTranslations = StringResources.get('multilingualDashboardRemainingString');
  302. } else {
  303. remainingTranslations = StringResources.get('multilingualDashboardRemainingStrings', {
  304. numTranslationsLeft: this.numTranslationsLeft
  305. });
  306. }
  307. this.$el.find('.translate-text').text(remainingTranslations);
  308. }
  309. };
  310. TranslationService.prototype.downloadTranslations = function downloadTranslations(selectedLanguage) {
  311. var localizedStrings = this._getLocalizedStrings(selectedLanguage);
  312. var filename = 'OriginalStrings_' + selectedLanguage;
  313. this.dashboardApi.getFeature('CsvExport').export(filename, [localizedStrings]);
  314. };
  315. TranslationService.prototype.removeTranslations = function removeTranslations(selectedLanguage) {
  316. var _this4 = this;
  317. var language = this.getContentLocales()[selectedLanguage];
  318. var dlg = new ConfirmationDialog('warning', StringResources.get('multilingualDeleteTitle'), StringResources.get('multilingualDeleteLanguageWarning', { language: language }));
  319. dlg.confirm(function () {
  320. var undoRedoTransactionId = _.uniqueId('removeTranslations');
  321. for (var itemId in _this4.localizedItems) {
  322. var model = _this4.localizedItems[itemId].model;
  323. var multilingualAttributesInfo = model.getMultilingualAttributes();
  324. multilingualAttributesInfo.forEach(function (_ref) {
  325. var propertyName = _ref.propertyName,
  326. propertyParentModel = _ref.propertyParentModel;
  327. var payload = {};
  328. payload[propertyName] = {
  329. value: null,
  330. locale: selectedLanguage
  331. };
  332. propertyParentModel.set(payload, {
  333. sender: 'TranslationService',
  334. payloadData: {
  335. undoRedoTransactionId: undoRedoTransactionId
  336. }
  337. });
  338. });
  339. _this4._onMultilingualPropertyChange(itemId);
  340. }
  341. _this4.eventRouter.trigger('properties:refreshPane', {
  342. focusSelector: '.r_addLanguage-1'
  343. });
  344. }, function () {});
  345. };
  346. TranslationService.prototype.changeDefaultLanguage = function changeDefaultLanguage(selectedLanguage) {
  347. this.boardModel.properties.set({
  348. defaultLocale: selectedLanguage
  349. });
  350. };
  351. /**
  352. *
  353. * @param {Object} property It should has the following structure:
  354. * {
  355. * editor: {
  356. * uiControl: {}
  357. * }
  358. * }
  359. * @param {MultilingualAttribute Object} multilingualProperty
  360. * @returns The passed in property
  361. * @description This will end up being called by PropertyUIControlView after the property has been rendered.
  362. */
  363. TranslationService.prototype.processMultilingualProperty = function processMultilingualProperty(property, multilingualProperty) {
  364. if (multilingualProperty) {
  365. var appendTranslationIcon = function appendTranslationIcon($el) {
  366. if (multilingualProperty.needsTranslation()) {
  367. this.appendTranslationIcon($el);
  368. }
  369. };
  370. property.editor.uiControl.appendTranslationIcon = appendTranslationIcon.bind(this);
  371. }
  372. return property;
  373. };
  374. /**
  375. * Currently only needed by LiveWidget to deal with the fact they have 2 model representing the same information
  376. */
  377. TranslationService.prototype._onMultilingualPropertyChange = function _onMultilingualPropertyChange(modelId) {
  378. var localizedItem = this.localizedItems[modelId];
  379. if (localizedItem && localizedItem.onMultilingualPropertyChange) {
  380. localizedItem.onMultilingualPropertyChange();
  381. }
  382. };
  383. TranslationService.prototype._onChangeDefaultLocale = function _onChangeDefaultLocale() {
  384. var _this5 = this;
  385. var defaultLocale = this.getDefaultLanguage();
  386. this.boardModel.setDefaultLocale(defaultLocale);
  387. var _loop = function _loop(itemId) {
  388. var model = _this5.localizedItems[itemId].model;
  389. var multilingualAttributesInfo = model.getMultilingualAttributes();
  390. multilingualAttributesInfo.forEach(function (_ref2) {
  391. var propertyName = _ref2.propertyName,
  392. propertyParentModel = _ref2.propertyParentModel,
  393. multilingualProperty = _ref2.multilingualProperty;
  394. multilingualProperty.setDefaultLocale(defaultLocale);
  395. _this5._updateView(propertyParentModel, propertyName, _this5.localizedItems[itemId]);
  396. });
  397. _this5._onMultilingualPropertyChange(itemId);
  398. };
  399. for (var itemId in this.localizedItems) {
  400. _loop(itemId);
  401. }
  402. this.eventRouter.trigger('properties:refreshPane', {
  403. focusSelector: '.clickablelanguage_' + defaultLocale
  404. });
  405. };
  406. TranslationService.prototype._onChangeToLocale = function _onChangeToLocale() {
  407. var _this6 = this;
  408. var options = this.boardModel.properties.get('switchLanguageInfo');
  409. var _loop2 = function _loop2(itemId) {
  410. var model = _this6.localizedItems[itemId].model;
  411. var multilingualAttributesInfo = model.getMultilingualAttributes();
  412. multilingualAttributesInfo.forEach(function (_ref3) {
  413. var propertyName = _ref3.propertyName,
  414. propertyParentModel = _ref3.propertyParentModel,
  415. multilingualProperty = _ref3.multilingualProperty;
  416. multilingualProperty.switchLocale(options);
  417. _this6._updateView(propertyParentModel, propertyName, _this6.localizedItems[itemId]);
  418. });
  419. _this6._onMultilingualPropertyChange(itemId);
  420. };
  421. for (var itemId in this.localizedItems) {
  422. _loop2(itemId);
  423. }
  424. this.eventRouter.trigger('properties:refreshPane', {
  425. focusSelector: '.clickablelanguage_' + options.to
  426. });
  427. };
  428. /**
  429. * @param {String} options.from - locale switch from
  430. * @param {String} options.to - locale switching to
  431. */
  432. TranslationService.prototype.switchLanguage = function switchLanguage(options) {
  433. if (options.from === this.getDefaultLanguage()) {
  434. this.changeDefaultLanguage(options.to);
  435. } else {
  436. // Set the property silently so the undo/redo stack will get the correct 'before' value
  437. this.boardModel.properties.set({
  438. switchLanguageInfo: {
  439. from: options.to,
  440. to: options.from
  441. }
  442. }, {
  443. silent: true,
  444. payloadData: {
  445. skipUndoRedo: true
  446. }
  447. });
  448. this.boardModel.properties.set({
  449. switchLanguageInfo: options
  450. });
  451. }
  452. };
  453. TranslationService.prototype.getDefaultLanguage = function getDefaultLanguage() {
  454. return this.boardModel.get('properties').get('defaultLocale');
  455. };
  456. TranslationService.prototype._getLocalizedStrings = function _getLocalizedStrings(language) {
  457. var _this7 = this;
  458. var stringList = [];
  459. for (var itemId in this.localizedItems) {
  460. var model = this.localizedItems[itemId].model;
  461. var multilingualAttributes = model.getMultilingualAttributes();
  462. multilingualAttributes.forEach(function (_ref4) {
  463. var propertyName = _ref4.propertyName,
  464. multilingualProperty = _ref4.multilingualProperty;
  465. if (_this7.blacklistCSVAttributes.indexOf(propertyName) !== -1) {
  466. return;
  467. }
  468. var value = multilingualProperty.getValue(language);
  469. if (!value) {
  470. return;
  471. }
  472. if (_this7.propsStoredAsHTML.indexOf(propertyName) !== -1) {
  473. var $textNode = void 0;
  474. try {
  475. $textNode = $(value);
  476. } catch (error) {
  477. $textNode = [];
  478. } finally {
  479. if ($textNode.length) {
  480. value = $textNode.text();
  481. }
  482. }
  483. }
  484. value = value.trim();
  485. stringList.push(value);
  486. });
  487. }
  488. return stringList;
  489. };
  490. TranslationService.prototype._addTo = function _addTo(list, values) {
  491. return _.union(list, Object.keys(values));
  492. };
  493. /**
  494. * Gets all the locales the dashboard has been translated into
  495. */
  496. TranslationService.prototype.getSelectedLanguages = function getSelectedLanguages() {
  497. var languageList = [];
  498. for (var itemId in this.localizedItems) {
  499. var model = this.localizedItems[itemId].model;
  500. var multilingualAttributes = model.getMultilingualAttributes();
  501. multilingualAttributes.forEach(function (_ref5) {
  502. var multilingualProperty = _ref5.multilingualProperty;
  503. languageList = languageList.concat(multilingualProperty.getLanguages());
  504. });
  505. }
  506. return _.uniq(languageList);
  507. };
  508. TranslationService.prototype.destroy = function destroy() {
  509. if (this.dashboardApi) {
  510. this.dashboardApi.getFeature('Properties').deregisterProvider(this);
  511. }
  512. this.localizedItems = null;
  513. this._contentLocales = null;
  514. };
  515. TranslationService.prototype.getPropertyLayoutList = function getPropertyLayoutList() {
  516. return [{
  517. id: 'advanced',
  518. type: 'Section',
  519. label: StringResources.get('sectionName_advanced'),
  520. position: 99
  521. }, {
  522. id: 'languages',
  523. type: 'Section',
  524. label: StringResources.get('multilingualDashboardsLabel'),
  525. collapsible: false,
  526. style: 'light'
  527. }];
  528. };
  529. TranslationService.prototype.getPropertyList = function getPropertyList() {
  530. var propertiesManager = this.dashboardApi.getFeature('propertiesManager');
  531. if (!propertiesManager) {
  532. return [];
  533. }
  534. if (this.getDefaultLanguage() === 'Default') {
  535. //Advanced.languages property's selection list is populated using content locale list
  536. //Hide Advanced.languages property when there are no available content locales
  537. if (this.getContentLocales()) {
  538. return this._getLanguageSpecWhenNoLocaleSet(propertiesManager);
  539. } else {
  540. return [];
  541. }
  542. }
  543. return this._getMultilingualProperties(propertiesManager);
  544. };
  545. /**
  546. * Language property spec when no language has been selected yet
  547. */
  548. TranslationService.prototype._getLanguageSpecWhenNoLocaleSet = function _getLanguageSpecWhenNoLocaleSet(propertiesManager) {
  549. var _this8 = this;
  550. var defaultLanguage = this.getDefaultLanguage();
  551. return [{
  552. id: 'language_' + defaultLanguage,
  553. editor: {
  554. sectionId: 'general.advanced',
  555. position: 3,
  556. uiControl: {
  557. type: 'SingleLineLinks',
  558. items: [{
  559. align: 'left',
  560. items: [{
  561. type: 'text',
  562. id: 'text' + defaultLanguage,
  563. value: StringResources.get('multilingualDashboardsLabel')
  564. }]
  565. }, {
  566. align: 'right',
  567. items: [{
  568. type: 'text',
  569. value: StringResources.get('multilingualDashboardsSetDefault'),
  570. clickCallback: function clickCallback() {
  571. _this8.launchLanguageSelectSlideout(defaultLanguage, false, propertiesManager);
  572. }
  573. }]
  574. }]
  575. }
  576. }
  577. }];
  578. };
  579. TranslationService.prototype._getMultilingualProperties = function _getMultilingualProperties(propertiesManager) {
  580. var _this9 = this;
  581. var defaultLanguage = this.getDefaultLanguage();
  582. var properties = [].concat(this._createLanguageRow(defaultLanguage, true));
  583. // Rows for all other available languages
  584. this.getSelectedLanguages().sort(function (a, b) {
  585. return _this9.getLanguageName(a) > _this9.getLanguageName(b) ? 1 : -1;
  586. }).forEach(function (language) {
  587. if (language !== defaultLanguage && language !== 'Default') {
  588. properties.push(_this9._createLanguageRow(language, false));
  589. }
  590. });
  591. properties.push({
  592. id: 'addLanguage',
  593. editor: {
  594. sectionId: 'general.advanced.languages',
  595. uiControl: {
  596. type: 'SingleLineLinks',
  597. isDisabled: this.translationModeOn,
  598. items: [{
  599. align: 'right',
  600. items: [{
  601. type: 'text',
  602. value: StringResources.get('multilingualDashboardsAddLinkText'),
  603. clickCallback: function clickCallback() {
  604. _this9.launchLanguageSelectSlideout(null, true, propertiesManager);
  605. }
  606. }]
  607. }]
  608. }
  609. }
  610. });
  611. return properties;
  612. };
  613. /**
  614. * Creats a SingleLineLink property spec that describes a language
  615. */
  616. TranslationService.prototype._createLanguageRow = function _createLanguageRow(locale, isDefaultLocale) {
  617. var _this10 = this;
  618. var languageName = this.getLanguageName(locale);
  619. return {
  620. id: 'language_' + locale,
  621. editor: {
  622. sectionId: 'general.advanced.languages',
  623. uiControl: {
  624. type: 'SingleLineLinks',
  625. indent: 2,
  626. disabled: this.translationModeOn,
  627. items: [{
  628. align: 'left',
  629. items: []
  630. }, {
  631. align: 'right',
  632. items: [{
  633. type: 'text',
  634. id: 'text' + locale,
  635. value: isDefaultLocale ? StringResources.get('multilingualDashboardsDefault', { defaultLanguage: languageName }) : languageName
  636. }, {
  637. type: 'icon',
  638. svgIcon: 'common-menuoverflow',
  639. iconTooltip: StringResources.get('multilingualDashboardIconMore', {
  640. currentLanguage: languageName
  641. }),
  642. clickCallback: function clickCallback(evt) {
  643. _this10.launchLanguageMenu(evt, locale);
  644. }
  645. }]
  646. }]
  647. }
  648. }
  649. };
  650. };
  651. /**
  652. * When picking a language, we launch an overlay slideout with all the content locales
  653. */
  654. TranslationService.prototype.launchLanguageSelectSlideout = function launchLanguageSelectSlideout(selectedLocale, addLanguage, propertiesManager) {
  655. var _this11 = this;
  656. // ensure properties manager is available
  657. propertiesManager = propertiesManager || this.dashboardApi.getFeature('propertiesManager');
  658. propertiesManager.addChild({
  659. overlay: true,
  660. label: StringResources.get('multilingualSelectLanguage'),
  661. content: {
  662. module: 'dashboard-core/js/dashboard/contentpane/PropertyUIControlView',
  663. items: [{
  664. value: StringResources.get('multilingualSelectLanguage'),
  665. centerLabel: true,
  666. type: 'Banner',
  667. backButton: true,
  668. ariaLabel: StringResources.get('multilingualSelectLanguage')
  669. }, {
  670. type: 'RadioButtonGroup',
  671. name: 'language',
  672. separator: true,
  673. ariaLabel: StringResources.get('multilingualSelectLanguage'),
  674. value: selectedLocale,
  675. selectOnNavigation: false,
  676. items: this.getLanguageRadioItems(),
  677. onChange: function onChange(name, newLocale) {
  678. propertiesManager.closeChild();
  679. if (selectedLocale === 'Default') {
  680. _this11.changeDefaultLanguage(newLocale);
  681. } else if (addLanguage) {
  682. _this11.startTranslationMode(newLocale);
  683. } else {
  684. _this11.switchLanguage({
  685. from: selectedLocale,
  686. to: newLocale
  687. });
  688. }
  689. }
  690. }]
  691. }
  692. });
  693. };
  694. /**
  695. * User clicked on the ..., so show the menu
  696. */
  697. TranslationService.prototype.launchLanguageMenu = function launchLanguageMenu(evt, locale) {
  698. var position = {};
  699. if (evt.pageX === undefined || evt.gesture && (evt.gesture.center === undefined || evt.gesture.center.pageX === undefined)) {
  700. position = $(evt.target).offset();
  701. } else {
  702. position.left = evt.pageX || evt.gesture.center.pageX;
  703. position.top = evt.pageY || evt.gesture.center.pageY;
  704. }
  705. this.glassContext.appController.showContextMenu({
  706. position: {
  707. pageX: position.left,
  708. pageY: position.top
  709. },
  710. menuId: 'com.ibm.bi.dashboard.languageMenu',
  711. activeObject: {
  712. selectedLocale: locale,
  713. translationService: this,
  714. layoutBaseView: this
  715. }
  716. });
  717. };
  718. return TranslationService;
  719. }();
  720. return TranslationService;
  721. });
  722. //# sourceMappingURL=TranslationService.js.map