import { Project } from '../types';
interface Props {
+ height: number;
organization?: { key: string };
project: Project;
type?: string;
import { Project } from '../types';
interface Props {
+ height: number;
organization?: { key: string };
project: Project;
}
-export default function ProjectCardLeak({ organization, project }: Props) {
+export default function ProjectCardLeak({ height, organization, project }: Props) {
const { measures } = project;
const isPrivate = project.visibility === 'private';
const hasTags = project.tags.length > 0;
return (
- <div className="boxed-group project-card" data-key={project.key}>
+ <div className="boxed-group project-card" data-key={project.key} style={{ height }}>
<div className="boxed-group-header clearfix">
<div className="project-card-header">
{project.isFavorite != null && (
import { Project } from '../types';
interface Props {
+ height: number;
organization?: { key: string };
project: Project;
}
-export default function ProjectCardOverall({ organization, project }: Props) {
+export default function ProjectCardOverall({ height, organization, project }: Props) {
const { measures } = project;
const isPrivate = project.visibility === 'private';
const hasTags = project.tags.length > 0;
return (
- <div className="boxed-group project-card" data-key={project.key}>
+ <div className="boxed-group project-card" data-key={project.key} style={{ height }}>
<div className="boxed-group-header clearfix">
<div className="project-card-header">
{project.isFavorite !== undefined && (
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { AutoSizer } from 'react-virtualized/dist/commonjs/AutoSizer';
+import { List, ListRowProps } from 'react-virtualized/dist/commonjs/List';
+import { WindowScroller } from 'react-virtualized/dist/commonjs/WindowScroller';
import ProjectCard from './ProjectCard';
import NoFavoriteProjects from './NoFavoriteProjects';
import EmptyInstance from './EmptyInstance';
}
export default class ProjectsList extends React.PureComponent<Props> {
+ getCardHeight = () => {
+ return this.props.cardType === 'leak' ? 159 : 143;
+ };
+
renderNoProjects() {
const { isFavorite, isFiltered, query } = this.props;
if (isFiltered) {
return isFavorite ? <NoFavoriteProjects /> : <EmptyInstance />;
}
+ renderRow = ({ index, key, style }: ListRowProps) => {
+ const project = this.props.projects[index];
+ const height = this.getCardHeight();
+ return (
+ <div key={key} style={{ ...style, height }}>
+ <ProjectCard
+ height={height}
+ key={project.key}
+ organization={this.props.organization}
+ project={project}
+ type={this.props.cardType}
+ />
+ </div>
+ );
+ };
+
+ renderList() {
+ const cardHeight = this.getCardHeight();
+ return (
+ <WindowScroller>
+ {({ height, isScrolling, registerChild, onChildScroll, scrollTop }) => (
+ <AutoSizer disableHeight={true}>
+ {({ width }) => (
+ <div ref={registerChild as any}>
+ <List
+ autoHeight={true}
+ height={height}
+ isScrolling={isScrolling}
+ onScroll={onChildScroll}
+ overscanRowCount={2}
+ rowCount={this.props.projects.length}
+ rowHeight={cardHeight + 20}
+ rowRenderer={this.renderRow}
+ scrollTop={scrollTop}
+ style={{ outline: 'none' }}
+ width={width}
+ />
+ </div>
+ )}
+ </AutoSizer>
+ )}
+ </WindowScroller>
+ );
+ }
+
render() {
const { projects } = this.props;
return (
<div className="projects-list">
- {projects.length > 0
- ? projects.map(project => (
- <ProjectCard
- key={project.key}
- organization={this.props.organization}
- project={project}
- type={this.props.cardType}
- />
- ))
- : this.renderNoProjects()}
+ {projects.length > 0 ? this.renderList() : this.renderNoProjects()}
</div>
);
}
};
it('should display analysis date and leak start date', () => {
- const card = shallow(<ProjectCardLeak project={PROJECT} />);
+ const card = shallow(<ProjectCardLeak height={100} project={PROJECT} />);
expect(card.find('.project-card-dates').exists()).toBeTruthy();
expect(card.find('.project-card-dates').find('DateFromNow')).toHaveLength(1);
expect(card.find('.project-card-dates').find('DateTimeFormatter')).toHaveLength(1);
it('should not display analysis date or leak start date', () => {
const project = { ...PROJECT, analysisDate: undefined };
- const card = shallow(<ProjectCardLeak project={project} />);
+ const card = shallow(<ProjectCardLeak height={100} project={project} />);
expect(card.find('.project-card-dates').exists()).toBeFalsy();
});
it('should display tags', () => {
const project = { ...PROJECT, tags: ['foo', 'bar'] };
expect(
- shallow(<ProjectCardLeak project={project} />)
+ shallow(<ProjectCardLeak height={100} project={project} />)
.find('TagsList')
.exists()
).toBeTruthy();
it('should private badge', () => {
const project = { ...PROJECT, visibility: 'private' };
expect(
- shallow(<ProjectCardLeak project={project} />)
+ shallow(<ProjectCardLeak height={100} project={project} />)
.find('PrivateBadge')
.exists()
).toBeTruthy();
});
it('should display the leak measures and quality gate', () => {
- expect(shallow(<ProjectCardLeak project={PROJECT} />)).toMatchSnapshot();
+ expect(shallow(<ProjectCardLeak height={100} project={PROJECT} />)).toMatchSnapshot();
});
it('should display analysis date (and not leak period) when defined', () => {
expect(
- shallow(<ProjectCardOverall project={PROJECT} />)
+ shallow(<ProjectCardOverall height={100} project={PROJECT} />)
.find('.project-card-dates')
.exists()
).toBeTruthy();
expect(
- shallow(<ProjectCardOverall project={{ ...PROJECT, analysisDate: undefined }} />)
+ shallow(<ProjectCardOverall height={100} project={{ ...PROJECT, analysisDate: undefined }} />)
.find('.project-card-dates')
.exists()
).toBeFalsy();
it('should not display the quality gate', () => {
const project = { ...PROJECT, analysisDate: undefined };
expect(
- shallow(<ProjectCardOverall project={project} />)
+ shallow(<ProjectCardOverall height={100} project={project} />)
.find('ProjectCardOverallQualityGate')
.exists()
).toBeFalsy();
it('should display tags', () => {
const project = { ...PROJECT, tags: ['foo', 'bar'] };
expect(
- shallow(<ProjectCardOverall project={project} />)
+ shallow(<ProjectCardOverall height={100} project={project} />)
.find('TagsList')
.exists()
).toBeTruthy();
it('should private badge', () => {
const project = { ...PROJECT, visibility: 'private' };
expect(
- shallow(<ProjectCardOverall project={project} />)
+ shallow(<ProjectCardOverall height={100} project={project} />)
.find('PrivateBadge')
.exists()
).toBeTruthy();
});
it('should display the overall measures and quality gate', () => {
- expect(shallow(<ProjectCardOverall project={PROJECT} />)).toMatchSnapshot();
+ expect(shallow(<ProjectCardOverall height={100} project={PROJECT} />)).toMatchSnapshot();
});
<div
className="boxed-group project-card"
data-key="foo"
+ style={
+ Object {
+ "height": 100,
+ }
+ }
>
<div
className="boxed-group-header clearfix"
<div
className="boxed-group project-card"
data-key="foo"
+ style={
+ Object {
+ "height": 100,
+ }
+ }
>
<div
className="boxed-group-header clearfix"
<div
className="projects-list"
>
- <ProjectCard
- key="foo"
- project={
- Object {
- "key": "foo",
- "name": "Foo",
- }
- }
- type="overall"
- />
- <ProjectCard
- key="bar"
- project={
- Object {
- "key": "bar",
- "name": "Bar",
- }
- }
- type="overall"
+ <WindowScroller
+ onResize={[Function]}
+ onScroll={[Function]}
+ scrollElement={[Window]}
+ scrollingResetTimeInterval={150}
+ serverHeight={0}
+ serverWidth={0}
/>
</div>
`;