diff options
author | Revanshu Paliwal <revanshu.paliwal@sonarsource.com> | 2022-05-03 15:23:53 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2022-05-25 20:03:15 +0000 |
commit | b387af3df9473266b07efcad6b02833bddabc86c (patch) | |
tree | f3124151444d72644df5c6183127b293e560e0d8 /server/sonar-web/src/main/js | |
parent | c28353ec8b036b74bb070ca03420bfea29b1ca8d (diff) | |
download | sonarqube-b387af3df9473266b07efcad6b02833bddabc86c.tar.gz sonarqube-b387af3df9473266b07efcad6b02833bddabc86c.zip |
SONAR-16316 Page and link to download regulatory report
Diffstat (limited to 'server/sonar-web/src/main/js')
7 files changed, 163 insertions, 1 deletions
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 index 00000000000..0f5e0041972 --- /dev/null +++ b/server/sonar-web/src/main/js/api/regulatory-report.ts @@ -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()}`; +} diff --git a/server/sonar-web/src/main/js/app/components/nav/component/Menu.tsx b/server/sonar-web/src/main/js/app/components/nav/component/Menu.tsx index 7b33626b62a..a3e13786bfd 100644 --- a/server/sonar-web/src/main/js/app/components/nav/component/Menu.tsx +++ b/server/sonar-web/src/main/js/app/components/nav/component/Menu.tsx @@ -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 }; diff --git a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx index 622c56db585..5ad4881c396 100644 --- a/server/sonar-web/src/main/js/app/utils/startReactApp.tsx +++ b/server/sonar-web/src/main/js/app/utils/startReactApp.tsx @@ -240,6 +240,12 @@ function renderComponentRoutes() { 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 index 00000000000..f8cda88b0cc --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projectRegulatoryReport/RegulatoryReport.tsx @@ -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 index 00000000000..9b8cd7153aa --- /dev/null +++ b/server/sonar-web/src/main/js/apps/projectRegulatoryReport/__tests__/RegulatoryReport-it.tsx @@ -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: '' }} />); +} diff --git a/server/sonar-web/src/main/js/components/controls/buttons.css b/server/sonar-web/src/main/js/components/controls/buttons.css index 6b192b73c40..98620b70763 100644 --- a/server/sonar-web/src/main/js/components/controls/buttons.css +++ b/server/sonar-web/src/main/js/components/controls/buttons.css @@ -320,3 +320,7 @@ .no-select { user-select: none !important; } + +a[download].button.disabled { + pointer-events: none; +} diff --git a/server/sonar-web/src/main/js/types/appstate.ts b/server/sonar-web/src/main/js/types/appstate.ts index 62555148764..306de8d6ac6 100644 --- a/server/sonar-web/src/main/js/types/appstate.ts +++ b/server/sonar-web/src/main/js/types/appstate.ts @@ -39,4 +39,5 @@ export interface AppState { standalone?: boolean; version: string; webAnalyticsJsPath?: string; + regulatoryReportFeatureEnabled?: boolean; } |