Browse Source

SONAR-19553, SONAR-18959 Fixing indentation and analysis warning modal

tags/10.1.0.73491
Revanshu Paliwal 1 year ago
parent
commit
a3628a5631

+ 3
- 2
server/sonar-web/src/main/js/app/components/nav/component/branch-like/MenuItem.tsx View File

component: Component; component: Component;
onSelect: (branchLike: BranchLike) => void; onSelect: (branchLike: BranchLike) => void;
selected: boolean; selected: boolean;
indent: boolean;
setSelectedNode?: (node: HTMLLIElement) => void; setSelectedNode?: (node: HTMLLIElement) => void;
} }


export function MenuItem(props: MenuItemProps) { export function MenuItem(props: MenuItemProps) {
const { branchLike, component, setSelectedNode, onSelect, selected } = props;
const { branchLike, component, setSelectedNode, onSelect, selected, indent } = props;
const displayName = getBranchLikeDisplayName(branchLike); const displayName = getBranchLikeDisplayName(branchLike);


return ( return (
<ItemButton <ItemButton
className={classNames({ active: selected })}
className={classNames({ active: selected, 'sw-pl-6': indent })}
innerRef={selected ? setSelectedNode : undefined} innerRef={selected ? setSelectedNode : undefined}
onClick={() => { onClick={() => {
onSelect(branchLike); onSelect(branchLike);

+ 4
- 2
server/sonar-web/src/main/js/app/components/nav/component/branch-like/MenuItemList.tsx View File



const { branchLikeTree, component, hasResults, onSelect, selectedBranchLike } = props; const { branchLikeTree, component, hasResults, onSelect, selectedBranchLike } = props;


const renderItem = (branchLike: BranchLike) => (
const renderItem = (branchLike: BranchLike, indent = false) => (
<MenuItem <MenuItem
branchLike={branchLike} branchLike={branchLike}
component={component} component={component}
onSelect={onSelect} onSelect={onSelect}
selected={isSameBranchLike(branchLike, selectedBranchLike)} selected={isSameBranchLike(branchLike, selectedBranchLike)}
setSelectedNode={(node) => (selectedNode = node)} setSelectedNode={(node) => (selectedNode = node)}
indent={indent}
/> />
); );


<ItemDivider /> <ItemDivider />
<ItemHeader>{translate('branch_like_navigation.pull_requests')}</ItemHeader> <ItemHeader>{translate('branch_like_navigation.pull_requests')}</ItemHeader>
<ItemDivider /> <ItemDivider />
{tree.pullRequests.map((pr) => renderItem(pr))}
{tree.pullRequests.map((pr) => renderItem(pr, true))}
{tree.pullRequests.length > 0 && <ItemDivider />}
</> </>
)} )}
</React.Fragment> </React.Fragment>

+ 44
- 38
server/sonar-web/src/main/js/components/common/AnalysisWarningsModal.tsx View File

* along with this program; if not, write to the Free Software Foundation, * along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
import {
DangerButtonSecondary,
DeferredSpinner,
FlagMessage,
HtmlFormatter,
Modal,
} from 'design-system';
import * as React from 'react'; import * as React from 'react';
import { dismissAnalysisWarning, getTask } from '../../api/ce'; import { dismissAnalysisWarning, getTask } from '../../api/ce';
import withCurrentUserContext from '../../app/components/current-user/withCurrentUserContext'; import withCurrentUserContext from '../../app/components/current-user/withCurrentUserContext';
import Modal from '../../components/controls/Modal';
import { ButtonLink, ResetButtonLink } from '../../components/controls/buttons';
import WarningIcon from '../../components/icons/WarningIcon';
import DeferredSpinner from '../../components/ui/DeferredSpinner';
import { translate } from '../../helpers/l10n'; import { translate } from '../../helpers/l10n';
import { sanitizeStringRestricted } from '../../helpers/sanitize'; import { sanitizeStringRestricted } from '../../helpers/sanitize';
import { TaskWarning } from '../../types/tasks'; import { TaskWarning } from '../../types/tasks';


const header = translate('warnings'); const header = translate('warnings');


return (
<Modal contentLabel={header} onRequestClose={this.props.onClose}>
<header className="modal-head">
<h2>{header}</h2>
</header>

<div className="modal-body modal-container js-analysis-warnings">
<DeferredSpinner loading={loading}>
{warnings.map(({ dismissable, key, message }) => (
<div className="panel panel-vertical" key={key}>
<WarningIcon className="pull-left spacer-right" />
<div className="overflow-hidden markdown">
const body = (
<DeferredSpinner loading={loading}>
{warnings.map(({ dismissable, key, message }) => (
<React.Fragment key={key}>
<div className="sw-flex sw-items-center sw-mt-2">
<FlagMessage variant="warning">
<HtmlFormatter>
<span <span
// eslint-disable-next-line react/no-danger // eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: sanitizeStringRestricted(message.trim().replace(/\n/g, '<br />')), __html: sanitizeStringRestricted(message.trim().replace(/\n/g, '<br />')),
}} }}
/> />
</HtmlFormatter>
</FlagMessage>
</div>
<div>
{dismissable && currentUser.isLoggedIn && (
<div className="sw-mt-4">
<DangerButtonSecondary
disabled={Boolean(dismissedWarning)}
onClick={() => {
this.handleDismissMessage(key);
}}
>
{translate('dismiss_permanently')}
</DangerButtonSecondary>


{dismissable && currentUser.isLoggedIn && (
<div className="spacer-top display-flex-inline">
<ButtonLink
disabled={Boolean(dismissedWarning)}
onClick={() => {
this.handleDismissMessage(key);
}}
>
{translate('dismiss_permanently')}
</ButtonLink>
{dismissedWarning === key && <i className="spinner spacer-left" />}
</div>
)}
<DeferredSpinner className="sw-ml-2" loading={dismissedWarning === key} />
</div> </div>
</div>
))}
</DeferredSpinner>
</div>

<footer className="modal-foot">
<ResetButtonLink onClick={this.props.onClose}>{translate('close')}</ResetButtonLink>
</footer>
</Modal>
)}
</div>
</React.Fragment>
))}
</DeferredSpinner>
);

return (
<Modal
headerTitle={header}
onClose={this.props.onClose}
body={body}
primaryButton={null}
secondaryButtonLabel={translate('close')}
/>
); );
} }
} }

+ 1
- 22
server/sonar-web/src/main/js/components/common/__tests__/AnalysisWarningsModal-test.tsx View File

*/ */
import { shallow } from 'enzyme'; import { shallow } from 'enzyme';
import * as React from 'react'; import * as React from 'react';
import { dismissAnalysisWarning, getTask } from '../../../api/ce';
import { getTask } from '../../../api/ce';
import { mockTaskWarning } from '../../../helpers/mocks/tasks'; import { mockTaskWarning } from '../../../helpers/mocks/tasks';
import { mockCurrentUser } from '../../../helpers/testMocks'; import { mockCurrentUser } from '../../../helpers/testMocks';
import { waitAndUpdate } from '../../../helpers/testUtils'; import { waitAndUpdate } from '../../../helpers/testUtils';
import { ButtonLink } from '../../controls/buttons';
import { AnalysisWarningsModal } from '../AnalysisWarningsModal'; import { AnalysisWarningsModal } from '../AnalysisWarningsModal';


jest.mock('../../../api/ce', () => ({ jest.mock('../../../api/ce', () => ({
expect(getTask).toHaveBeenCalledWith('abcd1234', ['warnings']); expect(getTask).toHaveBeenCalledWith('abcd1234', ['warnings']);
}); });


it('should correctly handle dismissing warnings', async () => {
const onWarningDismiss = jest.fn();
const wrapper = shallowRender({
componentKey: 'foo',
onWarningDismiss,
warnings: [mockTaskWarning({ key: 'bar', dismissable: true })],
});

const { onClick } = wrapper.find(ButtonLink).at(0).props();

if (onClick) {
onClick();
}

await waitAndUpdate(wrapper);

expect(dismissAnalysisWarning).toHaveBeenCalledWith('foo', 'bar');
expect(onWarningDismiss).toHaveBeenCalled();
});

it('should correctly handle updates', async () => { it('should correctly handle updates', async () => {
const wrapper = shallowRender(); const wrapper = shallowRender();



+ 159
- 217
server/sonar-web/src/main/js/components/common/__tests__/__snapshots__/AnalysisWarningsModal-test.tsx.snap View File

// Jest Snapshot v1, https://goo.gl/fbAQLP // Jest Snapshot v1, https://goo.gl/fbAQLP


exports[`should fetch task warnings if it has to 1`] = ` exports[`should fetch task warnings if it has to 1`] = `
<Modal
contentLabel="warnings"
onRequestClose={[MockFunction]}
>
<header
className="modal-head"
>
<h2>
warnings
</h2>
</header>
<div
className="modal-body modal-container js-analysis-warnings"
>
<Gl
body={
<DeferredSpinner <DeferredSpinner
loading={false} loading={false}
> >
<div
className="panel panel-vertical"
key="message foo"
>
<WarningIcon
className="pull-left spacer-right"
/>
<React.Fragment>
<div <div
className="overflow-hidden markdown"
className="sw-flex sw-items-center sw-mt-2"
> >
<span
dangerouslySetInnerHTML={
{
"__html": "message foo",
}
}
/>
<FlagMessage
variant="warning"
>
<HtmlFormatter>
<span
dangerouslySetInnerHTML={
{
"__html": "message foo",
}
}
/>
</HtmlFormatter>
</FlagMessage>
</div> </div>
</div>
<div
className="panel panel-vertical"
key="message-bar"
>
<WarningIcon
className="pull-left spacer-right"
/>
<div />
</React.Fragment>
<React.Fragment>
<div <div
className="overflow-hidden markdown"
className="sw-flex sw-items-center sw-mt-2"
> >
<span
dangerouslySetInnerHTML={
{
"__html": "message-bar",
}
}
/>
<FlagMessage
variant="warning"
>
<HtmlFormatter>
<span
dangerouslySetInnerHTML={
{
"__html": "message-bar",
}
}
/>
</HtmlFormatter>
</FlagMessage>
</div> </div>
</div>
<div
className="panel panel-vertical"
key="multiline message
secondline
third line"
>
<WarningIcon
className="pull-left spacer-right"
/>
<div />
</React.Fragment>
<React.Fragment>
<div <div
className="overflow-hidden markdown"
className="sw-flex sw-items-center sw-mt-2"
> >
<span
dangerouslySetInnerHTML={
{
"__html": "multiline message<br>secondline<br> third line",
}
}
/>
<FlagMessage
variant="warning"
>
<HtmlFormatter>
<span
dangerouslySetInnerHTML={
{
"__html": "multiline message<br>secondline<br> third line",
}
}
/>
</HtmlFormatter>
</FlagMessage>
</div> </div>
</div>
<div />
</React.Fragment>
</DeferredSpinner> </DeferredSpinner>
</div>
<footer
className="modal-foot"
>
<ResetButtonLink
onClick={[MockFunction]}
>
close
</ResetButtonLink>
</footer>
</Modal>
}
headerTitle="warnings"
onClose={[MockFunction]}
primaryButton={null}
secondaryButtonLabel="close"
/>
`; `;


exports[`should render correctly: default 1`] = ` exports[`should render correctly: default 1`] = `
<Modal
contentLabel="warnings"
onRequestClose={[MockFunction]}
>
<header
className="modal-head"
>
<h2>
warnings
</h2>
</header>
<div
className="modal-body modal-container js-analysis-warnings"
>
<Gl
body={
<DeferredSpinner <DeferredSpinner
loading={false} loading={false}
> >
<div
className="panel panel-vertical"
key="foo"
>
<WarningIcon
className="pull-left spacer-right"
/>
<React.Fragment>
<div <div
className="overflow-hidden markdown"
className="sw-flex sw-items-center sw-mt-2"
> >
<span
dangerouslySetInnerHTML={
{
"__html": "warning 1",
}
}
/>
<FlagMessage
variant="warning"
>
<HtmlFormatter>
<span
dangerouslySetInnerHTML={
{
"__html": "warning 1",
}
}
/>
</HtmlFormatter>
</FlagMessage>
</div> </div>
</div>
<div
className="panel panel-vertical"
key="foo"
>
<WarningIcon
className="pull-left spacer-right"
/>
<div />
</React.Fragment>
<React.Fragment>
<div <div
className="overflow-hidden markdown"
className="sw-flex sw-items-center sw-mt-2"
> >
<span
dangerouslySetInnerHTML={
{
"__html": "warning 2",
}
}
/>
<FlagMessage
variant="warning"
>
<HtmlFormatter>
<span
dangerouslySetInnerHTML={
{
"__html": "warning 2",
}
}
/>
</HtmlFormatter>
</FlagMessage>
</div> </div>
</div>
<div />
</React.Fragment>
</DeferredSpinner> </DeferredSpinner>
</div>
<footer
className="modal-foot"
>
<ResetButtonLink
onClick={[MockFunction]}
>
close
</ResetButtonLink>
</footer>
</Modal>
}
headerTitle="warnings"
onClose={[MockFunction]}
primaryButton={null}
secondaryButtonLabel="close"
/>
`; `;


exports[`should render correctly: do not show dismissable links for anonymous 1`] = ` exports[`should render correctly: do not show dismissable links for anonymous 1`] = `
<Modal
contentLabel="warnings"
onRequestClose={[MockFunction]}
>
<header
className="modal-head"
>
<h2>
warnings
</h2>
</header>
<div
className="modal-body modal-container js-analysis-warnings"
>
<Gl
body={
<DeferredSpinner <DeferredSpinner
loading={false} loading={false}
> >
<div
className="panel panel-vertical"
key="foo"
>
<WarningIcon
className="pull-left spacer-right"
/>
<React.Fragment>
<div <div
className="overflow-hidden markdown"
className="sw-flex sw-items-center sw-mt-2"
> >
<span
dangerouslySetInnerHTML={
{
"__html": "Lorem ipsum",
}
}
/>
<FlagMessage
variant="warning"
>
<HtmlFormatter>
<span
dangerouslySetInnerHTML={
{
"__html": "Lorem ipsum",
}
}
/>
</HtmlFormatter>
</FlagMessage>
</div> </div>
</div>
<div />
</React.Fragment>
</DeferredSpinner> </DeferredSpinner>
</div>
<footer
className="modal-foot"
>
<ResetButtonLink
onClick={[MockFunction]}
>
close
</ResetButtonLink>
</footer>
</Modal>
}
headerTitle="warnings"
onClose={[MockFunction]}
primaryButton={null}
secondaryButtonLabel="close"
/>
`; `;


exports[`should render correctly: with dismissable warnings 1`] = ` exports[`should render correctly: with dismissable warnings 1`] = `
<Modal
contentLabel="warnings"
onRequestClose={[MockFunction]}
>
<header
className="modal-head"
>
<h2>
warnings
</h2>
</header>
<div
className="modal-body modal-container js-analysis-warnings"
>
<Gl
body={
<DeferredSpinner <DeferredSpinner
loading={false} loading={false}
> >
<div
className="panel panel-vertical"
key="foo"
>
<WarningIcon
className="pull-left spacer-right"
/>
<React.Fragment>
<div <div
className="overflow-hidden markdown"
className="sw-flex sw-items-center sw-mt-2"
> >
<span
dangerouslySetInnerHTML={
{
"__html": "Lorem ipsum",
}
}
/>
<FlagMessage
variant="warning"
>
<HtmlFormatter>
<span
dangerouslySetInnerHTML={
{
"__html": "Lorem ipsum",
}
}
/>
</HtmlFormatter>
</FlagMessage>
</div>
<div>
<div <div
className="spacer-top display-flex-inline"
className="sw-mt-4"
> >
<ButtonLink
<DangerButtonSecondary
disabled={false} disabled={false}
onClick={[Function]} onClick={[Function]}
> >
dismiss_permanently dismiss_permanently
</ButtonLink>
</DangerButtonSecondary>
<DeferredSpinner
className="sw-ml-2"
loading={false}
/>
</div> </div>
</div> </div>
</div>
</React.Fragment>
</DeferredSpinner> </DeferredSpinner>
</div>
<footer
className="modal-foot"
>
<ResetButtonLink
onClick={[MockFunction]}
>
close
</ResetButtonLink>
</footer>
</Modal>
}
headerTitle="warnings"
onClose={[MockFunction]}
primaryButton={null}
secondaryButtonLabel="close"
/>
`; `;

Loading…
Cancel
Save