You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DownloadButton.tsx 3.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101
  1. /*
  2. * SonarQube
  3. * Copyright (C) 2009-2022 SonarSource SA
  4. * mailto:info AT sonarsource DOT com
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 3 of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public License
  17. * along with this program; if not, write to the Free Software Foundation,
  18. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. import classNames from 'classnames';
  21. import { endOfDay, startOfDay, subDays } from 'date-fns';
  22. import * as React from 'react';
  23. import { now } from '../../../helpers/dates';
  24. import { translate } from '../../../helpers/l10n';
  25. import { getBaseUrl } from '../../../helpers/system';
  26. import '../style.css';
  27. import { RangeOption } from '../utils';
  28. export interface DownloadButtonProps {
  29. dateRange?: { from?: Date; to?: Date };
  30. downloadStarted: boolean;
  31. onStartDownload: () => void;
  32. selection: RangeOption;
  33. }
  34. const RANGE_OPTION_START = {
  35. [RangeOption.Today]: () => now(),
  36. [RangeOption.Week]: () => subDays(now(), 7),
  37. [RangeOption.Month]: () => subDays(now(), 30),
  38. [RangeOption.Trimester]: () => subDays(now(), 90)
  39. };
  40. const toISODateString = (date: Date) => date.toISOString();
  41. function getRangeParams(selection: RangeOption, dateRange?: { from?: Date; to?: Date }) {
  42. if (selection === RangeOption.Custom) {
  43. // dateRange should be complete if 'custom' is selected
  44. // This is not strickly necessary since submit is disable
  45. // when the if condition is true.
  46. if (!(dateRange?.to && dateRange?.from)) {
  47. return '';
  48. }
  49. return new URLSearchParams({
  50. from: toISODateString(startOfDay(dateRange.from)),
  51. to: toISODateString(endOfDay(dateRange.to))
  52. }).toString();
  53. }
  54. return new URLSearchParams({
  55. from: toISODateString(startOfDay(RANGE_OPTION_START[selection]())),
  56. to: toISODateString(now())
  57. }).toString();
  58. }
  59. export default function DownloadButton(props: DownloadButtonProps) {
  60. const { dateRange, downloadStarted, selection } = props;
  61. const downloadDisabled =
  62. downloadStarted ||
  63. (selection === RangeOption.Custom &&
  64. (dateRange?.from === undefined || dateRange?.to === undefined));
  65. const downloadUrl = downloadDisabled
  66. ? '#'
  67. : `${getBaseUrl()}/api/audit_logs/download?${getRangeParams(selection, dateRange)}`;
  68. return (
  69. <>
  70. <a
  71. className={classNames('button button-primary', { disabled: downloadDisabled })}
  72. download="audit_logs.json"
  73. aria-disabled={downloadDisabled}
  74. onClick={downloadDisabled ? undefined : props.onStartDownload}
  75. href={downloadUrl}
  76. rel="noopener noreferrer"
  77. target="_blank">
  78. {translate('download_verb')}
  79. </a>
  80. {downloadStarted && (
  81. <div className="spacer-top">
  82. <p>{translate('audit_logs.download_start.sentence.1')}</p>
  83. <p>{translate('audit_logs.download_start.sentence.2')}</p>
  84. <br />
  85. <p>{translate('audit_logs.download_start.sentence.3')}</p>
  86. </div>
  87. )}
  88. </>
  89. );
  90. }