AppConfigWrapper.tsx 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // Libraries
  2. import { css } from '@emotion/css';
  3. import { cloneDeep, extend } from 'lodash';
  4. import React, { PureComponent } from 'react';
  5. import { PluginMeta, AppPlugin, deprecationWarning } from '@grafana/data';
  6. import { AngularComponent, getAngularLoader, getBackendSrv } from '@grafana/runtime';
  7. import { Button } from '@grafana/ui';
  8. interface Props {
  9. app: AppPlugin;
  10. }
  11. interface State {
  12. angularCtrl: AngularComponent | null;
  13. refresh: number;
  14. }
  15. export class AppConfigCtrlWrapper extends PureComponent<Props, State> {
  16. element: HTMLElement | null = null;
  17. //@ts-ignore
  18. model: PluginMeta;
  19. // Needed for angular scope
  20. preUpdateHook = () => Promise.resolve();
  21. postUpdateHook = () => Promise.resolve();
  22. constructor(props: Props) {
  23. super(props);
  24. this.state = {
  25. angularCtrl: null,
  26. refresh: 0,
  27. };
  28. }
  29. componentDidMount() {
  30. // Force a reload after the first mount -- is there a better way to do this?
  31. setTimeout(() => {
  32. this.setState({ refresh: this.state.refresh + 1 });
  33. }, 5);
  34. }
  35. componentDidUpdate(prevProps: Props) {
  36. if (!this.element || this.state.angularCtrl) {
  37. return;
  38. }
  39. // Set a copy of the meta
  40. this.model = cloneDeep(this.props.app.meta);
  41. const loader = getAngularLoader();
  42. const template = '<plugin-component type="app-config-ctrl"></plugin-component>';
  43. const scopeProps = {
  44. ctrl: this,
  45. // used by angular injectorMonkeyPatch to detect this scenario
  46. isAppConfigCtrl: true,
  47. };
  48. const angularCtrl = loader.load(this.element, scopeProps, template);
  49. this.setState({ angularCtrl });
  50. }
  51. render() {
  52. const model = this.model;
  53. const withRightMargin = css({ marginRight: '8px' });
  54. return (
  55. <div>
  56. <div ref={(element) => (this.element = element)} />
  57. <br />
  58. <br />
  59. {model && (
  60. <div className="gf-form">
  61. {!model.enabled && (
  62. <Button variant="primary" onClick={this.enable} className={withRightMargin}>
  63. Enable
  64. </Button>
  65. )}
  66. {model.enabled && (
  67. <Button variant="primary" onClick={this.update} className={withRightMargin}>
  68. Update
  69. </Button>
  70. )}
  71. {model.enabled && (
  72. <Button variant="destructive" onClick={this.disable} className={withRightMargin}>
  73. Disable
  74. </Button>
  75. )}
  76. </div>
  77. )}
  78. </div>
  79. );
  80. }
  81. //-----------------------------------------------------------
  82. // Copied from plugin_edit_ctrl
  83. //-----------------------------------------------------------
  84. update = () => {
  85. const pluginId = this.model.id;
  86. this.preUpdateHook()
  87. .then(() => {
  88. const updateCmd = extend(
  89. {
  90. enabled: this.model.enabled,
  91. pinned: this.model.pinned,
  92. jsonData: this.model.jsonData,
  93. secureJsonData: this.model.secureJsonData,
  94. },
  95. {}
  96. );
  97. return getBackendSrv().post(`/api/plugins/${pluginId}/settings`, updateCmd);
  98. })
  99. .then(this.postUpdateHook)
  100. .then((res) => {
  101. window.location.href = window.location.href;
  102. });
  103. };
  104. setPreUpdateHook = (callback: () => any) => {
  105. this.preUpdateHook = callback;
  106. };
  107. setPostUpdateHook = (callback: () => any) => {
  108. this.postUpdateHook = callback;
  109. };
  110. // Stub to avoid unknown function in legacy code
  111. importDashboards = (): Promise<void> => {
  112. deprecationWarning('AppConfig', 'importDashboards()');
  113. return Promise.resolve();
  114. };
  115. enable = () => {
  116. this.model.enabled = true;
  117. this.model.pinned = true;
  118. this.update();
  119. };
  120. disable = () => {
  121. this.model.enabled = false;
  122. this.model.pinned = false;
  123. this.update();
  124. };
  125. }