]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16316 Page and link to download regulatory report
authorRevanshu Paliwal <revanshu.paliwal@sonarsource.com>
Tue, 3 May 2022 13:23:53 +0000 (15:23 +0200)
committersonartech <sonartech@sonarsource.com>
Wed, 25 May 2022 20:03:15 +0000 (20:03 +0000)
server/sonar-web/src/main/js/api/regulatory-report.ts [new file with mode: 0644]
server/sonar-web/src/main/js/app/components/nav/component/Menu.tsx
server/sonar-web/src/main/js/app/utils/startReactApp.tsx
server/sonar-web/src/main/js/apps/projectRegulatoryReport/RegulatoryReport.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/apps/projectRegulatoryReport/__tests__/RegulatoryReport-it.tsx [new file with mode: 0644]
server/sonar-web/src/main/js/components/controls/buttons.css
server/sonar-web/src/main/js/types/appstate.ts
sonar-core/src/main/resources/org/sonar/l10n/core.properties

diff --git a/server/sonar-web/src/main/js/api/regulatory-report.ts b/server/sonar-web/src/main/js/api/regulatory-report.ts
new file mode 100644 (file)
index 0000000..0f5e004
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import { getBaseUrl } from '../helpers/system';
+
+export function getRegulatoryReportUrl(project: string, branch?: string): string {
+  const params = new URLSearchParams({ project });
+  if (branch) {
+    params.append('branch', branch);
+  }
+  return `${getBaseUrl()}/api/regulatory_reports/download?${params.toString()}`;
+}
index 7b33626b62a962e8ef4d9c9706e5a49b1c93efd0..a3e13786bfdf18b0c280fcdc55b38e80362fddbe 100644 (file)
@@ -329,7 +329,8 @@ export class Menu extends React.PureComponent<Props> {
       this.renderBackgroundTasksLink(query),
       this.renderUpdateKeyLink(query),
       this.renderWebhooksLink(query, isProject),
-      this.renderDeletionLink(query)
+      this.renderDeletionLink(query),
+      this.renderRegulatoryReport(query)
     ];
   };
 
@@ -541,6 +542,19 @@ export class Menu extends React.PureComponent<Props> {
     );
   };
 
+  renderRegulatoryReport = (query: Query) => {
+    if (!this.props.appState.regulatoryReportFeatureEnabled) {
+      return null;
+    }
+    return (
+      <li key="project_regulatory_report">
+        <Link activeClassName="active" to={{ pathname: '/project/regulatory-report', query }}>
+          {translate('regulatory_report.page')}
+        </Link>
+      </li>
+    );
+  };
+
   renderExtension = ({ key, name }: Extension, isAdmin: boolean, baseQuery: Query) => {
     const pathname = isAdmin ? `/project/admin/extension/${key}` : `/project/extension/${key}`;
     const query = { ...baseQuery, qualifier: this.props.component.qualifier };
index 622c56db5853d6fee78bfc0f24faa88e6b9e639b..5ad4881c39624ed2a7411cbdb30364edd7e49a6d 100644 (file)
@@ -239,6 +239,12 @@ function renderComponentRoutes() {
           path="project/deletion"
           component={lazyLoadComponent(() => import('../../apps/projectDeletion/App'))}
         />
+        <Route
+          path="project/regulatory-report"
+          component={lazyLoadComponent(() =>
+            import('../../apps/projectRegulatoryReport/RegulatoryReport')
+          )}
+        />
         <Route
           path="project/links"
           component={lazyLoadComponent(() => import('../../apps/projectLinks/App'))}
diff --git a/server/sonar-web/src/main/js/apps/projectRegulatoryReport/RegulatoryReport.tsx b/server/sonar-web/src/main/js/apps/projectRegulatoryReport/RegulatoryReport.tsx
new file mode 100644 (file)
index 0000000..f8cda88
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import classNames from 'classnames';
+import * as React from 'react';
+import { getRegulatoryReportUrl } from '../../api/regulatory-report';
+import { isBranch } from '../../helpers/branch-like';
+import { translate } from '../../helpers/l10n';
+import { BranchLike } from '../../types/branch-like';
+import { Component } from '../../types/types';
+
+interface Props {
+  component: Pick<Component, 'key' | 'name'>;
+  branchLike?: BranchLike;
+}
+
+function RegulatoryReport(props: Props) {
+  const { component, branchLike } = props;
+  const branchName = branchLike && isBranch(branchLike) ? branchLike.name : undefined;
+  const [downloadStarted, setDownloadStarted] = React.useState(false);
+  return (
+    <div className="page page-limited">
+      <header className="page-header">
+        <h1 className="page-title">{translate('regulatory_report.page')}</h1>
+      </header>
+      <div className="page-description">
+        <p>{translate('regulatory_report.description1')}</p>
+        <p>{translate('regulatory_report.description2')}</p>
+        <div className="big-spacer-top">
+          <a
+            className={classNames('button button-primary', { disabled: downloadStarted })}
+            download={[component.name, branchName, 'PDF Report.pdf'].filter(s => !!s).join(' - ')}
+            onClick={() => setDownloadStarted(true)}
+            href={downloadStarted ? '#' : getRegulatoryReportUrl(component.key, branchName)}
+            target="_blank"
+            rel="noopener noreferrer">
+            {translate('download_verb')}
+          </a>
+          {downloadStarted && (
+            <div className="spacer-top">
+              <p>{translate('regulatory_page.download_start.sentence')}</p>
+            </div>
+          )}
+        </div>
+      </div>
+    </div>
+  );
+}
+
+export default RegulatoryReport;
diff --git a/server/sonar-web/src/main/js/apps/projectRegulatoryReport/__tests__/RegulatoryReport-it.tsx b/server/sonar-web/src/main/js/apps/projectRegulatoryReport/__tests__/RegulatoryReport-it.tsx
new file mode 100644 (file)
index 0000000..9b8cd71
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2022 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import { screen } from '@testing-library/react';
+import userEvent from '@testing-library/user-event';
+import * as React from 'react';
+import { renderComponent } from '../../../helpers/testReactTestingUtils';
+import RegulatoryReport from '../RegulatoryReport';
+
+it('should open the regulatory report page', async () => {
+  const user = userEvent.setup();
+  renderRegulatoryReportApp();
+  expect(await screen.findByText('regulatory_report.page')).toBeInTheDocument();
+  expect(screen.getByText('regulatory_report.description1')).toBeInTheDocument();
+  expect(screen.getByText('regulatory_report.description2')).toBeInTheDocument();
+
+  const downloadButton = screen.getByText('download_verb');
+  expect(downloadButton).toBeInTheDocument();
+
+  expect(screen.queryByText('regulatory_page.download_start.sentence')).not.toBeInTheDocument();
+  await user.click(downloadButton);
+  expect(screen.getByText('regulatory_page.download_start.sentence')).toBeInTheDocument();
+});
+
+function renderRegulatoryReportApp() {
+  renderComponent(<RegulatoryReport branchLike={undefined} component={{ key: '', name: '' }} />);
+}
index 6b192b73c408f13ab09f47af8ab5c579ad024343..98620b70763aa6f7cfbfeea05180ae29429aa397 100644 (file)
 .no-select {
   user-select: none !important;
 }
+
+a[download].button.disabled {
+  pointer-events: none;
+}
index 625551487645725c8aeb560c32892788a2070da0..306de8d6ac67174fe0b1f713a80d02b7851af0d4 100644 (file)
@@ -39,4 +39,5 @@ export interface AppState {
   standalone?: boolean;
   version: string;
   webAnalyticsJsPath?: string;
+  regulatoryReportFeatureEnabled?: boolean;
 }
index 6adedd92aaeaafdd408c5f1cb40fe0d2f8a1d8eb..3639e2af689116e18257fbbfd95fc400a56e84da 100644 (file)
@@ -646,6 +646,11 @@ baseline.branch_analyses.ranges.30days=Last 30 days
 baseline.branch_analyses.ranges.allTime=All time
 baseline.no_analyses=No analyses
 
+regulatory_report.page=Regulatory Report
+regulatory_report.description1=The regulatory report is a zip file containing a snapshot of the branch you selected. It contains an overview of the project, the configuration items relevant to its quality (quality profile, quality gate and analysis exclusions), as well as lists of findings for both new code and overall code.
+regulatory_report.description2=The file is created on demand when you download it. This may take some time.
+regulatory_page.download_start.sentence=Your download should start shortly. This may take some time.
+
 #------------------------------------------------------------------------------
 #
 # OTHER PAGE TITLES
@@ -665,7 +670,6 @@ portfolios.page=Portfolios
 portfolio_breakdown.page=Portfolio Breakdown
 project_activity.page=Activity
 
-
 #------------------------------------------------------------------------------
 #
 # ASYNC PROCESS