Skip to content
This repository has been archived by the owner on Jan 16, 2022. It is now read-only.

Refactor/116 RegistryInfoContent is converted to functional component #229

Merged
merged 18 commits into from
Nov 2, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 9 additions & 8 deletions src/components/PackageList/PackageList.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Fragment, ReactElement } from 'react';
import React, { Fragment, ReactNode } from 'react';

import Package from '../Package';
import Help from '../Help';
Expand All @@ -12,22 +12,23 @@ interface Props {
packages: PackageInterface[];
}

export const PackageList: React.FC<Props> = props => {
const renderPackages: () => ReactElement<HTMLElement>[] = () => {
return props.packages.map((pkg, i) => {
const { name, version, description, time, keywords, dist, homepage, bugs, author } = pkg;
export const PackageList: React.FC<Props> = ({ packages }) => {
const renderPackages: () => ReactNode[] = () => {
return packages.map(({ name, version, description, time, keywords, dist, homepage, bugs, author, license }, i) => {
// TODO: move format license to API side.
const license = formatLicense(pkg.license);
const _license = formatLicense(license);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please why did you add _ ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we cant name this variable license the props already have a prop named license I presume this why the component was not destructuring the props before. this way we could call pkg.license

return (
<Fragment key={i}>
{i !== 0 && <Divider />}
<Package {...{ name, dist, version, author, description, license, time, keywords, homepage, bugs }} />
<Package
{...{ name, dist, version, author, description, license: _license, time, keywords, homepage, bugs }}
/>
</Fragment>
);
});
};

const hasPackages: () => boolean = () => props.packages.length > 0;
const hasPackages: () => boolean = () => packages.length > 0;

return (
<div className={'package-list-items'}>
Expand Down
36 changes: 24 additions & 12 deletions src/components/RegistryInfoContent/RegistryInfoContent.test.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,35 @@
import React from 'react';
import { mount } from 'enzyme';
import { render, cleanup, fireEvent } from '@testing-library/react';

import RegistryInfoContent from './RegistryInfoContent';

describe('<RegistryInfoContent /> component', () => {
test('should render the component in default state with npm tab', () => {
const wrapper = mount(<RegistryInfoContent registryUrl="https://registry.verdaccio.org" scope="@" />);
expect(wrapper.html()).toMatchSnapshot();
afterEach(() => {
cleanup();
});

test('should render the component in default state with pnpm tab', () => {
const wrapper = mount(<RegistryInfoContent registryUrl="https://registry.verdaccio.org" scope="@" />);
wrapper.setState({ tabPosition: 1 });
expect(wrapper.html()).toMatchSnapshot();
test('should load the component with no data', () => {
const { getByTestId } = render(<RegistryInfoContent registryUrl={''} scope={''} />);
const unorderedListOfTodos = getByTestId('tabs-el');
expect(unorderedListOfTodos.children.length).toBe(1);
});

test('should render the component in default state with yarn tab', () => {
const wrapper = mount(<RegistryInfoContent registryUrl="https://registry.verdaccio.org" scope="@" />);
wrapper.setState({ tabPosition: 2 });
expect(wrapper.html()).toMatchSnapshot();
test('should load the appropiate tab content when the tab is clicked', () => {
const props = { registryUrl: 'http://localhost:4872', scope: '@' };
const pnpmTabTextContent = `pnpm adduser --registry ${props.registryUrl}`;

// Render the component.
const { container, getByTestId } = render(
<RegistryInfoContent registryUrl={props.registryUrl} scope={props.scope} />
);

// Assert the text content for pnpm tab is not present intially
expect(container.textContent).not.toContain(pnpmTabTextContent);

const pnpmTab = getByTestId('pnpm-tab');
fireEvent.click(pnpmTab);

// Assert the text content is correct after clicking on the tab.
expect(container.textContent).toContain(pnpmTabTextContent);
});
});
117 changes: 54 additions & 63 deletions src/components/RegistryInfoContent/RegistryInfoContent.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { Component } from 'react';
import React, { useState } from 'react';
priscilawebdev marked this conversation as resolved.
Show resolved Hide resolved
import { css } from 'emotion';

import CopyToClipBoard from '../CopyToClipBoard';
Expand All @@ -11,86 +11,77 @@ import Tab from '../../muiComponents/Tab';
import { CommandContainer } from './styles';
import { Props, State } from './types';

/* eslint react/prop-types:0 */
function TabContainer({ children }): JSX.Element {
return (
<CommandContainer>
<Typography
className={css`
padding: 0;
min-height: 170;
`}
component="div">
{children}
</Typography>
</CommandContainer>
);
}
const RegistryInfoContent: React.FC<Props> = props => {
const [tabPosition, setTabPosition] = useState<State['tabPosition']>(0);
priscilawebdev marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const [tabPosition, setTabPosition] = useState<State['tabPosition']>(0);
const [tabPosition, setTabPosition] = useState(0);

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

as discussed I think it should be ok to be explicit here

const handleChange = (event: React.ChangeEvent<{}>, tabPosition: number): void => {
event.preventDefault();
setTabPosition(tabPosition);
};

class RegistryInfoContent extends Component<Props, State> {
public state = {
tabPosition: 0,
const renderNpmTab = (scope: string, registryUrl: string): JSX.Element => {
return (
<>
<CopyToClipBoard text={getCLISetConfigRegistry(`${NODE_MANAGER.npm} set`, scope, registryUrl)} />
<CopyToClipBoard text={getCLISetRegistry(`${NODE_MANAGER.npm} adduser`, registryUrl)} />
<CopyToClipBoard text={getCLIChangePassword(NODE_MANAGER.npm, registryUrl)} />
</>
);
};

public render(): JSX.Element {
return <div>{this.renderTabs()}</div>;
}
const renderPnpmTab = (scope: string, registryUrl: string): JSX.Element => {
return (
<>
<CopyToClipBoard text={getCLISetConfigRegistry(`${NODE_MANAGER.pnpm} set`, scope, registryUrl)} />
<CopyToClipBoard text={getCLISetRegistry(`${NODE_MANAGER.pnpm} adduser`, registryUrl)} />
<CopyToClipBoard text={getCLIChangePassword(NODE_MANAGER.pnpm, registryUrl)} />
</>
);
};

private handleChange = (event: React.ChangeEvent<{}>, tabPosition: number) => {
event.preventDefault();
this.setState({ tabPosition });
const renderYarnTab = (scope: string, registryUrl: string): JSX.Element => {
return <CopyToClipBoard text={getCLISetConfigRegistry(`${NODE_MANAGER.yarn} config set`, scope, registryUrl)} />;
};

private renderTabs(): JSX.Element {
const { scope, registryUrl } = this.props;
const { tabPosition } = this.state;
const renderTabs = (): JSX.Element => {
const { scope, registryUrl } = props;

return (
<React.Fragment>
<>
<Tabs
data-testid={'tabs-el'}
indicatorColor="primary"
onChange={this.handleChange}
onChange={handleChange}
textColor="primary"
value={tabPosition}
variant="fullWidth">
<Tab label={NODE_MANAGER.npm} />
<Tab label={NODE_MANAGER.pnpm} />
<Tab label={NODE_MANAGER.yarn} />
<Tab data-testid={'npm-tab'} label={NODE_MANAGER.npm} />
<Tab data-testid={'pnpm-tab'} label={NODE_MANAGER.pnpm} />
<Tab data-testid={'yarn-tab'} label={NODE_MANAGER.yarn} />
</Tabs>
{tabPosition === 0 && <TabContainer>{this.renderNpmTab(scope, registryUrl)}</TabContainer>}
{tabPosition === 1 && <TabContainer>{this.renderPNpmTab(scope, registryUrl)}</TabContainer>}
{tabPosition === 2 && <TabContainer>{this.renderYarnTab(scope, registryUrl)}</TabContainer>}
</React.Fragment>
{tabPosition === 0 && <TabContainer>{renderNpmTab(scope, registryUrl)}</TabContainer>}
{tabPosition === 1 && <TabContainer>{renderPnpmTab(scope, registryUrl)}</TabContainer>}
{tabPosition === 2 && <TabContainer>{renderYarnTab(scope, registryUrl)}</TabContainer>}
</>
);
}
};

private renderNpmTab(scope: string, registryUrl: string): JSX.Element {
/* eslint react/prop-types:0 */
const TabContainer = ({ children }): JSX.Element => {
return (
<React.Fragment>
<CopyToClipBoard text={getCLISetConfigRegistry(`${NODE_MANAGER.npm} set`, scope, registryUrl)} />
<CopyToClipBoard text={getCLISetRegistry(`${NODE_MANAGER.npm} adduser`, registryUrl)} />
<CopyToClipBoard text={getCLIChangePassword(NODE_MANAGER.npm, registryUrl)} />
</React.Fragment>
<CommandContainer>
<Typography
className={css`
padding: 0;
min-height: 170;
`}
component="div">
{children}
</Typography>
</CommandContainer>
);
}

private renderPNpmTab(scope: string, registryUrl: string): JSX.Element {
return (
<React.Fragment>
<CopyToClipBoard text={getCLISetConfigRegistry(`${NODE_MANAGER.pnpm} set`, scope, registryUrl)} />
<CopyToClipBoard text={getCLISetRegistry(`${NODE_MANAGER.pnpm} adduser`, registryUrl)} />
<CopyToClipBoard text={getCLIChangePassword(NODE_MANAGER.pnpm, registryUrl)} />
</React.Fragment>
);
}
};

private renderYarnTab(scope: string, registryUrl: string): JSX.Element {
return (
<React.Fragment>
<CopyToClipBoard text={getCLISetConfigRegistry(`${NODE_MANAGER.yarn} config set`, scope, registryUrl)} />
</React.Fragment>
);
}
}
return <div>{renderTabs()}</div>;
};

export default RegistryInfoContent;

This file was deleted.