@@ -48,7 +48,7 @@ | |||
"jsx-quotes": 2, | |||
"key-spacing": 2, | |||
"keyword-spacing": 2, | |||
"max-len": [2, 100], | |||
// "max-len": [2, 100], | |||
"new-parens": 2, | |||
"no-lonely-if": 2, | |||
"no-multi-spaces": 2, | |||
@@ -71,7 +71,7 @@ | |||
"prefer-const": 2, | |||
"prefer-spread": 2, | |||
"quote-props": [2, "as-needed"], | |||
"quotes": [2, "single"], | |||
"quotes": [2, "single", { "avoidEscape": true }], | |||
"rest-spread-spacing": 2, | |||
"semi": [2, "always"], | |||
"semi-spacing": 2, |
@@ -57,7 +57,7 @@ | |||
"css-loader": "0.28.4", | |||
"enzyme": "^2.6.0", | |||
"enzyme-to-json": "^1.4.5", | |||
"eslint": "^3.12.2", | |||
"eslint": "3.14.1", | |||
"eslint-loader": "1.8.0", | |||
"eslint-plugin-flowtype": "^2.29.1", | |||
"eslint-plugin-import": "^2.2.0", | |||
@@ -73,10 +73,7 @@ | |||
"less": "2.7.1", | |||
"less-loader": "4.0.4", | |||
"postcss-loader": "2.0.6", | |||
"prettier": "1.2.2", | |||
"prettier-css": "0.0.7", | |||
"prettier-eslint": "5.1.0", | |||
"prettier-eslint-cli": "3.4.1", | |||
"prettier": "1.5.2", | |||
"react-addons-test-utils": "15.4.2", | |||
"react-dev-utils": "3.0.0", | |||
"react-error-overlay": "1.0.7", | |||
@@ -92,8 +89,7 @@ | |||
"build": "node scripts/build.js", | |||
"test": "node scripts/test.js", | |||
"coverage": "npm test -- --coverage", | |||
"format": "prettier-eslint --write \"src/main/js/!(libs)/**/*.js\"", | |||
"format-css": "prettier-css \"src/main/js/**/*.css\"", | |||
"format": "prettier --write --single-quote --jsx-bracket-same-line --print-width 100 'src/main/{js,less}/!(libs)/**/*.{js,css,less}'", | |||
"lint": "eslint src/main/js", | |||
"typecheck": "flow src/main/js", | |||
"validate": "eslint src/main/js && flow check src/main/js && NODE_ENV=test jest" | |||
@@ -110,15 +106,8 @@ | |||
], | |||
"jest": { | |||
"coverageDirectory": "<rootDir>/target/coverage", | |||
"coveragePathIgnorePatterns": [ | |||
"<rootDir>/node_modules", | |||
"<rootDir>/tests" | |||
], | |||
"moduleFileExtensions": [ | |||
"jsx", | |||
"js", | |||
"json" | |||
], | |||
"coveragePathIgnorePatterns": ["<rootDir>/node_modules", "<rootDir>/tests"], | |||
"moduleFileExtensions": ["jsx", "js", "json"], | |||
"moduleNameMapper": { | |||
"^.+\\.(hbs|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/config/jest/FileStub.js", | |||
"^.+\\.css$": "<rootDir>/config/jest/CSSStub.js" | |||
@@ -127,9 +116,7 @@ | |||
"<rootDir>/config/polyfills.js", | |||
"<rootDir>/config/jest/SetupTestEnvironment.js" | |||
], | |||
"snapshotSerializers": [ | |||
"enzyme-to-json/serializer" | |||
], | |||
"snapshotSerializers": ["enzyme-to-json/serializer"], | |||
"testPathIgnorePatterns": [ | |||
"<rootDir>/node_modules", | |||
"<rootDir>/src/main/webapp", |
@@ -47,14 +47,12 @@ export function deleteProject(project: string) { | |||
return post(url, data); | |||
} | |||
export function createProject( | |||
data: { | |||
branch?: string, | |||
name: string, | |||
project: string, | |||
organization?: string | |||
} | |||
) { | |||
export function createProject(data: { | |||
branch?: string, | |||
name: string, | |||
project: string, | |||
organization?: string | |||
}) { | |||
const url = '/api/projects/create'; | |||
return postJSON(url, data).catch(throwGlobalError); | |||
} |
@@ -117,9 +117,10 @@ export function editIssueComment(data: { comment: string, text: string }): Promi | |||
return postJSON(url, data); | |||
} | |||
export function setIssueAssignee( | |||
data: { issue: string, assignee?: string } | |||
): Promise<IssueResponse> { | |||
export function setIssueAssignee(data: { | |||
issue: string, | |||
assignee?: string | |||
}): Promise<IssueResponse> { | |||
const url = '/api/issues/assign'; | |||
return postJSON(url, data); | |||
} | |||
@@ -134,9 +135,10 @@ export function setIssueTags(data: { issue: string, tags: string }): Promise<Iss | |||
return postJSON(url, data); | |||
} | |||
export function setIssueTransition( | |||
data: { issue: string, transition: string } | |||
): Promise<IssueResponse> { | |||
export function setIssueTransition(data: { | |||
issue: string, | |||
transition: string | |||
}): Promise<IssueResponse> { | |||
const url = '/api/issues/do_transition'; | |||
return postJSON(url, data); | |||
} |
@@ -63,9 +63,13 @@ export const updateOrganization = (key: string, changes: {}) => | |||
export const deleteOrganization = (key: string) => | |||
post('/api/organizations/delete', { key }).catch(throwGlobalError); | |||
export const searchMembers = ( | |||
data: { organization?: string, p?: number, ps?: number, q?: string, selected?: string } | |||
) => getJSON('/api/organizations/search_members', data); | |||
export const searchMembers = (data: { | |||
organization?: string, | |||
p?: number, | |||
ps?: number, | |||
q?: string, | |||
selected?: string | |||
}) => getJSON('/api/organizations/search_members', data); | |||
export const addMember = (data: { login: string, organization: string }) => | |||
postJSON('/api/organizations/add_member', data).then(r => r.user); |
@@ -130,26 +130,22 @@ export function bulkApplyTemplate(data: Object) { | |||
return post(url, data); | |||
} | |||
export function grantTemplatePermissionToUser( | |||
data: { | |||
templateId: string, | |||
login: string, | |||
permission: string, | |||
organization?: string | |||
} | |||
) { | |||
export function grantTemplatePermissionToUser(data: { | |||
templateId: string, | |||
login: string, | |||
permission: string, | |||
organization?: string | |||
}) { | |||
const url = '/api/permissions/add_user_to_template'; | |||
return post(url, data); | |||
} | |||
export function revokeTemplatePermissionFromUser( | |||
data: { | |||
templateId: string, | |||
login: string, | |||
permission: string, | |||
organization?: string | |||
} | |||
) { | |||
export function revokeTemplatePermissionFromUser(data: { | |||
templateId: string, | |||
login: string, | |||
permission: string, | |||
organization?: string | |||
}) { | |||
const url = '/api/permissions/remove_user_from_template'; | |||
return post(url, data); | |||
} |
@@ -20,23 +20,33 @@ | |||
//@flow | |||
import { getJSON, post } from '../helpers/request'; | |||
export function searchUsersGroups( | |||
data: { f?: string, organization?: string, p?: number, ps?: number, q?: string } | |||
) { | |||
export function searchUsersGroups(data: { | |||
f?: string, | |||
organization?: string, | |||
p?: number, | |||
ps?: number, | |||
q?: string | |||
}) { | |||
const url = '/api/user_groups/search'; | |||
return getJSON(url, data); | |||
} | |||
export function addUserToGroup( | |||
data: { id?: string, name?: string, login?: string, organization?: string } | |||
) { | |||
export function addUserToGroup(data: { | |||
id?: string, | |||
name?: string, | |||
login?: string, | |||
organization?: string | |||
}) { | |||
const url = '/api/user_groups/add_user'; | |||
return post(url, data); | |||
} | |||
export function removeUserFromGroup( | |||
data: { id?: string, name?: string, login?: string, organization?: string } | |||
) { | |||
export function removeUserFromGroup(data: { | |||
id?: string, | |||
name?: string, | |||
login?: string, | |||
organization?: string | |||
}) { | |||
const url = '/api/user_groups/remove_user'; | |||
return post(url, data); | |||
} |
@@ -60,9 +60,13 @@ export default function GlobalFooter({ | |||
sonarqubeVersion && | |||
translateWithParameters('footer.version_x', sonarqubeVersion)} | |||
{!hideLoggedInInfo && sonarqubeVersion && ' - '} | |||
<a href="http://www.gnu.org/licenses/lgpl-3.0.txt">{translate('footer.licence')}</a> | |||
<a href="http://www.gnu.org/licenses/lgpl-3.0.txt"> | |||
{translate('footer.licence')} | |||
</a> | |||
{' - '} | |||
<a href="http://www.sonarqube.org">{translate('footer.community')}</a> | |||
<a href="http://www.sonarqube.org"> | |||
{translate('footer.community')} | |||
</a> | |||
{' - '} | |||
<a href="https://redirect.sonarsource.com/doc/home.html"> | |||
{translate('footer.documentation')} | |||
@@ -76,9 +80,15 @@ export default function GlobalFooter({ | |||
{translate('footer.plugins')} | |||
</a> | |||
{!hideLoggedInInfo && ' - '} | |||
{!hideLoggedInInfo && <Link to="/web_api">{translate('footer.web_api')}</Link>} | |||
{!hideLoggedInInfo && | |||
<Link to="/web_api"> | |||
{translate('footer.web_api')} | |||
</Link>} | |||
{!hideLoggedInInfo && ' - '} | |||
{!hideLoggedInInfo && <Link to="/about">{translate('footer.about')}</Link>} | |||
{!hideLoggedInInfo && | |||
<Link to="/about"> | |||
{translate('footer.about')} | |||
</Link>} | |||
</div> | |||
</div> | |||
); |
@@ -23,13 +23,14 @@ import React from 'react'; | |||
export default function GlobalFooterBranding() { | |||
return ( | |||
<div> | |||
This application is based on | |||
{' '} | |||
<a href="http://www.sonarqube.org/" title="SonarQube™">SonarQube™</a> | |||
{' '} | |||
but is <strong>not</strong> an official version provided by | |||
{' '} | |||
<a href="http://www.sonarsource.com" title="SonarSource SA">SonarSource SA</a>. | |||
This application is based on{' '} | |||
<a href="http://www.sonarqube.org/" title="SonarQube™"> | |||
SonarQube™ | |||
</a>{' '} | |||
but is <strong>not</strong> an official version provided by{' '} | |||
<a href="http://www.sonarsource.com" title="SonarSource SA"> | |||
SonarSource SA | |||
</a>. | |||
</div> | |||
); | |||
} |
@@ -26,24 +26,37 @@ export default function GlobalFooterForSonarQubeDotCom() { | |||
return ( | |||
<div id="footer" className="page-footer page-container"> | |||
<div> | |||
© 2008-2017, SonarCloud.io by | |||
{' '} | |||
<a href="http://www.sonarsource.com" title="SonarSource SA">SonarSource SA</a> | |||
© 2008-2017, SonarCloud.io by{' '} | |||
<a href="http://www.sonarsource.com" title="SonarSource SA"> | |||
SonarSource SA | |||
</a> | |||
. All rights reserved. | |||
</div> | |||
<div> | |||
<a href="https://about.sonarcloud.io/news/">{translate('footer.news')}</a> | |||
<a href="https://about.sonarcloud.io/news/"> | |||
{translate('footer.news')} | |||
</a> | |||
{' - '} | |||
<a href="https://about.sonarcloud.io/terms.pdf">{translate('footer.terms')}</a> | |||
<a href="https://about.sonarcloud.io/terms.pdf"> | |||
{translate('footer.terms')} | |||
</a> | |||
{' - '} | |||
<a href="https://twitter.com/sonarqube">{translate('footer.twitter')}</a> | |||
<a href="https://twitter.com/sonarqube"> | |||
{translate('footer.twitter')} | |||
</a> | |||
{' - '} | |||
<a href="https://about.sonarcloud.io/get-started/">{translate('footer.get_started')}</a> | |||
<a href="https://about.sonarcloud.io/get-started/"> | |||
{translate('footer.get_started')} | |||
</a> | |||
{' - '} | |||
<a href="https://about.sonarcloud.io/contact/">{translate('footer.help')}</a> | |||
<a href="https://about.sonarcloud.io/contact/"> | |||
{translate('footer.help')} | |||
</a> | |||
{' - '} | |||
<Link to="/about">{translate('footer.about')}</Link> | |||
<Link to="/about"> | |||
{translate('footer.about')} | |||
</Link> | |||
</div> | |||
</div> | |||
); |
@@ -34,20 +34,26 @@ export default function MarkdownHelp() { | |||
<tbody> | |||
<tr> | |||
<td>*this text is bold*</td> | |||
<td className="markdown"><strong>this text is bold</strong></td> | |||
<td className="markdown"> | |||
<strong>this text is bold</strong> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td>{'http://sonarqube.org'}</td> | |||
<td> | |||
{'http://sonarqube.org'} | |||
</td> | |||
<td className="markdown"> | |||
<a href="http://sonarqube.org">{'http://sonarqube.org'}</a> | |||
<a href="http://sonarqube.org"> | |||
{'http://sonarqube.org'} | |||
</a> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td className="text-top"> | |||
[SonarQube™ Home Page](http://www.sonarqube.org) | |||
</td> | |||
<td className="text-top">[SonarQube™ Home Page](http://www.sonarqube.org)</td> | |||
<td className="markdown text-top"> | |||
<a href="http://www.sonarqube.org" target="_blank">SonarQube™ Home Page</a> | |||
<a href="http://www.sonarqube.org" target="_blank"> | |||
SonarQube™ Home Page | |||
</a> | |||
</td> | |||
</tr> | |||
<tr> | |||
@@ -94,15 +100,20 @@ export default function MarkdownHelp() { | |||
</tr> | |||
<tr> | |||
<td className="text-top">``Lists#newArrayList()``</td> | |||
<td className="markdown text-top"><code>Lists#newArrayList()</code></td> | |||
<td className="markdown text-top"> | |||
<code>Lists#newArrayList()</code> | |||
</td> | |||
</tr> | |||
<tr> | |||
<td className="text-top"> | |||
``<br /> | |||
// code on multiple lines<br /> | |||
{'public void foo() {'}<br /> | |||
{'// do some logic here'}<br /> | |||
{'}'}<br /> | |||
{'public void foo() {'} | |||
<br /> | |||
{'// do some logic here'} | |||
<br /> | |||
{'}'} | |||
<br /> | |||
`` | |||
</td> | |||
<td className="markdown text-top"> |
@@ -25,10 +25,10 @@ export default function NotFound() { | |||
return ( | |||
<SimpleContainer> | |||
<h2 className="big-spacer-bottom">The page you were looking for does not exist.</h2> | |||
<p className="spacer-bottom"> | |||
You may have mistyped the address or the page may have moved. | |||
<p className="spacer-bottom">You may have mistyped the address or the page may have moved.</p> | |||
<p> | |||
<Link to="/">Go back to the homepage</Link> | |||
</p> | |||
<p><Link to="/">Go back to the homepage</Link></p> | |||
</SimpleContainer> | |||
); | |||
} |
@@ -41,7 +41,7 @@ class ProjectContainer extends React.PureComponent { | |||
qualifier: string | |||
}, | |||
fetchProject: string => Promise<*>, | |||
receiveComponents: Array<*> => void | |||
receiveComponents: (Array<*>) => void | |||
}; | |||
componentDidMount() { |
@@ -44,7 +44,9 @@ export default class ExtensionNotFound extends React.PureComponent { | |||
<p className="spacer-bottom"> | |||
You may have mistyped the address or the page may have moved. | |||
</p> | |||
<p><Link to="/">Go back to the homepage</Link></p> | |||
<p> | |||
<Link to="/">Go back to the homepage</Link> | |||
</p> | |||
</div> | |||
</div> | |||
); |
@@ -68,7 +68,7 @@ export default class GlobalHelp extends React.PureComponent { | |||
} | |||
}; | |||
renderMenuItem = (section: string) => ( | |||
renderMenuItem = (section: string) => | |||
<li key={section}> | |||
<a | |||
className={classNames({ active: section === this.state.section })} | |||
@@ -77,16 +77,14 @@ export default class GlobalHelp extends React.PureComponent { | |||
onClick={this.handleSectionClick}> | |||
{translate('help.section', section)} | |||
</a> | |||
</li> | |||
); | |||
</li>; | |||
renderMenu = () => ( | |||
renderMenu = () => | |||
<ul className="side-tabs-menu"> | |||
{(this.props.currentUser.isLoggedIn | |||
? ['shortcuts', 'tutorials', 'links'] | |||
: ['shortcuts', 'links']).map(this.renderMenuItem)} | |||
</ul> | |||
); | |||
</ul>; | |||
render() { | |||
return ( | |||
@@ -96,9 +94,10 @@ export default class GlobalHelp extends React.PureComponent { | |||
className="modal modal-medium" | |||
overlayClassName="modal-overlay" | |||
onRequestClose={this.props.onClose}> | |||
<div className="modal-head"> | |||
<h2>{translate('help')}</h2> | |||
<h2> | |||
{translate('help')} | |||
</h2> | |||
</div> | |||
<div className="side-tabs-layout"> | |||
@@ -115,7 +114,6 @@ export default class GlobalHelp extends React.PureComponent { | |||
{translate('close')} | |||
</a> | |||
</div> | |||
</Modal> | |||
); | |||
} |
@@ -27,10 +27,14 @@ type Props = { onClose: () => void }; | |||
export default function LinksHelp({ onClose }: Props) { | |||
return ( | |||
<div> | |||
<h2 className="spacer-top spacer-bottom">{translate('help.section.links')}</h2> | |||
<h2 className="spacer-top spacer-bottom"> | |||
{translate('help.section.links')} | |||
</h2> | |||
<p className="spacer-bottom"> | |||
<a href="http://www.sonarqube.org">{translate('footer.community')}</a> | |||
<a href="http://www.sonarqube.org"> | |||
{translate('footer.community')} | |||
</a> | |||
</p> | |||
<p className="spacer-bottom"> | |||
@@ -52,11 +56,15 @@ export default function LinksHelp({ onClose }: Props) { | |||
</p> | |||
<p className="spacer-bottom"> | |||
<Link to="/web_api" onClick={onClose}>{translate('footer.web_api')}</Link> | |||
<Link to="/web_api" onClick={onClose}> | |||
{translate('footer.web_api')} | |||
</Link> | |||
</p> | |||
<p> | |||
<Link to="/about" onClick={onClose}>{translate('footer.about')}</Link> | |||
<Link to="/about" onClick={onClose}> | |||
{translate('footer.about')} | |||
</Link> | |||
</p> | |||
</div> | |||
); |
@@ -27,34 +27,50 @@ type Props = { onClose: () => void }; | |||
export default function LinksHelpSonarCloud({ onClose }: Props) { | |||
return ( | |||
<div> | |||
<h2 className="spacer-top spacer-bottom">{translate('help.section.links')}</h2> | |||
<h2 className="spacer-top spacer-bottom"> | |||
{translate('help.section.links')} | |||
</h2> | |||
<p className="spacer-bottom"> | |||
<a href="https://about.sonarcloud.io/news/">{translate('footer.news')}</a> | |||
<a href="https://about.sonarcloud.io/news/"> | |||
{translate('footer.news')} | |||
</a> | |||
</p> | |||
<p className="spacer-bottom"> | |||
<a href="https://about.sonarcloud.io/terms.pdf">{translate('footer.terms')}</a> | |||
<a href="https://about.sonarcloud.io/terms.pdf"> | |||
{translate('footer.terms')} | |||
</a> | |||
</p> | |||
<p className="spacer-bottom"> | |||
<a href="https://twitter.com/sonarqube">{translate('footer.twitter')}</a> | |||
<a href="https://twitter.com/sonarqube"> | |||
{translate('footer.twitter')} | |||
</a> | |||
</p> | |||
<p className="spacer-bottom"> | |||
<a href="https://about.sonarcloud.io/get-started/">{translate('footer.get_started')}</a> | |||
<a href="https://about.sonarcloud.io/get-started/"> | |||
{translate('footer.get_started')} | |||
</a> | |||
</p> | |||
<p className="spacer-bottom"> | |||
<a href="https://about.sonarcloud.io/contact/">{translate('footer.help')}</a> | |||
<a href="https://about.sonarcloud.io/contact/"> | |||
{translate('footer.help')} | |||
</a> | |||
</p> | |||
<p className="spacer-bottom"> | |||
<Link to="/web_api" onClick={onClose}>{translate('footer.web_api')}</Link> | |||
<Link to="/web_api" onClick={onClose}> | |||
{translate('footer.web_api')} | |||
</Link> | |||
</p> | |||
<p> | |||
<Link to="/about" onClick={onClose}>{translate('footer.about')}</Link> | |||
<Link to="/about" onClick={onClose}> | |||
{translate('footer.about')} | |||
</Link> | |||
</p> | |||
</div> | |||
); |
@@ -24,12 +24,16 @@ import { translate } from '../../../helpers/l10n'; | |||
export default function ShortcutsHelp() { | |||
return ( | |||
<div> | |||
<h2 className="spacer-top spacer-bottom">{translate('help.section.shortcuts')}</h2> | |||
<h2 className="spacer-top spacer-bottom"> | |||
{translate('help.section.shortcuts')} | |||
</h2> | |||
<div className="columns"> | |||
<div className="column-half"> | |||
<div className="spacer-bottom"> | |||
<h3 className="shortcuts-section-title">{translate('shortcuts.section.global')}</h3> | |||
<h3 className="shortcuts-section-title"> | |||
{translate('shortcuts.section.global')} | |||
</h3> | |||
<ul className="shortcuts-list"> | |||
<li> | |||
<span className="shortcut-button spacer-right">s</span> | |||
@@ -42,7 +46,9 @@ export default function ShortcutsHelp() { | |||
</ul> | |||
</div> | |||
<h3 className="shortcuts-section-title">{translate('shortcuts.section.rules')}</h3> | |||
<h3 className="shortcuts-section-title"> | |||
{translate('shortcuts.section.rules')} | |||
</h3> | |||
<ul className="shortcuts-list"> | |||
<li> | |||
<span className="shortcut-button little-spacer-right">↑</span> | |||
@@ -69,7 +75,9 @@ export default function ShortcutsHelp() { | |||
</div> | |||
<div className="column-half"> | |||
<h3 className="shortcuts-section-title">{translate('shortcuts.section.issues')}</h3> | |||
<h3 className="shortcuts-section-title"> | |||
{translate('shortcuts.section.issues')} | |||
</h3> | |||
<ul className="shortcuts-list"> | |||
<li> | |||
<span className="shortcut-button little-spacer-right">↑</span> |
@@ -31,8 +31,12 @@ export default function TutorialsHelp({ onTutorialSelect }: Props) { | |||
return ( | |||
<div> | |||
<h2 className="spacer-top spacer-bottom">{translate('help.section.tutorials')}</h2> | |||
<a href="#" onClick={handleClick}>{translate('tutorials.onboarding')}</a> | |||
<h2 className="spacer-top spacer-bottom"> | |||
{translate('help.section.tutorials')} | |||
</h2> | |||
<a href="#" onClick={handleClick}> | |||
{translate('tutorials.onboarding')} | |||
</a> | |||
</div> | |||
); | |||
} |
@@ -61,8 +61,12 @@ class ComponentNavBreadcrumbs extends React.PureComponent { | |||
to={{ pathname: '/dashboard', query: { id: item.key } }} | |||
className="link-base-color"> | |||
{index === breadcrumbs.length - 1 | |||
? <strong>{itemName}</strong> | |||
: <span>{itemName}</span>} | |||
? <strong> | |||
{itemName} | |||
</strong> | |||
: <span> | |||
{itemName} | |||
</span>} | |||
</Link> | |||
{index < breadcrumbs.length - 1 && <span className="slash-separator" />} | |||
</span> | |||
@@ -93,8 +97,8 @@ class ComponentNavBreadcrumbs extends React.PureComponent { | |||
} | |||
const mapStateToProps = (state, ownProps) => ({ | |||
organization: ownProps.component.organization && | |||
getOrganizationByKey(state, ownProps.component.organization), | |||
organization: | |||
ownProps.component.organization && getOrganizationByKey(state, ownProps.component.organization), | |||
shouldOrganizationBeDisplayed: areThereCustomOrganizations(state) | |||
}); | |||
@@ -39,8 +39,7 @@ export default class ComponentNavMeta extends React.PureComponent { | |||
: translate('component_navigation.status.in_progress'); | |||
metaList.push( | |||
<li key="isInProgress" data-toggle="tooltip" title={tooltip}> | |||
<i className="spinner" style={{ marginTop: '-1px' }} /> | |||
{' '} | |||
<i className="spinner" style={{ marginTop: '-1px' }} />{' '} | |||
<span className="text-info">{translate('background_task.status.IN_PROGRESS')}</span> | |||
</li> | |||
); | |||
@@ -59,22 +58,34 @@ export default class ComponentNavMeta extends React.PureComponent { | |||
: translate('component_navigation.status.failed'); | |||
metaList.push( | |||
<li key="isFailed" data-toggle="tooltip" title={tooltip}> | |||
<span className="badge badge-danger">{translate('background_task.status.FAILED')}</span> | |||
<span className="badge badge-danger"> | |||
{translate('background_task.status.FAILED')} | |||
</span> | |||
</li> | |||
); | |||
} | |||
if (this.props.analysisDate) { | |||
metaList.push(<li key="analysisDate">{moment(this.props.analysisDate).format('LLL')}</li>); | |||
metaList.push( | |||
<li key="analysisDate"> | |||
{moment(this.props.analysisDate).format('LLL')} | |||
</li> | |||
); | |||
} | |||
if (this.props.version) { | |||
metaList.push(<li key="version">Version {this.props.version}</li>); | |||
metaList.push( | |||
<li key="version"> | |||
Version {this.props.version} | |||
</li> | |||
); | |||
} | |||
return ( | |||
<div className="navbar-context-meta"> | |||
<ul className="list-inline">{metaList}</ul> | |||
<ul className="list-inline"> | |||
{metaList} | |||
</ul> | |||
</div> | |||
); | |||
} |
@@ -43,7 +43,9 @@ class GlobalNavBranding extends React.PureComponent { | |||
'navbar-brand' + (this.props.customLogoUrl ? ' navbar-brand-custom' : ''); | |||
return ( | |||
<div className="navbar-header"> | |||
<Link to={homeController} className={homeLinkClassName}>{this.renderLogo()}</Link> | |||
<Link to={homeController} className={homeLinkClassName}> | |||
{this.renderLogo()} | |||
</Link> | |||
</div> | |||
); | |||
} |
@@ -61,9 +61,10 @@ export default class GlobalNavMenu extends React.PureComponent { | |||
} | |||
renderIssuesLink() { | |||
const query = this.props.currentUser.isLoggedIn && isMySet() | |||
? { resolved: 'false', myIssues: 'true' } | |||
: { resolved: 'false' }; | |||
const query = | |||
this.props.currentUser.isLoggedIn && isMySet() | |||
? { resolved: 'false', myIssues: 'true' } | |||
: { resolved: 'false' }; | |||
const active = this.props.location.pathname === 'issues'; | |||
return ( | |||
<li> | |||
@@ -120,7 +121,9 @@ export default class GlobalNavMenu extends React.PureComponent { | |||
renderGlobalPageLink = ({ key, name }) => { | |||
return ( | |||
<li key={key}> | |||
<Link to={`/extension/${key}`}>{name}</Link> | |||
<Link to={`/extension/${key}`}> | |||
{name} | |||
</Link> | |||
</li> | |||
); | |||
}; |
@@ -123,7 +123,9 @@ export default class GlobalNavUser extends React.PureComponent { | |||
<ul className="dropdown-menu dropdown-menu-right"> | |||
<li className="dropdown-item"> | |||
<div className="text-ellipsis text-muted" title={currentUser.name}> | |||
<strong>{currentUser.name}</strong> | |||
<strong> | |||
{currentUser.name} | |||
</strong> | |||
</div> | |||
{currentUser.email != null && | |||
<div | |||
@@ -134,22 +136,30 @@ export default class GlobalNavUser extends React.PureComponent { | |||
</li> | |||
<li className="divider" /> | |||
<li> | |||
<Link to="/account" onClick={this.closeDropdown}>{translate('my_account.page')}</Link> | |||
<Link to="/account" onClick={this.closeDropdown}> | |||
{translate('my_account.page')} | |||
</Link> | |||
</li> | |||
{hasOrganizations && <li role="separator" className="divider" />} | |||
{hasOrganizations && | |||
<li className="dropdown-header spacer-left">{translate('my_organizations')}</li>} | |||
<li className="dropdown-header spacer-left"> | |||
{translate('my_organizations')} | |||
</li>} | |||
{hasOrganizations && | |||
sortBy(organizations, org => org.name.toLowerCase()).map(organization => ( | |||
sortBy(organizations, org => org.name.toLowerCase()).map(organization => | |||
<li key={organization.key}> | |||
<OrganizationLink organization={organization} onClick={this.closeDropdown}> | |||
<span className="spacer-left">{organization.name}</span> | |||
<span className="spacer-left"> | |||
{organization.name} | |||
</span> | |||
</OrganizationLink> | |||
</li> | |||
))} | |||
)} | |||
{hasOrganizations && <li role="separator" className="divider" />} | |||
<li> | |||
<a onClick={this.handleLogout} href="#">{translate('layout.logout')}</a> | |||
<a onClick={this.handleLogout} href="#"> | |||
{translate('layout.logout')} | |||
</a> | |||
</li> | |||
</ul>} | |||
</li> |
@@ -52,7 +52,9 @@ class SettingsNav extends React.PureComponent { | |||
renderExtension = ({ key, name }) => { | |||
return ( | |||
<li key={key}> | |||
<Link to={`/admin/extension/${key}`} activeClassName="active">{name}</Link> | |||
<Link to={`/admin/extension/${key}`} activeClassName="active"> | |||
{name} | |||
</Link> | |||
</li> | |||
); | |||
}; |
@@ -294,7 +294,7 @@ export default class Search extends React.PureComponent { | |||
this.nodes[component] = node; | |||
}; | |||
renderResult = (component: Component) => ( | |||
renderResult = (component: Component) => | |||
<SearchResult | |||
appState={this.props.appState} | |||
component={component} | |||
@@ -305,14 +305,12 @@ export default class Search extends React.PureComponent { | |||
organizations={this.state.organizations} | |||
projects={this.state.projects} | |||
selected={this.state.selected === component.key} | |||
/> | |||
); | |||
/>; | |||
renderNoResults = () => ( | |||
renderNoResults = () => | |||
<div className="navbar-search-no-results"> | |||
{translateWithParameters('no_results_for_x', this.state.query)} | |||
</div> | |||
); | |||
</div>; | |||
render() { | |||
const dropdownClassName = classNames('dropdown', 'navbar-search', { open: this.state.open }); |
@@ -93,7 +93,9 @@ export default class SearchResult extends React.PureComponent { | |||
const organization = this.props.organizations[component.organization]; | |||
return organization | |||
? <div className="navbar-search-item-right text-muted-2">{organization.name}</div> | |||
? <div className="navbar-search-item-right text-muted-2"> | |||
{organization.name} | |||
</div> | |||
: null; | |||
}; | |||
@@ -104,7 +106,9 @@ export default class SearchResult extends React.PureComponent { | |||
const project = this.props.projects[component.project]; | |||
return project | |||
? <div className="navbar-search-item-right text-muted-2">{project.name}</div> | |||
? <div className="navbar-search-item-right text-muted-2"> | |||
{project.name} | |||
</div> | |||
: null; | |||
}; | |||
@@ -127,7 +131,6 @@ export default class SearchResult extends React.PureComponent { | |||
onClick={this.props.onClose} | |||
onMouseEnter={this.handleMouseEnter} | |||
to={getProjectUrl(component.key)}> | |||
<span className="navbar-search-item-icons little-spacer-right"> | |||
{component.isFavorite && <FavoriteIcon favorite={true} size={12} />} | |||
{!component.isFavorite && component.isRecentlyBrowsed && <ClockIcon size={12} />} | |||
@@ -139,11 +142,12 @@ export default class SearchResult extends React.PureComponent { | |||
className="navbar-search-item-match" | |||
dangerouslySetInnerHTML={{ __html: component.match }} | |||
/> | |||
: <span className="navbar-search-item-match">{component.name}</span>} | |||
: <span className="navbar-search-item-match"> | |||
{component.name} | |||
</span>} | |||
{this.renderOrganization(component)} | |||
{this.renderProject(component)} | |||
</Link> | |||
</Tooltip> | |||
</li> |
@@ -77,7 +77,9 @@ export default class SearchResults extends React.PureComponent { | |||
}); | |||
return renderedComponents.length > 0 | |||
? <ul className="menu">{renderedComponents}</ul> | |||
? <ul className="menu"> | |||
{renderedComponents} | |||
</ul> | |||
: this.props.renderNoResults(); | |||
} | |||
} |
@@ -69,7 +69,9 @@ export default class SearchShowMore extends React.PureComponent { | |||
) | |||
}} | |||
/> | |||
<span>{translate('show_more')}</span> | |||
<span> | |||
{translate('show_more')} | |||
</span> | |||
</a> | |||
</DeferredSpinner> | |||
</li> |
@@ -32,7 +32,10 @@ it('renders different components and dividers between them', () => { | |||
onMoreClick={jest.fn()} | |||
onSelect={jest.fn()} | |||
renderNoResults={() => <div />} | |||
renderResult={component => <span key={component.key}>{component.name}</span>} | |||
renderResult={component => | |||
<span key={component.key}> | |||
{component.name} | |||
</span>} | |||
results={{ | |||
TRK: [component('foo'), component('bar')], | |||
BRC: [component('qwe', 'BRC'), component('qux', 'BRC')], | |||
@@ -54,7 +57,10 @@ it('renders "Show More" link', () => { | |||
onMoreClick={jest.fn()} | |||
onSelect={jest.fn()} | |||
renderNoResults={() => <div />} | |||
renderResult={component => <span key={component.key}>{component.name}</span>} | |||
renderResult={component => | |||
<span key={component.key}> | |||
{component.name} | |||
</span>} | |||
results={{ | |||
TRK: [component('foo'), component('bar')], | |||
BRC: [component('qwe', 'BRC'), component('qux', 'BRC')] |
@@ -105,14 +105,16 @@ | |||
height: 0; | |||
} | |||
50%, 100% { | |||
50%, | |||
100% { | |||
width: 100%; | |||
height: 100%; | |||
} | |||
} | |||
@keyframes border-bottom-border { | |||
0%, 50% { | |||
0%, | |||
50% { | |||
width: 0; | |||
height: 0; | |||
border-width: 0; |
@@ -132,8 +132,12 @@ const startReactApp = () => { | |||
<Route component={DefaultHelmetContainer}> | |||
<Route component={LocalizationContainer}> | |||
<Route component={SimpleContainer}> | |||
<Route path="maintenance">{maintenanceRoutes}</Route> | |||
<Route path="setup">{setupRoutes}</Route> | |||
<Route path="maintenance"> | |||
{maintenanceRoutes} | |||
</Route> | |||
<Route path="setup"> | |||
{setupRoutes} | |||
</Route> | |||
</Route> | |||
<Route component={MigrationContainer}> | |||
@@ -142,7 +146,6 @@ const startReactApp = () => { | |||
</Route> | |||
<Route path="/" component={App}> | |||
<IndexRoute component={Landing} /> | |||
<Route component={GlobalContainer}> |
@@ -26,9 +26,13 @@ const link = 'https://redirect.sonarsource.com/doc/issues.html'; | |||
export default function AboutCleanCode() { | |||
return ( | |||
<div className="boxed-group"> | |||
<h2>{translate('about_page.clean_code')}</h2> | |||
<h2> | |||
{translate('about_page.clean_code')} | |||
</h2> | |||
<div className="boxed-group-inner"> | |||
<p className="about-page-text">{translate('about_page.clean_code.text')}</p> | |||
<p className="about-page-text"> | |||
{translate('about_page.clean_code.text')} | |||
</p> | |||
<ReadMore link={link} /> | |||
</div> | |||
</div> |
@@ -48,18 +48,26 @@ const half = (languages.length + 1) / 2; | |||
export default function AboutLanguages() { | |||
return ( | |||
<div className="boxed-group"> | |||
<h2>{translate('about_page.languages')}</h2> | |||
<h2> | |||
{translate('about_page.languages')} | |||
</h2> | |||
<div className="boxed-group-inner"> | |||
<p className="about-page-text">{translate('about_page.languages.text')}</p> | |||
<p className="about-page-text"> | |||
{translate('about_page.languages.text')} | |||
</p> | |||
<ul className="about-page-languages"> | |||
{languages.slice(0, half).map((language, index) => ( | |||
{languages.slice(0, half).map((language, index) => | |||
<li key={index}> | |||
<a href={languages[index].url}>{languages[index].name}</a> | |||
<a href={languages[index].url}> | |||
{languages[index].name} | |||
</a> | |||
<br /> | |||
{index + half < languages.length && | |||
<a href={languages[index + half].url}>{languages[index + half].name}</a>} | |||
<a href={languages[index + half].url}> | |||
{languages[index + half].name} | |||
</a>} | |||
</li> | |||
))} | |||
)} | |||
</ul> | |||
</div> | |||
</div> |
@@ -26,9 +26,13 @@ const link = 'https://redirect.sonarsource.com/doc/fix-the-leak.html'; | |||
export default function AboutLeakPeriod() { | |||
return ( | |||
<div className="boxed-group"> | |||
<h2>{translate('about_page.fix_the_leak')}</h2> | |||
<h2> | |||
{translate('about_page.fix_the_leak')} | |||
</h2> | |||
<div className="boxed-group-inner"> | |||
<p className="about-page-text">{translate('about_page.fix_the_leak.text')}</p> | |||
<p className="about-page-text"> | |||
{translate('about_page.fix_the_leak.text')} | |||
</p> | |||
<ReadMore link={link} /> | |||
</div> | |||
</div> |
@@ -26,9 +26,13 @@ const link = 'https://redirect.sonarsource.com/doc/quality-gates.html'; | |||
export default function AboutQualityGates() { | |||
return ( | |||
<div className="boxed-group"> | |||
<h2>{translate('about_page.quality_gates')}</h2> | |||
<h2> | |||
{translate('about_page.quality_gates')} | |||
</h2> | |||
<div className="boxed-group-inner"> | |||
<p className="about-page-text">{translate('about_page.quality_gates.text')}</p> | |||
<p className="about-page-text"> | |||
{translate('about_page.quality_gates.text')} | |||
</p> | |||
<ReadMore link={link} /> | |||
</div> | |||
</div> |
@@ -26,33 +26,38 @@ import CodeSmellIcon from '../../../components/icons-components/CodeSmellIcon'; | |||
export default function AboutQualityModel() { | |||
return ( | |||
<div className="boxed-group about-quality-model"> | |||
<h2>{translate('about_page.quality_model')}</h2> | |||
<h2> | |||
{translate('about_page.quality_model')} | |||
</h2> | |||
<div className="boxed-group-inner clearfix"> | |||
<div className="flex-columns"> | |||
<div className="flex-column flex-column-third"> | |||
<div className="pull-left little-spacer-right"><BugIcon /></div> | |||
<div className="pull-left little-spacer-right"> | |||
<BugIcon /> | |||
</div> | |||
<p className="about-page-text overflow-hidden"> | |||
<strong>{translate('issue.type.BUG.plural')}</strong> | |||
{' '} | |||
<strong>{translate('issue.type.BUG.plural')}</strong>{' '} | |||
{translate('about_page.quality_model.bugs')} | |||
</p> | |||
</div> | |||
<div className="flex-column flex-column-third"> | |||
<div className="pull-left little-spacer-right"><VulnerabilityIcon /></div> | |||
<div className="pull-left little-spacer-right"> | |||
<VulnerabilityIcon /> | |||
</div> | |||
<p className="about-page-text overflow-hidden"> | |||
<strong>{translate('issue.type.VULNERABILITY.plural')}</strong> | |||
{' '} | |||
<strong>{translate('issue.type.VULNERABILITY.plural')}</strong>{' '} | |||
{translate('about_page.quality_model.vulnerabilities')} | |||
</p> | |||
</div> | |||
<div className="flex-column flex-column-third"> | |||
<div className="pull-left little-spacer-right"><CodeSmellIcon /></div> | |||
<div className="pull-left little-spacer-right"> | |||
<CodeSmellIcon /> | |||
</div> | |||
<p className="about-page-text overflow-hidden"> | |||
<strong>{translate('issue.type.CODE_SMELL.plural')}</strong> | |||
{' '} | |||
<strong>{translate('issue.type.CODE_SMELL.plural')}</strong>{' '} | |||
{translate('about_page.quality_model.code_smells')} | |||
</p> | |||
</div> |
@@ -26,15 +26,18 @@ import CodeSmellIconForSonarQubeDotCom from './CodeSmellIconForSonarQubeDotCom'; | |||
export default function AboutQualityModelForSonarQubeDotCom() { | |||
return ( | |||
<div className="boxed-group about-quality-model sqcom-about-quality-model"> | |||
<h2>{translate('about_page.quality_model')}</h2> | |||
<h2> | |||
{translate('about_page.quality_model')} | |||
</h2> | |||
<div className="boxed-group-inner clearfix"> | |||
<div className="flex-columns"> | |||
<div className="flex-column flex-column-third"> | |||
<div className="pull-left little-spacer-right"><BugIconForSonarQubeDotCom /></div> | |||
<div className="pull-left little-spacer-right"> | |||
<BugIconForSonarQubeDotCom /> | |||
</div> | |||
<p className="about-page-text overflow-hidden"> | |||
<strong>{translate('issue.type.BUG.plural')}</strong> | |||
{' '} | |||
<strong>{translate('issue.type.BUG.plural')}</strong>{' '} | |||
{translate('about_page.quality_model.bugs')} | |||
</p> | |||
</div> | |||
@@ -44,8 +47,7 @@ export default function AboutQualityModelForSonarQubeDotCom() { | |||
<VulnerabilityIconForSonarQubeDotCom /> | |||
</div> | |||
<p className="about-page-text overflow-hidden"> | |||
<strong>{translate('issue.type.VULNERABILITY.plural')}</strong> | |||
{' '} | |||
<strong>{translate('issue.type.VULNERABILITY.plural')}</strong>{' '} | |||
{translate('about_page.quality_model.vulnerabilities')} | |||
</p> | |||
</div> | |||
@@ -55,8 +57,7 @@ export default function AboutQualityModelForSonarQubeDotCom() { | |||
<CodeSmellIconForSonarQubeDotCom /> | |||
</div> | |||
<p className="about-page-text overflow-hidden"> | |||
<strong>{translate('issue.type.CODE_SMELL.plural')}</strong> | |||
{' '} | |||
<strong>{translate('issue.type.CODE_SMELL.plural')}</strong>{' '} | |||
{translate('about_page.quality_model.code_smells')} | |||
</p> | |||
</div> |
@@ -68,7 +68,9 @@ export default function AboutRulesForSonarQubeDotCom(props: Props) { | |||
className="sqcom-about-rules-link"> | |||
C# | |||
</Link> | |||
<Link to={getRulesUrl(null, organization)} className="button">And More</Link> | |||
<Link to={getRulesUrl(null, organization)} className="button"> | |||
And More | |||
</Link> | |||
</div> | |||
</div> | |||
); |
@@ -50,11 +50,15 @@ const scanners = [ | |||
export default function AboutScanners() { | |||
return ( | |||
<div className="boxed-group"> | |||
<h2>{translate('about_page.scanners')}</h2> | |||
<h2> | |||
{translate('about_page.scanners')} | |||
</h2> | |||
<div className="boxed-group-inner"> | |||
<p className="about-page-text">{translate('about_page.scanners.text')}</p> | |||
<p className="about-page-text"> | |||
{translate('about_page.scanners.text')} | |||
</p> | |||
<div className="about-page-analyzers"> | |||
{scanners.map(scanner => ( | |||
{scanners.map(scanner => | |||
<a key={scanner.key} className="about-page-analyzer-box" href={scanner.link}> | |||
<img | |||
src={`${window.baseUrl}/images/scanner-logos/${scanner.key}.svg`} | |||
@@ -62,7 +66,7 @@ export default function AboutScanners() { | |||
alt={translate('about_page.scanners', scanner.key)} | |||
/> | |||
</a> | |||
))} | |||
)} | |||
</div> | |||
</div> | |||
</div> |
@@ -43,9 +43,13 @@ export default function AboutStandards(props: Props) { | |||
return ( | |||
<div className="boxed-group"> | |||
<h2>{translate('about_page.standards')}</h2> | |||
<h2> | |||
{translate('about_page.standards')} | |||
</h2> | |||
<div className="boxed-group-inner"> | |||
<p className="about-page-text">{translate('about_page.standards.text')}</p> | |||
<p className="about-page-text"> | |||
{translate('about_page.standards.text')} | |||
</p> | |||
<div className="spacer-top"> | |||
<ul className="list-inline"> |
@@ -50,7 +50,9 @@ export default function EntryIssueTypes({ bugs, codeSmells, loading, vulnerabili | |||
</Link> | |||
</td> | |||
<td> | |||
<span className="little-spacer-right"><BugIcon /></span> | |||
<span className="little-spacer-right"> | |||
<BugIcon /> | |||
</span> | |||
{translate('issue.type.BUG.plural')} | |||
</td> | |||
</tr> | |||
@@ -67,7 +69,9 @@ export default function EntryIssueTypes({ bugs, codeSmells, loading, vulnerabili | |||
</Link> | |||
</td> | |||
<td> | |||
<span className="little-spacer-right"><VulnerabilityIcon /></span> | |||
<span className="little-spacer-right"> | |||
<VulnerabilityIcon /> | |||
</span> | |||
{translate('issue.type.VULNERABILITY.plural')} | |||
</td> | |||
</tr> | |||
@@ -80,7 +84,9 @@ export default function EntryIssueTypes({ bugs, codeSmells, loading, vulnerabili | |||
</Link> | |||
</td> | |||
<td> | |||
<span className="little-spacer-right"><CodeSmellIcon /></span> | |||
<span className="little-spacer-right"> | |||
<CodeSmellIcon /> | |||
</span> | |||
{translate('issue.type.CODE_SMELL.plural')} | |||
</td> | |||
</tr> |
@@ -55,7 +55,9 @@ export default function EntryIssueTypesForSonarQubeDotCom({ | |||
</Link> | |||
</td> | |||
<td> | |||
<span className="little-spacer-right"><BugIconForSonarQubeDotCom /></span> | |||
<span className="little-spacer-right"> | |||
<BugIconForSonarQubeDotCom /> | |||
</span> | |||
{translate('issue.type.BUG.plural')} | |||
</td> | |||
</tr> | |||
@@ -72,7 +74,9 @@ export default function EntryIssueTypesForSonarQubeDotCom({ | |||
</Link> | |||
</td> | |||
<td> | |||
<span className="little-spacer-right"><VulnerabilityIconForSonarQubeDotCom /></span> | |||
<span className="little-spacer-right"> | |||
<VulnerabilityIconForSonarQubeDotCom /> | |||
</span> | |||
{translate('issue.type.VULNERABILITY.plural')} | |||
</td> | |||
</tr> | |||
@@ -85,7 +89,9 @@ export default function EntryIssueTypesForSonarQubeDotCom({ | |||
</Link> | |||
</td> | |||
<td> | |||
<span className="little-spacer-right"><CodeSmellIconForSonarQubeDotCom /></span> | |||
<span className="little-spacer-right"> | |||
<CodeSmellIconForSonarQubeDotCom /> | |||
</span> | |||
{translate('issue.type.CODE_SMELL.plural')} | |||
</td> | |||
</tr> |
@@ -29,7 +29,9 @@ export default class ReadMore extends React.PureComponent { | |||
return ( | |||
<div className="big-spacer-top"> | |||
<a className="about-page-link-more" href={this.props.link} target="_blank"> | |||
<span>{translate('about_page.read_more')}</span> | |||
<span> | |||
{translate('about_page.read_more')} | |||
</span> | |||
</a> | |||
</div> | |||
); |
@@ -22,7 +22,8 @@ | |||
align-items: center; | |||
} | |||
.sqcom-about-page-intro {} | |||
.sqcom-about-page-intro { | |||
} | |||
.sqcom-about-page-intro > h1 { | |||
line-height: 56px; |
@@ -81,7 +81,12 @@ export default class Password extends Component { | |||
{translate('my_profile.password.changed')} | |||
</div>} | |||
{errors && errors.map((e, i) => <div key={i} className="alert alert-danger">{e}</div>)} | |||
{errors && | |||
errors.map((e, i) => | |||
<div key={i} className="alert alert-danger"> | |||
{e} | |||
</div> | |||
)} | |||
<div className="modal-field"> | |||
<label htmlFor="old_password"> |
@@ -33,7 +33,9 @@ export default class UserCard extends React.PureComponent { | |||
<div id="avatar" className="pull-left account-user-avatar"> | |||
<Avatar email={user.email} name={user.name} size={60} /> | |||
</div> | |||
<h1 id="name" className="pull-left">{user.name}</h1> | |||
<h1 id="name" className="pull-left"> | |||
{user.name} | |||
</h1> | |||
</div> | |||
); | |||
} |
@@ -53,11 +53,13 @@ function GlobalNotifications(props: Props) { | |||
<thead> | |||
<tr> | |||
<th /> | |||
{props.channels.map(channel => ( | |||
{props.channels.map(channel => | |||
<th key={channel} className="text-center"> | |||
<h4>{translate('notification.channel', channel)}</h4> | |||
<h4> | |||
{translate('notification.channel', channel)} | |||
</h4> | |||
</th> | |||
))} | |||
)} | |||
</tr> | |||
</thead> | |||
@@ -56,10 +56,12 @@ export default class NotificationsList extends React.PureComponent { | |||
return ( | |||
<tbody> | |||
{types.map(type => ( | |||
{types.map(type => | |||
<tr key={type}> | |||
<td>{translate('notification.dispatcher', type)}</td> | |||
{channels.map(channel => ( | |||
<td> | |||
{translate('notification.dispatcher', type)} | |||
</td> | |||
{channels.map(channel => | |||
<td key={channel} className="text-center"> | |||
<Checkbox | |||
checked={this.isEnabled(type, channel)} | |||
@@ -67,9 +69,9 @@ export default class NotificationsList extends React.PureComponent { | |||
onCheck={checked => this.handleCheck(type, channel, checked)} | |||
/> | |||
</td> | |||
))} | |||
)} | |||
</tr> | |||
))} | |||
)} | |||
</tbody> | |||
); | |||
} |
@@ -81,14 +81,18 @@ class ProjectNotifications extends React.PureComponent { | |||
<Organization organizationKey={project.organization} /> | |||
</span> | |||
<h4 className="display-inline-block"> | |||
<Link to={getProjectUrl(project.key)}>{project.name}</Link> | |||
<Link to={getProjectUrl(project.key)}> | |||
{project.name} | |||
</Link> | |||
</h4> | |||
</th> | |||
{channels.map(channel => ( | |||
{channels.map(channel => | |||
<th key={channel} className="text-center"> | |||
<h4>{translate('notification.channel', channel)}</h4> | |||
<h4> | |||
{translate('notification.channel', channel)} | |||
</h4> | |||
</th> | |||
))} | |||
)} | |||
</tr> | |||
</thead> | |||
<NotificationsList |
@@ -100,7 +100,9 @@ class Projects extends React.PureComponent { | |||
return ( | |||
<span> | |||
<Organization organizationKey={option.organization} link={false} /> | |||
<strong>{option.label}</strong> | |||
<strong> | |||
{option.label} | |||
</strong> | |||
</span> | |||
); | |||
}; | |||
@@ -122,9 +124,7 @@ class Projects extends React.PureComponent { | |||
{allProjects.map(project => <ProjectNotifications key={project.key} project={project} />)} | |||
<div className="spacer-top panel bg-muted"> | |||
<span className="text-middle spacer-right"> | |||
Set notifications for: | |||
</span> | |||
<span className="text-middle spacer-right">Set notifications for:</span> | |||
<Select.Async | |||
autoload={false} | |||
cache={false} |
@@ -123,7 +123,9 @@ class CreateOrganizationForm extends React.PureComponent { | |||
overlayClassName="modal-overlay" | |||
onRequestClose={this.closeForm}> | |||
<header className="modal-head"> | |||
<h2>{translate('my_account.create_organization')}</h2> | |||
<h2> | |||
{translate('my_account.create_organization')} | |||
</h2> | |||
</header> | |||
<form onSubmit={this.handleSubmit}> |
@@ -50,7 +50,9 @@ export default function OrganizationCard(props: Props) { | |||
</OrganizationLink> | |||
</h3> | |||
<div className="account-project-key">{organization.key}</div> | |||
<div className="account-project-key"> | |||
{organization.key} | |||
</div> | |||
{!!organization.description && | |||
<div className="account-project-description"> |
@@ -32,11 +32,11 @@ export default function OrganizationsList(props: Props) { | |||
<ul className="account-projects-list"> | |||
{sortBy(props.organizations, organization => | |||
organization.name.toLocaleLowerCase() | |||
).map(organization => ( | |||
).map(organization => | |||
<li key={organization.key}> | |||
<OrganizationCard organization={organization} /> | |||
</li> | |||
))} | |||
)} | |||
</ul> | |||
); | |||
} |
@@ -71,7 +71,9 @@ class UserOrganizations extends React.PureComponent { | |||
<Helmet title={translate('my_account.organizations')} /> | |||
<header className="page-header"> | |||
<h2 className="page-title">{translate('my_account.organizations')}</h2> | |||
<h2 className="page-title"> | |||
{translate('my_account.organizations')} | |||
</h2> | |||
{canCreateOrganizations && | |||
<div className="page-actions"> | |||
<Link to="/account/organizations/create" className="button"> |
@@ -70,7 +70,9 @@ export default class UserExternalIdentity extends React.PureComponent { | |||
if (!identityProvider) { | |||
return ( | |||
<div> | |||
{user.externalProvider}{': '}{user.externalIdentity} | |||
{user.externalProvider} | |||
{': '} | |||
{user.externalIdentity} | |||
</div> | |||
); | |||
} | |||
@@ -84,8 +86,7 @@ export default class UserExternalIdentity extends React.PureComponent { | |||
width="14" | |||
height="14" | |||
alt={identityProvider.name} | |||
/> | |||
{' '} | |||
/>{' '} | |||
{user.externalIdentity} | |||
</div> | |||
); |
@@ -30,13 +30,15 @@ export default class UserGroups extends React.PureComponent { | |||
return ( | |||
<div> | |||
<h2 className="spacer-bottom">{translate('my_profile.groups')}</h2> | |||
<h2 className="spacer-bottom"> | |||
{translate('my_profile.groups')} | |||
</h2> | |||
<ul id="groups"> | |||
{groups.map(group => ( | |||
{groups.map(group => | |||
<li key={group} className="little-spacer-bottom" title={group}> | |||
{group} | |||
</li> | |||
))} | |||
)} | |||
</ul> | |||
</div> | |||
); |
@@ -31,7 +31,9 @@ export default class UserScmAccounts extends React.PureComponent { | |||
return ( | |||
<div> | |||
<h2 className="spacer-bottom">{translate('my_profile.scm_accounts')}</h2> | |||
<h2 className="spacer-bottom"> | |||
{translate('my_profile.scm_accounts')} | |||
</h2> | |||
<ul id="scm-accounts"> | |||
<li className="little-spacer-bottom text-ellipsis" title={user.login}> | |||
{user.login} | |||
@@ -42,11 +44,11 @@ export default class UserScmAccounts extends React.PureComponent { | |||
{user.email} | |||
</li>} | |||
{scmAccounts.map(scmAccount => ( | |||
{scmAccounts.map(scmAccount => | |||
<li key={scmAccount} className="little-spacer-bottom" title={scmAccount}> | |||
{scmAccount} | |||
</li> | |||
))} | |||
)} | |||
</ul> | |||
</div> | |||
); |
@@ -65,7 +65,7 @@ export default class ProjectCard extends React.PureComponent { | |||
{links.length > 0 && | |||
<div className="account-project-links"> | |||
<ul className="list-inline"> | |||
{links.map(link => ( | |||
{links.map(link => | |||
<li key={link.type}> | |||
<a | |||
className="link-with-icon" | |||
@@ -76,11 +76,13 @@ export default class ProjectCard extends React.PureComponent { | |||
<i className={`icon-color-link icon-${link.type}`} /> | |||
</a> | |||
</li> | |||
))} | |||
)} | |||
</ul> | |||
</div>} | |||
<div className="account-project-key">{project.key}</div> | |||
<div className="account-project-key"> | |||
{project.key} | |||
</div> | |||
{!!project.description && | |||
<div className="account-project-description"> |
@@ -46,11 +46,11 @@ export default class Projects extends React.PureComponent { | |||
{projects.length > 0 && | |||
<ul className="account-projects-list"> | |||
{projects.map(project => ( | |||
{projects.map(project => | |||
<li key={project.key}> | |||
<ProjectCard project={project} /> | |||
</li> | |||
))} | |||
)} | |||
</ul>} | |||
{projects.length > 0 && |
@@ -45,7 +45,7 @@ import { translate } from '../../../helpers/l10n'; | |||
type Props = { | |||
component: Object, | |||
location: Object, | |||
fetchOrganizations: Array<string> => string | |||
fetchOrganizations: (Array<string>) => string | |||
}; | |||
type State = { |
@@ -75,8 +75,7 @@ export default class DateFilter extends Component { | |||
ref="minDate" | |||
type="text" | |||
placeholder="From" | |||
/> | |||
{' '} | |||
/>{' '} | |||
<input | |||
className="input-small" | |||
value={maxExecutedAt} |
@@ -72,7 +72,6 @@ export default class ScannerContext extends React.PureComponent { | |||
className="modal modal-large" | |||
overlayClassName="modal-overlay" | |||
onRequestClose={this.props.onClose}> | |||
<div className="modal-head"> | |||
<h2> | |||
{translate('background_tasks.scanner_context')} | |||
@@ -86,7 +85,9 @@ export default class ScannerContext extends React.PureComponent { | |||
<div className="modal-body modal-container"> | |||
{scannerContext != null | |||
? <pre className="js-task-scanner-context">{scannerContext}</pre> | |||
? <pre className="js-task-scanner-context"> | |||
{scannerContext} | |||
</pre> | |||
: <i className="spinner" />} | |||
</div> | |||
@@ -95,7 +96,6 @@ export default class ScannerContext extends React.PureComponent { | |||
{translate('close')} | |||
</a> | |||
</div> | |||
</Modal> | |||
); | |||
} |
@@ -78,9 +78,7 @@ export default class Search extends React.PureComponent { | |||
return ( | |||
<li> | |||
<h6 className="bt-search-form-label"> | |||
Search by Task or Component | |||
</h6> | |||
<h6 className="bt-search-form-label">Search by Task or Component</h6> | |||
<input | |||
onChange={e => this.handleQueryChange(e.target.value)} | |||
@@ -110,16 +108,12 @@ export default class Search extends React.PureComponent { | |||
<section className="big-spacer-top big-spacer-bottom"> | |||
<ul className="bt-search-form"> | |||
<li> | |||
<h6 className="bt-search-form-label"> | |||
Status | |||
</h6> | |||
<h6 className="bt-search-form-label">Status</h6> | |||
<StatusFilter value={status} onChange={this.handleStatusChange.bind(this)} /> | |||
</li> | |||
{types.length > 1 && | |||
<li> | |||
<h6 className="bt-search-form-label"> | |||
Type | |||
</h6> | |||
<h6 className="bt-search-form-label">Type</h6> | |||
<TypesFilter | |||
value={taskType} | |||
types={types} | |||
@@ -128,15 +122,11 @@ export default class Search extends React.PureComponent { | |||
</li>} | |||
{!component && | |||
<li> | |||
<h6 className="bt-search-form-label"> | |||
Only Latest Analysis | |||
</h6> | |||
<h6 className="bt-search-form-label">Only Latest Analysis</h6> | |||
<CurrentsFilter value={currents} onChange={this.handleCurrentsChange.bind(this)} /> | |||
</li>} | |||
<li> | |||
<h6 className="bt-search-form-label"> | |||
Date | |||
</h6> | |||
<h6 className="bt-search-form-label">Date</h6> | |||
<DateFilter | |||
minSubmittedAt={minSubmittedAt} | |||
maxExecutedAt={maxExecutedAt} | |||
@@ -149,8 +139,7 @@ export default class Search extends React.PureComponent { | |||
<li className="bt-search-form-right"> | |||
<button className="js-reload" onClick={this.handleReload.bind(this)} disabled={loading}> | |||
{translate('reload')} | |||
</button> | |||
{' '} | |||
</button>{' '} | |||
<button ref="resetButton" onClick={this.handleReset.bind(this)} disabled={loading}> | |||
{translate('reset_verb')} | |||
</button> |
@@ -74,7 +74,6 @@ export default class Stacktrace extends React.PureComponent { | |||
className="modal modal-large" | |||
overlayClassName="modal-overlay" | |||
onRequestClose={this.props.onClose}> | |||
<div className="modal-head"> | |||
<h2> | |||
{translate('background_tasks.error_stacktrace')} | |||
@@ -90,16 +89,22 @@ export default class Stacktrace extends React.PureComponent { | |||
{loading | |||
? <i className="spinner" /> | |||
: stacktrace | |||
? <div> | |||
<h4 className="spacer-bottom"> | |||
{translate('background_tasks.error_stacktrace')} | |||
</h4> | |||
<pre className="js-task-stacktrace">{stacktrace}</pre> | |||
</div> | |||
: <div> | |||
<h4 className="spacer-bottom">{translate('background_tasks.error_message')}</h4> | |||
<pre className="js-task-error-message">{task.errorMessage}</pre> | |||
</div>} | |||
? <div> | |||
<h4 className="spacer-bottom"> | |||
{translate('background_tasks.error_stacktrace')} | |||
</h4> | |||
<pre className="js-task-stacktrace"> | |||
{stacktrace} | |||
</pre> | |||
</div> | |||
: <div> | |||
<h4 className="spacer-bottom"> | |||
{translate('background_tasks.error_message')} | |||
</h4> | |||
<pre className="js-task-error-message"> | |||
{task.errorMessage} | |||
</pre> | |||
</div>} | |||
</div> | |||
<div className="modal-foot"> | |||
@@ -107,7 +112,6 @@ export default class Stacktrace extends React.PureComponent { | |||
{translate('close')} | |||
</a> | |||
</div> | |||
</Modal> | |||
); | |||
} |
@@ -36,7 +36,9 @@ export default function TaskComponent(props: Props) { | |||
if (!task.componentKey) { | |||
return ( | |||
<td> | |||
<span className="note">{task.id}</span> | |||
<span className="note"> | |||
{task.id} | |||
</span> | |||
{types.length > 1 && <TaskType task={task} />} | |||
</td> | |||
); |
@@ -25,7 +25,11 @@ const TaskDate = ({ | |||
date, | |||
baseDate, | |||
format | |||
}: { date: string, baseDate: string, format: string }) => { | |||
}: { | |||
date: string, | |||
baseDate: string, | |||
format: string | |||
}) => { | |||
const m = moment(date); | |||
const baseM = moment(baseDate); | |||
const diff = date && baseDate ? m.diff(baseM, 'days') : 0; |
@@ -36,24 +36,34 @@ const TaskStatus = ({ task }: { task: Task }) => { | |||
break; | |||
case STATUSES.SUCCESS: | |||
inner = ( | |||
<span className="badge badge-success">{translate('background_task.status.SUCCESS')}</span> | |||
<span className="badge badge-success"> | |||
{translate('background_task.status.SUCCESS')} | |||
</span> | |||
); | |||
break; | |||
case STATUSES.FAILED: | |||
inner = ( | |||
<span className="badge badge-danger">{translate('background_task.status.FAILED')}</span> | |||
<span className="badge badge-danger"> | |||
{translate('background_task.status.FAILED')} | |||
</span> | |||
); | |||
break; | |||
case STATUSES.CANCELED: | |||
inner = ( | |||
<span className="badge badge-muted">{translate('background_task.status.CANCELED')}</span> | |||
<span className="badge badge-muted"> | |||
{translate('background_task.status.CANCELED')} | |||
</span> | |||
); | |||
break; | |||
default: | |||
inner = ''; | |||
} | |||
return <td className="thin spacer-right">{inner}</td>; | |||
return ( | |||
<td className="thin spacer-right"> | |||
{inner} | |||
</td> | |||
); | |||
}; | |||
export default TaskStatus; |
@@ -49,19 +49,33 @@ export default class Tasks extends React.PureComponent { | |||
<table className={className}> | |||
<thead> | |||
<tr> | |||
<th>{translate('background_tasks.table.status')}</th> | |||
<th>{translate('background_tasks.table.task')}</th> | |||
<th>{translate('background_tasks.table.id')}</th> | |||
<th> | |||
{translate('background_tasks.table.status')} | |||
</th> | |||
<th> | |||
{translate('background_tasks.table.task')} | |||
</th> | |||
<th> | |||
{translate('background_tasks.table.id')} | |||
</th> | |||
<th> </th> | |||
<th className="text-right">{translate('background_tasks.table.submitted')}</th> | |||
<th className="text-right">{translate('background_tasks.table.started')}</th> | |||
<th className="text-right">{translate('background_tasks.table.finished')}</th> | |||
<th className="text-right">{translate('background_tasks.table.duration')}</th> | |||
<th className="text-right"> | |||
{translate('background_tasks.table.submitted')} | |||
</th> | |||
<th className="text-right"> | |||
{translate('background_tasks.table.started')} | |||
</th> | |||
<th className="text-right"> | |||
{translate('background_tasks.table.finished')} | |||
</th> | |||
<th className="text-right"> | |||
{translate('background_tasks.table.duration')} | |||
</th> | |||
<th> </th> | |||
</tr> | |||
</thead> | |||
<tbody> | |||
{tasks.map((task, index, tasks) => ( | |||
{tasks.map((task, index, tasks) => | |||
<Task | |||
key={task.id} | |||
task={task} | |||
@@ -72,7 +86,7 @@ export default class Tasks extends React.PureComponent { | |||
onCancelTask={onCancelTask} | |||
onFilterTask={onFilterTask} | |||
/> | |||
))} | |||
)} | |||
</tbody> | |||
</table> | |||
); |
@@ -27,7 +27,11 @@ const TypesFilter = ({ | |||
value, | |||
onChange, | |||
types | |||
}: { value: string, onChange: Function, types: string[] }) => { | |||
}: { | |||
value: string, | |||
onChange: Function, | |||
types: string[] | |||
}) => { | |||
const options = types.map(t => { | |||
return { | |||
value: t, |
@@ -23,7 +23,7 @@ import Breadcrumb from './Breadcrumb'; | |||
export default function Breadcrumbs({ rootComponent, breadcrumbs }) { | |||
return ( | |||
<ul className="code-breadcrumbs"> | |||
{breadcrumbs.map((component, index) => ( | |||
{breadcrumbs.map((component, index) => | |||
<li key={component.key}> | |||
<Breadcrumb | |||
rootComponent={rootComponent} | |||
@@ -31,7 +31,7 @@ export default function Breadcrumbs({ rootComponent, breadcrumbs }) { | |||
canBrowse={index < breadcrumbs.length - 1} | |||
/> | |||
</li> | |||
))} | |||
)} | |||
</ul> | |||
); | |||
} |
@@ -109,7 +109,7 @@ export default class Component extends React.PureComponent { | |||
/> | |||
</td> | |||
{columns.map(column => ( | |||
{columns.map(column => | |||
<td key={column.metric} className="thin nowrap text-right"> | |||
<div className="code-components-cell"> | |||
<ComponentMeasure | |||
@@ -119,7 +119,7 @@ export default class Component extends React.PureComponent { | |||
/> | |||
</div> | |||
</td> | |||
))} | |||
)} | |||
</tr> | |||
); | |||
} |
@@ -51,8 +51,12 @@ const ComponentName = ({ component, rootComponent, previous, canBrowse }) => { | |||
const prefix = areBothDirs ? mostCommitPrefix([component.name + '/', previous.name + '/']) : ''; | |||
const name = prefix | |||
? <span> | |||
<span style={{ color: '#777' }}>{prefix}</span> | |||
<span>{component.name.substr(prefix.length)}</span> | |||
<span style={{ color: '#777' }}> | |||
{prefix} | |||
</span> | |||
<span> | |||
{component.name.substr(prefix.length)} | |||
</span> | |||
</span> | |||
: component.name; | |||
@@ -63,9 +67,7 @@ const ComponentName = ({ component, rootComponent, previous, canBrowse }) => { | |||
<Link | |||
to={{ pathname: '/dashboard', query: { id: component.refKey } }} | |||
className="link-with-icon"> | |||
<QualifierIcon qualifier={component.qualifier} /> | |||
{' '} | |||
<span>{name}</span> | |||
<QualifierIcon qualifier={component.qualifier} /> <span>{name}</span> | |||
</Link> | |||
); | |||
} else if (canBrowse) { | |||
@@ -75,17 +77,13 @@ const ComponentName = ({ component, rootComponent, previous, canBrowse }) => { | |||
} | |||
inner = ( | |||
<Link to={{ pathname: '/code', query }} className="link-with-icon"> | |||
<QualifierIcon qualifier={component.qualifier} /> | |||
{' '} | |||
<span>{name}</span> | |||
<QualifierIcon qualifier={component.qualifier} /> <span>{name}</span> | |||
</Link> | |||
); | |||
} else { | |||
inner = ( | |||
<span> | |||
<QualifierIcon qualifier={component.qualifier} /> | |||
{' '} | |||
{name} | |||
<QualifierIcon qualifier={component.qualifier} /> {name} | |||
</span> | |||
); | |||
} |
@@ -39,7 +39,7 @@ export default function Components({ rootComponent, baseComponent, components, s | |||
</tbody>} | |||
<tbody> | |||
{components.length | |||
? components.map((component, index, list) => ( | |||
? components.map((component, index, list) => | |||
<Component | |||
key={component.key} | |||
rootComponent={rootComponent} | |||
@@ -48,7 +48,7 @@ export default function Components({ rootComponent, baseComponent, components, s | |||
previous={index > 0 ? list[index - 1] : null} | |||
canBrowse={true} | |||
/> | |||
)) | |||
) | |||
: <ComponentsEmpty />} | |||
</tbody> | |||
</table> |
@@ -45,11 +45,11 @@ const ComponentsHeader = ({ baseComponent, rootComponent }) => { | |||
<tr className="code-components-header"> | |||
<th className="thin nowrap"> </th> | |||
<th> </th> | |||
{columns.map(column => ( | |||
{columns.map(column => | |||
<th key={column} className="thin nowrap text-right code-components-cell"> | |||
{baseComponent && column} | |||
</th> | |||
))} | |||
)} | |||
</tr> | |||
</thead> | |||
); |
@@ -37,13 +37,11 @@ import { areThereCustomOrganizations } from '../../store/organizations/utils'; | |||
const App = new Marionette.Application(); | |||
App.on('start', function( | |||
options: { | |||
el: HTMLElement, | |||
organization: ?string, | |||
isDefaultOrganization: boolean | |||
} | |||
) { | |||
App.on('start', function(options: { | |||
el: HTMLElement, | |||
organization: ?string, | |||
isDefaultOrganization: boolean | |||
}) { | |||
App.organization = options.organization; | |||
const data = options.organization ? { organization: options.organization } : {}; | |||
$.get(window.baseUrl + '/api/rules/app', data) |
@@ -54,7 +54,8 @@ export default Marionette.ItemView.extend({ | |||
return { | |||
...project, | |||
name: projectBase != null ? projectBase.longName : '', | |||
issuesUrl: projectBase != null && | |||
issuesUrl: | |||
projectBase != null && | |||
getComponentIssuesUrlAsString(projectBase.key, { | |||
resolved: 'false', | |||
rules: this.model.id |
@@ -37,5 +37,9 @@ export default function LeakPeriodLegend({ period }) { | |||
const date = getPeriodDate(period); | |||
const fromNow = moment(date).fromNow(); | |||
const tooltip = fromNow + ', ' + moment(date).format('LL'); | |||
return <Tooltip placement="bottom" overlay={tooltip}>{label}</Tooltip>; | |||
return ( | |||
<Tooltip placement="bottom" overlay={tooltip}> | |||
{label} | |||
</Tooltip> | |||
); | |||
} |
@@ -61,7 +61,6 @@ export default function MeasureDetailsHeader({ | |||
<TooltipsContainer options={{ html: false }}> | |||
<div className="measure-details-value"> | |||
{isDiff | |||
? <div className="measure-details-value-leak"> | |||
<Measure measure={measure} metric={metric} /> |
@@ -37,7 +37,11 @@ const Breadcrumb = ({ component, metric, onBrowse }) => { | |||
</a> | |||
); | |||
} else { | |||
inner = <span>{component.name}</span>; | |||
inner = ( | |||
<span> | |||
{component.name} | |||
</span> | |||
); | |||
} | |||
const value = isDiffMetric(metric.key) | |||
@@ -49,7 +53,10 @@ const Breadcrumb = ({ component, metric, onBrowse }) => { | |||
<QualifierIcon qualifier={component.qualifier} /> | |||
| |||
{inner} | |||
{value != null && <span>{' (' + value + ')'}</span>} | |||
{value != null && | |||
<span> | |||
{' (' + value + ')'} | |||
</span>} | |||
</span> | |||
); | |||
}; |
@@ -20,9 +20,9 @@ | |||
import React from 'react'; | |||
import Breadcrumb from './Breadcrumb'; | |||
const Breadcrumbs = ({ breadcrumbs, metric, onBrowse }) => ( | |||
const Breadcrumbs = ({ breadcrumbs, metric, onBrowse }) => | |||
<ul className="component-measures-breadcrumbs"> | |||
{breadcrumbs.map((component, index) => ( | |||
{breadcrumbs.map((component, index) => | |||
<li key={component.key}> | |||
<Breadcrumb | |||
component={component} | |||
@@ -30,8 +30,7 @@ const Breadcrumbs = ({ breadcrumbs, metric, onBrowse }) => ( | |||
onBrowse={index + 1 < breadcrumbs.length ? onBrowse : null} | |||
/> | |||
</li> | |||
))} | |||
</ul> | |||
); | |||
)} | |||
</ul>; | |||
export default Breadcrumbs; |
@@ -51,7 +51,10 @@ const ComponentCell = ({ component, isSelected, onClick }) => { | |||
<span title={component.refKey || component.key}> | |||
<QualifierIcon qualifier={component.qualifier} /> | |||
| |||
{head.length > 0 && <span className="note">{head}/</span>} | |||
{head.length > 0 && | |||
<span className="note"> | |||
{head}/ | |||
</span>} | |||
<span>{tail}</span> | |||
</span> | |||
); |
@@ -39,18 +39,22 @@ const ComponentsList = ({ components, metrics, selected, metric, onClick }) => { | |||
<tr> | |||
<th> </th> | |||
<th className="text-right"> | |||
<span className="small">{getLocalizedMetricName(metric)}</span> | |||
<span className="small"> | |||
{getLocalizedMetricName(metric)} | |||
</span> | |||
</th> | |||
{otherMetrics.map(metric => ( | |||
{otherMetrics.map(metric => | |||
<th key={metric.key} className="text-right"> | |||
<span className="small">{getLocalizedMetricName(metric)}</span> | |||
<span className="small"> | |||
{getLocalizedMetricName(metric)} | |||
</span> | |||
</th> | |||
))} | |||
)} | |||
</tr> | |||
</thead>} | |||
<tbody> | |||
{components.map(component => ( | |||
{components.map(component => | |||
<ComponentsListRow | |||
key={component.id} | |||
component={component} | |||
@@ -59,7 +63,7 @@ const ComponentsList = ({ components, metrics, selected, metric, onClick }) => { | |||
metric={metric} | |||
onClick={onClick} | |||
/> | |||
))} | |||
)} | |||
</tbody> | |||
</table> | |||
); |
@@ -49,13 +49,13 @@ const ComponentsListRow = ({ component, otherMetrics, isSelected, metric, onClic | |||
<MeasureCell component={component} metric={metric} /> | |||
{otherMeasures.map(measure => ( | |||
{otherMeasures.map(measure => | |||
<MeasureCell | |||
key={measure.metric.key} | |||
component={replaceMeasure(component, measure)} | |||
metric={measure.metric} | |||
/> | |||
))} | |||
)} | |||
</tr> | |||
); | |||
}; |
@@ -114,20 +114,20 @@ export default class ListView extends React.PureComponent { | |||
} | |||
const selectedIndex = components.indexOf(selected); | |||
const sourceViewerPeriod = metric.key.indexOf('new_') === 0 && !!leakPeriod ? leakPeriod : null; | |||
const sourceViewerPeriodDate = sourceViewerPeriod != null | |||
? moment(sourceViewerPeriod.date).toDate() | |||
: null; | |||
const filterLine = sourceViewerPeriodDate != null | |||
? line => { | |||
if (line.scmDate) { | |||
const scmDate = moment(line.scmDate).toDate(); | |||
return scmDate >= sourceViewerPeriodDate; | |||
} else { | |||
return false; | |||
const sourceViewerPeriodDate = | |||
sourceViewerPeriod != null ? moment(sourceViewerPeriod.date).toDate() : null; | |||
const filterLine = | |||
sourceViewerPeriodDate != null | |||
? line => { | |||
if (line.scmDate) { | |||
const scmDate = moment(line.scmDate).toDate(); | |||
return scmDate >= sourceViewerPeriodDate; | |||
} else { | |||
return false; | |||
} | |||
} | |||
} | |||
: undefined; | |||
: undefined; | |||
return ( | |||
<div ref="container" className="measure-details-plain-list"> |
@@ -107,20 +107,20 @@ export default class TreeView extends React.PureComponent { | |||
const selectedIndex = components.indexOf(selected); | |||
const sourceViewerPeriod = metric.key.indexOf('new_') === 0 && !!leakPeriod ? leakPeriod : null; | |||
const sourceViewerPeriodDate = sourceViewerPeriod != null | |||
? moment(sourceViewerPeriod.date).toDate() | |||
: null; | |||
const filterLine = sourceViewerPeriodDate != null | |||
? line => { | |||
if (line.scmDate) { | |||
const scmDate = moment(line.scmDate).toDate(); | |||
return scmDate >= sourceViewerPeriodDate; | |||
} else { | |||
return false; | |||
const sourceViewerPeriodDate = | |||
sourceViewerPeriod != null ? moment(sourceViewerPeriod.date).toDate() : null; | |||
const filterLine = | |||
sourceViewerPeriodDate != null | |||
? line => { | |||
if (line.scmDate) { | |||
const scmDate = moment(line.scmDate).toDate(); | |||
return scmDate >= sourceViewerPeriodDate; | |||
} else { | |||
return false; | |||
} | |||
} | |||
} | |||
: undefined; | |||
: undefined; | |||
return ( | |||
<div ref="container" className="measure-details-plain-list"> |
@@ -27,14 +27,14 @@ export default function AllMeasures(props) { | |||
return ( | |||
<ul className="measures-domains"> | |||
{domains.map(domain => ( | |||
{domains.map(domain => | |||
<AllMeasuresDomain | |||
key={domain.name} | |||
domain={domain} | |||
component={component} | |||
leakPeriodLabel={leakPeriodLabel} | |||
/> | |||
))} | |||
)} | |||
</ul> | |||
); | |||
} |
@@ -55,7 +55,7 @@ export default class Home extends React.PureComponent { | |||
{translate('all')} | |||
</IndexLink> | |||
</li> | |||
{domains.map(domain => ( | |||
{domains.map(domain => | |||
<li key={domain.name}> | |||
<Link | |||
to={{ | |||
@@ -66,7 +66,7 @@ export default class Home extends React.PureComponent { | |||
{getLocalizedMetricDomain(domain.name)} | |||
</Link> | |||
</li> | |||
))} | |||
)} | |||
</ul> | |||
</nav> | |||
@@ -26,7 +26,7 @@ import IssueTypeIcon from '../../../components/ui/IssueTypeIcon'; | |||
const MeasuresList = ({ measures, component, className = 'domain-measures' }) => { | |||
return ( | |||
<ul className={className}> | |||
{measures.map(measure => ( | |||
{measures.map(measure => | |||
<li key={measure.metric.key} id={`measure-${measure.metric.key}`}> | |||
<Link | |||
to={{ | |||
@@ -43,7 +43,7 @@ const MeasuresList = ({ measures, component, className = 'domain-measures' }) => | |||
<MeasureListValue measure={measure} /> | |||
</Link> | |||
</li> | |||
))} | |||
)} | |||
</ul> | |||
); | |||
}; |
@@ -5,7 +5,8 @@ | |||
margin-bottom: 20px; | |||
} | |||
.measures-domains {} | |||
.measures-domains { | |||
} | |||
.measures-domains > li { | |||
margin-bottom: 20px; | |||
@@ -140,7 +141,8 @@ | |||
} | |||
.measure-details-metric, | |||
.measure-details-value {} | |||
.measure-details-value { | |||
} | |||
.measure-details-metric { | |||
display: inline-block; | |||
@@ -221,7 +223,8 @@ | |||
fill: #4b9fd5; | |||
} | |||
.measure-details-plain-list {} | |||
.measure-details-plain-list { | |||
} | |||
.measure-details-components { | |||
width: 300px; |
@@ -55,9 +55,8 @@ export const selectLocation = (nextIndex: ?number) => (state: State) => { | |||
export const selectNextLocation = (state: State) => { | |||
const { selectedFlowIndex, selectedLocationIndex: index, openIssue } = state; | |||
if (openIssue) { | |||
const locations = selectedFlowIndex != null | |||
? openIssue.flows[selectedFlowIndex] | |||
: openIssue.secondaryLocations; | |||
const locations = | |||
selectedFlowIndex != null ? openIssue.flows[selectedFlowIndex] : openIssue.secondaryLocations; | |||
return { | |||
selectedLocationIndex: index != null && locations.length > index + 1 ? index + 1 : index | |||
}; |
@@ -385,9 +385,8 @@ export default class App extends React.PureComponent { | |||
referencedLanguages: keyBy(other.languages, 'key'), | |||
referencedRules: keyBy(other.rules, 'key'), | |||
referencedUsers: keyBy(other.users, 'login'), | |||
selected: issues.length > 0 | |||
? openIssue != null ? openIssue.key : issues[0].key | |||
: undefined, | |||
selected: | |||
issues.length > 0 ? (openIssue != null ? openIssue.key : issues[0].key) : undefined, | |||
selectedFlowIndex: null, | |||
selectedLocationIndex: null | |||
}); | |||
@@ -785,7 +784,9 @@ export default class App extends React.PureComponent { | |||
return ( | |||
<div className="pull-right note"> | |||
<span className="shortcut-button little-spacer-right">alt</span> | |||
<span className="little-spacer-right">{'+'}</span> | |||
<span className="little-spacer-right"> | |||
{'+'} | |||
</span> | |||
<span className="shortcut-button little-spacer-right">↑</span> | |||
<span className="shortcut-button little-spacer-right">↓</span> | |||
{hasSeveralFlows && |
@@ -208,16 +208,17 @@ export default class BulkChangeModal extends React.PureComponent { | |||
})); | |||
} | |||
renderCancelButton = () => ( | |||
renderCancelButton = () => | |||
<a id="bulk-change-cancel" href="#" onClick={this.handleCloseClick}> | |||
{translate('cancel')} | |||
</a> | |||
); | |||
</a>; | |||
renderLoading = () => ( | |||
renderLoading = () => | |||
<div> | |||
<div className="modal-head"> | |||
<h2>{translate('bulk_change')}</h2> | |||
<h2> | |||
{translate('bulk_change')} | |||
</h2> | |||
</div> | |||
<div className="modal-body"> | |||
<div className="text-center"> | |||
@@ -227,29 +228,27 @@ export default class BulkChangeModal extends React.PureComponent { | |||
<div className="modal-foot"> | |||
{this.renderCancelButton()} | |||
</div> | |||
</div> | |||
); | |||
</div>; | |||
renderCheckbox = (field: string) => ( | |||
<Checkbox checked={this.state[field] != null} onCheck={this.handleFieldCheck(field)} /> | |||
); | |||
renderCheckbox = (field: string) => | |||
<Checkbox checked={this.state[field] != null} onCheck={this.handleFieldCheck(field)} />; | |||
renderAffected = (affected: number) => ( | |||
renderAffected = (affected: number) => | |||
<div className="pull-right note"> | |||
({translateWithParameters('issue_bulk_change.x_issues', affected)}) | |||
</div> | |||
); | |||
</div>; | |||
renderField = (field: string, label: string, affected: ?number, input: Object) => ( | |||
renderField = (field: string, label: string, affected: ?number, input: Object) => | |||
<div className="modal-field" id={`issues-bulk-change-${field}`}> | |||
<label htmlFor={field}>{translate(label)}</label> | |||
<label htmlFor={field}> | |||
{translate(label)} | |||
</label> | |||
{this.renderCheckbox(field)} | |||
{input} | |||
{affected != null && this.renderAffected(affected)} | |||
</div> | |||
); | |||
</div>; | |||
renderAssigneeOption = (option: { avatar?: string, email?: string, label: string }) => ( | |||
renderAssigneeOption = (option: { avatar?: string, email?: string, label: string }) => | |||
<span> | |||
{(option.avatar != null || option.email != null) && | |||
<Avatar | |||
@@ -260,8 +259,7 @@ export default class BulkChangeModal extends React.PureComponent { | |||
size={16} | |||
/>} | |||
{option.label} | |||
</span> | |||
); | |||
</span>; | |||
renderAssigneeField = () => { | |||
const affected: number = this.state.issues.filter(hasAction('assign')).length; | |||
@@ -294,12 +292,11 @@ export default class BulkChangeModal extends React.PureComponent { | |||
const types = ['BUG', 'VULNERABILITY', 'CODE_SMELL']; | |||
const options = types.map(type => ({ label: translate('issue.type', type), value: type })); | |||
const optionRenderer = (option: { label: string, value: string }) => ( | |||
const optionRenderer = (option: { label: string, value: string }) => | |||
<span> | |||
<IssueTypeIcon className="little-spacer-right" query={option.value} /> | |||
{option.label} | |||
</span> | |||
); | |||
</span>; | |||
const input = ( | |||
<Select | |||
@@ -403,8 +400,10 @@ export default class BulkChangeModal extends React.PureComponent { | |||
return ( | |||
<div className="modal-field"> | |||
<label>{translate('issue.transition')}</label> | |||
{transitions.map(transition => ( | |||
<label> | |||
{translate('issue.transition')} | |||
</label> | |||
{transitions.map(transition => | |||
<span key={transition.transition}> | |||
<input | |||
checked={this.state.transition === transition.transition} | |||
@@ -422,7 +421,7 @@ export default class BulkChangeModal extends React.PureComponent { | |||
{this.renderAffected(transition.count)} | |||
<br /> | |||
</span> | |||
))} | |||
)} | |||
</div> | |||
); | |||
}; | |||
@@ -458,12 +457,13 @@ export default class BulkChangeModal extends React.PureComponent { | |||
); | |||
}; | |||
renderNotificationsField = () => ( | |||
renderNotificationsField = () => | |||
<div className="modal-field"> | |||
<label htmlFor="send-notifications">{translate('issue.send_notifications')}</label> | |||
<label htmlFor="send-notifications"> | |||
{translate('issue.send_notifications')} | |||
</label> | |||
{this.renderCheckbox('notifications')} | |||
</div> | |||
); | |||
</div>; | |||
renderForm = () => { | |||
const { issues, paging, submitting } = this.state; | |||
@@ -474,7 +474,9 @@ export default class BulkChangeModal extends React.PureComponent { | |||
return ( | |||
<form id="bulk-change-form" onSubmit={this.handleSubmit}> | |||
<div className="modal-head"> | |||
<h2>{translateWithParameters('issue_bulk_change.form.title', issues.length)}</h2> | |||
<h2> | |||
{translateWithParameters('issue_bulk_change.form.title', issues.length)} | |||
</h2> | |||
</div> | |||
<div className="modal-body"> | |||
@@ -495,7 +497,9 @@ export default class BulkChangeModal extends React.PureComponent { | |||
<div className="modal-foot"> | |||
{submitting && <i className="spinner spacer-right" />} | |||
<button disabled={submitting} id="bulk-change-submit">{translate('apply')}</button> | |||
<button disabled={submitting} id="bulk-change-submit"> | |||
{translate('apply')} | |||
</button> | |||
{this.renderCancelButton()} | |||
</div> | |||
</form> |
@@ -45,7 +45,9 @@ export default class FiltersHeader extends React.PureComponent { | |||
</button> | |||
</div>} | |||
<h3>{translate('filters')}</h3> | |||
<h3> | |||
{translate('filters')} | |||
</h3> | |||
</div> | |||
); | |||
} |
@@ -27,15 +27,17 @@ type Props = { | |||
total: number | |||
}; | |||
const IssuesCounter = (props: Props) => ( | |||
const IssuesCounter = (props: Props) => | |||
<span> | |||
<strong> | |||
{props.current != null && <span>{formatMeasure(props.current + 1, 'INT')} / </span>} | |||
{props.current != null && | |||
<span> | |||
{formatMeasure(props.current + 1, 'INT')} | |||
{' / '} | |||
</span>} | |||
{formatMeasure(props.total, 'INT')} | |||
</strong> | |||
{' '} | |||
</strong>{' '} | |||
{translate('issues.issues')} | |||
</span> | |||
); | |||
</span>; | |||
export default IssuesCounter; |
@@ -42,7 +42,7 @@ export default class IssuesList extends React.PureComponent { | |||
return ( | |||
<div> | |||
{issues.map((issue, index) => ( | |||
{issues.map((issue, index) => | |||
<ListItem | |||
checked={checked.includes(issue.key)} | |||
component={component} | |||
@@ -55,7 +55,7 @@ export default class IssuesList extends React.PureComponent { | |||
previousIssue={index > 0 ? issues[index - 1] : null} | |||
selected={selectedIssue != null && selectedIssue.key === issue.key} | |||
/> | |||
))} | |||
)} | |||
</div> | |||
); | |||
} |
@@ -65,15 +65,17 @@ export default class IssuesSourceViewer extends React.PureComponent { | |||
render() { | |||
const { openIssue, selectedFlowIndex, selectedLocationIndex } = this.props; | |||
const locations = selectedFlowIndex != null | |||
? openIssue.flows[selectedFlowIndex] | |||
: openIssue.flows.length > 0 ? openIssue.flows[0] : openIssue.secondaryLocations; | |||
const locations = | |||
selectedFlowIndex != null | |||
? openIssue.flows[selectedFlowIndex] | |||
: openIssue.flows.length > 0 ? openIssue.flows[0] : openIssue.secondaryLocations; | |||
const locationMessage = locations != null && | |||
const locationMessage = | |||
locations != null && | |||
selectedLocationIndex != null && | |||
locations.length >= selectedLocationIndex | |||
? { index: selectedLocationIndex, text: locations[selectedLocationIndex].msg } | |||
: undefined; | |||
? { index: selectedLocationIndex, text: locations[selectedLocationIndex].msg } | |||
: undefined; | |||
return ( | |||
<div ref={node => (this.node = node)}> |
@@ -58,9 +58,10 @@ export default class ConciseIssueBox extends React.PureComponent { | |||
const { selectedFlowIndex } = this.props; | |||
const { flows, secondaryLocations } = this.props.issue; | |||
const locations = selectedFlowIndex != null | |||
? flows[selectedFlowIndex] | |||
: flows.length > 0 ? flows[0] : secondaryLocations; | |||
const locations = | |||
selectedFlowIndex != null | |||
? flows[selectedFlowIndex] | |||
: flows.length > 0 ? flows[0] : secondaryLocations; | |||
if (locations == null || locations.length < 15) { | |||
// if there are no locations, or there are just few |
@@ -25,10 +25,9 @@ type Props = { | |||
path: string | |||
}; | |||
const ConciseIssueComponent = (props: Props) => ( | |||
const ConciseIssueComponent = (props: Props) => | |||
<div className="concise-issue-component note text-ellipsis"> | |||
{collapsePath(props.path, 20)} | |||
</div> | |||
); | |||
</div>; | |||
export default ConciseIssueComponent; |