diff options
author | Stas Vilchik <vilchiks@gmail.com> | 2016-01-07 17:48:53 +0100 |
---|---|---|
committer | Stas Vilchik <vilchiks@gmail.com> | 2016-01-07 17:52:22 +0100 |
commit | fddb2fb947e8b92e0b6ef41416a87bcbfface23f (patch) | |
tree | f1676cb7b2d38c257647a3796566bcc1cd1217a1 | |
parent | db61853e7dbad7ee08a34e740a7a2dd1d8da58e0 (diff) | |
download | sonarqube-fddb2fb947e8b92e0b6ef41416a87bcbfface23f.tar.gz sonarqube-fddb2fb947e8b92e0b6ef41416a87bcbfface23f.zip |
SONAR-7144 pin file in the workspace
6 files changed, 146 insertions, 139 deletions
diff --git a/server/sonar-web/src/main/js/apps/code/components/Component.js b/server/sonar-web/src/main/js/apps/code/components/Component.js index de9a7e1055f..205af9cef65 100644 --- a/server/sonar-web/src/main/js/apps/code/components/Component.js +++ b/server/sonar-web/src/main/js/apps/code/components/Component.js @@ -22,63 +22,77 @@ import React from 'react'; import ComponentName from './ComponentName'; import ComponentMeasure from './ComponentMeasure'; import ComponentDetach from './ComponentDetach'; +import ComponentPin from './ComponentPin'; -const Component = ({ component, previous, coverageMetric, onBrowse }) => ( - <tr> - <td className="thin nowrap"> - <span className="spacer-right"> - <ComponentDetach component={component}/> - </span> - </td> - <td className="code-name-cell"> - <ComponentName - component={component} - previous={previous} - onBrowse={onBrowse}/> - </td> - <td className="thin nowrap text-right"> - <div className="code-components-cell"> - <ComponentMeasure - component={component} - metricKey="ncloc" - metricType="SHORT_INT"/> - </div> - </td> - <td className="thin nowrap text-right"> - <div className="code-components-cell"> - <ComponentMeasure - component={component} - metricKey="sqale_index" - metricType="SHORT_WORK_DUR"/> - </div> - </td> - <td className="thin nowrap text-right"> - <div className="code-components-cell"> - <ComponentMeasure - component={component} - metricKey="violations" - metricType="SHORT_INT"/> - </div> - </td> - <td className="thin nowrap text-right"> - <div className="code-components-cell"> - <ComponentMeasure - component={component} - metricKey={coverageMetric} - metricType="PERCENT"/> - </div> - </td> - <td className="thin nowrap text-right"> - <div className="code-components-cell"> - <ComponentMeasure +const Component = ({ component, previous, coverageMetric, onBrowse }) => { + let componentAction = null; + + switch (component.qualifier) { + case 'FIL': + case 'UTS': + componentAction = <ComponentPin component={component}/>; + break; + default: + componentAction = <ComponentDetach component={component}/>; + } + + return ( + <tr> + <td className="thin nowrap"> + <span className="spacer-right"> + {componentAction} + </span> + </td> + <td className="code-name-cell"> + <ComponentName component={component} - metricKey="duplicated_lines_density" - metricType="PERCENT"/> - </div> - </td> - </tr> -); + previous={previous} + onBrowse={onBrowse}/> + </td> + <td className="thin nowrap text-right"> + <div className="code-components-cell"> + <ComponentMeasure + component={component} + metricKey="ncloc" + metricType="SHORT_INT"/> + </div> + </td> + <td className="thin nowrap text-right"> + <div className="code-components-cell"> + <ComponentMeasure + component={component} + metricKey="sqale_index" + metricType="SHORT_WORK_DUR"/> + </div> + </td> + <td className="thin nowrap text-right"> + <div className="code-components-cell"> + <ComponentMeasure + component={component} + metricKey="violations" + metricType="SHORT_INT"/> + </div> + </td> + <td className="thin nowrap text-right"> + <div className="code-components-cell"> + <ComponentMeasure + component={component} + metricKey={coverageMetric} + metricType="PERCENT"/> + </div> + </td> + <td className="thin nowrap text-right"> + <div className="code-components-cell"> + <ComponentMeasure + component={component} + metricKey="duplicated_lines_density" + metricType="PERCENT"/> + </div> + </td> + </tr> + ); +}; export default Component; diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js b/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js index 37d6f62dc4e..b686188538a 100644 --- a/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js +++ b/server/sonar-web/src/main/js/apps/code/components/ComponentDetach.js @@ -26,8 +26,7 @@ import { translate } from '../../../helpers/l10n'; const ComponentDetach = ({ component }) => ( <a className="icon-detach" - target="_blank" - title={translate('code.open_in_new_tab')} + title={translate('code.open_component_page')} href={getComponentUrl(component.key)}/> ); diff --git a/server/sonar-web/src/main/js/apps/code/components/ComponentPin.js b/server/sonar-web/src/main/js/apps/code/components/ComponentPin.js new file mode 100644 index 00000000000..80382734ffd --- /dev/null +++ b/server/sonar-web/src/main/js/apps/code/components/ComponentPin.js @@ -0,0 +1,45 @@ +/* + * SonarQube :: Web + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; + +import Workspace from '../../../components/workspace/main'; +import PinIcon from '../../../components/shared/pin-icon'; +import { translate } from '../../../helpers/l10n'; + + +const ComponentPin = ({ component }) => { + const handleClick = (e) => { + e.preventDefault(); + Workspace.openComponent({ uuid: component.uuid }); + }; + + return ( + <a + className="link-no-underline" + onClick={handleClick} + title={translate('component_viewer.open_in_workspace')} + href="#"> + <PinIcon/> + </a> + ); +}; + + +export default ComponentPin; diff --git a/server/sonar-web/src/main/js/components/shared/pin-icon.js b/server/sonar-web/src/main/js/components/shared/pin-icon.js new file mode 100644 index 00000000000..d6b26a886fc --- /dev/null +++ b/server/sonar-web/src/main/js/components/shared/pin-icon.js @@ -0,0 +1,31 @@ +/* + * SonarQube :: Web + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import React from 'react'; + +const PinIcon = () => ( + <svg width="9" height="14" viewBox="0 0 288 448"> + <path + fill="#236a97" + d="M120 216v-112q0-3.5-2.25-5.75t-5.75-2.25-5.75 2.25-2.25 5.75v112q0 3.5 2.25 5.75t5.75 2.25 5.75-2.25 2.25-5.75zM288 304q0 6.5-4.75 11.25t-11.25 4.75h-107.25l-12.75 120.75q-0.5 3-2.625 5.125t-5.125 2.125h-0.25q-6.75 0-8-6.75l-19-121.25h-101q-6.5 0-11.25-4.75t-4.75-11.25q0-30.75 19.625-55.375t44.375-24.625v-128q-13 0-22.5-9.5t-9.5-22.5 9.5-22.5 22.5-9.5h160q13 0 22.5 9.5t9.5 22.5-9.5 22.5-22.5 9.5v128q24.75 0 44.375 24.625t19.625 55.375z"/> + </svg> +); + +export default PinIcon; + diff --git a/server/sonar-web/tests/apps/code/components-test.js b/server/sonar-web/tests/apps/code/components-test.js index 7729bf7b5ab..a31591cf24e 100644 --- a/server/sonar-web/tests/apps/code/components-test.js +++ b/server/sonar-web/tests/apps/code/components-test.js @@ -7,11 +7,9 @@ import TestUtils from 'react-addons-test-utils'; import Breadcrumb from '../../../src/main/js/apps/code/components/Breadcrumb'; import Breadcrumbs from '../../../src/main/js/apps/code/components/Breadcrumbs'; -import Component from '../../../src/main/js/apps/code/components/Component'; import ComponentDetach from '../../../src/main/js/apps/code/components/ComponentDetach'; import ComponentMeasure from '../../../src/main/js/apps/code/components/ComponentMeasure'; import ComponentName from '../../../src/main/js/apps/code/components/ComponentName'; -import Components from '../../../src/main/js/apps/code/components/Components'; import ComponentsEmpty from '../../../src/main/js/apps/code/components/ComponentsEmpty'; import Truncated from '../../../src/main/js/apps/code/components/Truncated'; @@ -87,50 +85,6 @@ describe('Code :: Components', () => { }); }); - describe('<Component/>', () => { - let output; - - before(() => { - output = shallow( - <Component - component={exampleComponent} - coverageMetric="coverage" - onBrowse={exampleOnBrowse}/>); - }); - - it('should render <ComponentName/>', () => { - const findings = output.find(ComponentName); - expect(findings) - .to.have.length(1); - expect(findings.first().props()) - .to.deep.equal({ component: exampleComponent, previous: undefined, onBrowse: exampleOnBrowse }); - }); - - it('should render <ComponentMeasure/>s', () => { - const findings = output.find(ComponentMeasure); - expect(findings) - .to.have.length(5); - expect(findings.at(0).props()) - .to.deep.equal({ component: exampleComponent, metricKey: 'ncloc', metricType: 'SHORT_INT' }); - expect(findings.at(1).props()) - .to.deep.equal({ component: exampleComponent, metricKey: 'sqale_index', metricType: 'SHORT_WORK_DUR' }); - expect(findings.at(2).props()) - .to.deep.equal({ component: exampleComponent, metricKey: 'violations', metricType: 'SHORT_INT' }); - expect(findings.at(3).props()) - .to.deep.equal({ component: exampleComponent, metricKey: 'coverage', metricType: 'PERCENT' }); - expect(findings.at(4).props()) - .to.deep.equal({ component: exampleComponent, metricKey: 'duplicated_lines_density', metricType: 'PERCENT' }); - }); - - it('should render <ComponentDetach/>', () => { - const findings = output.find(ComponentDetach); - expect(findings) - .to.have.length(1); - expect(findings.first().props()) - .to.deep.equal({ component: exampleComponent }); - }); - }); - describe('<ComponentDetach/>', () => { it('should render link', () => { const output = shallow( @@ -139,8 +93,6 @@ describe('Code :: Components', () => { expect(output.type()) .to.equal('a'); - expect(output.prop('target')) - .to.equal('_blank'); expect(output.prop('href')) .to.equal(expectedUrl); }); @@ -228,40 +180,6 @@ describe('Code :: Components', () => { }); }); - describe('<Components/>', () => { - let output; - - before(() => { - output = shallow( - <Components - baseComponent={exampleComponent} - components={[exampleComponent2, exampleComponent3]} - onBrowse={exampleOnBrowse}/>); - }); - - it('should render base component', () => { - const findings = output.findWhere(node => { - return node.type() === Component && node.prop('component') === exampleComponent; - }); - - expect(findings) - .to.have.length(1); - expect(findings.first().prop('onBrowse')) - .to.not.be.ok; - }); - - it('should render children component', () => { - const findings = output.findWhere(node => { - return node.type() === Component && node.prop('component') !== exampleComponent; - }); - - expect(findings) - .to.have.length(2); - expect(findings.at(0).prop('onBrowse')) - .to.equal(exampleOnBrowse) - }); - }); - describe('<ComponentsEmpty/>', () => { it('should render', () => { const output = shallow(<ComponentsEmpty/>); diff --git a/sonar-core/src/main/resources/org/sonar/l10n/core.properties b/sonar-core/src/main/resources/org/sonar/l10n/core.properties index 8f4abb3efae..22198010256 100644 --- a/sonar-core/src/main/resources/org/sonar/l10n/core.properties +++ b/sonar-core/src/main/resources/org/sonar/l10n/core.properties @@ -3170,4 +3170,4 @@ api_documentation.internal_tooltip=Use at your own risk; internal services are s # CODE # #------------------------------------------------------------------------------ -code.open_in_new_tab=Open in New Tab +code.open_component_page=Open Component's Page |