mirror of
https://github.com/SomboChea/ui
synced 2024-11-28 08:54:27 +07:00
refactor: convert Author component to hooks (#150)
This commit is contained in:
parent
a365ec548a
commit
d2f1f1c06a
@ -1,24 +1,15 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
|
|
||||||
|
import { DetailContext } from '../../pages/Version';
|
||||||
|
|
||||||
import Authors from './Author';
|
import Authors from './Author';
|
||||||
|
|
||||||
const mockPackageMeta = jest.fn(() => ({
|
const withAuthorComponent = (packageMeta: React.ContextType<typeof DetailContext>['packageMeta']): JSX.Element => (
|
||||||
latest: {
|
<DetailContext.Provider value={{ packageMeta }}>
|
||||||
homepage: 'https://verdaccio.tld',
|
<Authors />
|
||||||
bugs: {
|
</DetailContext.Provider>
|
||||||
url: 'https://verdaccio.tld/bugs',
|
);
|
||||||
},
|
|
||||||
dist: {
|
|
||||||
tarball: 'https://verdaccio.tld/download',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
jest.mock('../../pages/Version', () => ({
|
|
||||||
DetailContextConsumer: component => {
|
|
||||||
return component.children({ packageMeta: mockPackageMeta() });
|
|
||||||
},
|
|
||||||
}));
|
|
||||||
|
|
||||||
describe('<Author /> component', () => {
|
describe('<Author /> component', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
@ -36,13 +27,12 @@ describe('<Author /> component', () => {
|
|||||||
url: '',
|
url: '',
|
||||||
avatar: 'https://www.gravatar.com/avatar/000000',
|
avatar: 'https://www.gravatar.com/avatar/000000',
|
||||||
},
|
},
|
||||||
|
dist: { fileCount: 0, unpackedSize: 0 },
|
||||||
},
|
},
|
||||||
|
_uplinks: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
// @ts-ignore
|
const wrapper = mount(withAuthorComponent(packageMeta));
|
||||||
mockPackageMeta.mockImplementation(() => packageMeta);
|
|
||||||
|
|
||||||
const wrapper = mount(<Authors />);
|
|
||||||
expect(wrapper.html()).toMatchSnapshot();
|
expect(wrapper.html()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -51,14 +41,13 @@ describe('<Author /> component', () => {
|
|||||||
latest: {
|
latest: {
|
||||||
name: 'verdaccio',
|
name: 'verdaccio',
|
||||||
version: '4.0.0',
|
version: '4.0.0',
|
||||||
|
dist: { fileCount: 0, unpackedSize: 0 },
|
||||||
},
|
},
|
||||||
|
_uplinks: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
// @ts-ignore
|
const wrapper = mount(withAuthorComponent(packageMeta));
|
||||||
mockPackageMeta.mockImplementation(() => packageMeta);
|
expect(wrapper.html()).toBeNull();
|
||||||
|
|
||||||
const wrapper = mount(<Authors />);
|
|
||||||
expect(wrapper.html()).toEqual('');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test('should render the component when there is no author email', () => {
|
test('should render the component when there is no author email', () => {
|
||||||
@ -71,13 +60,12 @@ describe('<Author /> component', () => {
|
|||||||
url: '',
|
url: '',
|
||||||
avatar: 'https://www.gravatar.com/avatar/000000',
|
avatar: 'https://www.gravatar.com/avatar/000000',
|
||||||
},
|
},
|
||||||
|
dist: { fileCount: 0, unpackedSize: 0 },
|
||||||
},
|
},
|
||||||
|
_uplinks: {},
|
||||||
};
|
};
|
||||||
|
|
||||||
// @ts-ignore
|
const wrapper = mount(withAuthorComponent(packageMeta));
|
||||||
mockPackageMeta.mockImplementation(() => packageMeta);
|
|
||||||
|
|
||||||
const wrapper = mount(<Authors />);
|
|
||||||
expect(wrapper.html()).toMatchSnapshot();
|
expect(wrapper.html()).toMatchSnapshot();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,58 +1,44 @@
|
|||||||
import React, { Component, ReactNode, ReactElement } from 'react';
|
import React, { FC, useContext } from 'react';
|
||||||
|
|
||||||
import Avatar from '@material-ui/core/Avatar';
|
import Avatar from '@material-ui/core/Avatar';
|
||||||
import List from '@material-ui/core/List';
|
import List from '@material-ui/core/List';
|
||||||
|
|
||||||
import { DetailContextConsumer } from '../../pages/Version';
|
import { DetailContext } from '../../pages/Version';
|
||||||
import { Heading, AuthorListItem, AuthorListItemText } from './styles';
|
import { Heading, AuthorListItem, AuthorListItemText } from './styles';
|
||||||
import { isEmail } from '../../utils/url';
|
import { isEmail } from '../../utils/url';
|
||||||
|
|
||||||
class Authors extends Component {
|
const Authors: FC = () => {
|
||||||
public render(): ReactElement<HTMLElement> {
|
const { packageMeta } = useContext(DetailContext);
|
||||||
return (
|
|
||||||
<DetailContextConsumer>
|
|
||||||
{context => {
|
|
||||||
const { packageMeta } = context;
|
|
||||||
|
|
||||||
if (!packageMeta) {
|
if (!packageMeta) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return this.renderAuthor(packageMeta);
|
const { author, name: packageName, version } = packageMeta.latest;
|
||||||
}}
|
|
||||||
</DetailContextConsumer>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public renderLinkForMail(email: string, avatarComponent: ReactNode, packageName: string, version: string): ReactElement<HTMLElement> | ReactNode {
|
|
||||||
if (!email || isEmail(email) === false) {
|
|
||||||
return avatarComponent;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<a href={`mailto:${email}?subject=${packageName}@${version}`} target={'_top'}>
|
|
||||||
{avatarComponent}
|
|
||||||
</a>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public renderAuthor = ({ latest }) => {
|
|
||||||
const { author, name: packageName, version } = latest;
|
|
||||||
|
|
||||||
if (!author) {
|
if (!author) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const { email, name } = author;
|
||||||
|
|
||||||
const avatarComponent = <Avatar alt={author.name} src={author.avatar} />;
|
const avatarComponent = <Avatar alt={author.name} src={author.avatar} />;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<List subheader={<Heading variant={'subtitle1'}>{'Author'}</Heading>}>
|
<List subheader={<Heading variant={'subtitle1'}>{'Author'}</Heading>}>
|
||||||
<AuthorListItem button={true}>
|
<AuthorListItem button={true}>
|
||||||
{this.renderLinkForMail(author.email, avatarComponent, packageName, version)}
|
{!email || !isEmail(email) ? (
|
||||||
<AuthorListItemText primary={author.name} />
|
avatarComponent
|
||||||
|
) : (
|
||||||
|
<a href={`mailto:${email}?subject=${packageName}@${version}`} target={'_top'}>
|
||||||
|
{avatarComponent}
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<AuthorListItemText primary={name} />
|
||||||
</AuthorListItem>
|
</AuthorListItem>
|
||||||
</List>
|
</List>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
export default Authors;
|
export default Authors;
|
||||||
|
@ -5,7 +5,7 @@ import Grid from '@material-ui/core/Grid';
|
|||||||
import HomeIcon from '@material-ui/icons/Home';
|
import HomeIcon from '@material-ui/icons/Home';
|
||||||
import ListItem from '@material-ui/core/ListItem';
|
import ListItem from '@material-ui/core/ListItem';
|
||||||
|
|
||||||
import { PackageMetaInterface } from 'types/packageMeta';
|
import { PackageMetaInterface, Author as PackageAuthor } from 'types/packageMeta';
|
||||||
import Tag from '../Tag';
|
import Tag from '../Tag';
|
||||||
import fileSizeSI from '../../utils/file-size';
|
import fileSizeSI from '../../utils/file-size';
|
||||||
import { formatDate, formatDateDistance } from '../../utils/package';
|
import { formatDate, formatDateDistance } from '../../utils/package';
|
||||||
@ -28,11 +28,6 @@ import {
|
|||||||
WrapperLink,
|
WrapperLink,
|
||||||
} from './styles';
|
} from './styles';
|
||||||
import { isURL } from '../../utils/url';
|
import { isURL } from '../../utils/url';
|
||||||
interface Author {
|
|
||||||
name: string;
|
|
||||||
avatar?: string;
|
|
||||||
email?: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Bugs {
|
interface Bugs {
|
||||||
url: string;
|
url: string;
|
||||||
@ -45,7 +40,7 @@ export interface PackageInterface {
|
|||||||
name: string;
|
name: string;
|
||||||
version: string;
|
version: string;
|
||||||
time?: number | string;
|
time?: number | string;
|
||||||
author: Author;
|
author: PackageAuthor;
|
||||||
description?: string;
|
description?: string;
|
||||||
keywords?: string[];
|
keywords?: string[];
|
||||||
license?: PackageMetaInterface['latest']['license'];
|
license?: PackageMetaInterface['latest']['license'];
|
||||||
|
@ -3,12 +3,14 @@ export interface PackageMetaInterface {
|
|||||||
distTags?: DistTags;
|
distTags?: DistTags;
|
||||||
time?: Time;
|
time?: Time;
|
||||||
latest: {
|
latest: {
|
||||||
|
author?: Author;
|
||||||
name: string;
|
name: string;
|
||||||
dist: {
|
dist: {
|
||||||
fileCount: number;
|
fileCount: number;
|
||||||
unpackedSize: number;
|
unpackedSize: number;
|
||||||
};
|
};
|
||||||
license?: Partial<LicenseInterface> | string;
|
license?: Partial<LicenseInterface> | string;
|
||||||
|
version: string;
|
||||||
};
|
};
|
||||||
_uplinks: {};
|
_uplinks: {};
|
||||||
}
|
}
|
||||||
@ -41,10 +43,11 @@ export interface Version {
|
|||||||
keywords?: string[];
|
keywords?: string[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Author {
|
export interface Author {
|
||||||
name?: string;
|
name?: string;
|
||||||
email?: string;
|
email?: string;
|
||||||
url?: string;
|
url?: string;
|
||||||
|
avatar?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Maintainer {
|
interface Maintainer {
|
||||||
|
Loading…
Reference in New Issue
Block a user