FolderSettingsPage.tsx 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import React, { PureComponent } from 'react';
  2. import { connect, ConnectedProps } from 'react-redux';
  3. import { Button, LegacyForms } from '@grafana/ui';
  4. const { Input } = LegacyForms;
  5. import appEvents from 'app/core/app_events';
  6. import Page from 'app/core/components/Page/Page';
  7. import { GrafanaRouteComponentProps } from 'app/core/navigation/types';
  8. import { getNavModel } from 'app/core/selectors/navModel';
  9. import { StoreState } from 'app/types';
  10. import { ShowConfirmModalEvent } from '../../types/events';
  11. import { deleteFolder, getFolderByUid, saveFolder } from './state/actions';
  12. import { getLoadingNav } from './state/navModel';
  13. import { setFolderTitle } from './state/reducers';
  14. export interface OwnProps extends GrafanaRouteComponentProps<{ uid: string }> {}
  15. const mapStateToProps = (state: StoreState, props: OwnProps) => {
  16. const uid = props.match.params.uid;
  17. return {
  18. navModel: getNavModel(state.navIndex, `folder-settings-${uid}`, getLoadingNav(2)),
  19. folderUid: uid,
  20. folder: state.folder,
  21. };
  22. };
  23. const mapDispatchToProps = {
  24. getFolderByUid,
  25. saveFolder,
  26. setFolderTitle,
  27. deleteFolder,
  28. };
  29. const connector = connect(mapStateToProps, mapDispatchToProps);
  30. export type Props = OwnProps & ConnectedProps<typeof connector>;
  31. export interface State {
  32. isLoading: boolean;
  33. }
  34. export class FolderSettingsPage extends PureComponent<Props, State> {
  35. constructor(props: Props) {
  36. super(props);
  37. this.state = {
  38. isLoading: false,
  39. };
  40. }
  41. componentDidMount() {
  42. this.props.getFolderByUid(this.props.folderUid);
  43. }
  44. onTitleChange = (evt: React.ChangeEvent<HTMLInputElement>) => {
  45. this.props.setFolderTitle(evt.target.value);
  46. };
  47. onSave = async (evt: React.FormEvent<HTMLFormElement>) => {
  48. evt.preventDefault();
  49. evt.stopPropagation();
  50. this.setState({ isLoading: true });
  51. await this.props.saveFolder(this.props.folder);
  52. this.setState({ isLoading: false });
  53. };
  54. onDelete = (evt: React.MouseEvent<HTMLButtonElement>) => {
  55. evt.stopPropagation();
  56. evt.preventDefault();
  57. const confirmationText = `Do you want to delete this folder and all its dashboards and alerts?`;
  58. appEvents.publish(
  59. new ShowConfirmModalEvent({
  60. title: 'Delete',
  61. text: confirmationText,
  62. icon: 'trash-alt',
  63. yesText: 'Delete',
  64. onConfirm: () => {
  65. this.props.deleteFolder(this.props.folder.uid);
  66. },
  67. })
  68. );
  69. };
  70. render() {
  71. const { navModel, folder } = this.props;
  72. return (
  73. <Page navModel={navModel}>
  74. <Page.Contents isLoading={this.state.isLoading}>
  75. <h3 className="page-sub-heading">Folder settings</h3>
  76. <div className="section gf-form-group">
  77. <form name="folderSettingsForm" onSubmit={this.onSave}>
  78. <div className="gf-form">
  79. <label className="gf-form-label width-7">Name</label>
  80. <Input
  81. type="text"
  82. className="gf-form-input width-30"
  83. value={folder.title}
  84. onChange={this.onTitleChange}
  85. />
  86. </div>
  87. <div className="gf-form-button-row">
  88. <Button type="submit" disabled={!folder.canSave || !folder.hasChanged}>
  89. Save
  90. </Button>
  91. <Button variant="destructive" onClick={this.onDelete} disabled={!folder.canDelete}>
  92. Delete
  93. </Button>
  94. </div>
  95. </form>
  96. </div>
  97. </Page.Contents>
  98. </Page>
  99. );
  100. }
  101. }
  102. export default connector(FolderSettingsPage);