Переглянути джерело

SONAR-16141 Security hotspot status radio UI

tags/9.4.0.54424
Guillaume Peoc'h 2 роки тому
джерело
коміт
c34fc36ca3

+ 5
- 0
server/sonar-web/src/main/js/app/styles/init/misc.css Переглянути файл

@@ -489,6 +489,11 @@ th.huge-spacer-right {
align-items: baseline;
}

.display-inline-flex-start {
display: inline-flex !important;
align-items: flex-start;
}

.display-inline-flex-center {
display: inline-flex !important;
align-items: center;

+ 4
- 0
server/sonar-web/src/main/js/apps/security-hotspots/components/HotspotViewer.css Переглянути файл

@@ -33,3 +33,7 @@
.hotspot-content .markdown {
line-height: 1.8;
}

.status-radio i {
margin-top: 5px;
}

+ 6
- 2
server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusDescription.tsx Переглянути файл

@@ -18,6 +18,7 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import styled from '@emotion/styled';
import classNames from 'classnames';
import * as React from 'react';
import { translate } from '../../../../helpers/l10n';
import { HotspotStatusOption } from '../../../../types/security-hotspots';
@@ -25,16 +26,19 @@ import { HotspotStatusOption } from '../../../../types/security-hotspots';
export interface StatusDescriptionProps {
statusOption: HotspotStatusOption;
showTitle?: boolean;
statusInBadge?: boolean;
}

export default function StatusDescription(props: StatusDescriptionProps) {
const { statusOption, showTitle } = props;
const { statusOption, showTitle, statusInBadge = true } = props;

return (
<Container>
<h3>
{showTitle && `${translate('status')}: `}
<div className="badge">{translate('hotspots.status_option', statusOption)}</div>
<div className={classNames({ badge: statusInBadge })}>
{translate('hotspots.status_option', statusOption)}
</div>
</h3>
<div className="little-spacer-top">
{translate('hotspots.status_option', statusOption, 'description')}

+ 3
- 2
server/sonar-web/src/main/js/apps/security-hotspots/components/status/StatusSelectionRenderer.tsx Переглянути файл

@@ -45,10 +45,11 @@ export default function StatusSelectionRenderer(props: StatusSelectionRendererPr
return (
<Radio
checked={selectedStatus === status}
className="big-spacer-bottom"
className="big-spacer-bottom status-radio"
alignLabel={true}
onCheck={props.onStatusChange}
value={status}>
<StatusDescription statusOption={status} />
<StatusDescription statusOption={status} statusInBadge={false} />
</Radio>
);
};

+ 1
- 0
server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/StatusDescription-test.tsx Переглянути файл

@@ -25,6 +25,7 @@ import StatusDescription, { StatusDescriptionProps } from '../StatusDescription'
it('should render correctly', () => {
expect(shallowRender()).toMatchSnapshot();
expect(shallowRender({ showTitle: true })).toMatchSnapshot('with title');
expect(shallowRender({ statusInBadge: false })).toMatchSnapshot('without status in badge');
});

function shallowRender(props?: Partial<StatusDescriptionProps>) {

+ 17
- 0
server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/__snapshots__/StatusDescription-test.tsx.snap Переглянути файл

@@ -34,3 +34,20 @@ exports[`should render correctly: with title 1`] = `
</div>
</Styled(div)>
`;

exports[`should render correctly: without status in badge 1`] = `
<Styled(div)>
<h3>
<div
className=""
>
hotspots.status_option.TO_REVIEW
</div>
</h3>
<div
className="little-spacer-top"
>
hotspots.status_option.TO_REVIEW.description
</div>
</Styled(div)>
`;

+ 24
- 8
server/sonar-web/src/main/js/apps/security-hotspots/components/status/__tests__/__snapshots__/StatusSelectionRenderer-test.tsx.snap Переглянути файл

@@ -8,42 +8,50 @@ exports[`should render correctly 1`] = `
className="big-padded"
>
<Radio
alignLabel={true}
checked={true}
className="big-spacer-bottom"
className="big-spacer-bottom status-radio"
onCheck={[MockFunction]}
value="TO_REVIEW"
>
<StatusDescription
statusInBadge={false}
statusOption="TO_REVIEW"
/>
</Radio>
<Radio
alignLabel={true}
checked={false}
className="big-spacer-bottom"
className="big-spacer-bottom status-radio"
onCheck={[MockFunction]}
value="ACKNOWLEDGED"
>
<StatusDescription
statusInBadge={false}
statusOption="ACKNOWLEDGED"
/>
</Radio>
<Radio
alignLabel={true}
checked={false}
className="big-spacer-bottom"
className="big-spacer-bottom status-radio"
onCheck={[MockFunction]}
value="FIXED"
>
<StatusDescription
statusInBadge={false}
statusOption="FIXED"
/>
</Radio>
<Radio
alignLabel={true}
checked={false}
className="big-spacer-bottom"
className="big-spacer-bottom status-radio"
onCheck={[MockFunction]}
value="SAFE"
>
<StatusDescription
statusInBadge={false}
statusOption="SAFE"
/>
</Radio>
@@ -88,42 +96,50 @@ exports[`should render correctly: loading 1`] = `
className="big-padded"
>
<Radio
alignLabel={true}
checked={true}
className="big-spacer-bottom"
className="big-spacer-bottom status-radio"
onCheck={[MockFunction]}
value="TO_REVIEW"
>
<StatusDescription
statusInBadge={false}
statusOption="TO_REVIEW"
/>
</Radio>
<Radio
alignLabel={true}
checked={false}
className="big-spacer-bottom"
className="big-spacer-bottom status-radio"
onCheck={[MockFunction]}
value="ACKNOWLEDGED"
>
<StatusDescription
statusInBadge={false}
statusOption="ACKNOWLEDGED"
/>
</Radio>
<Radio
alignLabel={true}
checked={false}
className="big-spacer-bottom"
className="big-spacer-bottom status-radio"
onCheck={[MockFunction]}
value="FIXED"
>
<StatusDescription
statusInBadge={false}
statusOption="FIXED"
/>
</Radio>
<Radio
alignLabel={true}
checked={false}
className="big-spacer-bottom"
className="big-spacer-bottom status-radio"
onCheck={[MockFunction]}
value="SAFE"
>
<StatusDescription
statusInBadge={false}
statusOption="SAFE"
/>
</Radio>

+ 8
- 2
server/sonar-web/src/main/js/components/controls/Radio.tsx Переглянути файл

@@ -24,6 +24,7 @@ import './Radio.css';
interface Props {
checked: boolean;
className?: string;
alignLabel?: boolean;
disabled?: boolean;
onCheck: (value: string) => void;
value: string;
@@ -39,12 +40,17 @@ export default class Radio extends React.PureComponent<Props> {
};

render() {
const { className, checked, children, disabled } = this.props;
const { className, checked, children, disabled, alignLabel = false } = this.props;

return (
<a
aria-checked={checked}
className={classNames('display-inline-flex-center link-radio', className, { disabled })}
className={classNames(
alignLabel ? 'display-inline-flex-start' : 'display-inline-flex-center',
'link-radio',
className,
{ disabled }
)}
href="#"
onClick={this.handleClick}
role="radio">

Завантаження…
Відмінити
Зберегти