DeleteLibraryPanelModal.tsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. import React, { FC, useEffect, useMemo, useReducer } from 'react';
  2. import { LoadingState } from '@grafana/data';
  3. import { Button, Modal, useStyles } from '@grafana/ui';
  4. import { getModalStyles } from '../../styles';
  5. import { LibraryElementDTO } from '../../types';
  6. import { asyncDispatcher } from '../LibraryPanelsView/actions';
  7. import { getConnectedDashboards } from './actions';
  8. import { deleteLibraryPanelModalReducer, initialDeleteLibraryPanelModalState } from './reducer';
  9. interface Props {
  10. libraryPanel: LibraryElementDTO;
  11. onConfirm: () => void;
  12. onDismiss: () => void;
  13. }
  14. export const DeleteLibraryPanelModal: FC<Props> = ({ libraryPanel, onDismiss, onConfirm }) => {
  15. const styles = useStyles(getModalStyles);
  16. const [{ dashboardTitles, loadingState }, dispatch] = useReducer(
  17. deleteLibraryPanelModalReducer,
  18. initialDeleteLibraryPanelModalState
  19. );
  20. const asyncDispatch = useMemo(() => asyncDispatcher(dispatch), [dispatch]);
  21. useEffect(() => {
  22. asyncDispatch(getConnectedDashboards(libraryPanel));
  23. }, [asyncDispatch, libraryPanel]);
  24. const connected = Boolean(dashboardTitles.length);
  25. const done = loadingState === LoadingState.Done;
  26. return (
  27. <Modal className={styles.modal} title="Delete library panel" icon="trash-alt" onDismiss={onDismiss} isOpen={true}>
  28. {!done ? <LoadingIndicator /> : null}
  29. {done ? (
  30. <div>
  31. {connected ? <HasConnectedDashboards dashboardTitles={dashboardTitles} /> : null}
  32. {!connected ? <Confirm /> : null}
  33. <Modal.ButtonRow>
  34. <Button variant="secondary" onClick={onDismiss} fill="outline">
  35. Cancel
  36. </Button>
  37. <Button variant="destructive" onClick={onConfirm} disabled={connected}>
  38. Delete
  39. </Button>
  40. </Modal.ButtonRow>
  41. </div>
  42. ) : null}
  43. </Modal>
  44. );
  45. };
  46. const LoadingIndicator: FC = () => <span>Loading library panel...</span>;
  47. const Confirm: FC = () => {
  48. const styles = useStyles(getModalStyles);
  49. return <div className={styles.modalText}>Do you want to delete this panel?</div>;
  50. };
  51. const HasConnectedDashboards: FC<{ dashboardTitles: string[] }> = ({ dashboardTitles }) => {
  52. const styles = useStyles(getModalStyles);
  53. const suffix = dashboardTitles.length === 1 ? 'dashboard.' : 'dashboards.';
  54. const message = `${dashboardTitles.length} ${suffix}`;
  55. if (dashboardTitles.length === 0) {
  56. return null;
  57. }
  58. return (
  59. <div>
  60. <p className={styles.textInfo}>
  61. {'This library panel can not be deleted because it is connected to '}
  62. <strong>{message}</strong>
  63. {' Remove the library panel from the dashboards listed below and retry.'}
  64. </p>
  65. <table className={styles.myTable}>
  66. <thead>
  67. <tr>
  68. <th>Dashboard name</th>
  69. </tr>
  70. </thead>
  71. <tbody>
  72. {dashboardTitles.map((title, i) => (
  73. <tr key={`dash-title-${i}`}>
  74. <td>{title}</td>
  75. </tr>
  76. ))}
  77. </tbody>
  78. </table>
  79. </div>
  80. );
  81. };