rsOpenHelper.js 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467
  1. /*
  2. IBM Confidential
  3. OCO Source Materials
  4. IBM Cognos Products: rs
  5. (C) Copyright IBM Corp. 2003, 2021
  6. The source code for this program is not published or otherwise divested of its trade secrets, irrespective of what has been deposited with the U.S. Copyright Office.
  7. */
  8. define([
  9. 'jquery',
  10. 'q',
  11. 'bi/authoring/utils/rsIFrameManager',
  12. 'bi/authoring/utils/rsCommon',
  13. 'bi/authoring/nls/StringResource',
  14. 'bi/commons/utils/LegacyUtils',
  15. 'bi/authoring/utils/pat/rsLaunchParameters',
  16. 'bi/authoring/utils/pat/rsPromptParameters'
  17. ],
  18. function($, Q, rsIFrameManager, rsCommon, StringResource, LegacyUtils, rsLaunchParameters, rsPromptParameters){
  19. 'use strict';
  20. var legacyUtils = null;
  21. /**
  22. * This method extends LegacyUtils by adding the method we need
  23. * Once LegacyUtils in ba-core-client is updated we can remove this method and
  24. * use LegacyUtils directly
  25. */
  26. function getLegacyUtils() {
  27. if (!legacyUtils) {
  28. legacyUtils = LegacyUtils;
  29. if (!legacyUtils.getLegacyLaunchUrl) {
  30. legacyUtils.getLegacyLaunchUrl = function(glassContext, tool, object, action)
  31. {
  32. var qParms = this._getLaunchParms(glassContext, tool, object);
  33. qParms['ui.action'] = action;
  34. return this._getUrl(qParms);
  35. }.bind(LegacyUtils);
  36. }
  37. }
  38. return legacyUtils;
  39. }
  40. /**
  41. * Retrieve the URL that will launch the legacy application
  42. * Reject if unable to retrieve URL
  43. */
  44. function getLegacyLaunchUrl( oOpenSpec ) {
  45. var tool = oOpenSpec.cmProperties.type == 'query' ? 'QueryStudio' : 'AnalysisStudio';
  46. var searchPath = 'storeID("' + oOpenSpec.cmProperties.id + '")';
  47. var v_sLaunchURL = getLegacyUtils().getLegacyLaunchUrl( oOpenSpec.glassContext, tool, searchPath, 'edit' );
  48. if (oOpenSpec.urlMap.prompt != undefined) {
  49. v_sLaunchURL = v_sLaunchURL + '&prompt=' + (oOpenSpec.urlMap.prompt ? 'true' : 'false');
  50. }
  51. // TODO add content and product locale to URL
  52. var v_sParameterValuesXML = oOpenSpec.urlMap.parameterValuesXML;
  53. if (!v_sParameterValuesXML && oOpenSpec.urlMap.parameterValuesJSON)
  54. {
  55. v_sParameterValuesXML = rsPromptParameters.rsBuildPromptParameters(null, oOpenSpec.urlMap.parameterValuesJSON, "parameters");
  56. }
  57. if (v_sParameterValuesXML)
  58. {
  59. v_sLaunchURL = v_sLaunchURL + '&ui.drillThroughTargetParameterValues=' + encodeURIComponent(v_sParameterValuesXML);
  60. }
  61. return v_sLaunchURL;
  62. }
  63. function runActiveReportInNewWindow( urlMap ) {
  64. //console.log('rsOpenHelper.runActiveReportInNewWindow ...');
  65. var deferred = Q.defer();
  66. var v_sCmPath = 'storeID("' + urlMap.id + '")';
  67. var v_sA11y = urlMap.a11y ? '&' + encodeURIComponent('system.http://developer.cognos.com/ceba/constants/systemOptionEnum#accessibilityFeatures') + '=true' : '';
  68. var v_sBidi = urlMap.bidi ? '&' + encodeURIComponent('biDirectional.http://developer.cognos.com/ceba/constants/biDirectionalOptionEnum#biDirectionalFeaturesEnabled') + '=true' : '';
  69. var v_sPrompt = urlMap.prompt != undefined ? ('&run.prompt=' + urlMap.prompt) : '';
  70. var v_sUri = 'v1/disp?b_action=cognosViewer&ui.action=run&ui.object='+ v_sCmPath + v_sPrompt + v_sA11y + v_sBidi;
  71. try {
  72. var v_oWin = window.open( v_sUri, '', '');
  73. v_oWin.focus();
  74. //console.log('rsOpenHelper.runActiveReportInNewWindow ... succeeded');
  75. deferred.resolve(v_oWin);
  76. }
  77. catch(e) {
  78. rsCommon.reject( deferred, 'Failed to opend window: ' + e.toString(), 'rsOpenHelper.runActiveReportInNewWindow' );
  79. }
  80. finally {
  81. return deferred.promise;
  82. }
  83. }
  84. function isActiveReport( cmProperties ) {
  85. return rsCommon.isObjectOfType( cmProperties, 'interactiveReport' );
  86. }
  87. function isDataSet2( cmProperties ) {
  88. return rsCommon.isObjectOfType( cmProperties, 'dataSet2' );
  89. }
  90. function isReport_ish( cmProperties ) {
  91. return rsCommon.isObjectOfType( cmProperties, ['report', 'reportView', 'reportTemplate', 'interactiveReport', 'dataSet2', 'query', 'analysis'] );
  92. }
  93. function loadCmProperties( v_oUrlMap, v_oCmProperties ) {
  94. if (v_oCmProperties) {
  95. // The id identifies the content-view.
  96. // By convention we are using the store-id to uniquely identify loaded content views.
  97. v_oUrlMap.cmProperties = v_oCmProperties;
  98. v_oUrlMap.id = v_oCmProperties.id;
  99. v_oUrlMap.type = v_oCmProperties.type;
  100. }
  101. }
  102. function getType(v_sId, glassContext)
  103. {
  104. var v_sSearchPathUrl =
  105. "v1/search_path?searchPath=" +
  106. encodeURIComponent("storeID('" + v_sId + "')") +
  107. "&fields=type";
  108. return glassContext.services.fetch.get(v_sSearchPathUrl)
  109. .then( function(v_oCmInfoResponse) {
  110. return v_oCmInfoResponse.data.data[0].type;
  111. });
  112. }
  113. /**
  114. * Return the default action based on the action ID and the CM properties.
  115. * null means no action is allowed.
  116. * undefined means we can't determine the default action.
  117. */
  118. function determineDefaultAction(v_sActionId, v_oCmProperties, glassContext, urlMap) {
  119. if (urlMap && (urlMap.m_oPromptContext || (urlMap.m_oLaunchParameters && urlMap.m_oLaunchParameters.promptContext))) {
  120. // If we have a prompt context then we are handling prompting so the action is run
  121. // The classic and authoring perspectives load the prompt context differently hence the || in the condition.
  122. return glassContext.hasCapability('canUseCognosViewer') ? 'run' : 'none';
  123. }
  124. var v_sAction; // = undefined;
  125. if (v_oCmProperties && v_oCmProperties.defaultPortalAction) {
  126. var v_bDefault = true;
  127. v_sAction = v_oCmProperties.defaultPortalAction;
  128. var v_sType = v_oCmProperties.type;
  129. switch (v_sActionId)
  130. {
  131. case 'com.ibm.bi.authoring.run':
  132. case 'com.ibm.bi.contentApps.action.runAs':
  133. case 'com.ibm.bi.authoringContrib.runBtn':
  134. v_sAction = 'run';
  135. v_bDefault = false;
  136. break;
  137. default:
  138. if (v_sActionId && v_sActionId.indexOf('com.ibm.bi.contentApps.defaultAction.') == -1) {
  139. // A non-default action id was specified that is not one of the values above
  140. // Assume edit.
  141. v_sAction = 'edit';
  142. v_bDefault = false;
  143. }
  144. }
  145. switch (v_sType)
  146. {
  147. case 'dataSet2':
  148. // Can only edit datasets. Switch action to edit if allowed.
  149. v_sAction = (v_oCmProperties.permissions.indexOf("read") != -1 && glassContext.hasCapability( 'canUseMyDataSets' )) ? 'edit' : null;
  150. break;
  151. case 'reportTemplate':
  152. // Can only edit report templates. Switch action to edit if allowed.
  153. v_sAction = (v_oCmProperties.permissions.indexOf("read") != -1 && glassContext.hasCapability( 'canUseReportStudio' )) ? 'edit' : null;
  154. break;
  155. case 'reportView':
  156. if (v_sAction == 'edit')
  157. {
  158. // Can't edit report views. Switch action to run instead.
  159. v_sAction = v_bDefault ? 'run' : null;
  160. }
  161. // fall through to default case
  162. default:
  163. var v_sStudioCapability;
  164. var v_bIsLegacy = false;
  165. switch (v_sType)
  166. {
  167. case 'query':
  168. v_sStudioCapability = 'canUseQueryStudio';
  169. v_bIsLegacy = true;
  170. break;
  171. case 'analysis':
  172. v_sStudioCapability = 'canUseAnalysisStudio';
  173. v_bIsLegacy = true;
  174. break;
  175. default:
  176. v_sStudioCapability = 'canUseReportStudio';
  177. }
  178. if (v_bIsLegacy && v_sAction == 'edit')
  179. {
  180. var v_bTool = LegacyUtils.canUseLegacyTool( glassContext, v_sType == 'query' ? 'QueryStudio' : 'AnalysisStudio');
  181. // Change edit to legacy if it is supported (e.g. Chrome does not support Query Studio) else run
  182. v_sAction = v_bTool ? 'legacy' : 'run';
  183. }
  184. switch (v_sAction) {
  185. case 'edit':
  186. case 'legacy':
  187. if (v_oCmProperties.permissions.indexOf("read") == -1 || !glassContext.hasCapability( v_sStudioCapability ))
  188. {
  189. // Can't edit object without read access or the appropriate capability. Switch action to run if allowed.
  190. v_sAction = (v_oCmProperties.permissions.indexOf("execute") != -1 && v_bDefault) ? 'run' : null;
  191. }
  192. break;
  193. case 'run':
  194. if (v_oCmProperties.permissions.indexOf("execute") == -1)
  195. {
  196. // Can't execute report. Switch action to view if allowed.
  197. v_sAction = (v_oCmProperties.permissions.indexOf("read") != -1 && v_bDefault) ? 'viewOutput' : null;
  198. }
  199. break;
  200. case 'viewOutput':
  201. if (v_oCmProperties.permissions.indexOf("read") == -1)
  202. {
  203. // Can't view report. Switch action to run if allowed.
  204. v_sAction = (v_oCmProperties.permissions.indexOf("execute") != -1 && v_bDefault) ? 'run' : null;
  205. }
  206. break;
  207. default:
  208. v_sAction = null;
  209. }
  210. if ((v_sAction == 'run' || v_sAction == 'viewOutput') && !glassContext.hasCapability('canUseCognosViewer'))
  211. {
  212. v_sAction = null;
  213. }
  214. break;
  215. }
  216. }
  217. else if (urlMap && urlMap.isNew) {
  218. // No object available so either creating something new or we have an inline spec
  219. if (urlMap.isViewer) {
  220. v_sAction = glassContext.hasCapability('canUseCognosViewer') ? 'run' : 'none';
  221. }
  222. else if (urlMap.perspective == 'authoring') {
  223. v_sAction = glassContext.hasCapability('canUseReportStudio') ? 'edit' : 'none';
  224. }
  225. else if (urlMap.perspective == 'datasets') {
  226. v_sAction = glassContext.hasCapability('canUseMyDataSets') ? 'edit' : 'none';
  227. }
  228. else {
  229. v_sAction = 'none';
  230. }
  231. }
  232. return v_sAction;
  233. }
  234. function determineAction(v_oOpenSpec)
  235. {
  236. var v_sAction;
  237. var v_bAllowLegacy = true;
  238. var v_sCreateType;
  239. switch (v_oOpenSpec.actionId)
  240. {
  241. case "com.ibm.bi.authoring.run":
  242. case "com.ibm.bi.contentApps.action.runAs":
  243. v_sAction = 'run';
  244. break;
  245. case "com.ibm.bi.authoring.createReportFromModule":
  246. case "com.ibm.bi.authoring.createReportFromPackage":
  247. v_sCreateType = "report";
  248. v_sAction = 'edit';
  249. break;
  250. case "com.ibm.bi.datasets.createDataSetFromModule":
  251. case "com.ibm.bi.datasets.createDataSetFromPackage":
  252. v_sCreateType = "dataSet2";
  253. v_sAction = 'edit';
  254. break;
  255. case 'com.ibm.bi.authoring.convertToReport':
  256. v_sAction = 'edit';
  257. v_bAllowLegacy = false; // force edit
  258. break;
  259. default:
  260. v_sAction = v_oOpenSpec.urlMap.action;
  261. }
  262. var sObjectType = v_oOpenSpec.urlMap.cmProperties ? v_oOpenSpec.urlMap.cmProperties.type : undefined;
  263. switch (sObjectType)
  264. {
  265. case 'reportVersion':
  266. case 'output':
  267. // reportVersion and output objects can only be viewed
  268. v_sAction = v_oOpenSpec.glassContext.hasCapability('canUseCognosViewer') ? 'viewOutput' : 'none';
  269. break;
  270. default:
  271. switch (v_sAction)
  272. {
  273. case 'run':
  274. case 'edit':
  275. case 'viewOutput':
  276. if (v_oOpenSpec.urlMap.isNew || !isReport_ish( v_oOpenSpec.urlMap.cmProperties )) {
  277. v_sAction = v_oOpenSpec.glassContext.hasCapability(v_sCreateType == 'dataSet2' ? 'canUseMyDataSets' : 'canUseReportStudio') ? 'edit' : 'none';
  278. }
  279. if (v_sAction == 'edit' && (sObjectType == 'query' || sObjectType == 'analysis') && v_bAllowLegacy)
  280. {
  281. // edit on query and analysis means run the corresponding studio, not RS
  282. // But if the tool is not allowed, switch to run
  283. v_sAction = (LegacyUtils.canUseLegacyTool( v_oOpenSpec.glassContext, sObjectType == 'query' ? 'QueryStudio' : 'AnalysisStudio')) ? 'legacy' : 'run';
  284. }
  285. break;
  286. case 'default': // classic viewer sends this
  287. case undefined:
  288. // Action unspecified, determine default from object
  289. v_sAction = determineDefaultAction(v_oOpenSpec.actionId, v_oOpenSpec.urlMap.cmProperties, v_oOpenSpec.glassContext, v_oOpenSpec.urlMap);
  290. v_oOpenSpec.defaultAction = true;
  291. break;
  292. default:
  293. // Unexpected action, change to null
  294. v_sAction = null;
  295. }
  296. }
  297. v_oOpenSpec.urlMap.action = v_sAction;
  298. }
  299. /**
  300. * Initialize the urlMap in the given open spec
  301. * @return the updated open spec
  302. */
  303. function prepareUrlMap(v_oOpenSpec, v_oCmProperties) {
  304. // console.log('rsOpenHelper.prepareUrlMap');
  305. var urlMap = v_oOpenSpec.urlMap || {};
  306. rsCommon.convertStringQSToValues(urlMap, v_oOpenSpec.glassContext, v_oOpenSpec.trimURLParameterValues);
  307. var dataset = false;
  308. switch (v_oOpenSpec.actionId)
  309. {
  310. case "com.ibm.bi.datasets.createDataSetFromModule":
  311. case "com.ibm.bi.datasets.createDataSetFromPackage":
  312. urlMap.startingTemplate = "DatasetList";
  313. dataset = true;
  314. urlMap.isNew = true;
  315. break;
  316. case "com.ibm.bi.contentApps.defaultAction.dataSet2":
  317. case "com.ibm.bi.datasets.editDataset":
  318. dataset = true;
  319. break;
  320. case "com.ibm.bi.authoring.createReportFromModule":
  321. case "com.ibm.bi.authoring.createReportFromPackage":
  322. urlMap.isNew = true;
  323. break;
  324. default:
  325. // In case there is no CM object and somehow the perspective was specified, use it to determine if we are dealing with a dataset
  326. dataset = isDataSet2(v_oCmProperties) || (!v_oCmProperties && urlMap.perspective == 'datasets');
  327. // If object type is not one of the report-ish types, assume we are doing a new and the CM object is the metadata source object (package/module)
  328. urlMap.isNew = !isReport_ish( v_oCmProperties );
  329. break;
  330. }
  331. loadCmProperties( urlMap, v_oCmProperties );
  332. urlMap.isApplication = isActiveReport(v_oCmProperties);
  333. if (!urlMap.perspective && dataset)
  334. {
  335. // perspective not specified but we know we are dealing with a dataset
  336. // so only option is the dataset perspective
  337. urlMap.perspective = 'datasets';
  338. }
  339. urlMap.UIProfile = urlMap.perspective == 'datasets' ? "TitanDataset" : "Titan";
  340. rsCommon.decodeAndMoveRSOptions(urlMap);
  341. v_oOpenSpec.urlMap = urlMap;
  342. determineAction(v_oOpenSpec);
  343. return v_oOpenSpec;
  344. }
  345. // CM Options are an array like:
  346. // [
  347. // 0: {name: optionName1, value: optionValue1, type: cmOptionType }
  348. // 1: {name: optionName2, value: optionValue2, type: cmOptionType }
  349. // 2: {name: optionName1, value: optionValue3, type: cmOptionType }
  350. // ...
  351. // ]
  352. //
  353. // convert into a regular object
  354. // {
  355. // optionName1: [optionValue1, optionValue3],
  356. // optionName2: optionValue2
  357. // ...
  358. // }
  359. function convertToObjectFromCmOptionsArray(aCmOptions) {
  360. if (!aCmOptions || !Array.isArray(aCmOptions))
  361. {
  362. return aCmOptions;
  363. }
  364. var oReturn = {};
  365. aCmOptions.forEach(function(oOption){
  366. if (typeof oReturn[oOption.name] === 'undefined')
  367. {
  368. oReturn[oOption.name] = oOption.value;
  369. }
  370. else if (Array.isArray(oReturn[oOption.name]))
  371. {
  372. oReturn[oOption.name].push( oOption.value);
  373. }
  374. else
  375. {
  376. // we already have value and it's not an array
  377. // add existing value AND the new value into an array
  378. // replace the whole value with the new array
  379. oReturn[oOption.name] = [oReturn[oOption.name], oOption.value];
  380. }
  381. });
  382. return oReturn;
  383. }
  384. function convertCmOptionsToSimpleArray(cmProperties) {
  385. // convert options
  386. cmProperties.options = convertToObjectFromCmOptionsArray(cmProperties.options);
  387. // convert options in base if any
  388. if (cmProperties.base && cmProperties.base.length > 0 && cmProperties.base[0])
  389. {
  390. cmProperties.base[0].options = convertToObjectFromCmOptionsArray( cmProperties.base[0].options );
  391. }
  392. }
  393. function getCMInfoForOpen( cmProperties, v_aProperties, glassContext ) {
  394. // console.log('rsOpenHelper.getCMInfoForOpen ...');
  395. var deferred = Q.defer();
  396. var v_sReportViewUrl = 'v1/objects/' + cmProperties.id;
  397. var v_aFields = [];
  398. v_aProperties.forEach(function(v_sField){
  399. v_aFields.push(v_sField);
  400. });
  401. v_aFields.join(',');
  402. var v_sReportViewPropsUrl = v_sReportViewUrl.concat('?fields=', v_aFields.join(','));
  403. glassContext.services.ajax.ajax({
  404. url: v_sReportViewPropsUrl,
  405. type: 'GET',
  406. dataType: 'json'
  407. })
  408. .fail( function(err){
  409. console.log('rsOpenHelper.getCMInfo ... FAILED');
  410. deferred.reject(err);
  411. })
  412. .done( function(resp){
  413. if (! resp || ! resp.data || resp.data.length <= 0 )
  414. {
  415. rsCommon.reject( deferred, 'unexpected response', 'rsOpenHelper.getCMInfoForOpen' );
  416. return;
  417. }
  418. var v_oData = resp.data[0];
  419. convertCmOptionsToSimpleArray(v_oData);
  420. convertCmOptionsToSimpleArray(cmProperties);
  421. // Extend new cm properties with the ones we already have
  422. var v_oCurrentCmProperties = cmProperties;
  423. for (var v_sProperty in v_oCurrentCmProperties)
  424. {
  425. if (v_oCurrentCmProperties.hasOwnProperty(v_sProperty) && v_oData[v_sProperty] == undefined) {
  426. v_oData[v_sProperty] = v_oCurrentCmProperties[v_sProperty];
  427. }
  428. }
  429. //console.log('rsOpenHelper.getCMInfo ... succeeded');
  430. deferred.resolve( v_oData );
  431. });
  432. return deferred.promise;
  433. }
  434. function f_determineMissingProperties( v_aProperties, v_oCmProperties )
  435. {
  436. var v_aMissingProperties= [];
  437. // Check if we are missing any of the required properties
  438. var len = v_aProperties.length;
  439. for ( var i = 0; i < len; ++i ) {
  440. var v_sProperty = v_aProperties[i];
  441. if (typeof v_oCmProperties[v_sProperty] == 'undefined') {
  442. v_aMissingProperties.push( v_sProperty );
  443. }
  444. }
  445. return v_aMissingProperties;
  446. }
  447. // The list of CM properties required by rs (all scenarios including edit, viewer, share etc.)
  448. var m_aProperties = [
  449. 'ancestors',
  450. 'defaultDescription',
  451. 'defaultName',
  452. 'defaultPortalAction',
  453. 'id',
  454. 'modificationTime',
  455. 'options',
  456. 'owner',
  457. 'parent',
  458. 'permissions',
  459. 'routingServerGroup',
  460. 'runInAdvancedViewer',
  461. 'searchPath',
  462. 'format',
  463. 'type'
  464. ];
  465. var m_aOutputProperties = [
  466. 'ancestors',
  467. 'dataDescriptor',
  468. 'defaultName',
  469. 'burstKey',
  470. 'id',
  471. 'modificationTime',
  472. 'owner',
  473. 'parent',
  474. 'permissions',
  475. 'searchPath',
  476. 'type',
  477. 'format',
  478. 'locale',
  479. 'lastPage'
  480. ];
  481. var m_aReportVersionProperties = [
  482. 'decoratedSpecification',
  483. 'id',
  484. 'parent'
  485. ];
  486. function extractProperties( v_aPropertiesSpec, type )
  487. {
  488. var v_aProperties;
  489. if (v_aPropertiesSpec) {
  490. v_aProperties = [];
  491. for (var idx = 0; idx < v_aPropertiesSpec.length; ++idx) {
  492. if (!type || !v_aPropertiesSpec[idx].type || v_aPropertiesSpec[idx].type.includes(type)) {
  493. v_aProperties.push(v_aPropertiesSpec[idx].property);
  494. }
  495. }
  496. }
  497. return v_aProperties;
  498. }
  499. /**
  500. * Get the cm object with all the necessary properties.
  501. * @param v_oCmProperties Current know properties.
  502. * @param glassContext The glass context.
  503. * @param v_aPropertiesSpec Set of properties to be retrieved. This is optional and if unspecified,
  504. * the complete set of properties needed by authoring will be retrieved.
  505. * This is an array of objects { property, type } where prop is the property and type is an optional array of types
  506. * to which the property applies.
  507. * @return The requested cm properties.
  508. */
  509. function retreiveCMInfo(v_oCmProperties, glassContext, v_aPropertiesSpec) {
  510. //console.log('rsOpenHelper.retreiveCMInfo ...');
  511. var deferred = Q.defer();
  512. if (v_oCmProperties && v_oCmProperties.id && !v_oCmProperties.type) {
  513. // deal with situation where we were given an id but no type (URL with perspective and objRef)
  514. return getType(v_oCmProperties.id, glassContext)
  515. .then(function(v_sType){
  516. v_oCmProperties.type = v_sType;
  517. return retreiveCMInfo(v_oCmProperties, glassContext, v_aPropertiesSpec);
  518. });
  519. }
  520. // Based on type of given object, retrieve all potentially required information
  521. switch (v_oCmProperties ? v_oCmProperties.type : "none")
  522. {
  523. case undefined:
  524. rsCommon.reject( deferred, 'Missing properties or id', 'rsOpenHelper.retreiveCMInfo' );
  525. break;
  526. case "none":
  527. deferred.resolve(undefined);
  528. break;
  529. case 'output':
  530. var v_aRequestProperties = f_determineMissingProperties( extractProperties(v_aPropertiesSpec, 'output') || m_aOutputProperties, v_oCmProperties );
  531. getCMInfoForOpen( v_oCmProperties, v_aRequestProperties, glassContext )
  532. .then( function( v_oOutput ) {
  533. if (v_aPropertiesSpec) {
  534. deferred.resolve(v_oOutput);
  535. }
  536. else {
  537. // For output, we need the reportVersion
  538. var v_oCmProperties = { id: v_oOutput.parent[0].id };
  539. getCMInfoForOpen( v_oCmProperties, m_aReportVersionProperties, glassContext )
  540. .then( function( v_oVersion ) {
  541. v_oOutput.parent[0] = v_oVersion; // link version to output
  542. // We also need the reportVersion parent (report, active report, reortView, query, analysis)
  543. // Since we are dealing with an output, we don't need the full set of report properties
  544. // so only ask for the minimal set.
  545. var v_oCmProperties = { id: v_oVersion.parent[0].id };
  546. getCMInfoForOpen( v_oCmProperties, ['id', 'defaultName', 'type', 'base.type'], glassContext )
  547. .then( function(v_oReport) {
  548. v_oVersion.parent[0] = v_oReport; // link report to reportVersion
  549. deferred.resolve(v_oOutput);
  550. });
  551. });
  552. }
  553. })
  554. .catch( function(err){
  555. console.log('rsOpenHelper.retreiveCMInfo ... FAILED');
  556. deferred.reject(err);
  557. });
  558. break;
  559. case 'reportVersion':
  560. var v_aRequestProperties = f_determineMissingProperties( extractProperties(v_aPropertiesSpec, 'reportVersion') || m_aReportVersionProperties, v_oCmProperties );
  561. getCMInfoForOpen( v_oCmProperties, v_aRequestProperties, glassContext )
  562. .then( function( v_oVersion ) {
  563. if (v_aPropertiesSpec) {
  564. deferred.resolve(v_oVersion);
  565. }
  566. else {
  567. // We also need the reportVersion parent (report, active report, reortView, query, analysis)
  568. // Since we are dealing with an output, we don't need the full set of report properties
  569. // so only ask for the minimal set.
  570. var v_oCmProperties = { id: v_oVersion.parent[0].id };
  571. getCMInfoForOpen( v_oCmProperties, ['id', 'defaultName', 'type', 'base.type'], glassContext )
  572. .then( function(v_oReport) {
  573. v_oVersion.parent[0] = v_oReport;
  574. deferred.resolve(v_oVersion);
  575. });
  576. }
  577. })
  578. .catch( function(err){
  579. console.log('rsOpenHelper.retreiveCMInfo ... FAILED');
  580. deferred.reject(err);
  581. });
  582. break;
  583. case 'report':
  584. case 'reportView':
  585. case 'reportTemplate':
  586. case 'interactiveReport':
  587. case 'dataSet2':
  588. case 'query':
  589. case 'analysis':
  590. var v_aRequestProperties = f_determineMissingProperties( extractProperties(v_aPropertiesSpec, 'report') || m_aProperties, v_oCmProperties );
  591. var v_bNeedBase = !v_aPropertiesSpec && v_oCmProperties.type == 'reportView';
  592. if (v_bNeedBase) {
  593. // Dealing with a report view, get base properties
  594. var l = v_aRequestProperties.length;
  595. for (var i = 0; i < l; ++i)
  596. {
  597. v_aRequestProperties.push( 'base.' + v_aRequestProperties[i] );
  598. }
  599. }
  600. else if (v_oCmProperties.type == 'report' &&
  601. !(v_oCmProperties.metadataModelPackage && v_oCmProperties.metadataModelPackage[0] && v_oCmProperties.metadataModelPackage[0].effectiveUserCapabilities)) {
  602. v_aRequestProperties.push( 'metadataModelPackage.effectiveUserCapabilities' );
  603. }
  604. if (v_aRequestProperties.length > 0)
  605. {
  606. getCMInfoForOpen( v_oCmProperties, v_aRequestProperties, glassContext )
  607. .catch( function(err){
  608. console.log('rsOpenHelper.retreiveCMInfo ... FAILED');
  609. deferred.reject(err);
  610. })
  611. .then(function(v_oUpdatedCmProperties) {
  612. //console.log('rsOpenHelper.retreiveCMInfo ... resolve/succeeded');
  613. deferred.resolve(v_oUpdatedCmProperties);
  614. });
  615. }
  616. else
  617. {
  618. // We know everything we need to
  619. //console.log('rsOpenHelper.retreiveCMInfo ... succeeded');
  620. deferred.resolve(v_oCmProperties);
  621. }
  622. break;
  623. default:
  624. // Non-report like object, simply return it
  625. var v_aRequestProperties = f_determineMissingProperties( extractProperties(v_aPropertiesSpec, null) || ['type', 'searchPath'], v_oCmProperties );
  626. if (v_aRequestProperties.length > 0)
  627. {
  628. getCMInfoForOpen( v_oCmProperties, v_aRequestProperties, glassContext )
  629. .catch( function(err){
  630. console.log('rsOpenHelper.retreiveCMInfo ... FAILED');
  631. deferred.reject(err);
  632. })
  633. .then(function(v_oUpdatedCmProperties) {
  634. //console.log('rsOpenHelper.retreiveCMInfo ... resolve/succeeded');
  635. deferred.resolve(v_oUpdatedCmProperties);
  636. });
  637. }
  638. else
  639. {
  640. // We know everything we need to
  641. //console.log('rsOpenHelper.retreiveCMInfo ... succeeded');
  642. deferred.resolve(v_oCmProperties);
  643. }
  644. }
  645. return deferred.promise;
  646. }
  647. // 'spreadsheetML' | 'xlsxData' | 'PDF' | 'HTML' | 'CSV' | 'XML'
  648. function isOutputFormatSupportedInAdvancedViewer(v_sOutputFormat) {
  649. return ['HTML', 'PDF', 'spreadsheetML', 'xlsxData', 'CSV', 'XML'].indexOf(v_sOutputFormat) !== -1;
  650. }
  651. function isOutputForDownload(v_sOutputFormat) {
  652. return ['spreadsheetML', 'xlsxData', 'CSV', 'XML'].indexOf(v_sOutputFormat) !== -1;
  653. }
  654. function getValueFromFieldIfDefined(v_o, v_sField)
  655. {
  656. if (!v_o)
  657. {
  658. return;
  659. }
  660. // v_o may have come from a JSON response
  661. // JSON does not support undefined as a value
  662. // therefore we treat null as undefined
  663. if (typeof v_o[v_sField] === 'undefined' || v_o[v_sField] === null)
  664. {
  665. return;
  666. }
  667. return {value: v_o[v_sField]};
  668. }
  669. function getFirstValueFromArrayFieldIfDefined(v_o, v_sField)
  670. {
  671. var o = getValueFromFieldIfDefined(v_o, v_sField);
  672. if (!o)
  673. {
  674. return;
  675. }
  676. var a = o.value;
  677. if (a.length < 1)
  678. {
  679. return;
  680. }
  681. // In certain cases 'a' is not an array but a string (powerPlay8Report for example)
  682. return {value: (Array.isArray(a) ? a[0]: a)};
  683. }
  684. // Run in advanced viewer if the property says so
  685. function determineRunInAdvancedViewer(v_oProperties) {
  686. var o = getValueFromFieldIfDefined(v_oProperties, "runInAdvancedViewer");
  687. return o ? o.value : false;
  688. }
  689. function consolidateRunInAdvancedViewer(v_oOpenSpec, v_sFormat) {
  690. // Determine the consolidated runInAdvancedViewer
  691. // The default for v_bRunInAdvancedViewer is false.
  692. // Why?
  693. // * For 'analysis' and 'query' we want to direct people to classic viewer to preserve their previous experience.
  694. // * For 'report' it maybe set, in which case we use the set value, or if not set, we use the default
  695. // * For 'interactiveReport' we don't care because we don't "view" them in the authoring perspective
  696. //
  697. var v_bRunInAdvancedViewer = false;
  698. var v_oProperties = v_oOpenSpec.launchSpec.cmProperties;
  699. if (determineRunInAdvancedViewer( v_oProperties.base && v_oProperties.base[0] ) || determineRunInAdvancedViewer( v_oProperties ))
  700. {
  701. v_bRunInAdvancedViewer = true;
  702. }
  703. if ( v_bRunInAdvancedViewer && v_sFormat && ! isOutputFormatSupportedInAdvancedViewer(v_sFormat))
  704. {
  705. v_bRunInAdvancedViewer = false;
  706. }
  707. return v_bRunInAdvancedViewer;
  708. }
  709. function isRunInAdvancedViewer(v_oOpenSpec, v_sFormat) {
  710. // Determine the consolidated runInAdvancedViewer
  711. // The default for v_bRunInAdvancedViewer is false.
  712. // Why?
  713. // * For 'analysis' and 'query' we want to direct people to classic viewer to preserve their previous experience.
  714. // * For 'report' it maybe set, in which case we use the set value, or if not set, we use the default
  715. // * For 'interactiveReport' we don't care because we don't "view" them in the authoring perspective
  716. //
  717. var v_bRunInAdvancedViewer = false;
  718. var v_oCmProperties = v_oOpenSpec.urlMap.cmProperties;
  719. if ((v_oCmProperties && v_oCmProperties.base) ? determineRunInAdvancedViewer( v_oCmProperties.base[0] ) : determineRunInAdvancedViewer( v_oCmProperties ))
  720. {
  721. v_bRunInAdvancedViewer = true;
  722. }
  723. if ( v_bRunInAdvancedViewer && v_sFormat && ! isOutputFormatSupportedInAdvancedViewer(v_sFormat))
  724. {
  725. v_bRunInAdvancedViewer = false;
  726. }
  727. return v_bRunInAdvancedViewer;
  728. }
  729. // Any run settings that have to be consolidated/reconciled from several sources,
  730. // i.e., the ultimate or final values
  731. //
  732. // returns
  733. //
  734. // {
  735. // format : null | 'HTML' | 'PDF' | etc
  736. // runInAdvancedViewer: true | false
  737. // prompt: true | false
  738. // }
  739. function consolidateAndReconcileRunOptions(v_oOpenSpec) {
  740. var urlMap = v_oOpenSpec.urlMap;
  741. var v_oCmBaseProperties = (urlMap.cmProperties && urlMap.cmProperties.base) ? urlMap.cmProperties.base[0] : null;
  742. var v_oCmProperties = urlMap.cmProperties || {};
  743. var v_oPreferences = v_oOpenSpec.glassContext.services.userProfile.preferences;
  744. // Determine the consolidated output format
  745. if (urlMap.format == undefined) {
  746. var v_sFormat = v_oPreferences.format;
  747. var o = getFirstValueFromArrayFieldIfDefined(v_oCmBaseProperties && v_oCmBaseProperties.options, "outputFormat");
  748. if (o)
  749. {
  750. v_sFormat = o.value || v_sFormat;
  751. }
  752. o = getFirstValueFromArrayFieldIfDefined(v_oCmProperties.options, "outputFormat");
  753. if (o)
  754. {
  755. v_sFormat = o.value || v_sFormat;
  756. }
  757. if (isActiveReport(v_oCmProperties) || !rsCommon.isOutputFormatAllowed(v_sFormat, v_oOpenSpec.glassContext))
  758. {
  759. // Replace invalid system determined format with HTML if format is invalid for current user
  760. v_sFormat = 'HTML';
  761. }
  762. o = getValueFromFieldIfDefined(v_oOpenSpec.runOptions, "format");
  763. if (o)
  764. {
  765. v_sFormat = o.value || v_sFormat;
  766. }
  767. urlMap.format = v_sFormat;
  768. }
  769. // Determine the consolidated a11y mode.
  770. // Note there is no run option for a11y in Titan, but there is a user preference & a report option
  771. if (urlMap.a11y == undefined) {
  772. var v_bA11y = v_oPreferences.accessibilityFeatures;
  773. var o = getValueFromFieldIfDefined(v_oCmBaseProperties && v_oCmBaseProperties.options, "http://developer.cognos.com/ceba/constants/systemOptionEnum#accessibilityFeatures");
  774. if (o)
  775. {
  776. v_bA11y = o.value || v_bA11y;
  777. }
  778. o = getValueFromFieldIfDefined(v_oCmProperties.options, "http://developer.cognos.com/ceba/constants/systemOptionEnum#accessibilityFeatures");
  779. if (o)
  780. {
  781. v_bA11y = o.value || v_bA11y;
  782. }
  783. urlMap.a11y = v_bA11y;
  784. }
  785. // Get bidi from user preferences - only place to set it in titan
  786. if (urlMap.bidi == undefined) {
  787. urlMap.bidi = v_oPreferences.biDirectionalFeaturesEnabled;
  788. }
  789. urlMap.Download = isOutputForDownload(urlMap.format) ? "true" : "false";
  790. // Determine consolidated prompt value
  791. if (urlMap.prompt == undefined) {
  792. var v_bPrompt; // default value is undefined
  793. o = getValueFromFieldIfDefined(v_oCmBaseProperties && v_oCmBaseProperties.options, "prompt");
  794. if (o)
  795. {
  796. v_bPrompt = o.value;
  797. }
  798. o = getValueFromFieldIfDefined(v_oCmProperties.options, "prompt");
  799. if (o)
  800. {
  801. v_bPrompt = o.value;
  802. }
  803. // urlMap uses Prompt instead of executionPrompt, this happen in run options dialog in RS
  804. o = (urlMap.m_oLaunchParameters && urlMap.m_oLaunchParameters.RunOptions) ? getValueFromFieldIfDefined(urlMap.m_oLaunchParameters.RunOptions, "Prompt") : getValueFromFieldIfDefined(urlMap, "Prompt");
  805. if (o)
  806. {
  807. v_bPrompt = (typeof o.value === "string") ? (o.value === "true") : !!o.value;
  808. }
  809. // runOptions uses prompt instead of executionPrompt
  810. o = getValueFromFieldIfDefined(v_oOpenSpec.runOptions, "prompt");
  811. if (o)
  812. {
  813. v_bPrompt = o.value;
  814. }
  815. urlMap.prompt = v_bPrompt;
  816. }
  817. }
  818. function getActiveReportOutputURL( v_oCMProperties, v_oOutputProperties ) {
  819. var v_sReportId, v_sOutputId;
  820. if (v_oOutputProperties)
  821. {
  822. v_sReportId = v_oCMProperties.id;
  823. v_sOutputId = v_oOutputProperties.id;
  824. }
  825. else
  826. {
  827. if (v_oCMProperties.type == 'output')
  828. {
  829. v_sReportId = v_oCMProperties.parent[0].parent[0].id;
  830. v_sOutputId = v_oCMProperties.id;
  831. }
  832. else
  833. {
  834. v_sReportId = v_oCMProperties.id;
  835. v_sOutputId = 'default';
  836. }
  837. }
  838. return 'v1/disp/repository/sid/cm/rid/' + v_sReportId + '/oid/' + v_sOutputId + '/content/mht/content';
  839. }
  840. /**
  841. * Launch a URL by posting a form instead of using window.open
  842. * This ensures there are no issues with URL length.
  843. * @param sHref The URL to be opened
  844. * @param bNewWindow Specifies whether a new window (true) or current window (false) should be used.
  845. */
  846. function openUrlViaForm(sHref, bNewWindow)
  847. {
  848. var v_nDrillForm;
  849. try
  850. {
  851. var v_sTarget = '_self';
  852. if (bNewWindow)
  853. {
  854. v_sTarget = 'rsTarget' + Date.now();
  855. if (!window.open("", v_sTarget))
  856. {
  857. return false;
  858. }
  859. }
  860. var v_aUrlParts = sHref.split("?");
  861. v_nDrillForm = document.body.appendChild(document.createElement("form"));
  862. v_nDrillForm.setAttribute("name", "drillForm");
  863. v_nDrillForm.setAttribute("method", "post");
  864. v_nDrillForm.setAttribute("action", decodeURIComponent(v_aUrlParts[0]));
  865. v_nDrillForm.setAttribute("target", v_sTarget);
  866. v_nDrillForm.style.display = "none";
  867. if (v_aUrlParts.length == 2)
  868. {
  869. // Create an input element in the form for each parameter in the query string.
  870. var v_aParams = v_aUrlParts[1].split("&");
  871. for (var i = 0; i < v_aParams.length; i++)
  872. {
  873. var v_aPair = v_aParams[i].split("=");
  874. var v_nFormField = v_nDrillForm.appendChild( document.createElement("input") );
  875. v_nFormField.setAttribute("type", "hidden");
  876. v_nFormField.setAttribute("name", decodeURIComponent(v_aPair[0]));
  877. v_nFormField.setAttribute("value", decodeURIComponent(v_aPair[1]));
  878. }
  879. }
  880. v_nDrillForm.submit();
  881. }
  882. catch (e)
  883. {
  884. // If something went wrong, remove the form if it exists and return false indicating the window was not opened.
  885. if (v_nDrillForm)
  886. {
  887. document.body.removeChild(v_nDrillForm);
  888. }
  889. return false;
  890. }
  891. document.body.removeChild(v_nDrillForm);
  892. return true;
  893. }
  894. function launchViewSavedOutputApp(v_oOpenSpec, deferred) {
  895. if (v_oOpenSpec.href) {
  896. // classic active reports open in new window
  897. openUrlViaForm( v_oOpenSpec.href, true );
  898. deferred.resolve();
  899. }
  900. else {
  901. v_oOpenSpec.glassContext.openAppView(v_oOpenSpec.urlMap.perspective, {content: v_oOpenSpec.urlMap } )
  902. .then( function() {
  903. deferred.resolve();
  904. });
  905. }
  906. }
  907. /**
  908. * This method either opens an object in the editor or runs's it and displays the results in a viewer.
  909. */
  910. function launchEditOrRunApp(v_oOpenSpec, deferred) {
  911. var urlMap = v_oOpenSpec.urlMap;
  912. if (urlMap.action == 'run' && urlMap.isApplication && urlMap.perspective == "classicviewer")
  913. {
  914. // We are running an active report with the classic viewer.
  915. // This is done in a new window.
  916. runActiveReportInNewWindow( urlMap )
  917. .then( function(v_activeReportResult){
  918. //console.log('launchEditOrRunApp resolved');
  919. deferred.resolve(v_activeReportResult);
  920. })
  921. .catch( function(err) {
  922. console.log('launchEditOrRunApp rejected');
  923. deferred.reject(err);
  924. });
  925. return deferred.promise;
  926. }
  927. if (urlMap.perspective == "authoring")
  928. {
  929. var v_oRSParameters = rsCommon.createRSParameters(urlMap, v_oOpenSpec.glassContext);
  930. var v_oIFrameTemplateParameters = rsCommon.createTemplateParameters(v_oRSParameters);
  931. urlMap.launchPromise = rsIFrameManager.F_LaunchRS(v_oIFrameTemplateParameters, v_oOpenSpec.glassContext);
  932. // Pass RS parameters to rsContentView
  933. urlMap.m_oRSParameters = v_oRSParameters;
  934. }
  935. //console.log(' rsOpenHelper.launchEditOrRunApp - openingAppView ...');
  936. // N.B. openAppView returns a jQuery deferred / promise
  937. v_oOpenSpec.glassContext.openAppView(urlMap.perspective, {content: urlMap } )
  938. .fail(function(err){
  939. console.log(' rsOpenHelper.launchEditOrRunApp - openingAppView ... FAILED');
  940. deferred.reject(err);
  941. })
  942. .done( function(v_oResult){
  943. //console.log(' rsOpenHelper.launchEditOrRunApp - openingAppView ... succeeded');
  944. deferred.resolve(v_oResult);
  945. });
  946. }
  947. function launchApp(v_oOpenSpec) {
  948. //console.log('rsOpenHelper.launchApp ...');
  949. var deferred = Q.defer();
  950. switch (v_oOpenSpec.urlMap.action)
  951. {
  952. case 'none':
  953. // No action is available
  954. v_oOpenSpec.glassContext.showToast(StringResource.get('no_action_available'), {'type':'warning', 'btnLabel':'OK'});
  955. deferred.resolve();
  956. break;
  957. case 'viewOutput':
  958. launchViewSavedOutputApp(v_oOpenSpec, deferred);
  959. break;
  960. case 'run':
  961. case 'edit':
  962. launchEditOrRunApp(v_oOpenSpec, deferred);
  963. break;
  964. case 'legacy':
  965. var v_sLaunchUrl = getLegacyLaunchUrl( v_oOpenSpec );
  966. if (!openUrlViaForm( v_sLaunchUrl, true ))
  967. {
  968. rsCommon.reject( deferred, 'Could not launch a new tab.', 'rsOpenHelper.launchApp' );
  969. }
  970. else
  971. {
  972. deferred.resolve();
  973. }
  974. break;
  975. default:
  976. rsCommon.reject( deferred, 'Unexpected action ' + v_oOpenSpec.urlMap.action + '.', 'rsOpenHelper.launchApp' );
  977. }
  978. return deferred.promise;
  979. }
  980. function getSavedOutput(v_oGlassContext, v_oCmProperties, format, contentLocale)
  981. {
  982. if (v_oCmProperties.type == 'output')
  983. {
  984. // Already have the output which should include the required parentage from rsOpenHelper.retreiveCMInfo
  985. return Q.resolve( v_oCmProperties );
  986. }
  987. return v_oGlassContext.getSvc('.Content')
  988. .then(function(v_oContentSvc) {
  989. // Get the appropriate output
  990. var v_sFormatHint = '"' + (format || '') + '"';
  991. var v_sLocaleHint = '"' + (contentLocale || '') + '"';
  992. var v_sSearchPath = 'defaultOutput(storeID("' + v_oCmProperties.id + '"),' + v_sFormatHint + ',' + v_sLocaleHint + ')';
  993. var v_sCMQueryUrl = v_oContentSvc.getSearchPathUrl( v_sSearchPath ) + '&fields=dataDescriptor,parent,locale,format,permissions,ancestors,lastPage';
  994. return v_oContentSvc.get(v_sCMQueryUrl, {})
  995. .then(function( v_oSavedOutputResp ){
  996. if (v_oSavedOutputResp && v_oSavedOutputResp.data && v_oSavedOutputResp.data.length > 0)
  997. {
  998. var v_oOutput = v_oSavedOutputResp.data[0];
  999. if (v_oCmProperties.type == 'reportVersion') {
  1000. // Already have the version and it's parent (as resolved by retreiveCMInfo)
  1001. v_oOutput.parent[0] = v_oCmProperties; // link version in output
  1002. return v_oOutput;
  1003. }
  1004. // Get the reportVersion and link to output
  1005. var v_sCMQueryUrl = v_oContentSvc.getBaseObjectsURL() + '/' + v_oOutput.parent[0].id + '?fields=decoratedSpecification,id,parent';
  1006. return v_oContentSvc.get(v_sCMQueryUrl, {})
  1007. .then(function(v_oVersionResponse){
  1008. var v_oVersion = v_oVersionResponse.data[0];
  1009. v_oVersion.parent[0] = v_oCmProperties; // link report (or whatever) in version
  1010. v_oOutput.parent[0] = v_oVersion; // link version in output
  1011. return v_oOutput;
  1012. });
  1013. }
  1014. return null;
  1015. });
  1016. });
  1017. }
  1018. function resolveUrlMapForSavedOutput(v_oOpenSpec)
  1019. {
  1020. if (!v_oOpenSpec.urlMap.action) {
  1021. return Q.reject();
  1022. }
  1023. if (v_oOpenSpec.urlMap.action != 'viewOutput') {
  1024. return Q.resolve(v_oOpenSpec);
  1025. }
  1026. return getSavedOutput( v_oOpenSpec.glassContext, v_oOpenSpec.urlMap.cmProperties, v_oOpenSpec.urlMap.format, v_oOpenSpec.urlMap.contentLocale )
  1027. .fail( function(err) {
  1028. // Handle 404 response when there is no output
  1029. return Q.resolve(null);
  1030. })
  1031. .then(function(v_oOutput) {
  1032. if (v_oOutput && v_oOutput.type == 'output' && v_oOutput.format != 'dataSet')
  1033. {
  1034. var v_bActiveReport = isActiveReport(v_oOutput);
  1035. var v_sActiveReportOutputHref = v_bActiveReport ? getActiveReportOutputURL( v_oOutput ) : null;
  1036. if (v_sActiveReportOutputHref && (!v_oOutput.dataDescriptor || v_oOutput.dataDescriptor.type != "interactive")) {
  1037. // Force share URL that displays saved active report output of an activeReport
  1038. // that uses the classic viewer to simply open the interactive report without the glass
  1039. v_oOpenSpec.href = v_sActiveReportOutputHref;
  1040. return Q.resolve( v_oOpenSpec );
  1041. }
  1042. var v_oUrlMap = v_oOpenSpec.urlMap;
  1043. //Required by glass: If a saved output has been found, the id will be set as the report id, that is used to trying to
  1044. //open the view, the objRef will be updated to the saved output
  1045. return rsCommon.getAvailableOutputs(v_oOpenSpec.glassContext, v_oOutput)
  1046. .then(function(v_oSavedOutputFormats) {
  1047. if (!v_oSavedOutputFormats || !v_oSavedOutputFormats.data || v_oSavedOutputFormats.data.length <= 0)
  1048. {
  1049. return Q.reject(new Error('unexpected response for rsCommon.getAvailableOutputs'));
  1050. }
  1051. v_oUrlMap.perspective = 'classicviewer';
  1052. if ((v_oOutput.dataDescriptor && v_oOutput.dataDescriptor.type == "interactive") || v_oOutput.format == 'PDF')
  1053. {
  1054. // If output is tagged as interactive or it is PDF then use interactive viewer
  1055. v_oUrlMap.perspective = 'authoring';
  1056. v_oUrlMap.outputSpec = v_oOutput.parent[0].decoratedSpecification;
  1057. }
  1058. if ( v_oOpenSpec.glassContext.isEmbedded() ) {
  1059. v_oUrlMap.perspective += '_embedded';
  1060. }
  1061. if (!v_bActiveReport)
  1062. {
  1063. v_oUrlMap.format = v_oOutput.format || v_oUrlMap.format;
  1064. }
  1065. else
  1066. {
  1067. // active reports support only 1 format so no need to specify
  1068. delete v_oUrlMap.format;
  1069. }
  1070. var v_oOutputLookup = {};
  1071. for (var i = 0; i < v_oSavedOutputFormats.data.length; ++i)
  1072. {
  1073. var v_oAltOutput = v_oSavedOutputFormats.data[i];
  1074. if (v_oAltOutput.locale == v_oOutput.locale)
  1075. {
  1076. v_oOutputLookup[v_oAltOutput.format] = v_oAltOutput;
  1077. }
  1078. }
  1079. v_oUrlMap.outputFormatLookup = v_oOutputLookup;
  1080. v_oUrlMap.reportProperties = { // report is output grand-parent
  1081. id : v_oOutput.parent[0].parent[0].id,
  1082. type : v_oOutput.parent[0].parent[0].type
  1083. };
  1084. loadCmProperties( v_oUrlMap, v_oOutput );
  1085. v_oUrlMap.objRef = v_oOutput.id; // use id of output object
  1086. delete v_oUrlMap.pathRef;
  1087. return Q.resolve(v_oOpenSpec);
  1088. });
  1089. }
  1090. else
  1091. {
  1092. // No saved output, determine alternate action
  1093. var v_aPermissions = v_oOpenSpec.urlMap.cmProperties.permissions;
  1094. var v_sCmType = v_oOpenSpec.urlMap.cmProperties.type;
  1095. switch (v_sCmType)
  1096. {
  1097. case 'query':
  1098. case 'analysis':
  1099. if (v_aPermissions.indexOf("execute") != -1)
  1100. {
  1101. // For analysis and query, the view action becomes edit if there is no saved output (but only if user can launch studio)
  1102. // otherwise try run
  1103. var v_bRead = v_aPermissions.indexOf("read") != -1;
  1104. var v_bCapability = v_oOpenSpec.glassContext.hasCapability( v_sCmType == 'query' ? 'canUseQueryStudio' : 'canUseAnalysisStudio' );
  1105. var v_bTool = LegacyUtils.canUseLegacyTool( v_oOpenSpec.glassContext, v_sCmType == 'query' ? 'QueryStudio' : 'AnalysisStudio');
  1106. v_oOpenSpec.urlMap.action = (v_bRead && v_bCapability && v_bTool) ? 'legacy' : 'run';
  1107. }
  1108. else
  1109. {
  1110. // use none as an indication that no action is allowed
  1111. v_oOpenSpec.urlMap.action = 'none';
  1112. }
  1113. break;
  1114. default:
  1115. // The value none is an indication that no action is allowed
  1116. v_oOpenSpec.urlMap.action = 'none';
  1117. if (v_aPermissions.indexOf("execute") != -1 && v_oOpenSpec.glassContext.hasCapability('canUseCognosViewer'))
  1118. {
  1119. // viewOutput becomes run if there is no output
  1120. v_oOpenSpec.urlMap.action = 'run';
  1121. }
  1122. // If still no action and we are dealing with a default action, use edit if allowed
  1123. if (v_oOpenSpec.urlMap.action == 'none' && v_oOpenSpec.defaultAction && v_aPermissions.indexOf("read") != -1 && v_oOpenSpec.glassContext.hasCapability('canUseReportStudio'))
  1124. {
  1125. v_oOpenSpec.urlMap.action = 'edit';
  1126. }
  1127. }
  1128. return Q.resolve(v_oOpenSpec);
  1129. }
  1130. });
  1131. }
  1132. function resolveUrlMapForEditRun(v_oOpenSpec)
  1133. {
  1134. if (v_oOpenSpec.urlMap.action == 'viewOutput')
  1135. {
  1136. return Q.resolve(v_oOpenSpec);
  1137. }
  1138. if (!v_oOpenSpec.urlMap.perspective) {
  1139. if (isDataSet2(v_oOpenSpec.urlMap.cmProperties))
  1140. {
  1141. v_oOpenSpec.urlMap.perspective = 'datasets';
  1142. }
  1143. else
  1144. {
  1145. var v_bRunInAdvancedViewer = isRunInAdvancedViewer(v_oOpenSpec, v_oOpenSpec.urlMap.format);
  1146. // If using advanced viewer, perspective is authoring. Otherwise perspective is classic
  1147. // unless we are editing then it is authoring.
  1148. v_oOpenSpec.urlMap.perspective = (v_bRunInAdvancedViewer || v_oOpenSpec.urlMap.action == 'edit') ? 'authoring' : 'classicviewer';
  1149. }
  1150. }
  1151. if ( v_oOpenSpec.glassContext.isEmbedded() ) {
  1152. v_oOpenSpec.urlMap.perspective += '_embedded';
  1153. }
  1154. consolidateAndReconcileRunOptions(v_oOpenSpec);
  1155. return Q.resolve(v_oOpenSpec);
  1156. }
  1157. function resolveUrlMap(v_oOpenSpec)
  1158. {
  1159. return retreiveCMInfo(v_oOpenSpec.cmProperties, v_oOpenSpec.glassContext)
  1160. .then(prepareUrlMap.bind(null, v_oOpenSpec))
  1161. .then(resolveUrlMapForSavedOutput)
  1162. .then(resolveUrlMapForEditRun)
  1163. .then(function(v_oResolvedSpec) {
  1164. v_oResolvedSpec.urlMap.rsResolved = true;
  1165. return v_oResolvedSpec;
  1166. });
  1167. }
  1168. /**
  1169. * Replace the current window with the given URL and
  1170. * ensure glass does not complain or
  1171. * open URL in new window and keep glass on current perspective.
  1172. */
  1173. function processHref( sHref, deferred, glassContext )
  1174. {
  1175. var v_oPerspective;
  1176. var v_oCurrentContentView = (glassContext && glassContext.currentAppView) ? glassContext.currentAppView.currentContentView : null;
  1177. if (v_oCurrentContentView)
  1178. {
  1179. // We have a current perspective, open url in new window and remain on current perspective
  1180. v_oPerspective = {
  1181. perspective: v_oCurrentContentView.perspective,
  1182. id: v_oCurrentContentView.id
  1183. };
  1184. if (!openUrlViaForm(sHref, true))
  1185. {
  1186. rsCommon.reject( deferred, 'Could not launch a new tab.', 'rsOpenHelper.processHref' );
  1187. return;
  1188. }
  1189. }
  1190. else {
  1191. // Give something safe to glass to avoid error messages until window is replaced
  1192. v_oPerspective = {perspective: 'home'};
  1193. // Replace current window with given href
  1194. openUrlViaForm(sHref, false);
  1195. }
  1196. deferred.resolve( v_oPerspective );
  1197. }
  1198. return {
  1199. isReport_ish: isReport_ish,
  1200. /**
  1201. * Open the appropriate view based on input.
  1202. * Minimum required information is
  1203. * openSpec {
  1204. * cmProperties { id, type }
  1205. * glassContext
  1206. * }
  1207. */
  1208. openView: function( v_oOpenSpec ) {
  1209. //console.log('rsOpenHelper.openView ...');
  1210. var deferred = Q.defer();
  1211. resolveUrlMap( v_oOpenSpec )
  1212. .then(launchApp)
  1213. .catch( function(err){
  1214. console.log('rsOpenHelper.openView ... FAILED');
  1215. deferred.reject(err);
  1216. }).done( function(v_oLaunchResult){
  1217. //console.log('rsOpenHelper.openView ... succeeded');
  1218. deferred.resolve(v_oLaunchResult);
  1219. });
  1220. return deferred.promise;
  1221. },
  1222. retrieveCmProperties: function (v_oGlassContext, v_oCmProperties, v_sStoreId) {
  1223. var deferred = Q.defer();
  1224. if (v_sStoreId) {
  1225. // Create an open spec compatible with retreiveCMInfo
  1226. if (!v_oCmProperties) {
  1227. v_oCmProperties = {};
  1228. }
  1229. if (!v_oCmProperties.id) {
  1230. v_oCmProperties.id = v_sStoreId;
  1231. }
  1232. if (v_oCmProperties.id != v_sStoreId) {
  1233. // drill through between report and output
  1234. v_oCmProperties.id = v_sStoreId;
  1235. }
  1236. retreiveCMInfo(v_oCmProperties, v_oGlassContext)
  1237. .done(function (cmProperties) {
  1238. deferred.resolve(cmProperties);
  1239. });
  1240. }
  1241. else {
  1242. deferred.resolve(v_oCmProperties);
  1243. }
  1244. return deferred.promise;
  1245. },
  1246. /**
  1247. * Generate the urlMap with the appropriate entries to process the given open specification
  1248. * The perspective is one of the values determined by this method which is used by the glass
  1249. * when it needs to open a perspective for which the actual perspective is unknown
  1250. * (e.g. share URL)
  1251. */
  1252. getPerspective: function(v_oOpenSpec) {
  1253. var deferred = Q.defer();
  1254. if (v_oOpenSpec.urlMap)
  1255. {
  1256. v_oOpenSpec.glassContext.getCoreSvc('.Config').getConfigValue('RS.TrimURLParameterValues')
  1257. .done(function(result){
  1258. // Indicates if parameter values in the urlMap should be trimmed of leading and trailing spaces
  1259. v_oOpenSpec.trimURLParameterValues = result === 'true';
  1260. resolveUrlMap(v_oOpenSpec)
  1261. .catch( function(err) {
  1262. console.log('rsOpenHelper.getPerspective ... FAILED');
  1263. deferred.reject(err);
  1264. }).done( function(v_oOpenSpecResolved) {
  1265. if (!v_oOpenSpecResolved) {
  1266. // Could not resolve, report error so that glass can try next registered handler
  1267. deferred.reject();
  1268. }
  1269. else
  1270. {
  1271. if (v_oOpenSpecResolved.urlMap && v_oOpenSpecResolved.urlMap.action == 'legacy')
  1272. {
  1273. if (v_oOpenSpec.urlMap.launchParametersKey)
  1274. {
  1275. var v_oLaunchParameters = rsLaunchParameters.Retrieve(v_oOpenSpec.urlMap.launchParametersKey);
  1276. delete v_oOpenSpec.urlMap.launchParametersKey;
  1277. $.extend(true, v_oOpenSpec.urlMap, v_oLaunchParameters);
  1278. }
  1279. // legacy means the classic query/analysis studio should be launched.
  1280. processHref( getLegacyLaunchUrl( v_oOpenSpec ), deferred, v_oOpenSpec.glassContext );
  1281. }
  1282. else if (v_oOpenSpecResolved.href) {
  1283. processHref( v_oOpenSpecResolved.href, deferred );
  1284. }
  1285. else {
  1286. deferred.resolve(v_oOpenSpecResolved.urlMap);
  1287. }
  1288. }
  1289. });
  1290. }.bind(this));
  1291. }
  1292. else
  1293. {
  1294. rsCommon.reject( deferred, 'urlMap is missing', 'rsOpenHelper.getPerspective' );
  1295. }
  1296. return deferred.promise;
  1297. },
  1298. determineDefaultAction: determineDefaultAction,
  1299. resolveUrlMap: resolveUrlMap,
  1300. updateCmProperties: function (v_oView, v_sStoreId) {
  1301. // Clear existing values to avoid using stale data
  1302. delete v_oView.cmProperties;
  1303. delete v_oView.reportProperties;
  1304. return this.retrieveCmProperties( v_oView.glassContext, null, v_sStoreId )
  1305. .then( function( v_oCmProperties ) {
  1306. v_oView.cmProperties = v_oCmProperties;
  1307. v_oView.id = v_oCmProperties.id; // whishfull thinking
  1308. v_oView.type = v_oCmProperties.type;
  1309. var v_oBaseReport;
  1310. switch (v_oCmProperties.type) {
  1311. case 'output':
  1312. v_oBaseReport = v_oCmProperties.parent[0].parent[0];
  1313. break;
  1314. case 'reportVersion':
  1315. v_oBaseReport = v_oCmProperties.parent[0];
  1316. break;
  1317. }
  1318. if (v_oBaseReport) {
  1319. v_oView.reportProperties = {
  1320. id : v_oBaseReport.id,
  1321. type : v_oBaseReport.type
  1322. };
  1323. }
  1324. }.bind(this));
  1325. },
  1326. //Interface for protected functions, used in rsShareHelper
  1327. retreiveCMInfo: retreiveCMInfo
  1328. };
  1329. });