settings.tsx 2.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. import isEqual from 'lodash/isEqual';
  2. import {Form, FormState} from 'sentry/components/deprecatedforms';
  3. import LoadingIndicator from 'sentry/components/loadingIndicator';
  4. import DefaultSettings from 'sentry/plugins/components/settings';
  5. type Props = DefaultSettings['props'];
  6. type State = DefaultSettings['state'] & {
  7. // NB: "On-premises" here refers to on-premises SessionStack, not Sentry.
  8. // That said, we only support connecting to an on-premises SessionStack from
  9. // a self-hosted Sentry: https://docs.sessionstack.com/docs/sentry.
  10. showOnPremisesConfiguration?: boolean;
  11. };
  12. class Settings extends DefaultSettings<Props, State> {
  13. REQUIRED_FIELDS = ['account_email', 'api_token', 'website_id'];
  14. ON_PREMISES_FIELDS = ['api_url', 'player_url'];
  15. renderFields(fields: State['fieldList']) {
  16. return fields?.map(f =>
  17. this.renderField({
  18. config: f,
  19. formData: this.state.formData,
  20. formErrors: this.state.errors,
  21. onChange: this.changeField.bind(this, f.name),
  22. })
  23. );
  24. }
  25. filterFields(fields: State['fieldList'], fieldNames: string[]) {
  26. return fields?.filter(field => fieldNames.includes(field.name)) ?? [];
  27. }
  28. toggleOnPremisesConfiguration = () => {
  29. this.setState({
  30. showOnPremisesConfiguration: !this.state.showOnPremisesConfiguration,
  31. });
  32. };
  33. render() {
  34. if (this.state.state === FormState.LOADING) {
  35. return <LoadingIndicator />;
  36. }
  37. if (this.state.state === FormState.ERROR && !this.state.fieldList) {
  38. return (
  39. <div className="alert alert-error m-b-1">
  40. An unknown error occurred. Need help with this?{' '}
  41. <a href="https://sentry.io/support/">Contact support</a>
  42. </div>
  43. );
  44. }
  45. const isSaving = this.state.state === FormState.SAVING;
  46. const hasChanges = !isEqual(this.state.initialData, this.state.formData);
  47. const requiredFields = this.filterFields(this.state.fieldList, this.REQUIRED_FIELDS);
  48. const onPremisesFields = this.filterFields(
  49. this.state.fieldList,
  50. this.ON_PREMISES_FIELDS
  51. );
  52. return (
  53. <Form onSubmit={this.onSubmit} submitDisabled={isSaving || !hasChanges}>
  54. {this.state.errors.__all__ && (
  55. <div className="alert alert-block alert-error">
  56. <ul>
  57. <li>{this.state.errors.__all__}</li>
  58. </ul>
  59. </div>
  60. )}
  61. {this.renderFields(requiredFields)}
  62. {onPremisesFields.length > 0 ? (
  63. <div className="control-group">
  64. <button
  65. className="btn btn-default"
  66. type="button"
  67. onClick={this.toggleOnPremisesConfiguration}
  68. >
  69. Configure on-premises
  70. </button>
  71. </div>
  72. ) : null}
  73. {this.state.showOnPremisesConfiguration
  74. ? this.renderFields(onPremisesFields)
  75. : null}
  76. </Form>
  77. );
  78. }
  79. }
  80. export default Settings;