SnapshotListTable.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. import React, { FC, useState, useCallback } from 'react';
  2. import useAsync from 'react-use/lib/useAsync';
  3. import { getBackendSrv, locationService } from '@grafana/runtime';
  4. import { ConfirmModal, Button, LinkButton } from '@grafana/ui';
  5. import { Snapshot } from '../types';
  6. export function getSnapshots() {
  7. return getBackendSrv()
  8. .get('/api/dashboard/snapshots')
  9. .then((result: Snapshot[]) => {
  10. return result.map((snapshot) => ({
  11. ...snapshot,
  12. url: `/dashboard/snapshot/${snapshot.key}`,
  13. }));
  14. });
  15. }
  16. export const SnapshotListTable: FC = () => {
  17. const [snapshots, setSnapshots] = useState<Snapshot[]>([]);
  18. const [removeSnapshot, setRemoveSnapshot] = useState<Snapshot | undefined>();
  19. const currentPath = locationService.getLocation().pathname;
  20. const fullUrl = window.location.href;
  21. const baseUrl = fullUrl.substring(0, fullUrl.indexOf(currentPath));
  22. useAsync(async () => {
  23. const response = await getSnapshots();
  24. setSnapshots(response);
  25. }, [setSnapshots]);
  26. const doRemoveSnapshot = useCallback(
  27. async (snapshot: Snapshot) => {
  28. const filteredSnapshots = snapshots.filter((ss) => ss.key !== snapshot.key);
  29. setSnapshots(filteredSnapshots);
  30. await getBackendSrv()
  31. .delete(`/api/snapshots/${snapshot.key}`)
  32. .catch(() => {
  33. setSnapshots(snapshots);
  34. });
  35. },
  36. [snapshots]
  37. );
  38. return (
  39. <div>
  40. <table className="filter-table">
  41. <thead>
  42. <tr>
  43. <th>
  44. <strong>Name</strong>
  45. </th>
  46. <th>
  47. <strong>Snapshot url</strong>
  48. </th>
  49. <th style={{ width: '70px' }}></th>
  50. <th style={{ width: '30px' }}></th>
  51. <th style={{ width: '25px' }}></th>
  52. </tr>
  53. </thead>
  54. <tbody>
  55. {snapshots.map((snapshot) => {
  56. const url = snapshot.externalUrl || snapshot.url;
  57. const fullUrl = snapshot.externalUrl || `${baseUrl}${snapshot.url}`;
  58. return (
  59. <tr key={snapshot.key}>
  60. <td>
  61. <a href={url}>{snapshot.name}</a>
  62. </td>
  63. <td>
  64. <a href={url}>{fullUrl}</a>
  65. </td>
  66. <td>{snapshot.external && <span className="query-keyword">External</span>}</td>
  67. <td className="text-center">
  68. <LinkButton href={url} variant="secondary" size="sm" icon="eye">
  69. View
  70. </LinkButton>
  71. </td>
  72. <td className="text-right">
  73. <Button variant="destructive" size="sm" icon="times" onClick={() => setRemoveSnapshot(snapshot)} />
  74. </td>
  75. </tr>
  76. );
  77. })}
  78. </tbody>
  79. </table>
  80. <ConfirmModal
  81. isOpen={!!removeSnapshot}
  82. icon="trash-alt"
  83. title="Delete"
  84. body={`Are you sure you want to delete '${removeSnapshot?.name}'?`}
  85. confirmText="Delete"
  86. onDismiss={() => setRemoveSnapshot(undefined)}
  87. onConfirm={() => {
  88. doRemoveSnapshot(removeSnapshot!);
  89. setRemoveSnapshot(undefined);
  90. }}
  91. />
  92. </div>
  93. );
  94. };