]> source.dussan.org Git - sonarqube.git/blob
3d61193be3df4a7a034e3024b8afc16202179e72
[sonarqube.git] /
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 * as React from 'react';
21 import { ButtonLink } from '../../../../../components/controls/buttons';
22 import ModalButton from '../../../../../components/controls/ModalButton';
23 import PrivacyBadgeContainer from '../../../../../components/common/PrivacyBadgeContainer';
24 import { translate } from '../../../../../helpers/l10n';
25 import { ComponentQualifier } from '../../../../../types/component';
26 import { Component, Measure } from '../../../../../types/types';
27 import DrawerLink from './DrawerLink';
28 import MetaKey from './meta/MetaKey';
29 import MetaLinks from './meta/MetaLinks';
30 import MetaQualityGate from './meta/MetaQualityGate';
31 import MetaQualityProfiles from './meta/MetaQualityProfiles';
32 import MetaSize from './meta/MetaSize';
33 import MetaTags from './meta/MetaTags';
34 import { ProjectInformationPages } from './ProjectInformationPages';
35 import RegulatoryReportModal from './projectRegulatoryReport/RegulatoryReportModal';
36 import withAppStateContext from '../../../app-state/withAppStateContext';
37 import { AppState } from '../../../../../types/appstate';
38 import { BranchLike } from '../../../../../types/branch-like';
39
40 export interface ProjectInformationRendererProps {
41   appState: AppState;
42   canConfigureNotifications: boolean;
43   canUseBadges: boolean;
44   component: Component;
45   branchLike?: BranchLike;
46   measures?: Measure[];
47   onComponentChange: (changes: {}) => void;
48   onPageChange: (page: ProjectInformationPages) => void;
49 }
50
51 export function ProjectInformationRenderer(props: ProjectInformationRendererProps) {
52   const {
53     canConfigureNotifications,
54     canUseBadges,
55     component,
56     measures = [],
57     appState,
58     branchLike
59   } = props;
60
61   const heading = React.useRef<HTMLHeadingElement>(null);
62   const isApp = component.qualifier === ComponentQualifier.Application;
63
64   React.useEffect(() => {
65     if (heading.current) {
66       // a11y: provide focus to the heading when the Project Information is opened.
67       heading.current.focus();
68     }
69   }, [heading]);
70
71   return (
72     <>
73       <div>
74         <h2 className="big-padded bordered-bottom" tabIndex={-1} ref={heading}>
75           {translate(isApp ? 'application' : 'project', 'info.title')}
76         </h2>
77       </div>
78
79       <div className="overflow-y-auto">
80         <div className="big-padded bordered-bottom">
81           <div className="display-flex-center">
82             <h3 className="spacer-right">{translate('project.info.description')}</h3>
83             {component.visibility && (
84               <PrivacyBadgeContainer
85                 qualifier={component.qualifier}
86                 visibility={component.visibility}
87               />
88             )}
89           </div>
90
91           {component.description && (
92             <p className="it__project-description">{component.description}</p>
93           )}
94
95           <MetaTags component={component} onComponentChange={props.onComponentChange} />
96         </div>
97
98         <div className="big-padded bordered-bottom it__project-loc-value">
99           <MetaSize component={component} measures={measures} />
100         </div>
101
102         {!isApp &&
103           (component.qualityGate ||
104             (component.qualityProfiles && component.qualityProfiles.length > 0)) && (
105             <div className="big-padded bordered-bottom">
106               {component.qualityGate && <MetaQualityGate qualityGate={component.qualityGate} />}
107
108               {component.qualityProfiles && component.qualityProfiles.length > 0 && (
109                 <MetaQualityProfiles
110                   headerClassName={component.qualityGate ? 'big-spacer-top' : undefined}
111                   profiles={component.qualityProfiles}
112                 />
113               )}
114             </div>
115           )}
116
117         {!isApp && <MetaLinks component={component} />}
118
119         <div className="big-padded bordered-bottom">
120           <MetaKey componentKey={component.key} qualifier={component.qualifier} />
121         </div>
122
123         <ul>
124           {canUseBadges && (
125             <li>
126               <DrawerLink
127                 label={translate('overview.badges.get_badge', component.qualifier)}
128                 onPageChange={props.onPageChange}
129                 to={ProjectInformationPages.badges}
130               />
131             </li>
132           )}
133           {canConfigureNotifications && (
134             <li>
135               <DrawerLink
136                 label={translate('project.info.to_notifications')}
137                 onPageChange={props.onPageChange}
138                 to={ProjectInformationPages.notifications}
139               />
140             </li>
141           )}
142           {component.qualifier === ComponentQualifier.Project &&
143             appState.regulatoryReportFeatureEnabled && (
144               <li className="big-padded bordered-bottom">
145                 <ModalButton
146                   modal={({ onClose }) => (
147                     <RegulatoryReportModal
148                       component={component}
149                       branchLike={branchLike}
150                       onClose={onClose}
151                     />
152                   )}>
153                   {({ onClick }) => (
154                     <ButtonLink onClick={onClick}>{translate('regulatory_report.page')}</ButtonLink>
155                   )}
156                 </ModalButton>
157               </li>
158             )}
159         </ul>
160       </div>
161     </>
162   );
163 }
164
165 export default withAppStateContext(React.memo(ProjectInformationRenderer));