PluginSettings.tsx 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. import React, { PureComponent } from 'react';
  2. import _ from 'lodash';
  3. import { Plugin } from 'app/types';
  4. import { DataSourceSettings, DataSourcePlugin } from '@grafana/ui/src/types';
  5. import { getAngularLoader, AngularComponent } from 'app/core/services/AngularLoader';
  6. export interface Props {
  7. plugin: DataSourcePlugin;
  8. dataSource: DataSourceSettings;
  9. dataSourceMeta: Plugin;
  10. onModelChange: (dataSource: DataSourceSettings) => void;
  11. }
  12. export class PluginSettings extends PureComponent<Props> {
  13. element: any;
  14. component: AngularComponent;
  15. scopeProps: {
  16. ctrl: { datasourceMeta: Plugin; current: DataSourceSettings };
  17. onModelChanged: (dataSource: DataSourceSettings) => void;
  18. };
  19. constructor(props) {
  20. super(props);
  21. this.scopeProps = {
  22. ctrl: { datasourceMeta: props.dataSourceMeta, current: _.cloneDeep(props.dataSource) },
  23. onModelChanged: this.onModelChanged,
  24. };
  25. this.onModelChanged = this.onModelChanged.bind(this);
  26. }
  27. componentDidMount() {
  28. const { plugin } = this.props;
  29. if (!this.element) {
  30. return;
  31. }
  32. if (!plugin.components.ConfigEditor) {
  33. // React editor is not specified, let's render angular editor
  34. // How to apprach this better? Introduce ReactDataSourcePlugin interface and typeguard it here?
  35. const loader = getAngularLoader();
  36. const template = '<plugin-component type="datasource-config-ctrl" />';
  37. this.component = loader.load(this.element, this.scopeProps, template);
  38. }
  39. }
  40. componentDidUpdate(prevProps) {
  41. const { plugin } = this.props;
  42. if (!plugin.components.ConfigEditor && this.props.dataSource !== prevProps.dataSource) {
  43. this.scopeProps.ctrl.current = _.cloneDeep(this.props.dataSource);
  44. this.component.digest();
  45. }
  46. }
  47. componentWillUnmount() {
  48. if (this.component) {
  49. this.component.destroy();
  50. }
  51. }
  52. onModelChanged = (dataSource: DataSourceSettings) => {
  53. this.props.onModelChange(dataSource);
  54. };
  55. render() {
  56. const { plugin, dataSource } = this.props;
  57. if (!plugin) {
  58. return null;
  59. }
  60. return (
  61. <div ref={element => (this.element = element)}>
  62. {plugin.components.ConfigEditor &&
  63. React.createElement(plugin.components.ConfigEditor, {
  64. options: dataSource,
  65. onOptionsChange: this.onModelChanged,
  66. })}
  67. </div>
  68. );
  69. }
  70. }
  71. export default PluginSettings;