*/ | */ | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Button } from '../../../components/controls/buttons'; | import { Button } from '../../../components/controls/buttons'; | ||||
import Tooltip from '../../../components/controls/Tooltip'; | |||||
import { translate } from '../../../helpers/l10n'; | import { translate } from '../../../helpers/l10n'; | ||||
export interface PortfolioNewCodeToggleProps { | export interface PortfolioNewCodeToggleProps { | ||||
enabled: boolean; | |||||
showNewCode: boolean; | showNewCode: boolean; | ||||
onNewCodeToggle: (newSelected: boolean) => void; | onNewCodeToggle: (newSelected: boolean) => void; | ||||
} | } | ||||
export default function PortfolioNewCodeToggle(props: PortfolioNewCodeToggleProps) { | export default function PortfolioNewCodeToggle(props: PortfolioNewCodeToggleProps) { | ||||
const { showNewCode } = props; | |||||
const { showNewCode, enabled } = props; | |||||
return ( | return ( | ||||
<div className="big-spacer-right"> | |||||
<div className="button-group"> | |||||
<Tooltip | |||||
overlay={translate('code_viewer.portfolio_code_toggle_disabled.help')} | |||||
visible={enabled ? false : undefined}> | |||||
<div className="big-spacer-right button-group"> | |||||
<Button | <Button | ||||
disabled={!enabled} | |||||
className={showNewCode ? 'button-active' : undefined} | className={showNewCode ? 'button-active' : undefined} | ||||
onClick={() => props.onNewCodeToggle(true)}> | onClick={() => props.onNewCodeToggle(true)}> | ||||
{translate('projects.view.new_code')} | {translate('projects.view.new_code')} | ||||
</Button> | </Button> | ||||
<Button | <Button | ||||
disabled={!enabled} | |||||
className={showNewCode ? undefined : 'button-active'} | className={showNewCode ? undefined : 'button-active'} | ||||
onClick={() => props.onNewCodeToggle(false)}> | onClick={() => props.onNewCodeToggle(false)}> | ||||
{translate('projects.view.overall_code')} | {translate('projects.view.overall_code')} | ||||
</Button> | </Button> | ||||
</div> | </div> | ||||
</div> | |||||
</Tooltip> | |||||
); | ); | ||||
} | } |
* 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. | ||||
*/ | */ | ||||
import { omit } from 'lodash'; | |||||
import { isEmpty, omit } from 'lodash'; | |||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { getTree } from '../../../api/components'; | import { getTree } from '../../../api/components'; | ||||
import SearchBox from '../../../components/controls/SearchBox'; | import SearchBox from '../../../components/controls/SearchBox'; | ||||
render() { | render() { | ||||
const { component, newCodeSelected } = this.props; | const { component, newCodeSelected } = this.props; | ||||
const { loading } = this.state; | |||||
const { loading, query } = this.state; | |||||
const isPortfolio = ['VW', 'SVW', 'APP'].includes(component.qualifier); | const isPortfolio = ['VW', 'SVW', 'APP'].includes(component.qualifier); | ||||
return ( | return ( | ||||
<div className="code-search" id="code-search"> | <div className="code-search" id="code-search"> | ||||
{isPortfolio && ( | {isPortfolio && ( | ||||
<PortfolioNewCodeToggle | <PortfolioNewCodeToggle | ||||
enabled={isEmpty(query)} | |||||
onNewCodeToggle={this.props.onNewCodeToggle} | onNewCodeToggle={this.props.onNewCodeToggle} | ||||
showNewCode={newCodeSelected} | showNewCode={newCodeSelected} | ||||
/> | /> |
import { shallow } from 'enzyme'; | import { shallow } from 'enzyme'; | ||||
import * as React from 'react'; | import * as React from 'react'; | ||||
import { Button } from '../../../../components/controls/buttons'; | import { Button } from '../../../../components/controls/buttons'; | ||||
import Tooltip from '../../../../components/controls/Tooltip'; | |||||
import PortfolioNewCodeToggle, { PortfolioNewCodeToggleProps } from '../PortfolioNewCodeToggle'; | import PortfolioNewCodeToggle, { PortfolioNewCodeToggleProps } from '../PortfolioNewCodeToggle'; | ||||
it('renders correctly', () => { | it('renders correctly', () => { | ||||
expect(shallowRender()).toMatchSnapshot(); | expect(shallowRender()).toMatchSnapshot(); | ||||
}); | }); | ||||
it('should show tooltips when disabled', () => { | |||||
const wrapper = shallowRender({ enabled: false }); | |||||
expect(wrapper.find(Tooltip).props().visible).toBeUndefined(); | |||||
wrapper.setProps({ enabled: true }); | |||||
expect(wrapper.find(Tooltip).props().visible).toBe(false); | |||||
}); | |||||
it('should toggle correctly', () => { | it('should toggle correctly', () => { | ||||
const onNewCodeToggle = jest.fn(); | const onNewCodeToggle = jest.fn(); | ||||
const wrapper = shallowRender({ onNewCodeToggle }); | const wrapper = shallowRender({ onNewCodeToggle }); | ||||
function shallowRender(props?: Partial<PortfolioNewCodeToggleProps>) { | function shallowRender(props?: Partial<PortfolioNewCodeToggleProps>) { | ||||
return shallow( | return shallow( | ||||
<PortfolioNewCodeToggle showNewCode={true} onNewCodeToggle={jest.fn()} {...props} /> | |||||
<PortfolioNewCodeToggle | |||||
showNewCode={true} | |||||
enabled={true} | |||||
onNewCodeToggle={jest.fn()} | |||||
{...props} | |||||
/> | |||||
); | ); | ||||
} | } |
expect(shallowRender()).toMatchSnapshot(); | expect(shallowRender()).toMatchSnapshot(); | ||||
expect( | expect( | ||||
shallowRender({ component: mockComponent({ qualifier: ComponentQualifier.Portfolio }) }) | shallowRender({ component: mockComponent({ qualifier: ComponentQualifier.Portfolio }) }) | ||||
).toMatchSnapshot('node code toggle for portfolio'); | |||||
).toMatchSnapshot('new code toggle for portfolio'); | |||||
expect( | |||||
shallowRender({ | |||||
component: mockComponent({ qualifier: ComponentQualifier.Portfolio }), | |||||
location: mockLocation({ query: { id: 'foo', search: 'bar' } }) | |||||
}) | |||||
).toMatchSnapshot('new code toggle for portfolio disabled'); | |||||
}); | }); | ||||
it('should search correct query on mount', async () => { | it('should search correct query on mount', async () => { |
// Jest Snapshot v1, https://goo.gl/fbAQLP | // Jest Snapshot v1, https://goo.gl/fbAQLP | ||||
exports[`renders correctly 1`] = ` | exports[`renders correctly 1`] = ` | ||||
<div | |||||
className="big-spacer-right" | |||||
<Tooltip | |||||
overlay="code_viewer.portfolio_code_toggle_disabled.help" | |||||
visible={false} | |||||
> | > | ||||
<div | <div | ||||
className="button-group" | |||||
className="big-spacer-right button-group" | |||||
> | > | ||||
<Button | <Button | ||||
className="button-active" | className="button-active" | ||||
disabled={false} | |||||
onClick={[Function]} | onClick={[Function]} | ||||
> | > | ||||
projects.view.new_code | projects.view.new_code | ||||
</Button> | </Button> | ||||
<Button | <Button | ||||
disabled={false} | |||||
onClick={[Function]} | onClick={[Function]} | ||||
> | > | ||||
projects.view.overall_code | projects.view.overall_code | ||||
</Button> | </Button> | ||||
</div> | </div> | ||||
</div> | |||||
</Tooltip> | |||||
`; | `; |
</div> | </div> | ||||
`; | `; | ||||
exports[`should render correcly: node code toggle for portfolio 1`] = ` | |||||
exports[`should render correcly: new code toggle for portfolio 1`] = ` | |||||
<div | <div | ||||
className="code-search" | className="code-search" | ||||
id="code-search" | id="code-search" | ||||
> | > | ||||
<PortfolioNewCodeToggle | <PortfolioNewCodeToggle | ||||
enabled={true} | |||||
onNewCodeToggle={[MockFunction]} | onNewCodeToggle={[MockFunction]} | ||||
showNewCode={false} | showNewCode={false} | ||||
/> | /> | ||||
/> | /> | ||||
</div> | </div> | ||||
`; | `; | ||||
exports[`should render correcly: new code toggle for portfolio disabled 1`] = ` | |||||
<div | |||||
className="code-search" | |||||
id="code-search" | |||||
> | |||||
<PortfolioNewCodeToggle | |||||
enabled={false} | |||||
onNewCodeToggle={[MockFunction]} | |||||
showNewCode={false} | |||||
/> | |||||
<SearchBox | |||||
minLength={3} | |||||
onChange={[Function]} | |||||
onKeyDown={[Function]} | |||||
placeholder="code.search_placeholder.portfolio" | |||||
value="bar" | |||||
/> | |||||
<DeferredSpinner | |||||
className="spacer-left" | |||||
loading={true} | |||||
/> | |||||
</div> | |||||
`; |
code_viewer.no_source_code_displayed_due_to_empty_analysis.SVW=No projects, applications, or portfolios in this portfolio. | code_viewer.no_source_code_displayed_due_to_empty_analysis.SVW=No projects, applications, or portfolios in this portfolio. | ||||
code_viewer.no_source_code_displayed_due_to_security=Due to security settings, no source code can be displayed. | code_viewer.no_source_code_displayed_due_to_security=Due to security settings, no source code can be displayed. | ||||
code_viewer.no_source_code_displayed_due_to_source_removed=The file was removed, no source code can be displayed. | code_viewer.no_source_code_displayed_due_to_source_removed=The file was removed, no source code can be displayed. | ||||
code_viewer.portfolio_code_toggle_disabled.help=New Code and Overall Code measures are not available when searching for projects or applications. | |||||
#------------------------------------------------------------------------------ | #------------------------------------------------------------------------------ | ||||
# | # |