PluginSettings.tsx 2.4 KB

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