EditNotificationChannelPage.tsx 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. import React, { PureComponent } from 'react';
  2. import { MapDispatchToProps, MapStateToProps } from 'react-redux';
  3. import { NavModel } from '@grafana/data';
  4. import { config } from '@grafana/runtime';
  5. import { Form, Spinner } from '@grafana/ui';
  6. import Page from 'app/core/components/Page/Page';
  7. import { connectWithCleanUp } from 'app/core/components/connectWithCleanUp';
  8. import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
  9. import { getNavModel } from 'app/core/selectors/navModel';
  10. import { NotificationChannelType, NotificationChannelDTO, StoreState } from 'app/types';
  11. import { NotificationChannelForm } from './components/NotificationChannelForm';
  12. import { loadNotificationChannel, testNotificationChannel, updateNotificationChannel } from './state/actions';
  13. import { resetSecureField } from './state/reducers';
  14. import { mapChannelsToSelectableValue, transformSubmitData, transformTestData } from './utils/notificationChannels';
  15. interface OwnProps extends GrafanaRouteComponentProps<{ id: string }> {}
  16. interface ConnectedProps {
  17. navModel: NavModel;
  18. notificationChannel: any;
  19. notificationChannelTypes: NotificationChannelType[];
  20. }
  21. interface DispatchProps {
  22. loadNotificationChannel: typeof loadNotificationChannel;
  23. testNotificationChannel: typeof testNotificationChannel;
  24. updateNotificationChannel: typeof updateNotificationChannel;
  25. resetSecureField: typeof resetSecureField;
  26. }
  27. type Props = OwnProps & ConnectedProps & DispatchProps;
  28. export class EditNotificationChannelPage extends PureComponent<Props> {
  29. componentDidMount() {
  30. this.props.loadNotificationChannel(parseInt(this.props.match.params.id, 10));
  31. }
  32. onSubmit = (formData: NotificationChannelDTO) => {
  33. const { notificationChannel } = this.props;
  34. this.props.updateNotificationChannel({
  35. /*
  36. Some settings which lives in a collapsed section will not be registered since
  37. the section will not be rendered if a user doesn't expand it. Therefore we need to
  38. merge the initialData with any changes from the form.
  39. */
  40. ...transformSubmitData({
  41. ...notificationChannel,
  42. ...formData,
  43. settings: { ...notificationChannel.settings, ...formData.settings },
  44. }),
  45. id: notificationChannel.id,
  46. });
  47. };
  48. onTestChannel = (formData: NotificationChannelDTO) => {
  49. const { notificationChannel } = this.props;
  50. /*
  51. Same as submit
  52. */
  53. this.props.testNotificationChannel(
  54. transformTestData({
  55. ...notificationChannel,
  56. ...formData,
  57. settings: { ...notificationChannel.settings, ...formData.settings },
  58. })
  59. );
  60. };
  61. render() {
  62. const { navModel, notificationChannel, notificationChannelTypes } = this.props;
  63. return (
  64. <Page navModel={navModel}>
  65. <Page.Contents>
  66. <h2 className="page-sub-heading">Edit notification channel</h2>
  67. {notificationChannel && notificationChannel.id > 0 ? (
  68. <Form
  69. maxWidth={600}
  70. onSubmit={this.onSubmit}
  71. defaultValues={{
  72. ...notificationChannel,
  73. type: notificationChannelTypes.find((n) => n.value === notificationChannel.type),
  74. }}
  75. >
  76. {({ control, errors, getValues, register, watch }) => {
  77. const selectedChannel = notificationChannelTypes.find((c) => c.value === getValues().type.value);
  78. return (
  79. <NotificationChannelForm
  80. selectableChannels={mapChannelsToSelectableValue(notificationChannelTypes, true)}
  81. selectedChannel={selectedChannel}
  82. imageRendererAvailable={config.rendererAvailable}
  83. onTestChannel={this.onTestChannel}
  84. register={register}
  85. watch={watch}
  86. errors={errors}
  87. getValues={getValues}
  88. control={control}
  89. resetSecureField={this.props.resetSecureField}
  90. secureFields={notificationChannel.secureFields}
  91. />
  92. );
  93. }}
  94. </Form>
  95. ) : (
  96. <div>
  97. Loading notification channel
  98. <Spinner />
  99. </div>
  100. )}
  101. </Page.Contents>
  102. </Page>
  103. );
  104. }
  105. }
  106. const mapStateToProps: MapStateToProps<ConnectedProps, OwnProps, StoreState> = (state) => {
  107. return {
  108. navModel: getNavModel(state.navIndex, 'channels'),
  109. notificationChannel: state.notificationChannel.notificationChannel,
  110. notificationChannelTypes: state.notificationChannel.notificationChannelTypes,
  111. };
  112. };
  113. const mapDispatchToProps: MapDispatchToProps<DispatchProps, OwnProps> = {
  114. loadNotificationChannel,
  115. testNotificationChannel,
  116. updateNotificationChannel,
  117. resetSecureField,
  118. };
  119. export default connectWithCleanUp(
  120. mapStateToProps,
  121. mapDispatchToProps,
  122. (state) => state.notificationChannel
  123. )(EditNotificationChannelPage);