plugin_component.ts 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  1. ///<reference path="../../headers/common.d.ts" />
  2. import angular from 'angular';
  3. import _ from 'lodash';
  4. import coreModule from '../core_module';
  5. function pluginDirectiveLoader($compile, datasourceSrv, $rootScope, $q) {
  6. function getPluginComponentDirective(options) {
  7. return function() {
  8. return {
  9. templateUrl: options.Component.templateUrl,
  10. restrict: 'E',
  11. controller: options.Component,
  12. controllerAs: 'ctrl',
  13. bindToController: true,
  14. scope: options.bindings,
  15. link: (scope, elem, attrs, ctrl) => {
  16. if (ctrl.link) {
  17. ctrl.link(scope, elem, attrs, ctrl);
  18. }
  19. }
  20. };
  21. };
  22. }
  23. function getModule(scope, attrs) {
  24. switch (attrs.type) {
  25. // QueryCtrl
  26. case "query-ctrl": {
  27. let datasource = scope.target.datasource || scope.ctrl.panel.datasource;
  28. return datasourceSrv.get(datasource).then(ds => {
  29. scope.datasource = ds;
  30. return System.import(ds.meta.module).then(dsModule => {
  31. return {
  32. name: 'query-ctrl-' + ds.meta.id,
  33. bindings: {target: "=", panelCtrl: "=", datasource: "="},
  34. attrs: {"target": "target", "panel-ctrl": "ctrl", datasource: "datasource"},
  35. Component: dsModule.QueryCtrl
  36. };
  37. });
  38. });
  39. }
  40. // QueryOptionsCtrl
  41. case "query-options-ctrl": {
  42. return datasourceSrv.get(scope.ctrl.panel.datasource).then(ds => {
  43. return System.import(ds.meta.module).then((dsModule): any => {
  44. if (!dsModule.QueryOptionsCtrl) {
  45. return {notFound: true};
  46. }
  47. return {
  48. name: 'query-options-ctrl-' + ds.meta.id,
  49. bindings: {panelCtrl: "="},
  50. attrs: {"panel-ctrl": "ctrl"},
  51. Component: dsModule.QueryOptionsCtrl
  52. };
  53. });
  54. });
  55. }
  56. // Annotations
  57. case "annotations-query-ctrl": {
  58. return System.import(scope.currentDatasource.meta.module).then(function(dsModule) {
  59. return {
  60. name: 'annotations-query-ctrl-' + scope.currentDatasource.meta.id,
  61. bindings: {annotation: "=", datasource: "="},
  62. attrs: {"annotation": "currentAnnotation", datasource: "currentDatasource"},
  63. Component: dsModule.AnnotationsQueryCtrl,
  64. };
  65. });
  66. }
  67. // ConfigCtrl
  68. case 'datasource-config-ctrl': {
  69. return System.import(scope.datasourceMeta.module).then(function(dsModule) {
  70. return {
  71. name: 'ds-config-' + scope.datasourceMeta.id,
  72. bindings: {meta: "=", current: "="},
  73. attrs: {meta: "datasourceMeta", current: "current"},
  74. Component: dsModule.ConfigCtrl,
  75. };
  76. });
  77. }
  78. default: {
  79. return $q.reject({message: "Could not find component type: " + attrs.type });
  80. }
  81. }
  82. }
  83. function appendAndCompile(scope, elem, componentInfo) {
  84. var child = angular.element(document.createElement(componentInfo.name));
  85. _.each(componentInfo.attrs, (value, key) => {
  86. child.attr(key, value);
  87. });
  88. $compile(child)(scope);
  89. elem.empty();
  90. elem.append(child);
  91. }
  92. function registerPluginComponent(scope, elem, attrs, componentInfo) {
  93. if (componentInfo.notFound) {
  94. elem.empty();
  95. return;
  96. }
  97. if (!componentInfo.Component) {
  98. throw {message: 'Failed to find exported plugin component for ' + componentInfo.name};
  99. }
  100. if (!componentInfo.Component.registered) {
  101. var directiveName = attrs.$normalize(componentInfo.name);
  102. var directiveFn = getPluginComponentDirective(componentInfo);
  103. coreModule.directive(directiveName, directiveFn);
  104. componentInfo.Component.registered = true;
  105. }
  106. appendAndCompile(scope, elem, componentInfo);
  107. }
  108. return {
  109. restrict: 'E',
  110. link: function(scope, elem, attrs) {
  111. getModule(scope, attrs).then(function (componentInfo) {
  112. registerPluginComponent(scope, elem, attrs, componentInfo);
  113. }).catch(err => {
  114. $rootScope.appEvent('alert-error', ['Plugin Error', err.message || err]);
  115. });
  116. }
  117. };
  118. }
  119. coreModule.directive('pluginComponent', pluginDirectiveLoader);