@@ -24,8 +24,7 @@ export default class EmptyInstance extends React.Component { | |||
render () { | |||
return ( | |||
<div className="projects-empty-list"> | |||
<h3>{translate('projects.no_projects.1')}</h3> | |||
<p className="big-spacer-top">{translate('projects.no_projects.empty_instance')}</p> | |||
<h3>{translate('projects.no_projects.empty_instance')}</h3> | |||
</div> | |||
); | |||
} |
@@ -28,10 +28,10 @@ export default class FavoriteFilter extends React.Component { | |||
} | |||
return ( | |||
<div className="pull-left big-spacer-left"> | |||
<div className="projects-sidebar pull-left text-center"> | |||
<div className="button-group"> | |||
<Link to="/projects/favorite" className="button" activeClassName="button-active"> | |||
{translate('my_favorite')} | |||
{translate('my_favorites')} | |||
</Link> | |||
<IndexLink to="/projects" className="button" activeClassName="button-active"> | |||
{translate('all')} |
@@ -32,7 +32,7 @@ export default class PageHeader extends React.Component { | |||
return ( | |||
<header className="page-header"> | |||
<div className="page-actions"> | |||
<div className="page-actions projects-page-actions"> | |||
{!!loading && ( | |||
<i className="spinner spacer-right"/> | |||
)} | |||
@@ -44,8 +44,6 @@ export default class PageHeader extends React.Component { | |||
)} | |||
</div> | |||
<h1 className="page-title">{translate('projects.page')}</h1> | |||
<FavoriteFilterContainer/> | |||
</header> | |||
); |
@@ -23,6 +23,7 @@ import ProjectCardQualityGate from './ProjectCardQualityGate'; | |||
import ProjectCardMeasures from './ProjectCardMeasures'; | |||
import FavoriteContainer from '../../../components/controls/FavoriteContainer'; | |||
import { getComponentUrl } from '../../../helpers/urls'; | |||
import { translate } from '../../../helpers/l10n'; | |||
export default class ProjectCard extends React.Component { | |||
static propTypes = { | |||
@@ -36,11 +37,14 @@ export default class ProjectCard extends React.Component { | |||
return null; | |||
} | |||
const className = classNames('boxed-group', 'project-card', { 'boxed-group-loading': this.props.measures == null }); | |||
const areProjectMeasuresLoaded = this.props.measures != null; | |||
const isProjectAnalyzed = areProjectMeasuresLoaded && this.props.measures.ncloc != null; | |||
const className = classNames('boxed-group', 'project-card', { 'boxed-group-loading': !areProjectMeasuresLoaded }); | |||
return ( | |||
<div data-key={project.key} className={className}> | |||
{this.props.measures != null && ( | |||
{isProjectAnalyzed && ( | |||
<div className="boxed-group-actions"> | |||
<ProjectCardQualityGate status={this.props.measures['alert_status']}/> | |||
</div> | |||
@@ -53,9 +57,17 @@ export default class ProjectCard extends React.Component { | |||
<a className="link-base-color" href={getComponentUrl(project.key)}>{project.name}</a> | |||
</h2> | |||
</div> | |||
<div className="boxed-group-inner"> | |||
<ProjectCardMeasures measures={this.props.measures}/> | |||
</div> | |||
{isProjectAnalyzed ? ( | |||
<div className="boxed-group-inner"> | |||
<ProjectCardMeasures measures={this.props.measures}/> | |||
</div> | |||
) : ( | |||
<div className="boxed-group-inner"> | |||
<div className="note project-card-not-analyzed"> | |||
{translate('projects.not_analyzed')} | |||
</div> | |||
</div> | |||
)} | |||
</div> | |||
); | |||
} |
@@ -58,11 +58,15 @@ const onFail = dispatch => error => { | |||
dispatch(updateState({ loading: false })); | |||
}; | |||
const onReceiveMeasures = dispatch => response => { | |||
const onReceiveMeasures = (dispatch, expectedProjectKeys) => response => { | |||
const byComponentKey = groupBy(response.measures, 'component'); | |||
const toStore = {}; | |||
// fill store with empty objects for expected projects | |||
// this is required to not have "null"s for provisioned projects | |||
expectedProjectKeys.forEach(projectKey => toStore[projectKey] = {}); | |||
Object.keys(byComponentKey).forEach(componentKey => { | |||
const measures = {}; | |||
byComponentKey[componentKey].forEach(measure => { | |||
@@ -80,7 +84,7 @@ const fetchProjectMeasures = projects => dispatch => { | |||
} | |||
const projectKeys = projects.map(project => project.key); | |||
return getMeasuresForProjects(projectKeys, METRICS).then(onReceiveMeasures(dispatch), onFail(dispatch)); | |||
return getMeasuresForProjects(projectKeys, METRICS).then(onReceiveMeasures(dispatch, projectKeys), onFail(dispatch)); | |||
}; | |||
const handleFavorites = (dispatch, projects) => { |
@@ -1,3 +1,7 @@ | |||
.projects-page-actions { | |||
margin-bottom: 0; | |||
} | |||
.projects-sidebar { | |||
width: 260px; | |||
} | |||
@@ -84,6 +88,10 @@ | |||
line-height: 24px; | |||
} | |||
.project-card-not-analyzed { | |||
padding: 14px 0; | |||
} | |||
.projects-facet-header { | |||
padding-top: 10px; | |||
padding-bottom: 10px; |
@@ -101,6 +101,7 @@ more=More | |||
more_actions=More Actions | |||
moreCriteria=+ More Criteria | |||
my_favorite=My Favorite | |||
my_favorites=My Favorites | |||
name=Name | |||
name_too_long_x=Name is too long (maximum is {0} characters) | |||
navigation=Navigation | |||
@@ -812,6 +813,7 @@ projects.clear_all_filters=Clear All Filters | |||
projects.no_favorite_projects=You don't have any favorite projects yet. | |||
projects.no_favorite_projects.engagement=Discover and mark as favorites projects you are interested in to have a quick access to them. | |||
projects.explore_projects=Explore Projects | |||
projects.not_analyzed=Project is not analyzed yet. | |||
#------------------------------------------------------------------------------ |