mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
160 lines
3.7 KiB
TypeScript
160 lines
3.7 KiB
TypeScript
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?.();
|
|
}
|
|
);
|
|
}
|
|
|
|
onSaveSuccess(callback, ...args) {
|
|
callback = callbackWithArgs(this, callback, ...args);
|
|
this.setState(
|
|
{
|
|
state: FormState.READY,
|
|
},
|
|
() => 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?.()
|
|
);
|
|
|
|
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?.();
|
|
}
|
|
|
|
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;
|