]> source.dussan.org Git - sonarqube.git/blob
e3135885d3331ca2e8a1fc943b60f30beb9daa18
[sonarqube.git] /
1 /*
2  * SonarQube
3  * Copyright (C) 2009-2024 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 { Badge, FlagErrorIcon, FormField, InputSelect, SelectionCard } from 'design-system';
21 import * as React from 'react';
22 import { MenuPlacement, OptionProps, components } from 'react-select';
23 import Tooltip from '../../../components/controls/Tooltip';
24 import { NewCodeDefinitionLevels } from '../../../components/new-code-definition/utils';
25 import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation';
26 import { translate, translateWithParameters } from '../../../helpers/l10n';
27 import { NewCodeDefinitionType } from '../../../types/new-code-definition';
28
29 export interface BaselineSettingReferenceBranchProps {
30   branchList: BranchOption[];
31   className?: string;
32   disabled?: boolean;
33   onChangeReferenceBranch: (value: string) => void;
34   onSelect: (selection: NewCodeDefinitionType) => void;
35   referenceBranch: string;
36   selected: boolean;
37   settingLevel: Exclude<
38     NewCodeDefinitionLevels,
39     NewCodeDefinitionLevels.NewProject | NewCodeDefinitionLevels.Global
40   >;
41   inputSelectMenuPlacement?: MenuPlacement;
42 }
43
44 export interface BranchOption {
45   isDisabled?: boolean;
46   isInvalid?: boolean;
47   isMain: boolean;
48   label: string;
49   value: string;
50 }
51
52 function renderBranchOption(props: OptionProps<BranchOption, false>) {
53   const { data: option } = props;
54
55   return (
56     <components.Option {...props}>
57       {option.isInvalid ? (
58         <Tooltip
59           overlay={translateWithParameters(
60             'baseline.reference_branch.does_not_exist',
61             option.value,
62           )}
63         >
64           <span>
65             {option.value} <FlagErrorIcon className="sw-ml-2" />
66           </span>
67         </Tooltip>
68       ) : (
69         <>
70           <span
71             title={
72               option.isDisabled
73                 ? translate('baseline.reference_branch.cannot_be_itself')
74                 : undefined
75             }
76           >
77             {option.value}
78           </span>
79           {option.isMain && <Badge className="sw-ml-2">{translate('branches.main_branch')}</Badge>}
80         </>
81       )}
82     </components.Option>
83   );
84 }
85
86 export default function NewCodeDefinitionSettingReferenceBranch(
87   props: Readonly<BaselineSettingReferenceBranchProps>,
88 ) {
89   const {
90     branchList,
91     className,
92     disabled,
93     referenceBranch,
94     selected,
95     settingLevel,
96     inputSelectMenuPlacement,
97   } = props;
98
99   const currentBranch = branchList.find((b) => b.value === referenceBranch) || {
100     label: referenceBranch,
101     value: referenceBranch,
102     isMain: false,
103     isInvalid: true,
104   };
105
106   return (
107     <SelectionCard
108       className={className}
109       disabled={disabled}
110       onClick={() => props.onSelect(NewCodeDefinitionType.ReferenceBranch)}
111       selected={selected}
112       title={translate('baseline.reference_branch')}
113     >
114       <>
115         <div>
116           <p className="sw-mb-3">{translate('baseline.reference_branch.description')}</p>
117           <p className="sw-mb-4">{translate('baseline.reference_branch.usecase')}</p>
118         </div>
119         {selected && (
120           <>
121             {settingLevel === NewCodeDefinitionLevels.Project && (
122               <p>{translate('baseline.reference_branch.description2')}</p>
123             )}
124             <div className="sw-flex sw-flex-col">
125               <MandatoryFieldsExplanation className="sw-mb-2" />
126
127               <FormField
128                 ariaLabel={translate('baseline.reference_branch.choose')}
129                 label={translate('baseline.reference_branch.choose')}
130                 htmlFor="new-code-definition-reference-branch"
131                 required
132               >
133                 <InputSelect
134                   inputId="new-code-definition-reference-branch"
135                   className="sw-w-abs-300"
136                   size="full"
137                   options={branchList}
138                   onChange={(option: BranchOption) => props.onChangeReferenceBranch(option.value)}
139                   value={currentBranch}
140                   components={{
141                     Option: renderBranchOption,
142                   }}
143                   menuPlacement={inputSelectMenuPlacement}
144                 />
145               </FormField>
146             </div>
147           </>
148         )}
149       </>
150     </SelectionCard>
151   );
152 }