aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/src
diff options
context:
space:
mode:
authorStas Vilchik <vilchiks@gmail.com>2017-05-01 15:06:25 +0200
committerStas Vilchik <stas-vilchik@users.noreply.github.com>2017-05-02 14:45:47 +0200
commit19f9ad34bdca23ae4cfcc0bd601581f7c9c5442e (patch)
treefb67bd5531c4c1f921149e937195a7bcd8d62e06 /server/sonar-web/src
parentcfa382b33eb58413abcf84635d5e45d1f21c4f21 (diff)
downloadsonarqube-19f9ad34bdca23ae4cfcc0bd601581f7c9c5442e.tar.gz
sonarqube-19f9ad34bdca23ae4cfcc0bd601581f7c9c5442e.zip
SONAR-9164 Display project visibility badge
Diffstat (limited to 'server/sonar-web/src')
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBreadcrumbs.js7
-rw-r--r--server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBreadcrumbs-test.js32
-rw-r--r--server/sonar-web/src/main/js/apps/projects-admin/main.js2
-rw-r--r--server/sonar-web/src/main/js/apps/projects-admin/projects.js4
-rw-r--r--server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js2
-rw-r--r--server/sonar-web/src/main/js/components/common/PrivateBadge.css12
-rw-r--r--server/sonar-web/src/main/js/components/common/PrivateBadge.js39
7 files changed, 93 insertions, 5 deletions
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBreadcrumbs.js b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBreadcrumbs.js
index 653ad06f901..6a8b16d5e36 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBreadcrumbs.js
+++ b/server/sonar-web/src/main/js/app/components/nav/component/ComponentNavBreadcrumbs.js
@@ -23,10 +23,14 @@ import { Link } from 'react-router';
import QualifierIcon from '../../../../components/shared/QualifierIcon';
import { getOrganizationByKey, areThereCustomOrganizations } from '../../../../store/rootReducer';
import OrganizationLink from '../../../../components/ui/OrganizationLink';
+import PrivateBadge from '../../../../components/common/PrivateBadge';
class ComponentNavBreadcrumbs extends React.PureComponent {
static propTypes = {
- breadcrumbs: React.PropTypes.array
+ breadcrumbs: React.PropTypes.array,
+ component: React.PropTypes.shape({
+ visibility: React.PropTypes.string
+ }).isRequired
};
render() {
@@ -73,6 +77,7 @@ class ComponentNavBreadcrumbs extends React.PureComponent {
<span className="slash-separator" />
</span>}
{items}
+ {this.props.component.visibility === 'private' && <PrivateBadge className="spacer-left" />}
</h2>
);
}
diff --git a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBreadcrumbs-test.js b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBreadcrumbs-test.js
index 6fce85f2d97..3a524a9ee61 100644
--- a/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBreadcrumbs-test.js
+++ b/server/sonar-web/src/main/js/app/components/nav/component/__tests__/ComponentNavBreadcrumbs-test.js
@@ -22,20 +22,46 @@ import { shallow } from 'enzyme';
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(<Unconnected breadcrumbs={breadcrumbs} />);
+ const component = {
+ key: 'my-project',
+ name: 'My Project',
+ qualifier: 'TRK',
+ visibility: 'public'
+ };
+ const breadcrumbs = [component];
+ const result = shallow(<Unconnected breadcrumbs={breadcrumbs} component={component} />);
expect(result).toMatchSnapshot();
});
it('should render organization', () => {
- const breadcrumbs = [{ key: 'my-project', name: 'My Project', qualifier: 'TRK' }];
+ const component = {
+ key: 'my-project',
+ name: 'My Project',
+ organization: 'foo',
+ qualifier: 'TRK',
+ visibility: 'public'
+ };
+ const breadcrumbs = [component];
const organization = { key: 'foo', name: 'The Foo Organization' };
const result = shallow(
<Unconnected
breadcrumbs={breadcrumbs}
+ component={component}
organization={organization}
shouldOrganizationBeDisplayed={true}
/>
);
expect(result).toMatchSnapshot();
});
+
+it('renders private badge', () => {
+ const component = {
+ key: 'my-project',
+ name: 'My Project',
+ qualifier: 'TRK',
+ visibility: 'private'
+ };
+ const breadcrumbs = [component];
+ const result = shallow(<Unconnected breadcrumbs={breadcrumbs} component={component} />);
+ expect(result.find('PrivateBadge')).toHaveLength(1);
+});
diff --git a/server/sonar-web/src/main/js/apps/projects-admin/main.js b/server/sonar-web/src/main/js/apps/projects-admin/main.js
index c7b6340673e..3079aae3c63 100644
--- a/server/sonar-web/src/main/js/apps/projects-admin/main.js
+++ b/server/sonar-web/src/main/js/apps/projects-admin/main.js
@@ -108,7 +108,7 @@ export default class Main extends React.PureComponent {
if (this.state.page > 1) {
projects = [].concat(this.state.projects, projects);
}
- this.setState({ ready: true, projects, total: r.total });
+ this.setState({ ready: true, projects, total: r.paging.total });
});
};
diff --git a/server/sonar-web/src/main/js/apps/projects-admin/projects.js b/server/sonar-web/src/main/js/apps/projects-admin/projects.js
index a6def849018..bcb3b1c82e0 100644
--- a/server/sonar-web/src/main/js/apps/projects-admin/projects.js
+++ b/server/sonar-web/src/main/js/apps/projects-admin/projects.js
@@ -24,6 +24,7 @@ import { getComponentPermissionsUrl } from '../../helpers/urls';
import ApplyTemplateView from '../permissions/project/views/ApplyTemplateView';
import Checkbox from '../../components/controls/Checkbox';
import QualifierIcon from '../../components/shared/QualifierIcon';
+import PrivateBadge from '../../components/common/PrivateBadge';
import { translate } from '../../helpers/l10n';
export default class Projects extends React.PureComponent {
@@ -81,6 +82,9 @@ export default class Projects extends React.PureComponent {
<td className="nowrap">
<span className="note">{project.key}</span>
</td>
+ <td className="width-20">
+ {project.visibility === 'private' && <PrivateBadge />}
+ </td>
<td className="thin nowrap">
<div className="dropdown">
<button className="dropdown-toggle" data-toggle="dropdown">
diff --git a/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js b/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js
index 018b753affc..40a74de7747 100644
--- a/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js
+++ b/server/sonar-web/src/main/js/apps/projects/components/ProjectCard.js
@@ -27,6 +27,7 @@ import ProjectCardMeasures from './ProjectCardMeasures';
import FavoriteContainer from '../../../components/controls/FavoriteContainer';
import Organization from '../../../components/shared/Organization';
import TagsList from '../../../components/tags/TagsList';
+import PrivateBadge from '../../../components/common/PrivateBadge';
import { translate, translateWithParameters } from '../../../helpers/l10n';
export default class ProjectCard extends React.PureComponent {
@@ -84,6 +85,7 @@ export default class ProjectCard extends React.PureComponent {
{project.name}
</Link>
</h2>
+ {project.visibility === 'private' && <PrivateBadge className="spacer-left" />}
{project.tags.length > 0 && <TagsList tags={project.tags} customClass="spacer-left" />}
</div>
diff --git a/server/sonar-web/src/main/js/components/common/PrivateBadge.css b/server/sonar-web/src/main/js/components/common/PrivateBadge.css
new file mode 100644
index 00000000000..6de55f9937f
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/common/PrivateBadge.css
@@ -0,0 +1,12 @@
+.private-badge {
+ display: inline-block;
+ vertical-align: middle;
+ height: 20px;
+ line-height: 19px;
+ padding: 0 8px;
+ border: 1px solid #cdcdcd;
+ border-radius: 2px;
+ box-sizing: border-box;
+ color: #777;
+ font-size: 12px;
+} \ No newline at end of file
diff --git a/server/sonar-web/src/main/js/components/common/PrivateBadge.js b/server/sonar-web/src/main/js/components/common/PrivateBadge.js
new file mode 100644
index 00000000000..775c0727911
--- /dev/null
+++ b/server/sonar-web/src/main/js/components/common/PrivateBadge.js
@@ -0,0 +1,39 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2017 SonarSource SA
+ * mailto:info 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.
+ */
+// @flow
+import React from 'react';
+import classNames from 'classnames';
+import Tooltip from '../controls/Tooltip';
+import { translate } from '../../helpers/l10n';
+import './PrivateBadge.css';
+
+type Props = {
+ className?: string
+};
+
+export default function PrivateBadge(props: Props) {
+ return (
+ <Tooltip overlay={translate('visibility.private.description')}>
+ <div className={classNames('private-badge', props.className)}>
+ {translate('visibility.private')}
+ </div>
+ </Tooltip>
+ );
+}