{this.state.projects && ( | {this.state.projects && ( | ||||
<ProjectsList | <ProjectsList | ||||
cardType={this.getView()} | cardType={this.getView()} | ||||
currentUser={this.props.currentUser} | |||||
isFavorite={this.props.isFavorite} | isFavorite={this.props.isFavorite} | ||||
isFiltered={hasFilterParams(this.state.query)} | isFiltered={hasFilterParams(this.state.query)} | ||||
organization={this.props.organization} | organization={this.props.organization} |
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import * as PropTypes from 'prop-types'; | |||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
import { Button } from '../../../components/ui/buttons'; | |||||
import { Organization, CurrentUser, isLoggedIn } from '../../../app/types'; | |||||
import { isSonarCloud } from '../../../helpers/system'; | |||||
export default function EmptyInstance() { | |||||
return ( | |||||
<div className="projects-empty-list"> | |||||
<h3>{translate('projects.no_projects.empty_instance')}</h3> | |||||
</div> | |||||
); | |||||
interface Props { | |||||
organization?: Organization; | |||||
currentUser: CurrentUser; | |||||
} | |||||
export default class EmptyInstance extends React.PureComponent<Props> { | |||||
static contextTypes = { | |||||
openProjectOnboarding: PropTypes.func | |||||
}; | |||||
render() { | |||||
const { currentUser, organization } = this.props; | |||||
const showNewProjectButton = isSonarCloud() | |||||
? organization && organization.canProvisionProjects | |||||
: isLoggedIn(currentUser); | |||||
return ( | |||||
<div className="projects-empty-list"> | |||||
<h3> | |||||
{showNewProjectButton | |||||
? translate('projects.no_projects.empty_instance.new_project') | |||||
: translate('projects.no_projects.empty_instance')} | |||||
</h3> | |||||
{showNewProjectButton && ( | |||||
<div> | |||||
<p className="big-spacer-top"> | |||||
{translate('projects.no_projects.empty_instance.how_to_add_projects')} | |||||
</p> | |||||
<p className="big-spacer-top"> | |||||
<Button onClick={this.context.openProjectOnboarding}> | |||||
{translate('embed_docs.analyze_new_project')} | |||||
</Button> | |||||
</p> | |||||
</div> | |||||
)} | |||||
</div> | |||||
); | |||||
} | |||||
} | } |
import EmptySearch from '../../../components/common/EmptySearch'; | import EmptySearch from '../../../components/common/EmptySearch'; | ||||
import { Project } from '../types'; | import { Project } from '../types'; | ||||
import { Query } from '../query'; | import { Query } from '../query'; | ||||
import { Organization } from '../../../app/types'; | |||||
import { Organization, CurrentUser } from '../../../app/types'; | |||||
interface Props { | interface Props { | ||||
cardType?: string; | cardType?: string; | ||||
currentUser: CurrentUser; | |||||
isFavorite: boolean; | isFavorite: boolean; | ||||
isFiltered: boolean; | isFiltered: boolean; | ||||
organization: Organization | undefined; | organization: Organization | undefined; | ||||
}; | }; | ||||
renderNoProjects() { | renderNoProjects() { | ||||
const { isFavorite, isFiltered, query } = this.props; | |||||
const { currentUser, isFavorite, isFiltered, organization, query } = this.props; | |||||
if (isFiltered) { | if (isFiltered) { | ||||
return isFavorite ? <EmptyFavoriteSearch query={query} /> : <EmptySearch />; | return isFavorite ? <EmptyFavoriteSearch query={query} /> : <EmptySearch />; | ||||
} | } | ||||
return isFavorite ? <NoFavoriteProjects /> : <EmptyInstance />; | |||||
return isFavorite ? ( | |||||
<NoFavoriteProjects /> | |||||
) : ( | |||||
<EmptyInstance currentUser={currentUser} organization={organization} /> | |||||
); | |||||
} | } | ||||
renderRow = ({ index, key, style }: ListRowProps) => { | renderRow = ({ index, key, style }: ListRowProps) => { |
* along with this program; if not, write to the Free Software Foundation, | * along with this program; if not, write to the Free Software Foundation, | ||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||||
*/ | */ | ||||
/* eslint-disable import/order */ | |||||
/* eslint-disable import/order, camelcase */ | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import AllProjects, { Props } from '../AllProjects'; | import AllProjects, { Props } from '../AllProjects'; |
import * as React from 'react'; | import * as React from 'react'; | ||||
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import EmptyInstance from '../EmptyInstance'; | import EmptyInstance from '../EmptyInstance'; | ||||
import { isSonarCloud } from '../../../../helpers/system'; | |||||
it('renders', () => { | |||||
expect(shallow(<EmptyInstance />)).toMatchSnapshot(); | |||||
jest.mock('../../../../helpers/system', () => ({ | |||||
isSonarCloud: jest.fn() | |||||
})); | |||||
it('renders correctly for SQ', () => { | |||||
(isSonarCloud as jest.Mock<any>).mockReturnValue(false); | |||||
expect( | |||||
shallow(<EmptyInstance currentUser={{ isLoggedIn: false }} organization={undefined} />) | |||||
).toMatchSnapshot(); | |||||
expect( | |||||
shallow(<EmptyInstance currentUser={{ isLoggedIn: true }} organization={undefined} />) | |||||
).toMatchSnapshot(); | |||||
}); | |||||
it('renders correctly for SC', () => { | |||||
(isSonarCloud as jest.Mock<any>).mockReturnValue(true); | |||||
expect( | |||||
shallow( | |||||
<EmptyInstance | |||||
currentUser={{ isLoggedIn: false }} | |||||
organization={{ key: 'foo', name: 'Foo' }} | |||||
/> | |||||
) | |||||
).toMatchSnapshot(); | |||||
expect( | |||||
shallow( | |||||
<EmptyInstance | |||||
currentUser={{ isLoggedIn: false }} | |||||
organization={{ canProvisionProjects: true, key: 'foo', name: 'Foo' }} | |||||
/> | |||||
) | |||||
).toMatchSnapshot(); | |||||
}); | }); |
return shallow( | return shallow( | ||||
<ProjectsList | <ProjectsList | ||||
cardType="overall" | cardType="overall" | ||||
currentUser={{ isLoggedIn: true }} | |||||
isFavorite={false} | isFavorite={false} | ||||
isFiltered={false} | isFiltered={false} | ||||
organization={undefined} | organization={undefined} |
> | > | ||||
<ProjectsList | <ProjectsList | ||||
cardType="overall" | cardType="overall" | ||||
currentUser={ | |||||
Object { | |||||
"isLoggedIn": true, | |||||
} | |||||
} | |||||
isFavorite={false} | isFavorite={false} | ||||
isFiltered={false} | isFiltered={false} | ||||
projects={ | projects={ |
// Jest Snapshot v1, https://goo.gl/fbAQLP | // Jest Snapshot v1, https://goo.gl/fbAQLP | ||||
exports[`renders 1`] = ` | |||||
exports[`renders correctly for SC 1`] = ` | |||||
<div | <div | ||||
className="projects-empty-list" | className="projects-empty-list" | ||||
> | > | ||||
</h3> | </h3> | ||||
</div> | </div> | ||||
`; | `; | ||||
exports[`renders correctly for SC 2`] = ` | |||||
<div | |||||
className="projects-empty-list" | |||||
> | |||||
<h3> | |||||
projects.no_projects.empty_instance.new_project | |||||
</h3> | |||||
<div> | |||||
<p | |||||
className="big-spacer-top" | |||||
> | |||||
projects.no_projects.empty_instance.how_to_add_projects | |||||
</p> | |||||
<p | |||||
className="big-spacer-top" | |||||
> | |||||
<Button> | |||||
embed_docs.analyze_new_project | |||||
</Button> | |||||
</p> | |||||
</div> | |||||
</div> | |||||
`; | |||||
exports[`renders correctly for SQ 1`] = ` | |||||
<div | |||||
className="projects-empty-list" | |||||
> | |||||
<h3> | |||||
projects.no_projects.empty_instance | |||||
</h3> | |||||
</div> | |||||
`; | |||||
exports[`renders correctly for SQ 2`] = ` | |||||
<div | |||||
className="projects-empty-list" | |||||
> | |||||
<h3> | |||||
projects.no_projects.empty_instance.new_project | |||||
</h3> | |||||
<div> | |||||
<p | |||||
className="big-spacer-top" | |||||
> | |||||
projects.no_projects.empty_instance.how_to_add_projects | |||||
</p> | |||||
<p | |||||
className="big-spacer-top" | |||||
> | |||||
<Button> | |||||
embed_docs.analyze_new_project | |||||
</Button> | |||||
</p> | |||||
</div> | |||||
</div> | |||||
`; |
<div | <div | ||||
className="projects-list" | className="projects-list" | ||||
> | > | ||||
<EmptyInstance /> | |||||
<EmptyInstance | |||||
currentUser={ | |||||
Object { | |||||
"isLoggedIn": true, | |||||
} | |||||
} | |||||
/> | |||||
</div> | </div> | ||||
`; | `; | ||||
projects.page=Projects | projects.page=Projects | ||||
projects._projects=projects | projects._projects=projects | ||||
projects.no_projects.empty_instance=Once you analyze some projects, they will show up here. | |||||
projects.no_projects.empty_instance=There is no visible project yet. | |||||
projects.no_projects.empty_instance.new_project=Once you analyze some projects, they will show up here. | |||||
projects.no_projects.empty_instance.how_to_add_projects=Here is how you can analyse new projects | |||||
projects.no_favorite_projects=You don't have any favorite projects yet. | 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.no_favorite_projects.engagement=Discover and mark as favorites projects you are interested in to have a quick access to them. | ||||
projects.no_favorite_projects.how_to_add_projects=Here is how to add projects to this page | projects.no_favorite_projects.how_to_add_projects=Here is how to add projects to this page |