123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159 |
- import {Component} from 'react';
- import isFunction from 'lodash/isFunction';
- import {
- addErrorMessage,
- addLoadingMessage,
- addSuccessMessage,
- clearIndicators,
- } from 'sentry/actionCreators/indicator';
- import {Client} from 'sentry/api';
- import GenericField from 'sentry/components/deprecatedforms/genericField';
- import FormState from 'sentry/components/forms/state';
- import {t} from 'sentry/locale';
- const callbackWithArgs = function (context: any, callback: any, ...args: any) {
- return isFunction(callback) ? callback.bind(context, ...args) : undefined;
- };
- type GenericFieldProps = Parameters<typeof GenericField>[0];
- type Props = {};
- type State = {state: FormState};
- class PluginComponentBase<
- P extends Props = Props,
- S extends State = State
- > extends Component<P, S> {
- constructor(props: P, context: any) {
- super(props, context);
- [
- 'onLoadSuccess',
- 'onLoadError',
- 'onSave',
- 'onSaveSuccess',
- 'onSaveError',
- 'onSaveComplete',
- 'renderField',
- ].map(method => (this[method] = this[method].bind(this)));
- if (this.fetchData) {
- this.fetchData = this.onLoad.bind(this, this.fetchData.bind(this));
- }
- if (this.onSubmit) {
- this.onSubmit = this.onSave.bind(this, this.onSubmit.bind(this));
- }
- this.state = {
- state: FormState.READY,
- } as Readonly<S>;
- }
- componentWillUnmount() {
- this.api.clear();
- window.clearTimeout(this.successMessageTimeout);
- window.clearTimeout(this.errorMessageTimeout);
- }
- successMessageTimeout: number | undefined = undefined;
- errorMessageTimeout: number | undefined = undefined;
- api = new Client();
- fetchData() {
- // Allow children to implement this
- }
- onSubmit() {
- // Allow children to implement this
- }
- onLoad(callback, ...args) {
- this.setState(
- {
- state: FormState.LOADING,
- },
- callbackWithArgs(this, callback, ...args)
- );
- }
- onLoadSuccess() {
- this.setState({
- state: FormState.READY,
- });
- }
- onLoadError(callback, ...args) {
- this.setState(
- {
- state: FormState.ERROR,
- },
- callbackWithArgs(this, callback, ...args)
- );
- addErrorMessage(t('An error occurred.'));
- }
- onSave(callback, ...args) {
- if (this.state.state === FormState.SAVING) {
- return;
- }
- callback = callbackWithArgs(this, callback, ...args);
- this.setState(
- {
- state: FormState.SAVING,
- },
- () => {
- addLoadingMessage(t('Saving changes\u2026'));
- callback && callback();
- }
- );
- }
- onSaveSuccess(callback, ...args) {
- callback = callbackWithArgs(this, callback, ...args);
- this.setState(
- {
- state: FormState.READY,
- },
- () => callback && callback()
- );
- window.clearTimeout(this.successMessageTimeout);
- this.successMessageTimeout = window.setTimeout(() => {
- addSuccessMessage(t('Success!'));
- }, 0);
- }
- onSaveError(callback, ...args) {
- callback = callbackWithArgs(this, callback, ...args);
- this.setState(
- {
- state: FormState.ERROR,
- },
- () => callback && callback()
- );
- window.clearTimeout(this.errorMessageTimeout);
- this.errorMessageTimeout = window.setTimeout(() => {
- addErrorMessage(t('Unable to save changes. Please try again.'));
- }, 0);
- }
- onSaveComplete(callback, ...args) {
- clearIndicators();
- callback = callbackWithArgs(this, callback, ...args);
- callback && callback();
- }
- renderField(props: Omit<GenericFieldProps, 'formState'>): React.ReactNode {
- props = {...props};
- const newProps = {
- ...props,
- formState: this.state.state,
- };
- return <GenericField key={newProps.config?.name} {...newProps} />;
- }
- }
- export default PluginComponentBase;
|