rsContentView.js 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452
  1. /*
  2. IBM Confidential
  3. OCO Source Materials
  4. IBM Cognos Products: authoring
  5. (C) Copyright IBM Corp. 2015, 2020
  6. The source code for this program is not published or otherwise divested
  7. of its trade secrets, irrespective of what has been deposited with the
  8. U.S. Copyright Office.
  9. */
  10. define( [
  11. 'bi/glass/app/ContentView',
  12. 'jquery',
  13. 'q',
  14. 'bi/authoring/nls/StringResource',
  15. 'bi/commons/utils/Utils',
  16. 'bi/authoring/utils/rsCommon',
  17. 'bi/authoring/utils/rsOpenHelper',
  18. 'bi/authoring/utils/rsPerformance',
  19. 'bi/authoring/utils/rsIFrameManager',
  20. 'bi/authoring/utils/pat/rsLaunchParameters',
  21. 'bi/authoring/utils/pat/rsPromptParameters',
  22. 'bi/authoring/utils/rsShareHelper',
  23. 'bi/admin/common/utils/parameters/ParameterValues'
  24. ],
  25. function(ContentView, $, Q, StringResource, Utils, rsCommon, rsOpenHelper, rsPerformance, rsIFrameManager, rsLaunchParameters,
  26. rsPromptParameters, rsShareHelper, ParameterValues)
  27. {
  28. 'use strict';
  29. var v_sObserverId = "/authoring/js/rsContentView";
  30. var v_aSpecModificationPluginIds = [
  31. "com.ibm.bi.authoring.saveAsBtn",
  32. "com.ibm.bi.authoring.undoBtn",
  33. "com.ibm.bi.authoring.redoBtn",
  34. "com.ibm.bi.authoring.toggleEditViewer"
  35. ];
  36. function handleTruthyValueAlreadySetOrAddObserver(v_oApplication, v_sPropertyName, v_fnOnChangeCallback) {
  37. if ( v_oApplication.SharedState.Get(v_sPropertyName) )
  38. {
  39. v_fnOnChangeCallback();
  40. }
  41. else
  42. {
  43. v_oApplication.SharedState.AddObserver(v_sObserverId, v_sPropertyName, v_fnOnChangeCallback);
  44. }
  45. }
  46. function handleTruthyValueAlreadySetAndAddObserver(v_oApplication, v_sPropertyName, v_fnOnChangeCallback) {
  47. if ( v_oApplication.SharedState.Get(v_sPropertyName) )
  48. {
  49. v_fnOnChangeCallback();
  50. }
  51. v_oApplication.SharedState.AddObserver(v_sObserverId, v_sPropertyName, v_fnOnChangeCallback);
  52. }
  53. var rsContentView = ContentView.extend({
  54. init: function(options, appView) {
  55. this.m_oLaunchPromise = options.launchPromise;
  56. delete options.launchPromise;
  57. rsCommon.decodeAndMoveCMProperties(options);
  58. rsCommon.convertStringQSToValues(options, options.glassContext);
  59. rsCommon.decodeAndMoveRSOptions(options);
  60. // After the following call, every member of options is now a member of this
  61. rsContentView.inherited('init', this, arguments);
  62. this.m_fOnWindowResize = this.syncIFrameSizeToView.bind(this);
  63. window.addEventListener("resize", this.m_fOnWindowResize, false);
  64. this.m_oAppView = appView;
  65. var v_oAppViewFirstLoadedDeferred = Q.defer();
  66. this.m_oRemoveAppViewLoadedHandler = this.glassContext.getCoreSvc('.Events').on(
  67. 'appView:loaded',
  68. this._handleFirstAppViewOnLoaded.bind(this,v_oAppViewFirstLoadedDeferred),
  69. this);
  70. this.m_oAppViewFirstLoadedPromise = v_oAppViewFirstLoadedDeferred.promise;
  71. // Extract information that is passed when creating view directly without going through open helper first.
  72. // Some examples are tryIt, launch from RS, invoking share URL with perspective specified.
  73. this.m_oRSParameters = this.m_oRSParameters || {}; // Make sure m_oRSParameters is initialized
  74. try {
  75. // to open a report passed on the URL and pass parameters, we need access to the
  76. // launch parameters stored in the calling window's Application object
  77. var v_oLaunchParameters = rsLaunchParameters.Retrieve(this.launchParametersKey);
  78. if (v_oLaunchParameters)
  79. {
  80. // This is the "run spec from RS" use case
  81. this.m_oLaunchParameters = v_oLaunchParameters;
  82. }
  83. else if (window.parent && this.launchParametersRef)
  84. {
  85. // This is the "edit parameter values" use case (typically called from share code)
  86. this.m_oLaunchParameters = window.parent[options.launchParametersRef];
  87. }
  88. if (window.opener && !window.opener.closed && window.opener.RSParameters)
  89. {
  90. if (this.isNemesis)
  91. {
  92. var o = window.opener.RSParameters;
  93. for (var v_sAttrName in o)
  94. {
  95. if (v_sAttrName == 'reportXML')
  96. {
  97. // Passing the report spec text in an HTML encoded JSON object
  98. // is difficult. There are multiple levels of encoding.
  99. // Instead we pass a sentinel value and stash the original value
  100. // for later retrieval.
  101. this.m_oRSParameters.useGlassReportXML = true;
  102. this.m_sReportSpecFromOpener = o[v_sAttrName];
  103. }
  104. else
  105. {
  106. this.m_oRSParameters[v_sAttrName] = o[v_sAttrName];
  107. }
  108. }
  109. if (this.m_oRSParameters.useGlassReportXML)
  110. {
  111. this.m_oRSParameters.model = "";
  112. }
  113. if (o.AppOnLoad)
  114. {
  115. this.AppOnLoad = window.opener[ o.AppOnLoad ];
  116. }
  117. }
  118. //HACK, BY - The following 3 lines are for 'Try it'. 'Try it' still launch authoring with parameters passed with window.opener.RSParameters
  119. //We need this until 'Try it' starts passing parameters from URL. A defect will be logged to track this.
  120. else if (!this.m_oLaunchParameters && !this.isHomepage)
  121. {
  122. var v_oSrcParameters = window.opener.RSParameters;
  123. window.opener.RSParameters = undefined;
  124. // Copy the parameters from the opener's and then clear the
  125. // the opener's value
  126. this.startingTemplate = v_oSrcParameters.startingTemplate;
  127. this.moduleId = v_oSrcParameters.module;
  128. this.isViewer = v_oSrcParameters.isViewer; // not sure if this one is ever set
  129. this.m_oLaunchParameters = rsLaunchParameters.Retrieve(v_oSrcParameters.launchParametersKey);
  130. //Try it launches us with a module and startingTemplate but not a moduleSearchPath. Construct the moduleSearchPath
  131. if (this.moduleId && !this.moduleSearchPath && this.startingTemplate)
  132. {
  133. this.m_bIsTryIt = true;
  134. this.moduleSearchPath = "storeID(\"" + this.moduleId + "\")";
  135. this.action = 'run';
  136. console.log("rsContentView.init() - launched from try it setting module search path " + this.m_oRSParameters["moduleSearchPath"]);
  137. }
  138. }
  139. }
  140. }
  141. catch(e)
  142. {
  143. console.log("rsContentView.init() - Call to window.opener failed, assume it doesn't exist");
  144. }
  145. this.m_bDisableRsLockUnlock = false;
  146. this.m_bFullyInitialized = false;
  147. },
  148. _postInit: function() {
  149. if (this.m_bFullyInitialized) {
  150. return;
  151. }
  152. this.m_bFullyInitialized = true;
  153. var options = this;
  154. // convert parameters from JSON to SOAPy Bus Parameters
  155. if (options.parameterValuesJSON)
  156. {
  157. // option.parameterValuesXML get set the following ways
  158. // 1) by options passed (options.parameterValuesXML in SOAPy bus xml) into the perspective or
  159. // 2) by converting the parameterValuesJSON to a SOAPy bus xml.
  160. // The goal is eventual to phase out passing the parameterValuesXML
  161. // and solely use the parameterValuesJSON.
  162. // Not certain if the above goal still applies.
  163. // It forces the conversion of parameter values from SOAP XML to JSON only to convert them back
  164. // The prompt values are currently either pass one of the two ways mentioned above, but never both.
  165. // if you hand bomb the URL, the parameterValuesJSON will take precedence.
  166. options.parameterValuesXML = rsPromptParameters.rsBuildPromptParameters(undefined, options.parameterValuesJSON);
  167. delete options.parameterValuesJSON;
  168. }
  169. //console.log("rsContentView.init");
  170. // If we have a launch promise then the RS parameters were already created
  171. // otherwise create them now but keep existing values
  172. if (!this.m_oLaunchPromise) {
  173. $.extend( this.m_oRSParameters, rsCommon.createRSParameters(options, this.glassContext) );
  174. }
  175. this.m_bNewlyCreatedReport = this.m_oRSParameters.reportStoreID ? false : true;
  176. if (options.isSlideout) {
  177. this.m_bDisableRsLockUnlock = true;
  178. }
  179. if (this.m_oLaunchParameters && this.m_oLaunchParameters['RunOptions'])
  180. {
  181. //console.log("setting format" + this.m_oLaunchParameters['RunOptions'].OutputFormat);
  182. if ( !this.m_oRSParameters["rsFinalRunOptions"] )
  183. {
  184. this.m_oRSParameters["rsFinalRunOptions"] = {};
  185. }
  186. if (this.m_oLaunchParameters['RunOptions'].OutputFormat)
  187. {
  188. this.m_oRSParameters["rsFinalRunOptions"].format = this.m_oLaunchParameters['RunOptions'].OutputFormat;
  189. }
  190. if (this.m_oLaunchParameters['RunOptions'].isApplication)
  191. {
  192. this.m_oRSParameters["rsFinalRunOptions"].isApplication = this.m_oLaunchParameters['RunOptions'].isApplication;
  193. }
  194. if (this.m_oLaunchParameters['RunOptions'].globalParameters)
  195. {
  196. // Make global parameters available to viewer when running from editor.
  197. this.m_oRSParameters["rsFinalRunOptions"].globalParameters = this.m_oLaunchParameters['RunOptions'].globalParameters;
  198. }
  199. }
  200. this.m_bInitialIsViewerState = this.m_oRSParameters.isViewer;
  201. if (this.m_oLaunchParameters && this.m_oLaunchParameters.parameterValuesJSON)
  202. {
  203. // convert parameters from JSON to SOAPy Bus Parameters
  204. this.m_oLaunchParameters["parameterValuesXML"] = rsPromptParameters.rsBuildPromptParameters(undefined, this.m_oLaunchParameters.parameterValuesJSON);
  205. delete this.m_oLaunchParameters.parameterValuesJSON;
  206. }
  207. },
  208. render: function() {
  209. if (this.rsResolved) {
  210. // urlMap already fully resolved so proceed with rendering
  211. return this._render();
  212. }
  213. // Perspective was launched directly without going through rsOpenHelper
  214. // Complete open resolution then proceed with render.
  215. if (!this.cmProperties && this.objRef) {
  216. // Create cmProperties from available information so resolution has something to work with
  217. this.cmProperties = {
  218. id: this.objRef,
  219. type: this.type // may or not be available but that is OK
  220. };
  221. }
  222. var v_oOpenSpec = {
  223. cmProperties: this.cmProperties,
  224. glassContext: this.glassContext,
  225. urlMap: this
  226. };
  227. return rsOpenHelper.resolveUrlMap(v_oOpenSpec).then(function(v_oResolvedOpenSpec) {
  228. // Merge resolved urlMap back into this instance and proceed with rendering
  229. $.extend(this, v_oResolvedOpenSpec.urlMap);
  230. return this._render();
  231. }.bind(this));
  232. },
  233. _render: function() {
  234. // Perform any final initialization now that urlMap is fully resolved
  235. this._postInit();
  236. // N.B. Glass expected jQuery promises
  237. var $renderDeferred = $.Deferred();
  238. if (this.m_oRSParameters.closePerspective || this.action == 'none')
  239. {
  240. // The perspective can't be opened
  241. var v_oState = {
  242. isViewer: true,
  243. objectType: '',
  244. runInAdvancedViewer: true
  245. };
  246. this._updatePlugins( v_oState );
  247. if (this.m_oRSParameters.closePerspective)
  248. {
  249. // Reject with message which the glass will display in a modal dialog
  250. var v_sError = StringResource.get('no_output_format_capability', {outputFormat: this.m_oRSParameters.rsFinalRunOptions.format});
  251. $renderDeferred.reject({ message: v_sError });
  252. }
  253. else
  254. {
  255. // Resolve without rendering anything and show toast.
  256. // We use toast so that this message is displayed in a consistent fashion (see rsOpenHelper)
  257. // We can't reject because the toast does not appear if we do.
  258. // Arrange to close perspective when toast is dismissed
  259. var v_sError = StringResource.get('no_action_available');
  260. this.glassContext.showToast(v_sError, {
  261. 'type':'warning',
  262. 'btnLabel':'OK',
  263. 'callback': function() {
  264. this.glassContext.closeAppView("authoring", this.id);
  265. }.bind(this)
  266. });
  267. $renderDeferred.resolve();
  268. }
  269. return $renderDeferred.promise();
  270. }
  271. //console.log("rsContentView.render() ...");
  272. rsPerformance.mark('rsContentView.render');
  273. console.timeEnd('rsperf: onSelectItem->render');
  274. console.time('rsperf: render->OnRSApplicationReadyForObservers');
  275. // This is the "early" rendering resolve - show the StartUp div right away
  276. $renderDeferred.resolve(this);
  277. // HACK: the Glass doesn't have an API to squish the sidebar
  278. this.m_oAppView.$('.navbar').addClass('narrow');
  279. if (!this.m_oLaunchPromise) {
  280. var v_oTemplateParameters = rsCommon.createTemplateParameters(this.m_oRSParameters);
  281. this.m_oLaunchPromise = rsIFrameManager.F_LaunchRS(v_oTemplateParameters, this.glassContext, this.m_oLaunchParameters);
  282. }
  283. this.m_oLaunchPromise
  284. .catch(function(err) {
  285. console.log(err);
  286. this.hackUnlockGlass();
  287. $renderDeferred.reject(err);
  288. }.bind(this))
  289. .done(this._onRSApplicationReady.bind(this, $renderDeferred));
  290. // Set the plugin state based on initial parameters.
  291. // This should reduce plugin "flickering".
  292. var v_oState = {
  293. isViewer: this.m_bInitialIsViewerState,
  294. objectType: '',
  295. runInAdvancedViewer: this.m_bNewlyCreatedReport
  296. };
  297. if (this.cmProperties)
  298. {
  299. v_oState.objectType = this.cmProperties.type;
  300. if ( this.cmProperties.runInAdvancedViewer )
  301. {
  302. v_oState.runInAdvancedViewer = true;
  303. }
  304. }
  305. this._updatePlugins( v_oState );
  306. // Instrumentation wants specific terms
  307. // Some glass actions won't be instrumented
  308. var v_oGlassActionToInstrumentationEventType = {
  309. 'run' : 'Ran Process',
  310. 'viewOutput': 'Read Object',
  311. 'edit': 'Read Object',
  312. 'create' : 'Created Object'
  313. };
  314. var v_sInstrumentationType = v_oGlassActionToInstrumentationEventType[ this.action ];
  315. if (v_sInstrumentationType && this.glassContext)
  316. {
  317. var v_oInstrumentationService = this.glassContext.getCoreSvc('.Instrumentation');
  318. if (v_oInstrumentationService && v_oInstrumentationService.enabled)
  319. {
  320. var v_sType;
  321. var v_sId;
  322. if (this.type == 'output' && this.cmProperties)
  323. {
  324. // our opener code should fill in the parent chain
  325. // cmProperties.parent[0] is the reportVersion object
  326. // cmProperties.parent[0].parent[0] is the object that has output versions
  327. var v_oVersionedAncestor = this.cmProperties.parent[0].parent[0];
  328. v_oVersionedAncestor = v_oVersionedAncestor.base || v_oVersionedAncestor;
  329. v_sType = v_oVersionedAncestor.type;
  330. v_sId = v_oVersionedAncestor.id;
  331. }
  332. else
  333. {
  334. v_sType = this.type;
  335. v_sId = this.id;
  336. }
  337. if (v_sInstrumentationType === v_oGlassActionToInstrumentationEventType.edit && this.isNew)
  338. {
  339. v_sInstrumentationType = v_oGlassActionToInstrumentationEventType.create;
  340. v_sId = 'null';
  341. if (!v_sType)
  342. {
  343. // if we don't have a type AND it's a new
  344. // assume we are creating a report
  345. v_sType = 'report';
  346. }
  347. }
  348. var v_oEvent = {
  349. type: v_sInstrumentationType,
  350. objectType: v_sType,
  351. object: v_sId,
  352. milestoneName: v_sInstrumentationType + '_' + v_sType
  353. };
  354. if (v_sInstrumentationType === v_oGlassActionToInstrumentationEventType.run)
  355. {
  356. v_oEvent['processType'] = 'Run a Report';
  357. }
  358. if ( [v_oGlassActionToInstrumentationEventType.run, v_oGlassActionToInstrumentationEventType.viewOutput].indexOf(v_sInstrumentationType) !== -1 )
  359. {
  360. v_oEvent['custom.viewer'] = 'interactive';
  361. v_oEvent['custom.outputFormat'] = this.format;
  362. }
  363. v_oInstrumentationService.track( v_oEvent );
  364. }
  365. }
  366. this.hackLockGlass();
  367. return $renderDeferred.promise();
  368. },
  369. getTitle: function() {
  370. if (this.isApplicationLoaded() )
  371. {
  372. return this.getAuthoringApplication().SharedState.Get("reportName");
  373. }
  374. else
  375. {
  376. return StringResource.get(this.perspective == 'datasets' ? 'dataset_welcome' : 'authoring_welcome');
  377. }
  378. },
  379. getIcon: function() {
  380. var v_sIcon;
  381. if (this.perspective == 'datasets')
  382. {
  383. v_sIcon = 'common-dataset';
  384. }
  385. else
  386. {
  387. var v_sReportType = this.getAuthoringApplication() && this.getAuthoringApplication().SharedState.Get("objectType");
  388. switch(v_sReportType)
  389. {
  390. case 'interactiveReport' :
  391. v_sIcon = 'common-interactiveReport';
  392. break;
  393. case 'reportView' :
  394. v_sIcon = 'common-report_view';
  395. break;
  396. default :
  397. v_sIcon = 'common-report';
  398. break;
  399. }
  400. }
  401. return v_sIcon;
  402. },
  403. getIconTooltip: function() {
  404. return StringResource.get( this.perspective == 'datasets' ? 'dataset_welcome' : 'authoring_welcome');
  405. },
  406. getType: function() {
  407. var v_sObjectType;
  408. if (this.isApplicationLoaded())
  409. {
  410. v_sObjectType = this.getAuthoringApplication().SharedState.Get("objectType");
  411. }
  412. return v_sObjectType;
  413. },
  414. isDirty: function() {
  415. var v_oSharedState = this.getAuthoringApplication() ? this.getAuthoringApplication().SharedState : null;
  416. var v_sObjectType = v_oSharedState ? v_oSharedState.Get("objectType") : "";
  417. // reportViews can't be saved so don't mark them as dirty
  418. if (v_sObjectType != 'reportView' && !this.isNemesis && this.isApplicationLoaded() && !this.m_bIsTryIt)
  419. {
  420. var v_bIsModified = v_oSharedState && v_oSharedState.Get("isModified");
  421. var v_bIsViewer = v_oSharedState && v_oSharedState.Get("isViewer");
  422. if (v_bIsModified && v_bIsViewer)
  423. {
  424. var v_bRead = (!this.cmProperties || !this.cmProperties.permissions || this.cmProperties.permissions.indexOf("read") != -1);
  425. var v_bWrite = (!this.cmProperties || !this.cmProperties.permissions || this.cmProperties.permissions.indexOf("write") != -1);
  426. var v_bSaveAsCapabilities = this.glassContext.hasCapability("canUseReportStudio") && this.glassContext.hasCapability("canUseReportStudioFileManagement");
  427. // Can't save if no read (unable to unstub in viewer) or no write (no save) and no save as capabilities
  428. if (!v_bRead || (!v_bWrite && !v_bSaveAsCapabilities))
  429. {
  430. // Can't save/save as in viewer so don't mark as dirty to avoid message indicating object changed on exit.
  431. v_bIsModified = false;
  432. }
  433. }
  434. return v_bIsModified;
  435. }
  436. else
  437. {
  438. return false;
  439. }
  440. },
  441. getAuthoringApplication: function() {
  442. return rsCommon.getAuthoringApplicationFromIFrame(this.m_iframeAuthoring);
  443. },
  444. isApplicationLoaded: function() {
  445. var v_Application = this.getAuthoringApplication();
  446. return !!(v_Application && v_Application.SharedState.Get("isAppLoaded"));
  447. },
  448. canRun: function() {
  449. var v_oAuthoringApp = this.getAuthoringApplication();
  450. return v_oAuthoringApp.SharedState.Get("canRun");
  451. },
  452. /*
  453. getContent - Called by the glass to cache the current state and set the url (eg for bookmarking)
  454. - By default we should return all our serializable state
  455. - when parameter options{mode:'bookmark'} is passed in, getContent is being called for the purposes of
  456. - determining the url/for bookmarking. We can discard transient state for this call.
  457. NOTE:
  458. If called too early getContent() returns undefined
  459. Else
  460. returns {
  461. .* // whatever was passed in as init(options)
  462. .cmProperties {
  463. // from the content team, typically includes:
  464. id
  465. type
  466. permissions ?
  467. }
  468. // maybe undefined if getContent() was called too early
  469. .application {
  470. .storeID, // the CM store id of the currently saved report, null if not saved
  471. .cmSearchPath, // the CM search path of the currently saved report, null if not saved
  472. .reportName, // the name of the current report
  473. .isModifed // true if there is a current report AND it needs to be saved
  474. .type // the CM type of the object
  475. }
  476. }
  477. */
  478. getContent: function(options) {
  479. // console.log("rsContentView.getContent" );
  480. return rsCommon.getContent( options, this, rsShareHelper );
  481. },
  482. getApplicationContent: function( v_oContent, v_oCmProperties )
  483. {
  484. var application = {};
  485. if (this.isApplicationLoaded())
  486. {
  487. var v_oAuthoringApp = this.getAuthoringApplication();
  488. var v_sStoreID = v_oAuthoringApp.SharedState.Get("storeID");
  489. application.storeID = v_sStoreID;
  490. application.isModified = v_oAuthoringApp.SharedState.Get("isModified");
  491. application.cmSearchPath = v_oAuthoringApp.SharedState.Get("cmSearchPath");
  492. application.reportName = this.getTitle();
  493. if ( ! v_oCmProperties )
  494. {
  495. console.log("rsContentView.getContent no .cmProperties");
  496. v_oCmProperties = { type: undefined };
  497. }
  498. // authoring only supports editing or running of
  499. // { report, interactiveReport, reportTemplate }
  500. // even if we open something else (like a query or an analysis)
  501. // it is converted into a report
  502. var v_sType = ( v_oContent.objRef && v_oContent.type) || (v_oCmProperties && v_oCmProperties.type);
  503. if (v_sType === 'reportTemplate' || v_sType === 'dataSet2')
  504. {
  505. // if we opened a template it must have stayed as a template
  506. // because we can't convert it from template to anything else
  507. application.type = v_sType;
  508. }
  509. else if (v_oAuthoringApp.SharedState.Get("isActiveReport"))
  510. {
  511. application.type = 'interactiveReport';
  512. }
  513. else
  514. {
  515. application.type = 'report';
  516. }
  517. }
  518. return application;
  519. },
  520. onAppLoaded: function() {
  521. var v_Application = this.getAuthoringApplication();
  522. //console.time('rsperf: rsContentView.onAppLoaded_1->ContentView.onAppLoaded_2');
  523. this.m_oAppViewFirstLoadedPromise.done( function(){
  524. //console.timeEnd('rsperf: rsContentView.onAppLoaded_1->ContentView.onAppLoaded_2');
  525. rsIFrameManager.F_PositionAndSizeIFrame( this.$el, this.m_iframeAuthoring);
  526. this.hackUnlockGlass();
  527. handleTruthyValueAlreadySetAndAddObserver(v_Application, "reportName",this.updateTitle.bind(this));
  528. handleTruthyValueAlreadySetOrAddObserver(v_Application, "isReportLoaded", this._on_isReportLoaded.bind(this));
  529. v_Application.SharedState.AddObserver(
  530. v_sObserverId,
  531. "isViewer",
  532. this._on_isViewer.bind(this));
  533. v_Application.SharedState.AddObserver(
  534. v_sObserverId,
  535. "isActiveReport",
  536. this._on_isActiveReport.bind(this));
  537. v_Application.SharedState.AddObserver(
  538. v_sObserverId,
  539. "runInAdvancedViewer",
  540. this._on_runInAdvancedViewer.bind(this));
  541. v_Application.SharedState.AddObserver(
  542. v_sObserverId,
  543. "viewer",
  544. this._on_viewer.bind(this));
  545. v_Application.SharedState.AddObserver(
  546. v_sObserverId,
  547. "isModified",
  548. this._on_isModified.bind(this));
  549. v_Application.SharedState.AddObserver(
  550. v_sObserverId,
  551. "storeID",
  552. this._on_storeID.bind(this));
  553. if (this.onSavedCallback) {
  554. v_Application.SharedState.AddObserver(null, "onDatasetSaved", this.onSavedCallback);
  555. delete this.onSavedCallback;
  556. }
  557. if (this.onCancelCallback) {
  558. v_Application.SharedState.AddObserver(null, "onDatasetCancelled", this.onCancelCallback);
  559. delete this.onCancelCallback;
  560. }
  561. handleTruthyValueAlreadySetOrAddObserver(v_Application, "firstBeforeDraw", this.onViewBeforeFirstDraw.bind(this));
  562. handleTruthyValueAlreadySetOrAddObserver(v_Application, "firstAfterDraw", this.onViewAfterFirstDraw.bind(this));
  563. if (this.isNew && !rsOpenHelper.isReport_ish( this.cmProperties ))
  564. {
  565. // New report and cm properties are for a non-report like object
  566. // Remove the cm properties (which were likely the package/module we started from)
  567. // so we don't inadvertently use information thinking we have a report object.
  568. delete this.cmProperties;
  569. }
  570. }.bind(this));
  571. },
  572. onViewBeforeFirstDraw: function() {
  573. console.time('rsperf: ViewBeforeDraw->ViewAfterDraw');
  574. rsPerformance.mark('rsContentView.onViewBeforeDraw');
  575. },
  576. onViewAfterFirstDraw: function() {
  577. rsPerformance.mark('rsContentView.onViewAfterDraw');
  578. rsPerformance.mark('authoring-selectItemAndDraw-stop');
  579. console.timeEnd('rsperf: ViewBeforeDraw->ViewAfterDraw');
  580. console.timeEnd('rsperf: total_RunReport');
  581. if (this.glassContext && this.glassContext.isDevInstall && this.glassContext.isDevInstall())
  582. {
  583. rsPerformance.summarizeInteractiveViewerRun( this);
  584. }
  585. var v_Application = this.getAuthoringApplication();
  586. if ((!this.m_oLaunchParameters || !this.m_oLaunchParameters["promptContext"]) && v_Application.GetUserDataSetting("PreLaunchRS"))
  587. {
  588. rsIFrameManager.F_PreLaunch(this.glassContext);
  589. }
  590. },
  591. enablePluginForApplicationState: function( v_oOption ) {
  592. var v_oState = this.getAuthoringApplication().SharedState.Get(v_oOption.state);
  593. this._setEnableForPlugins(v_oState, [v_oOption.plugin]);
  594. },
  595. highlightPluginForApplicationState: function( v_oOption ) {
  596. var v_oState = this.getAuthoringApplication().SharedState.Get(v_oOption.state);
  597. var v_oPlugin = this.glassContext.findPlugin(v_oOption.plugin);
  598. if (v_oPlugin)
  599. {
  600. if (v_oState)
  601. {
  602. console.log('rsContentView press %s', v_oOption.plugin);
  603. v_oPlugin.setPressed();
  604. }
  605. else
  606. {
  607. console.log('rsContentView unpress %s', v_oOption.plugin);
  608. v_oPlugin.setUnpressed();
  609. }
  610. }
  611. else
  612. {
  613. console.log("rsContentView highlightPluginForApplicationState - could not find plugin: %s", v_oOption.plugin);
  614. }
  615. },
  616. showPluginForApplicationState: function( v_oOption ) {
  617. var v_oPlugin = this.glassContext.findPlugin(v_oOption.plugin);
  618. if (v_oPlugin)
  619. {
  620. var v_oState = this.getAuthoringApplication().SharedState.Get(v_oOption.state);
  621. if (v_oState)
  622. {
  623. //console.log('rsContentView enable %s', v_oOption.plugin);
  624. v_oPlugin.show();
  625. }
  626. else
  627. {
  628. //console.log('rsContentView disable %s', v_oOption.plugin);
  629. v_oPlugin.hide();
  630. }
  631. }
  632. else
  633. {
  634. console.log("rsContentView showPluginForApplicationState - could not find plugin: %s", v_oOption.plugin);
  635. }
  636. },
  637. _setDisplayForPlugins: function(v_bShow, v_aPluginIds) {
  638. v_aPluginIds.forEach(
  639. function(v_sPluginId) {
  640. var v_oPlugin = this._hackFindPlugin(v_sPluginId);
  641. if ( v_oPlugin )
  642. {
  643. if (v_bShow)
  644. {
  645. v_oPlugin.show();
  646. }
  647. else
  648. {
  649. v_oPlugin.hide();
  650. }
  651. }
  652. else
  653. {
  654. console.log('could not find plugin: %s', v_sPluginId);
  655. }
  656. },
  657. this);
  658. },
  659. _setEnableForPlugins: function(v_bEnable, v_aPluginIds) {
  660. v_aPluginIds.forEach(
  661. function(v_sPluginId) {
  662. var v_oPlugin = this._hackFindPlugin(v_sPluginId);
  663. if ( v_oPlugin )
  664. {
  665. if (v_bEnable)
  666. {
  667. v_oPlugin.enable();
  668. }
  669. else
  670. {
  671. v_oPlugin.disable();
  672. }
  673. }
  674. else
  675. {
  676. console.log('could not find plugin: %s', v_sPluginId);
  677. }
  678. },
  679. this);
  680. },
  681. _updatePlugins: function(v_oState) {
  682. var v_aEditIds = [
  683. "com.ibm.bi.authoring.runMenu",
  684. "com.ibm.bi.authoring.insertableObjectsBtn"
  685. ];
  686. var v_aViewerIds = [
  687. "com.ibm.bi.authoring.runBtn",
  688. "com.ibm.bi.authoring.refreshBtn",
  689. "com.ibm.bi.authoring.consumptionFilter",
  690. "com.ibm.bi.contentApps.teamFoldersSlideout",
  691. "com.ibm.bi.contentApps.myContentFoldersSlideout",
  692. "com.ibm.bi.search.search",
  693. "com.ibm.bi.contentApps.mruSlideout"
  694. ];
  695. if (this.m_bIsTryIt)
  696. {
  697. this._setDisplayForPlugins(false, v_aViewerIds);
  698. this._setDisplayForPlugins(false, ["com.ibm.bi.authoring.saveAsBtn",
  699. "com.ibm.bi.authoring.outputBtn",
  700. "com.ibm.bi.authoring.runMenu"]);
  701. }
  702. else if (v_oState.objectType == 'output')
  703. {
  704. var v_bRun = this.cmProperties.permissions.indexOf("execute") != -1;
  705. this._setDisplayForPlugins(v_bRun,["com.ibm.bi.authoring.outputBtn"]);
  706. this._setDisplayForPlugins(false, [
  707. "com.ibm.bi.authoring.runBtn",
  708. "com.ibm.bi.authoring.insertableObjectsBtn",
  709. "com.ibm.bi.authoring.runMenu",
  710. "com.ibm.bi.authoring.refreshBtn",
  711. "com.ibm.bi.authoring.consumptionFilter",
  712. "com.ibm.bi.authoring.saveAsBtn",
  713. "com.ibm.bi.authoring.undoBtn",
  714. "com.ibm.bi.authoring.redoBtn"
  715. ]);
  716. }
  717. else
  718. {
  719. if (v_oState.objectType == 'reportView')
  720. {
  721. // No save on report view
  722. this._setDisplayForPlugins(false, ["com.ibm.bi.authoring.saveAsBtn"]);
  723. }
  724. this._setDisplayForPlugins(false, ["com.ibm.bi.authoring.outputBtn"]);
  725. this._setDisplayForPlugins(!v_oState.isViewer, v_aEditIds);
  726. this._setDisplayForPlugins(v_oState.isViewer, v_aViewerIds);
  727. if (!v_oState.isViewer)
  728. { // hide Group Content button for authoring mode.
  729. // for consumption mode, the custom folder will be display, along with the my content + team content folders if the user has access
  730. this._setDisplayForPlugins(false, ["com.ibm.bi.contentApps.customFoldersSlideout"]);
  731. }
  732. if (v_oState.isViewer && this.m_oRSParameters.rsFinalRunOptions.format == 'PDF')
  733. {
  734. this._setDisplayForPlugins(false, ["com.ibm.bi.authoring.consumptionFilter"] );
  735. }
  736. this._setDisplayForPlugins(!(v_oState.isViewer && v_oState.isFromRS), ["com.ibm.bi.glass.common.operations"]);
  737. }
  738. var v_bRead = (!this.cmProperties || !this.cmProperties.permissions || this.cmProperties.permissions.indexOf("read") != -1);
  739. var v_bCanToggleEditView = this.glassContext.hasCapability("canUseReportStudio")
  740. && v_oState.objectType == 'report' // this excludes interactiveReport and reportView
  741. && v_oState.runInAdvancedViewer
  742. && !v_oState.useReadOnlyViewer
  743. && !this.m_bIsTryIt
  744. && !(v_oState.isViewer && v_oState.isFromRS) // exclude viewers launched from RS (viewer running a spec)
  745. && (!v_oState.isViewer || v_bRead); // exclude viewers without read access (can't unstub report spec)
  746. if(v_oState.objectType == 'interactiveReport')
  747. {
  748. this._setDisplayForPlugins(false, ["com.ibm.bi.authoring.consumptionFilter",
  749. "com.ibm.bi.authoring.refreshBtn",
  750. "com.ibm.bi.authoring.outputBtn"]);
  751. }
  752. if (this.getAuthoringApplication())
  753. {
  754. if (!v_oState.isViewer)
  755. {
  756. this.getAuthoringApplication().SharedState.Set(null, "showFilters", false);
  757. }
  758. this.getAuthoringApplication().SharedState.Set(null, "canToggleEditView", v_bCanToggleEditView);
  759. }
  760. else {
  761. // Until app is loaded, don't show the button.
  762. // When app is loaded, we come through here again but then the the code above is executed
  763. // which determines state of button.
  764. this._setDisplayForPlugins(false, ["com.ibm.bi.authoring.toggleEditViewer"]);
  765. }
  766. },
  767. _updatePluginsForNewState: function()
  768. {
  769. var v_oState = {
  770. isViewer: this.getAuthoringApplication().SharedState.Get("isViewer"),
  771. objectType: this.getAuthoringApplication().SharedState.Get("objectType"),
  772. runInAdvancedViewer: this.getAuthoringApplication().SharedState.Get("runInAdvancedViewer"),
  773. useReadOnlyViewer: this.getAuthoringApplication().SharedState.Get("useReadOnlyViewer")
  774. };
  775. if (this.m_oLaunchParameters && this.m_oLaunchParameters['RunOptions'])
  776. {
  777. if (this.m_oLaunchParameters['RunOptions'].isFromRS == true)
  778. {
  779. v_oState.isFromRS = true;
  780. }
  781. }
  782. this._updatePlugins(v_oState);
  783. },
  784. _on_isViewer: function() {
  785. this._updatePluginsForNewState();
  786. },
  787. _on_isActiveReport: function() {
  788. this._updatePluginsForNewState();
  789. },
  790. _on_runInAdvancedViewer: function() {
  791. this._updatePluginsForNewState();
  792. },
  793. _on_viewer: function() {
  794. var v_Application = this.getAuthoringApplication();
  795. // if HTML show the spec modification buttons,
  796. // otherwise hide them
  797. this._setDisplayForPlugins( v_Application.SharedState.Get("viewer").toUpperCase() == "HTML", v_aSpecModificationPluginIds );
  798. this._updatePluginsForNewState();
  799. this._updateButtonState();
  800. },
  801. _on_storeID: function() {
  802. var v_Application = this.getAuthoringApplication();
  803. var v_sStoreId = v_Application.SharedState.Get("storeID");
  804. // If there is no storeID then we are most likely dealing with a new report but we may have cmProperties of the module/package.
  805. // In this case we want to keep the cmProeprties hence we only update if we have an actual storeID.
  806. // Also, we only update if the storeID is different.
  807. if (v_sStoreId && (!this.cmProperties || v_sStoreId != this.cmProperties.id)) {
  808. rsOpenHelper.updateCmProperties(this, v_sStoreId)
  809. .then( function () {
  810. this._updatePluginsForNewState();
  811. // Let glass know our id changed
  812. this.glassContext.updateCurrentCachedAppView();
  813. }.bind(this));
  814. }
  815. },
  816. _updateButtonState: function() {
  817. var v_Application = this.getAuthoringApplication();
  818. var v_aStateAndPlugin = [
  819. {state: "canUndo", plugin: "com.ibm.bi.authoring.undoBtn"},
  820. {state: "canRedo", plugin: "com.ibm.bi.authoring.redoBtn"},
  821. // run button is in the menu until we get a "menu button"
  822. {state: "canRun", plugin: "com.ibm.bi.authoring.runBtn"},
  823. {state: "canRun", plugin: "com.ibm.bi.authoring.runMenu"},
  824. {state: "canRun", plugin: "com.ibm.bi.authoring.refreshBtn"}
  825. ];
  826. v_aStateAndPlugin.forEach( function(v_o){
  827. // set the initial state
  828. this.enablePluginForApplicationState(v_o);
  829. // listen for future changes
  830. v_Application.SharedState.AddObserver(
  831. v_sObserverId,
  832. v_o.state,
  833. this.enablePluginForApplicationState.bind(this, v_o));
  834. },
  835. this);
  836. },
  837. _on_isReportLoaded: function() {
  838. var v_Application = this.getAuthoringApplication();
  839. if (v_Application.SharedState.Get("useReadOnlyViewer"))
  840. {
  841. this._setDisplayForPlugins( false, v_aSpecModificationPluginIds );
  842. var v_oStateAndPlugin = {state: "canRun", plugin: "com.ibm.bi.authoring.runBtn"};
  843. // set the initial state
  844. this.enablePluginForApplicationState(v_oStateAndPlugin);
  845. // listen for future changes
  846. v_Application.SharedState.AddObserver(
  847. v_sObserverId,
  848. v_oStateAndPlugin.state,
  849. this.enablePluginForApplicationState.bind(this, v_oStateAndPlugin));
  850. }
  851. else
  852. {
  853. this._updateButtonState();
  854. var v_aLeftSideStateAndPlugin = [
  855. {state: "showInsertableObjects", plugin: "com.ibm.bi.authoring.insertableObjectsBtn"}
  856. ];
  857. v_aLeftSideStateAndPlugin.forEach( function(v_o){
  858. this.highlightPluginForApplicationState(v_o);
  859. v_Application.SharedState.AddObserver(v_sObserverId, v_o.state, this.highlightPluginForApplicationState.bind(this, v_o));
  860. },
  861. this);
  862. var v_sToggleEditPluginId = "com.ibm.bi.authoring.toggleEditViewer";
  863. var v_oToggleEditButtonPlugin = this._hackFindPlugin(v_sToggleEditPluginId);
  864. if (!v_oToggleEditButtonPlugin)
  865. {
  866. console.log('could not find plugin: %s', v_sToggleEditPluginId);
  867. }
  868. else
  869. {
  870. var v_bIsViewer = v_Application.SharedState.Get("isViewer");
  871. if (v_bIsViewer)
  872. {
  873. v_oToggleEditButtonPlugin.setUnpressed();
  874. }
  875. else
  876. {
  877. v_oToggleEditButtonPlugin.setPressed();
  878. }
  879. this._updateToggleEditView();
  880. // listen for future changes
  881. v_Application.SharedState.AddObserver(v_sObserverId, "canToggleEditView", this._updateToggleEditView.bind(this));
  882. v_Application.SharedState.AddObserver(v_sObserverId, "canEditReport", this._updateToggleEditView.bind(this));
  883. }
  884. }
  885. this._updatePluginsForNewState();
  886. var v_oMRU;
  887. var v_oDummyCmProperties = { type: this.type };
  888. if (rsOpenHelper.isReport_ish( v_oDummyCmProperties ))
  889. {
  890. // Only process if type is a report-like type
  891. // It may be a package in some cases so we don't want a MRU for the package (they don't work well)
  892. if (this.objRef)
  893. {
  894. //TODO, BY - content api is not ready to take 'objRef' as input yet. Once they are ready
  895. //we will do v_oMRU = $.extend(true, {}, this.m_oSerializableInitOptions);
  896. v_oMRU = {};
  897. v_oMRU.id = this.objRef;
  898. v_oMRU.type = this.getAuthoringApplication().SharedState.Get("objectType");
  899. v_oMRU.defaultName= this.getAuthoringApplication().SharedState.Get("reportName");
  900. }
  901. else if (this.cmProperties)
  902. {
  903. v_oMRU = $.extend(true, {}, this.cmProperties);
  904. }
  905. }
  906. else
  907. {
  908. if (this.reportProperties)
  909. {
  910. v_oMRU = $.extend(true, {}, this.reportProperties);
  911. }
  912. }
  913. if (v_oMRU)
  914. {
  915. this._addToMRU(v_oMRU);
  916. }
  917. this.updateTitle();
  918. },
  919. _addToMRU: function(mruEntry) {
  920. return this.glassContext.getSvc('.Content').then(function(contentSvc) {
  921. return contentSvc.addToMRU(mruEntry);
  922. });
  923. },
  924. _updateToggleEditView: function() {
  925. var v_Application = this.getAuthoringApplication();
  926. if (v_Application.SharedState.Get('canToggleEditView') && v_Application.SharedState.Get('canEditReport'))
  927. {
  928. var v_oPlugin = this.glassContext.findPlugin("com.ibm.bi.authoring.toggleEditViewer");
  929. if (v_oPlugin)
  930. {
  931. v_oPlugin.show();
  932. }
  933. }
  934. },
  935. _on_isModified: function() {
  936. var v_oSharedState = this.getAuthoringApplication().SharedState;
  937. var v_bCantSaveModified = false;
  938. var v_bIsModified = v_oSharedState.Get("isModified");
  939. if (v_bIsModified && v_oSharedState.Get("isViewer"))
  940. {
  941. // If viewing and no read then can't save/save as since this requires spec unstubbing which requires read access.
  942. var v_bRead = (!this.cmProperties || !this.cmProperties.permissions || this.cmProperties.permissions.indexOf("read") != -1);
  943. var v_bWrite = (!this.cmProperties || !this.cmProperties.permissions || this.cmProperties.permissions.indexOf("write") != -1);
  944. var v_bSaveAsCapabilities = this.glassContext.hasCapability("canUseReportStudio") && this.glassContext.hasCapability("canUseReportStudioFileManagement");
  945. // Can't save if no read (unable to unstub) or no write (no save) and no save as capabilities
  946. v_bCantSaveModified = !v_bRead || (!v_bWrite && !v_bSaveAsCapabilities);
  947. }
  948. if (v_bCantSaveModified)
  949. {
  950. // can't save modified spec so disable save button and warn user
  951. this.glassContext.showToast(this.getAuthoringApplication().GetString("IDS_MSG_EDITS_LOST"), {'type':'info'});
  952. this._setEnableForPlugins(false, ["com.ibm.bi.authoring.saveAsBtn"]);
  953. }
  954. else
  955. {
  956. this._setEnableForPlugins(true, ["com.ibm.bi.authoring.saveAsBtn"]);
  957. }
  958. this.trigger('change:dirty', {value: v_bIsModified});
  959. },
  960. updateTitle: function() {
  961. var v_sReportName = this.getAuthoringApplication().SharedState.Get("reportName");
  962. this.trigger('change:title', {'value': v_sReportName});
  963. },
  964. // Add the "clsGlassUiDisplayed" class to the RS document body when the glass displays UI
  965. _addGlassBodyObserver: function()
  966. {
  967. if ( this.m_bIsIE === undefined )
  968. {
  969. this.m_bIsIE = ( ( navigator.userAgent.toLowerCase().search(/trident\/([0-9]+\.[0-9]+)/) != -1 ) ? parseFloat( RegExp.$1 ) : 0 ) >= 7.0;
  970. }
  971. if ( !this.m_bIsIE )
  972. {
  973. return;
  974. }
  975. this.m_oBodyObserver = new MutationObserver( function() {
  976. var v_aClasses = ["openedMenu" ,"openedSlideout", "openedAppViewSlideout", "openedDialog"];
  977. if ( v_aClasses.some( function( s ) { return this.contains( s ); }, document.body.classList ) )
  978. {
  979. this.m_iframeAuthoring.contentDocument.body.classList.add( "clsGlassUiDisplayed" );
  980. }
  981. else
  982. {
  983. this.m_iframeAuthoring.contentDocument.body.classList.remove( "clsGlassUiDisplayed" );
  984. }
  985. }.bind( this ) );
  986. this.m_oBodyObserver.observe( document.body, { attributes: true, attributeFilter: ["class"] } );
  987. },
  988. _removeGlassBodyObserver: function()
  989. {
  990. if ( this.m_oBodyObserver )
  991. {
  992. this.m_oBodyObserver.disconnect();
  993. this.m_oBodyObserver = null;
  994. }
  995. },
  996. show: function() {
  997. rsContentView.inherited('show', this, arguments);
  998. if (this.m_iframeAuthoring)
  999. {
  1000. // div has not been rendered in DOM yet so has no size, need a setTimeout to let it happen
  1001. setTimeout(rsIFrameManager.F_PositionAndSizeIFrame.bind(rsIFrameManager, this.$el, this.m_iframeAuthoring), 0);
  1002. this.getAuthoringApplication().Activate();
  1003. }
  1004. this._addGlassBodyObserver();
  1005. },
  1006. deactivate: function() {
  1007. this._removeGlassBodyObserver();
  1008. if (this.m_iframeAuthoring)
  1009. {
  1010. this.getAuthoringApplication().Deactivate();
  1011. rsIFrameManager.F_HideIFrame(this.m_iframeAuthoring);
  1012. }
  1013. },
  1014. remove: function() {
  1015. var v_oApplication = this.getAuthoringApplication();
  1016. if( this.m_bIsTryIt )
  1017. {
  1018. v_oApplication.DeleteTempModule(this.moduleId);
  1019. }
  1020. if (this.m_fOnWindowResize)
  1021. {
  1022. window.removeEventListener("resize", this.m_fOnWindowResize, false);
  1023. this.m_fOnWindowResize = null;
  1024. }
  1025. if (this.m_oRemoveAppViewLoadedHandler)
  1026. {
  1027. this.m_oRemoveAppViewLoadedHandler.remove();
  1028. this.m_oRemoveAppViewLoadedHandler = undefined;
  1029. }
  1030. if (this.m_iframeAuthoring)
  1031. {
  1032. // m_iframeAuthoring may not be defined if we are in an error state
  1033. rsIFrameManager.F_DetachIFrame(this.m_iframeAuthoring);
  1034. this.m_iframeAuthoring = null;
  1035. }
  1036. this.m_oLaunchPromise = null;
  1037. this.m_oAppView = null;
  1038. return true;
  1039. },
  1040. /**
  1041. * Hide a menu item from another provider.
  1042. *
  1043. * returns
  1044. * false: if there is a valid itemId present and authoring would like to hide that menu item
  1045. * true: for all other conditions
  1046. */
  1047. isMenuItemVisible: function (context){
  1048. // if the function is called very early we may not have an application yet
  1049. if (!this.getAuthoringApplication()) {
  1050. return true;
  1051. }
  1052. var v_sMenuItem = context.target.itemId;
  1053. if (v_sMenuItem) {
  1054. var v_oCurrentContentView = context.glassContext.currentAppView.currentContentView;
  1055. var v_bIsViewer = this.getAuthoringApplication().SharedState.Get("isViewer");
  1056. switch (v_sMenuItem) {
  1057. case 'com.ibm.bi.share.subscribe':
  1058. // hide Subscribe menu item in Edit mode or when prompting
  1059. if (!v_bIsViewer ||
  1060. !rsShareHelper.isShareable(v_oCurrentContentView, false)) {
  1061. return false;
  1062. }
  1063. break;
  1064. case 'com.ibm.bi.glass.common.setHome':
  1065. // hide Set Home menu item in Edit mode or prompting or for active report
  1066. if (!v_bIsViewer ||
  1067. !rsShareHelper.isShareable(v_oCurrentContentView, false) ||
  1068. this.getAuthoringApplication().SharedState.Get('isActiveReport')) {
  1069. return false;
  1070. }
  1071. break;
  1072. }
  1073. }
  1074. return true;
  1075. },
  1076. addPdfCssPositionStyling: function(v_sPositionStyle)
  1077. {
  1078. this.$el[0].style.position = v_sPositionStyle;
  1079. },
  1080. removePdfCssPositionStyling: function()
  1081. {
  1082. this.$el[0].style.position = "";
  1083. },
  1084. _onRSApplicationReady: function(v_oContentViewDeferred, v_idIFrameAuthoring)
  1085. {
  1086. this.m_iframeAuthoring = document.getElementById(v_idIFrameAuthoring);
  1087. console.timeEnd('rsperf: render->OnRSApplicationReadyForObservers');
  1088. rsPerformance.mark('rsContentView._onRSApplicationReady');
  1089. var v_oApplication = this.getAuthoringApplication();
  1090. this.glassContext.getCoreSvc(".UserProfile").getCapabilities().then(function(v_aCapabilities){
  1091. v_oApplication.SetGlassInfo({
  1092. "glassView": this,
  1093. "glassContext": this.glassContext,
  1094. "launchParameters": this.m_oLaunchParameters,
  1095. "capabilities": v_aCapabilities
  1096. });
  1097. handleTruthyValueAlreadySetOrAddObserver(v_oApplication, "isAppLoaded", this.onAppLoaded.bind(this));
  1098. v_oContentViewDeferred.resolve(this);
  1099. }.bind(this));
  1100. },
  1101. _onRsLaunchError: function(v_oDeferred)
  1102. {
  1103. console.log("rsContentView._onRsLaunchError(). ");
  1104. this.hackUnlockGlass();
  1105. v_oDeferred.reject( new Error("rsContentView: error during iframe load") );
  1106. },
  1107. _hackFindPlugin: function(id) {
  1108. return rsCommon._hackFindPlugin(this.m_oAppView, id);
  1109. },
  1110. hackLockGlass: function() {
  1111. if (!this.m_bDisableRsLockUnlock) {
  1112. rsCommon.hackLockGlass(this.m_oAppView);
  1113. }
  1114. },
  1115. hackUnlockGlass: function() {
  1116. if (!this.m_bDisableRsLockUnlock) {
  1117. rsCommon.hackUnlockGlass(this.m_oAppView);
  1118. }
  1119. },
  1120. getReportSpec: function() {
  1121. return this.m_sReportSpecFromOpener;
  1122. },
  1123. launchInExploration: function(v_nReport, v_aSelectionIids, v_sReportSpec, v_sExploreStoreID) {
  1124. return require(["bi/authoring/utils/V5ToDashboard"], function(V5ToDashboard)
  1125. {
  1126. var v_oAuthoringApp = this.getAuthoringApplication();
  1127. return V5ToDashboard.LaunchInExploration(v_nReport, v_oAuthoringApp, v_aSelectionIids, v_sReportSpec, v_sExploreStoreID, this.glassContext)
  1128. .then(function(){});
  1129. }.bind(this));
  1130. },
  1131. syncIFrameSizeToView : function() {
  1132. if (this.m_iframeAuthoring && this.m_iframeAuthoring.style.visibility == "visible")
  1133. {
  1134. rsIFrameManager.F_PositionAndSizeIFrame(this.$el, this.m_iframeAuthoring);
  1135. }
  1136. },
  1137. /**
  1138. * This method gets the parameters from the application
  1139. * and optionally removes credential parameters.
  1140. * This method should be used to get parameters values that will be exposed in URLs
  1141. * because they are large but more importantly they are a security risk since
  1142. * due to another defect, the contain username/passwords in plain text.
  1143. * This is a public method used by other components and as such
  1144. * must be defined in both rs and cv content views.
  1145. */
  1146. getParameterValues : function( bStripCredentials ) {
  1147. var v_oAuthoringApp = this.getAuthoringApplication();
  1148. var v_aParameters = null;
  1149. var v_aAppParameters = v_oAuthoringApp.GetParameterValues();
  1150. if (v_aAppParameters)
  1151. {
  1152. v_aParameters = [];
  1153. if (v_aAppParameters.length > 0) {
  1154. v_aAppParameters.forEach( function(v_oParameter) {
  1155. if (!bStripCredentials || !v_oParameter || !v_oParameter.name || v_oParameter.name.indexOf("credential:") != 0) {
  1156. v_aParameters.push( v_oParameter );
  1157. }
  1158. });
  1159. }
  1160. }
  1161. return v_aParameters;
  1162. },
  1163. /**
  1164. * Called by global parameter flyout to determine what parameters are used by the currently active view.
  1165. * @return Object with parameter names as members that currently in use by the report.
  1166. */
  1167. getParameters: function() {
  1168. var v_oAuthoringApp = this.getAuthoringApplication();
  1169. if (v_oAuthoringApp && v_oAuthoringApp.SharedState.Get("isViewer")) {
  1170. if (v_oAuthoringApp.SharedState.Get("isActiveReport"))
  1171. {
  1172. // When viewing active reports, global parameters can't be modified.
  1173. return {};
  1174. }
  1175. var v_aParameters = this.getParameterValues(true);
  1176. return rsPromptParameters.convertParameterArrayToObject(v_aParameters);
  1177. }
  1178. return null;
  1179. },
  1180. /**
  1181. * Called by global parameter flyout to let content view know what global parameters have changed.
  1182. * The method determines if any of the modified global parameters are used by the report and if so
  1183. * the report is refreshed.
  1184. * @param v_oGlobalParameters The global parameters that have been modified.
  1185. * @param glassContext The glass context used to access complete global parameters.
  1186. */
  1187. updateGlobalParameters: function( v_oNewGlobalParameters, v_oGlassContext ) {
  1188. var v_Application = this.getAuthoringApplication();
  1189. if (v_Application && v_oNewGlobalParameters && !v_Application.SharedState.Get("isActiveReport"))
  1190. {
  1191. // Don't apply global parameter changes to active reports.
  1192. var v_aGlobalParameters = rsCommon.convertToArray( v_oGlassContext ? v_oGlassContext.services.userProfile.userProfileSettings.parameter_values : null );
  1193. var v_sGlobalParameters = v_aGlobalParameters.length ? JSON.stringify( v_aGlobalParameters ) : null;
  1194. var v_aGlobalParametersDelta = rsCommon.convertToArray( v_oNewGlobalParameters );
  1195. var v_sGlobalParametersDelta = v_aGlobalParametersDelta.length ? JSON.stringify( v_aGlobalParametersDelta ) : null;
  1196. var v_oParameters = {
  1197. globalParameters : v_sGlobalParameters,
  1198. globalParametersDelta : v_sGlobalParametersDelta
  1199. };
  1200. v_Application.SharedState.Call(null, "updateGlobalParameters", v_oParameters);
  1201. }
  1202. },
  1203. /**
  1204. * Called by Collaboration to retrieve the DOM node for screen capturing and report's name.
  1205. * @returns {array} Array of objects containing the DOM element and the name.
  1206. */
  1207. getShareableItemsForCollaboration: function() {
  1208. if (this.isApplicationLoaded() && this.m_iframeAuthoring)
  1209. {
  1210. var v_oAuthoringApp = this.getAuthoringApplication();
  1211. if (v_oAuthoringApp)
  1212. {
  1213. var doc = this.m_iframeAuthoring.contentDocument;
  1214. var body = doc.body;
  1215. if (v_oAuthoringApp.SharedState.Get("isActiveReport"))
  1216. {
  1217. // active reports are inside an iframe, grab the body of that iframe instead.
  1218. var iframes = doc.querySelectorAll("iframe");
  1219. if (iframes && iframes.length === 1)
  1220. {
  1221. body = iframes[0].contentDocument.body;
  1222. }
  1223. }
  1224. return [{
  1225. el: body,
  1226. label: v_oAuthoringApp.SharedState.Get("reportName")
  1227. }];
  1228. }
  1229. }
  1230. return [];
  1231. },
  1232. _handleFirstAppViewOnLoaded: function(v_oDeferred, v_oEvent, v_sEventName) {
  1233. if (v_sEventName != 'appView:loaded')
  1234. {
  1235. return;
  1236. }
  1237. if ( !v_oEvent || !v_oEvent.appView || v_oEvent.appView != this.m_oAppView)
  1238. {
  1239. return;
  1240. }
  1241. console.info('rsContentView._handleFirstAppViewOnLoaded');
  1242. v_oDeferred.resolve(true);
  1243. this.m_oRemoveAppViewLoadedHandler.remove();
  1244. this.m_oRemoveAppViewLoadedHandler = undefined;
  1245. },
  1246. /**
  1247. * setFocus will be called whenever glass want to put focus inside contentView.
  1248. * here, the code will check if interactive viewer is loaded then focus inside report viewer
  1249. */
  1250. setFocus: function setFocus()
  1251. {
  1252. if (this.isApplicationLoaded())
  1253. {
  1254. var v_oApplication = this.getAuthoringApplication();
  1255. if (v_oApplication && v_oApplication.SharedState && v_oApplication.SharedState.Get( "isReportLoaded" ))
  1256. {
  1257. v_oApplication.SetFocusToWorkarea();
  1258. }
  1259. }
  1260. else
  1261. {
  1262. rsContentView.inherited('setFocus', this, arguments);
  1263. }
  1264. }
  1265. });
  1266. return rsContentView;
  1267. });