The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/public/app/features/plugins/wrappers/AppConfigWrapper.tsx

144 lines
3.7 KiB

// Libraries
import React, { PureComponent } from 'react';
import cloneDeep from 'lodash/cloneDeep';
import extend from 'lodash/extend';
import { Button } from '@grafana/ui';
import { PluginMeta, AppPlugin, deprecationWarning } from '@grafana/data';
import { AngularComponent, getAngularLoader, getBackendSrv } from '@grafana/runtime';
import { css } from 'emotion';
interface Props {
app: AppPlugin;
}
interface State {
angularCtrl: AngularComponent;
refresh: number;
}
export class AppConfigCtrlWrapper extends PureComponent<Props, State> {
element: HTMLElement; // for angular ctrl
// Needed for angular scope
preUpdateHook = () => Promise.resolve();
postUpdateHook = () => Promise.resolve();
model: PluginMeta;
constructor(props: Props) {
super(props);
this.state = {
angularCtrl: null,
refresh: 0,
};
}
componentDidMount() {
// Force a reload after the first mount -- is there a better way to do this?
setTimeout(() => {
this.setState({ refresh: this.state.refresh + 1 });
}, 5);
}
componentDidUpdate(prevProps: Props) {
if (!this.element || this.state.angularCtrl) {
return;
}
// Set a copy of the meta
this.model = cloneDeep(this.props.app.meta);
const loader = getAngularLoader();
const template = '<plugin-component type="app-config-ctrl"></plugin-component>';
const scopeProps = { ctrl: this };
const angularCtrl = loader.load(this.element, scopeProps, template);
this.setState({ angularCtrl });
}
render() {
const model = this.model;
const withRightMargin = css({ marginRight: '8px' });
return (
<div>
<div ref={element => (this.element = element)} />
<br />
<br />
{model && (
<div className="gf-form">
{!model.enabled && (
<Button variant="primary" onClick={this.enable} className={withRightMargin}>
Enable
</Button>
)}
{model.enabled && (
<Button variant="primary" onClick={this.update} className={withRightMargin}>
Update
</Button>
)}
{model.enabled && (
<Button variant="danger" onClick={this.disable} className={withRightMargin}>
Disable
</Button>
)}
</div>
)}
</div>
);
}
//-----------------------------------------------------------
// Copied from plugin_edit_ctrl
//-----------------------------------------------------------
update = () => {
const pluginId = this.model.id;
this.preUpdateHook()
.then(() => {
const updateCmd = extend(
{
enabled: this.model.enabled,
pinned: this.model.pinned,
jsonData: this.model.jsonData,
secureJsonData: this.model.secureJsonData,
},
{}
);
return getBackendSrv().post(`/api/plugins/${pluginId}/settings`, updateCmd);
})
.then(this.postUpdateHook)
.then(res => {
window.location.href = window.location.href;
});
};
setPreUpdateHook = (callback: () => any) => {
this.preUpdateHook = callback;
};
setPostUpdateHook = (callback: () => any) => {
this.postUpdateHook = callback;
};
// Stub to avoid unknown function in legacy code
importDashboards = (): Promise<void> => {
deprecationWarning('AppConfig', 'importDashboards()');
return Promise.resolve();
};
enable = () => {
this.model.enabled = true;
this.model.pinned = true;
this.update();
};
disable = () => {
this.model.enabled = false;
this.model.pinned = false;
this.update();
};
}