@@ -170,11 +170,16 @@ export default class CrossFileLocationNavigator extends React.PureComponent<Prop | |||
render() { | |||
const { locations } = this.props; | |||
const groups = this.groupByFile(locations); | |||
const MIN_LOCATION_LENGTH = 2; | |||
// below: fold the location list when there are >3 locations | |||
const MIN_LOCATION_LENGTH = 3; | |||
if (locations.length > MIN_LOCATION_LENGTH && groups.length > 1 && this.state.collapsed) { | |||
// the top and bottom locations are always displayed | |||
const nbLocationsAlwaysDisplayed = 2; | |||
const firstGroup = groups[0]; | |||
const lastGroup = groups[groups.length - 1]; | |||
return ( | |||
<div className="spacer-top"> | |||
{this.renderGroup(firstGroup, 0, { onlyFirst: true })} | |||
@@ -184,7 +189,7 @@ export default class CrossFileLocationNavigator extends React.PureComponent<Prop | |||
<a className="location-file-more" href="#" onClick={this.handleMoreLocationsClick}> | |||
{translateWithParameters( | |||
'issues.x_more_locations', | |||
locations.length - MIN_LOCATION_LENGTH | |||
locations.length - nbLocationsAlwaysDisplayed | |||
)} | |||
</a> | |||
</div> |
@@ -45,6 +45,13 @@ const location3: FlowLocation = { | |||
textRange: { startLine: 15, endLine: 16, startOffset: 4, endOffset: 6 }, | |||
}; | |||
const location4: FlowLocation = { | |||
component: 'bar', | |||
componentName: 'src/bar.js', | |||
msg: 'Do not use bar', | |||
textRange: { startLine: 17, endLine: 18, startOffset: 7, endOffset: 9 }, | |||
}; | |||
it('should render with no locations', () => { | |||
expect(shallowRender({ locations: [] })).toMatchSnapshot(); | |||
}); | |||
@@ -60,13 +67,13 @@ it('should render', () => { | |||
expect(wrapper.find('SingleFileLocationNavigator').length).toBe(2); | |||
click(wrapper.find('.location-file-more')); | |||
expect(wrapper.find('SingleFileLocationNavigator').length).toBe(3); | |||
expect(wrapper.find('SingleFileLocationNavigator').length).toBe(4); | |||
}); | |||
it('should render all locations', () => { | |||
const wrapper = shallowRender({ locations: [location1, location2] }); | |||
const wrapper = shallowRender({ locations: [location1, location2, location3] }); | |||
expect(wrapper.find('SingleFileLocationNavigator').length).toBe(2); | |||
expect(wrapper.find('SingleFileLocationNavigator').length).toBe(3); | |||
}); | |||
it('should expand all locations', () => { | |||
@@ -74,13 +81,13 @@ it('should expand all locations', () => { | |||
expect(wrapper.find('SingleFileLocationNavigator').length).toBe(2); | |||
wrapper.setProps({ selectedLocationIndex: 1 }); | |||
expect(wrapper.find('SingleFileLocationNavigator').length).toBe(3); | |||
expect(wrapper.find('SingleFileLocationNavigator').length).toBe(4); | |||
}); | |||
function shallowRender(props: Partial<CrossFileLocationsNavigator['props']> = {}) { | |||
return shallow<CrossFileLocationsNavigator>( | |||
<CrossFileLocationsNavigator | |||
locations={[location1, location2, location3]} | |||
locations={[location1, location2, location3, location4]} | |||
onLocationSelect={jest.fn()} | |||
selectedLocationIndex={undefined} | |||
{...props} |
@@ -42,7 +42,7 @@ exports[`should render 1`] = ` | |||
href="#" | |||
onClick={[Function]} | |||
> | |||
issues.x_more_locations.1 | |||
issues.x_more_locations.2 | |||
</a> | |||
</div> | |||
</div> | |||
@@ -62,8 +62,8 @@ exports[`should render 1`] = ` | |||
className="location-file-locations" | |||
> | |||
<SingleFileLocationNavigator | |||
index={2} | |||
key="2" | |||
index={3} | |||
key="3" | |||
message="Do not use bar" | |||
onClick={[MockFunction]} | |||
selected={false} |
@@ -944,7 +944,7 @@ issues.max_new_code_period=Max New Code Period | |||
issues.my_issues=My Issues | |||
issues.no_my_issues=There are no issues assigned to you. | |||
issues.no_issues=No Issues. Hooray! | |||
issues.x_more_locations=+ {0} more location(s) | |||
issues.x_more_locations=+ {0} more locations | |||
issues.not_all_issue_show=Not all issues are included | |||
issues.not_all_issue_show_why=You do not have access to all projects in this portfolio | |||