Browse Source

SONAR-8627 Display organization on the project dashboard

tags/6.3-RC1
Stas Vilchik 7 years ago
parent
commit
0eb12aca0e

+ 6
- 0
server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.css View File

@@ -4,6 +4,12 @@
height: 65px;
}

.navbar-context .navbar-nav > li > span {
display: inline-block;
padding: 3px 10px;
line-height: 20px;
}

.navbar-context-inner {
position: fixed;
z-index: 420;

+ 1
- 0
server/sonar-web/src/main/js/app/components/nav/component/ComponentNav.js View File

@@ -70,6 +70,7 @@ export default React.createClass({
favorite={this.props.component.isFavorite}/>

<ComponentNavBreadcrumbs
component={this.props.component}
breadcrumbs={this.props.component.breadcrumbs}/>

<TooltipsContainer options={{ delay: { show: 0, hide: 2000 } }}>

+ 31
- 9
server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBreadcrumbs.js View File

@@ -18,31 +18,53 @@
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import React from 'react';
import { connect } from 'react-redux';
import { Link } from 'react-router';
import QualifierIcon from '../../../../components/shared/qualifier-icon';
import { getOrganizationByKey, areThereCustomOrganizations } from '../../../../store/rootReducer';

export default class ComponentNavBreadcrumbs extends React.Component {
class ComponentNavBreadcrumbs extends React.Component {
static propTypes = {
breadcrumbs: React.PropTypes.array
};

render () {
if (!this.props.breadcrumbs) {
const { breadcrumbs, organization, shouldOrganizationBeDisplayed } = this.props;

if (!breadcrumbs) {
return null;
}

const items = this.props.breadcrumbs.map((item, index) => {
const url = `${window.baseUrl}/dashboard/index?id=${encodeURIComponent(item.key)}`;
const items = breadcrumbs.map(item => {
return (
<li key={index}>
<a href={url}>
<QualifierIcon qualifier={item.qualifier}/>&nbsp;{item.name}
</a>
<li key={item.key}>
<Link to={{ pathname: '/dashboard', query: { id: item.key } }}>
<QualifierIcon qualifier={item.qualifier}/>
{' '}
{item.name}
</Link>
</li>
);
});

return (
<ul className="nav navbar-nav nav-crumbs">{items}</ul>
<ul className="nav navbar-nav nav-crumbs">
{organization != null && shouldOrganizationBeDisplayed && (
<li>
<span>{organization.name}</span>
</li>
)}
{items}
</ul>
);
}
}

const mapStateToProps = (state, ownProps) => ({
organization: ownProps.component.organization && getOrganizationByKey(state, ownProps.component.organization),
shouldOrganizationBeDisplayed: areThereCustomOrganizations(state)
});

export default connect(mapStateToProps)(ComponentNavBreadcrumbs);

export const Unconnected = ComponentNavBreadcrumbs;

+ 14
- 4
server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBreadcrumbs-test.js View File

@@ -19,11 +19,21 @@
*/
import React from 'react';
import { shallow } from 'enzyme';
import ComponentNavBreadcrumbs from '../ComponentNavBreadcrumbs';
import { Unconnected } from '../ComponentNavBreadcrumbs';

it('should not render breadcrumbs with one element', () => {
const breadcrumbs = [{ key: 'my-project', name: 'My Project', qualifier: 'TRK' }];
const result = shallow(<ComponentNavBreadcrumbs breadcrumbs={breadcrumbs}/>);
expect(result.find('li').length).toBe(1);
expect(result.find('a').length).toBe(1);
const result = shallow(<Unconnected breadcrumbs={breadcrumbs}/>);
expect(result).toMatchSnapshot();
});

it('should render organization', () => {
const breadcrumbs = [{ key: 'my-project', name: 'My Project', qualifier: 'TRK' }];
const organization = { key: 'foo', name: 'The Foo Organization' };
const result = shallow(
<Unconnected
breadcrumbs={breadcrumbs}
organization={organization}
shouldOrganizationBeDisplayed={true}/>);
expect(result).toMatchSnapshot();
});

+ 52
- 0
server/sonar-web/src/main/js/app/components/nav/component/__tests__/__snapshots__/ComponentNavBreadcrumbs-test.js.snap View File

@@ -0,0 +1,52 @@
exports[`test should not render breadcrumbs with one element 1`] = `
<ul
className="nav navbar-nav nav-crumbs">
<li>
<Link
onlyActiveOnIndex={false}
style={Object {}}
to={
Object {
"pathname": "/dashboard",
"query": Object {
"id": "my-project",
},
}
}>
<qualifier-icon
qualifier="TRK" />
My Project
</Link>
</li>
</ul>
`;

exports[`test should render organization 1`] = `
<ul
className="nav navbar-nav nav-crumbs">
<li>
<span>
The Foo Organization
</span>
</li>
<li>
<Link
onlyActiveOnIndex={false}
style={Object {}}
to={
Object {
"pathname": "/dashboard",
"query": Object {
"id": "my-project",
},
}
}>
<qualifier-icon
qualifier="TRK" />
My Project
</Link>
</li>
</ul>
`;

+ 8
- 3
server/sonar-web/src/main/js/store/rootActions.js View File

@@ -46,8 +46,8 @@ export const fetchLanguages = () => dispatch => {
);
};

export const fetchOrganizations = () => dispatch => (
getOrganizations().then(
export const fetchOrganizations = (organizations?: Array<string>) => dispatch => (
getOrganizations(organizations).then(
r => dispatch(receiveOrganizations(r.organizations)),
onFail(dispatch)
)
@@ -60,7 +60,12 @@ const addQualifier = project => ({

export const fetchProject = key => dispatch => (
getComponentNavigation(key).then(
component => dispatch(receiveComponents([addQualifier(component)])),
component => {
dispatch(receiveComponents([addQualifier(component)]));
if (component.organization != null) {
dispatch(fetchOrganizations([component.organization]));
}
},
onFail(dispatch)
)
);

+ 1
- 1
server/sonar-web/src/main/less/components/navbar.less View File

@@ -230,7 +230,7 @@

.navbar-context-favorite {
float: left;
padding: 6px 0 0 10px;
padding: 7px 0 0 10px;
}

.navbar-context-meta {

+ 5
- 9
server/sonar-web/src/main/less/components/ui.less View File

@@ -139,6 +139,11 @@
}
}

> li {
font-size: 16px;
font-weight: 400;
}

> li + li:before {
content: "/";
float: left;
@@ -146,15 +151,6 @@
color: fade(@baseFontColor, 30%);
}

> li:first-child {
font-size: 18px;
font-weight: 400;

> a {
color: @baseFontColor;
}
}

[class^="icon-"], [class*=" icon-"] {
position: relative;
top: 2px;

Loading…
Cancel
Save