ServicesHelper.js 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. 'use strict';
  2. function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
  3. /**
  4. * Licensed Materials - Property of IBM
  5. * IBM Cognos Products: BI Cloud (C) Copyright IBM Corp. 2018, 2020
  6. * US Government Users Restricted Rights - Use, duplication or disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
  7. */
  8. define(['../../lib/@waca/core-client/js/core-client/utils/ClassFactory', './LifeCycleManager', '../../lib/@waca/dashboard-common/dist/utils/dnd/DnDManager', '../../lib/@waca/baglass/js/baglass/services/ServiceRegistry', './DashboardStringService', '../../features/FeatureLoader', './InlineFeatures', './DeprecatedInlineFeatures'], function (ClassFactory, LifeCycleManager, DnDManager, ServiceRegistry, DashboardStringService, FeatureLoader, inlineFeatures, deprecatedInlineFeatures) {
  9. /**
  10. * Helper class used to create the core dashboard services and services registry
  11. */
  12. var ServicesHelper = function () {
  13. function ServicesHelper(options) {
  14. _classCallCheck(this, ServicesHelper);
  15. this.glassContext = options.glassContext;
  16. this.eventRouter = options.eventRouter;
  17. this.appSettings = options.appSettings;
  18. this.logger = options.logger;
  19. this.dashboardAPI = options.dashboardAPI;
  20. this.inlineFeatures = options.inlineFeatures || inlineFeatures;
  21. this.internalDashboardAPI = options.internalDashboardAPI;
  22. }
  23. ServicesHelper.prototype.createServices = function createServices() {
  24. var _this = this;
  25. var response = {};
  26. response.lifeCycleManager = new LifeCycleManager();
  27. response.dnDManager = new DnDManager();
  28. response.stringService = new DashboardStringService();
  29. var lifeCycleFeature = {
  30. registerHandler: response.lifeCycleManager.registerLifeCycleHandler.bind(response.lifeCycleManager),
  31. invokeHandlers: response.lifeCycleManager.invokeLifeCycleHandlers.bind(response.lifeCycleManager)
  32. };
  33. this.featureLoader = new FeatureLoader({
  34. lifeCycleManager: lifeCycleFeature,
  35. featureNamePrefix: 'Dashboard'
  36. });
  37. // Temporary -- needed by the live widget priview in order to create a content API
  38. // TODO - cleanup the live widget preview to be created without needing this.
  39. this.featureLoader.registerFeature('DashboardFeatureLoader.internal', {
  40. getAPI: function getAPI() {
  41. return _this.featureLoader;
  42. }
  43. }, null, true);
  44. // Some feature require the dashboard api (or the internal API)..
  45. // let us added so it can be requested through dependencies
  46. this.featureLoader.registerFeature('API', {
  47. getAPI: function getAPI() {
  48. return _this.dashboardAPI;
  49. }
  50. }, null, true);
  51. this.featureLoader.registerFeature('internal', {
  52. getAPI: function getAPI() {
  53. return _this.internalDashboardAPI;
  54. }
  55. }, null, true);
  56. // Make the logger availale as a native feature so it could be required as a dependency
  57. this.featureLoader.registerFeature('Logger', {
  58. getAPI: function getAPI() {
  59. return _this.logger;
  60. }
  61. }, null, true);
  62. this.featureLoader.registerFeature('FeatureRegistry.internal', {
  63. getAPI: function getAPI() {
  64. return _this.featureLoader.getAPI();
  65. }
  66. }, null, true);
  67. this.featureLoader.registerFeature('LifeCycle', {
  68. getAPI: function getAPI() {
  69. return lifeCycleFeature;
  70. }
  71. }, null, true);
  72. // Core dashboard services - can be called using getSvcSync
  73. this.services = new ServiceRegistry({
  74. services: {
  75. 'Notification': {
  76. showError: this.glassContext.appController.showErrorMessage.bind(this.glassContext.appController)
  77. },
  78. 'Logger': this.logger,
  79. '.LifeCycleManager': response.lifeCycleManager,
  80. '.DndManager': response.dnDManager,
  81. '.StringResources': response.stringService
  82. }
  83. });
  84. // TODO - remove this services and cleanup the code that calls it
  85. this.services.biGlass = {
  86. glassContext: this.glassContext
  87. };
  88. response.serviceRegistry = this.services;
  89. response.featureLoader = this.featureLoader;
  90. return response;
  91. };
  92. ServicesHelper.prototype._registerServiceCollection = function _registerServiceCollection(dashboardApi, collection, isFeature) {
  93. var promises = [];
  94. if (collection) {
  95. collection.forEach(function (serviceExtension) {
  96. if (!serviceExtension.name || !serviceExtension.class) {
  97. return;
  98. }
  99. promises.push(ClassFactory.loadModule(serviceExtension.class).then(function (ServiceExtension) {
  100. var _this2 = this;
  101. var options = serviceExtension.options || {};
  102. options.services = this.services;
  103. options.eventRouter = this.eventRouter;
  104. options.glassContext = this.glassContext;
  105. options.dashboardApi = dashboardApi;
  106. var extension = new ServiceExtension(options);
  107. var whenInitialized = void 0;
  108. if (isFeature && extension.initialize && typeof extension.initialize === 'function') {
  109. whenInitialized = extension.initialize();
  110. } else {
  111. whenInitialized = Promise.resolve();
  112. }
  113. return whenInitialized.then(function () {
  114. var extensionAPI = null;
  115. if (isFeature && extension.getAPI && typeof extension.getAPI === 'function') {
  116. extensionAPI = extension.getAPI();
  117. }
  118. _this2.services.register(serviceExtension.name, extensionAPI || extension);
  119. _this2._registerServiceHooks(extension);
  120. });
  121. }.bind(this)).catch(function (err) {
  122. //continue working even if an extension failed to load
  123. this.logger.error(err);
  124. // recover
  125. // TODO: maybe we don't need to recover.
  126. // Please check
  127. }.bind(this)));
  128. }.bind(this));
  129. }
  130. return Promise.all(promises);
  131. };
  132. /**
  133. * Create runtime services: Register services/features to be used
  134. * @public
  135. * @param {Object} options Create runtime services options
  136. * @param {Object} options.dashboardApi Dashboard API
  137. * @param {Object} options.collections Collections used to inject features
  138. * @param {Array} options.collections.templates Array of template collection items for injecting template feature
  139. * @function ServicesHelper#createRuntimeServices
  140. */
  141. ServicesHelper.prototype.createRuntimeServices = function createRuntimeServices(options) {
  142. var _this3 = this;
  143. var dashboardApi = options.dashboardApi;
  144. return dashboardApi.findGlassCollection('com.ibm.bi.dashboard.features').then(function (collectionItems) {
  145. var items = collectionItems || [];
  146. items = items.concat(_this3.inlineFeatures);
  147. items.push({
  148. name: 'InternalProperties',
  149. class: 'dashboard-core/js/features/dashboard/dashboardProperties/DashboardInternalProperties',
  150. options: {
  151. templateCollection: options.collections ? options.collections.templates : []
  152. },
  153. dependencies: ['Properties']
  154. });
  155. items.push({
  156. name: 'ContentTypeRegistry',
  157. class: 'dashboard-core/js/features/dashboard/contentTypeRegistry/api/impl/ContentTypeRegistry',
  158. options: options.collections ? options.collections.contentTypes : [],
  159. dependencies: []
  160. });
  161. items.push({
  162. name: 'DashboardContentProvider',
  163. class: 'dashboard-core/js/features/dashboard/contentProvider/api/impl/DashboardContentProvider',
  164. dependencies: ['ContentFactory']
  165. });
  166. return _this3.featureLoader.loadFeaturesFromArray(items, dashboardApi.getFeature('internal').getBoardModel().getContentModel().features);
  167. }).then(function () {
  168. return _this3._getServiceExtensions().then(function (servicesCollection) {
  169. return _this3._getFeatureExtensions().then(function (featuresCollection) {
  170. var promises = [];
  171. promises.push(_this3._registerServiceCollection(dashboardApi, servicesCollection, false));
  172. // TODO - removed once all features under "core-features" are moved to the correct "features" collection
  173. promises.push(_this3._registerServiceCollection(dashboardApi, featuresCollection, true));
  174. return Promise.all(promises);
  175. });
  176. });
  177. });
  178. };
  179. /**
  180. * Deprecated service collection. The new core-features collecion must e userd for new features.
  181. */
  182. ServicesHelper.prototype._getServiceExtensions = function _getServiceExtensions() {
  183. var promise = Promise.resolve();
  184. if (this.appSettings.options && this.appSettings.options.collections.serviceExtension) {
  185. var collectionId = this.appSettings.options.collections.serviceExtension.id;
  186. promise = Promise.all([this.glassContext.appController.findCollection(collectionId)]).then(function (extensions) {
  187. return extensions[0];
  188. });
  189. }
  190. return promise;
  191. };
  192. ServicesHelper.prototype._getFeatureExtensions = function _getFeatureExtensions() {
  193. var promise = Promise.resolve(deprecatedInlineFeatures);
  194. if (this.appSettings.options && this.appSettings.options.collections.featureExtension) {
  195. var collectionId = this.appSettings.options.collections.featureExtension.id;
  196. promise = Promise.all([this.glassContext.appController.findCollection(collectionId)]).then(function (extensions) {
  197. var collection = extensions[0] || [];
  198. return deprecatedInlineFeatures.concat(collection);
  199. });
  200. }
  201. return promise;
  202. };
  203. ServicesHelper.prototype._registerServiceHooks = function _registerServiceHooks(serviceExtension) {
  204. if (typeof serviceExtension.getLifeCycleHandlers === 'function') {
  205. var lifeCycleManager = this.services.getSvcSync('.LifeCycleManager');
  206. var handlers = serviceExtension.getLifeCycleHandlers();
  207. if (!Array.isArray(handlers)) {
  208. throw new Error('serviceExtension getLifeCycleHandlers method is expected to return an array');
  209. }
  210. handlers.forEach(function (handler) {
  211. if (!handler.name || !handler.action) {
  212. throw new Error('serviceExtension handlers are expected to have a name and action property');
  213. }
  214. lifeCycleManager.registerLifeCycleHandler(handler.name, handler.action, handler.priority);
  215. });
  216. }
  217. };
  218. return ServicesHelper;
  219. }();
  220. return ServicesHelper;
  221. });
  222. //# sourceMappingURL=ServicesHelper.js.map