mirror of
https://github.com/verdaccio/verdaccio.git
synced 2025-01-06 22:40:26 -05:00
Merge pull request #1230 from verdaccio/4.x-improvements-to-new-pacakge-sidebar
[4.x]improvements to new package sidebar
This commit is contained in:
commit
e143b7d0fe
12 changed files with 94 additions and 77 deletions
|
@ -4,12 +4,13 @@
|
|||
|
||||
import React, { Component } from 'react';
|
||||
|
||||
import { DetailContextConsumer } from '../../pages/version/index';
|
||||
import Avatar from '@material-ui/core/Avatar/index';
|
||||
import List from '@material-ui/core/List/index';
|
||||
import ListItemText from '@material-ui/core/ListItemText/index';
|
||||
|
||||
import { DetailContextConsumer } from '../../pages/version/index';
|
||||
import { Heading, AuthorListItem } from './styles';
|
||||
|
||||
class Authors extends Component<any, any> {
|
||||
render() {
|
||||
return (
|
||||
|
@ -21,19 +22,19 @@ class Authors extends Component<any, any> {
|
|||
);
|
||||
}
|
||||
|
||||
renderLinkForMail(email, avatarComponent) {
|
||||
renderLinkForMail(email, avatarComponent, packageName, version) {
|
||||
if (!email) {
|
||||
return avatarComponent;
|
||||
}
|
||||
return (
|
||||
<a href={`mailto:${email}`} target={'_top'}>
|
||||
<a href={`mailto:${email}?subject=${packageName}@${version}`} target={'_top'}>
|
||||
{avatarComponent}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
renderAuthor = ({ packageMeta }) => {
|
||||
const { author } = packageMeta.latest;
|
||||
const { author, name: packageName, version } = packageMeta.latest;
|
||||
|
||||
if (!author) {
|
||||
return null;
|
||||
|
@ -43,7 +44,7 @@ class Authors extends Component<any, any> {
|
|||
return (
|
||||
<List subheader={<Heading variant={'subheading'}>{'Author'}</Heading>}>
|
||||
<AuthorListItem>
|
||||
{this.renderLinkForMail(author.email, avatarComponent)}
|
||||
{this.renderLinkForMail(author.email, avatarComponent, packageName, version)}
|
||||
<ListItemText primary={author.name} />
|
||||
</AuthorListItem>
|
||||
</List>
|
||||
|
|
|
@ -11,7 +11,7 @@ import CardContent from '@material-ui/core/CardContent/index';
|
|||
|
||||
import { DetailContextConsumer } from '../../pages/version';
|
||||
|
||||
import { Content, CardWrap, Heading, Tags, Tag } from './styles';
|
||||
import { CardWrap, Heading, Tags, Tag } from './styles';
|
||||
import NoItems from '../NoItems';
|
||||
|
||||
class DepDetail extends Component<any, any> {
|
||||
|
@ -87,27 +87,29 @@ class Dependencies extends Component<any, any> {
|
|||
);
|
||||
}
|
||||
|
||||
checkDependencyLength(dependency: Object = {}) {
|
||||
return Object.keys(dependency).length > 0;
|
||||
}
|
||||
|
||||
// $FlowFixMe
|
||||
renderDependencies({ packageMeta }) {
|
||||
const { latest } = packageMeta;
|
||||
const { dependencies, devDependencies, peerDependencies, name } = latest;
|
||||
|
||||
if (dependencies || devDependencies || peerDependencies) {
|
||||
return (
|
||||
<Content>
|
||||
<Fragment>
|
||||
{dependencies && <DependencyBlock dependencies={dependencies} title={'Dependencies'} />}
|
||||
{devDependencies && <DependencyBlock dependencies={devDependencies} title={'DevDependencies'} />}
|
||||
{peerDependencies && <DependencyBlock dependencies={peerDependencies} title={'PeerDependencies'} />}
|
||||
</Fragment>
|
||||
</Content>
|
||||
);
|
||||
const dependencyMap = { dependencies, devDependencies, peerDependencies };
|
||||
|
||||
const dependencyList = Object.keys(dependencyMap).reduce((result, value, key) => {
|
||||
const selectedDepndency = dependencyMap[value];
|
||||
if (selectedDepndency && this.checkDependencyLength(selectedDepndency)) {
|
||||
result.push(<DependencyBlock dependencies={selectedDepndency} key={key} title={value} />);
|
||||
}
|
||||
return result;
|
||||
}, []);
|
||||
|
||||
if (dependencyList.length) {
|
||||
return <Fragment>{dependencyList}</Fragment>;
|
||||
}
|
||||
return (
|
||||
<Content>
|
||||
<NoItems text={`${name} has no dependencies.`} />
|
||||
</Content>
|
||||
);
|
||||
return <NoItems text={`${name} has no dependencies.`} />;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,21 +8,16 @@ import Card from '@material-ui/core/Card/index';
|
|||
import Typography from '@material-ui/core/Typography/index';
|
||||
import Chip from '@material-ui/core/Chip/index';
|
||||
|
||||
export const Content = styled.div`
|
||||
&& {
|
||||
padding: 20px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const CardWrap = styled(Card)`
|
||||
&& {
|
||||
margin: 0 0 25px;
|
||||
margin: 0 0 16px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const Heading = styled(Typography)`
|
||||
&& {
|
||||
font-weight: 700;
|
||||
text-transform: capitalize;
|
||||
}
|
||||
`;
|
||||
|
||||
|
|
|
@ -30,25 +30,31 @@ class DetailContainer extends Component<any, any> {
|
|||
);
|
||||
}
|
||||
|
||||
handleChange = (event: any, tabPosition: number) => {
|
||||
event.preventDefault();
|
||||
this.setState({ tabPosition });
|
||||
};
|
||||
|
||||
// $FlowFixMe
|
||||
renderTabs = ({ readMe }) => {
|
||||
const { tabPosition } = this.state;
|
||||
|
||||
return (
|
||||
<React.Fragment>
|
||||
<Tabs indicatorColor={'primary'} onChange={this.handleChange} textColor={'primary'} value={tabPosition} variant={'fullWidth'}>
|
||||
<Tab label={'Readme'} />
|
||||
<Tab label={'Dependencies'} />
|
||||
<Tab label={'Versions'} />
|
||||
<Tab label={'Uplinks'} />
|
||||
</Tabs>
|
||||
<>
|
||||
<Content>
|
||||
<Tabs indicatorColor={'primary'} onChange={this.handleChange} textColor={'primary'} value={tabPosition} variant={'fullWidth'}>
|
||||
<Tab label={'Readme'} />
|
||||
<Tab label={'Dependencies'} />
|
||||
<Tab label={'Versions'} />
|
||||
<Tab label={'Uplinks'} />
|
||||
</Tabs>
|
||||
<br />
|
||||
{tabPosition === 0 && this.renderReadme(readMe)}
|
||||
{tabPosition === 1 && <Dependencies />}
|
||||
{tabPosition === 2 && <Versions />}
|
||||
{tabPosition === 3 && <UpLinks />}
|
||||
</Content>
|
||||
</React.Fragment>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
|
@ -57,11 +63,6 @@ class DetailContainer extends Component<any, any> {
|
|||
|
||||
return <Readme description={encodedReadme} />;
|
||||
};
|
||||
|
||||
handleChange = (event: any, tabPosition: number) => {
|
||||
event.preventDefault();
|
||||
this.setState({ tabPosition });
|
||||
};
|
||||
}
|
||||
|
||||
export default DetailContainer;
|
||||
|
|
|
@ -3,7 +3,6 @@ import React, {Component} from 'react';
|
|||
import Card from '@material-ui/core/Card/index';
|
||||
import CardContent from '@material-ui/core/CardContent/index';
|
||||
import List from '@material-ui/core/List/index';
|
||||
import ListItemText from '@material-ui/core/ListItemText/index';
|
||||
|
||||
import ActtionBar from '../ActionBar';
|
||||
import Author from '../Author';
|
||||
|
@ -16,7 +15,7 @@ import Repository from '../Repository';
|
|||
|
||||
import { DetailContextConsumer } from '../../pages/version/index';
|
||||
|
||||
import { TitleListItem } from './styles';
|
||||
import { TitleListItem, TitleListItemText } from './styles';
|
||||
|
||||
class DetailSidebar extends Component {
|
||||
render() {
|
||||
|
@ -51,7 +50,7 @@ class DetailSidebar extends Component {
|
|||
return (
|
||||
<List className={'detail-info'}>
|
||||
<TitleListItem alignItems={"flex-start"}>
|
||||
<ListItemText
|
||||
<TitleListItemText
|
||||
primary={<b>{packageName}</b>}
|
||||
secondary={packageMeta.latest.description}
|
||||
/>
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
import styled from 'react-emotion';
|
||||
import Avatar from '@material-ui/core/Avatar/index';
|
||||
import ListItem from '@material-ui/core/ListItem/index';
|
||||
import ListItemText from '@material-ui/core/ListItemText/index';
|
||||
|
||||
import colors from '../../utils/styles/colors';
|
||||
|
||||
|
@ -17,6 +18,14 @@ export const TitleListItem = styled(ListItem)`
|
|||
}
|
||||
`;
|
||||
|
||||
export const TitleListItemText = styled(ListItemText)`
|
||||
&& {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
padding-top: 8px;
|
||||
}
|
||||
`;
|
||||
|
||||
export const TitleAvatar = styled(Avatar)`
|
||||
&& {
|
||||
color: ${colors.greySuperLight};
|
||||
|
|
|
@ -24,7 +24,7 @@ class Developers extends Component<Props, any> {
|
|||
const { type } = this.props;
|
||||
const developerType = packageMeta.latest[type];
|
||||
if (!developerType || developerType.length === 0) return null;
|
||||
return this.renderDevelopers(developerType);
|
||||
return this.renderDevelopers(developerType, packageMeta);
|
||||
}}
|
||||
</DetailContextConsumer>
|
||||
);
|
||||
|
@ -34,7 +34,7 @@ class Developers extends Component<Props, any> {
|
|||
this.setState((prev) => ({ visibleDevs: prev.visibleDevs + 6 }));
|
||||
}
|
||||
|
||||
renderDevelopers = (developers) => {
|
||||
renderDevelopers = (developers, packageMeta) => {
|
||||
const { type } = this.props;
|
||||
const { visibleDevs } = this.state;
|
||||
return (
|
||||
|
@ -42,7 +42,7 @@ class Developers extends Component<Props, any> {
|
|||
<Heading variant={'subheading'}>{type}</Heading>
|
||||
<Content>
|
||||
{developers.slice(0, visibleDevs).map(developer => (
|
||||
<Details key={developer.email}>{this.renderDeveloperDetails(developer)}</Details>
|
||||
<Details key={developer.email}>{this.renderDeveloperDetails(developer, packageMeta)}</Details>
|
||||
))}
|
||||
{visibleDevs < developers.length &&
|
||||
<Fab onClick={this.handleLoadMore} size={'small'}><Add /></Fab>
|
||||
|
@ -52,22 +52,27 @@ class Developers extends Component<Props, any> {
|
|||
);
|
||||
}
|
||||
|
||||
renderLinkForMail(email, avatar) {
|
||||
renderLinkForMail(email, avatarComponent, packageName, version) {
|
||||
if(!email) {
|
||||
return avatar;
|
||||
return avatarComponent;
|
||||
}
|
||||
return (
|
||||
<a href={`mailto:${email}`} target={"_top"}>
|
||||
{avatar}
|
||||
<a href={`mailto:${email}?subject=${packageName}@${version}`} target={"_top"}>
|
||||
{avatarComponent}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
renderDeveloperDetails = ({ name, avatar, email }) => {
|
||||
renderDeveloperDetails = ({ name, avatar, email }, packageMeta) => {
|
||||
const {
|
||||
name: packageName,
|
||||
version,
|
||||
} = packageMeta.latest;
|
||||
|
||||
const avatarComponent = <Avatar aria-label={name} src={avatar} />;
|
||||
return (
|
||||
<Tooltip title={name}>
|
||||
{this.renderLinkForMail(email, avatarComponent)}
|
||||
{this.renderLinkForMail(email, avatarComponent, packageName, version)}
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -18,7 +18,6 @@ const renderTooltip = () => (
|
|||
<Flag name={'nicaragua'} size={'md'} />
|
||||
<Flag name={'india'} size={'md'} />
|
||||
<Flag name={'brazil'} size={'md'} />
|
||||
<Flag name={'pakistan'} size={'md'} />
|
||||
<Flag name={'china'} size={'md'} />
|
||||
<Flag name={'austria'} size={'md'} />
|
||||
</Flags>
|
||||
|
|
|
@ -27,13 +27,16 @@ class Repository extends Component<any, any> {
|
|||
}
|
||||
|
||||
renderRepository = ({packageMeta}) => {
|
||||
const { repository, homepage } = packageMeta.latest;
|
||||
if (!repository) {
|
||||
const {
|
||||
repository: {
|
||||
url,
|
||||
} = {},
|
||||
} = packageMeta.latest;
|
||||
|
||||
if (!url) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// we prefer homepage first, because it's more cleaner
|
||||
const url = homepage || repository.url;
|
||||
return (
|
||||
<>
|
||||
<List dense={true} subheader={<Heading variant={"subheading"}>{'Repository'}</Heading>}>
|
||||
|
|
|
@ -38,7 +38,6 @@ class UpLinks extends React.PureComponent<any> {
|
|||
);
|
||||
|
||||
renderContent(uplinks, { name }) {
|
||||
console.log(uplinks);
|
||||
if (Object.keys(uplinks).length > 0) {
|
||||
return (
|
||||
uplinks && (
|
||||
|
|
|
@ -17,40 +17,44 @@ class Versions extends React.PureComponent<any> {
|
|||
// $FlowFixMe
|
||||
<DetailContextConsumer>
|
||||
{({ packageMeta }) => {
|
||||
return this.renderContent(packageMeta[DIST_TAGS], packageMeta.versions);
|
||||
return this.renderContent(packageMeta);
|
||||
}}
|
||||
</DetailContextConsumer>
|
||||
);
|
||||
}
|
||||
|
||||
renderPackageList = (packages: any, isVersion: boolean = false) => (
|
||||
<List>
|
||||
{Object.keys(packages)
|
||||
.reverse()
|
||||
.map(version => (
|
||||
<ListItem key={version}>
|
||||
<ListItemText>{version}</ListItemText>
|
||||
<Spacer />
|
||||
<ListItemText>{isVersion ? `${formatDateDistance('2017-10-26T09:03:15.044Z')} ago` : packages[version]}</ListItemText>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
);
|
||||
renderPackageList = (packages: any, isVersion: boolean = false, timeMap: Object = {}) => {
|
||||
return (
|
||||
<List>
|
||||
{Object.keys(packages)
|
||||
.reverse()
|
||||
.map(version => (
|
||||
<ListItem key={version}>
|
||||
<ListItemText>{version}</ListItemText>
|
||||
<Spacer />
|
||||
<ListItemText>{isVersion && timeMap[version] ? `${formatDateDistance(timeMap[version])} ago` : packages[version]}</ListItemText>
|
||||
</ListItem>
|
||||
))}
|
||||
</List>
|
||||
);
|
||||
};
|
||||
|
||||
// $FlowFixMe
|
||||
renderContent(distTags: object, versions: object) {
|
||||
renderContent(packageMeta) {
|
||||
const { versions = {}, time: timeMap = {}, [DIST_TAGS]: distTags = {} } = packageMeta;
|
||||
|
||||
return (
|
||||
<>
|
||||
{distTags && (
|
||||
<>
|
||||
<Heading variant={'subheading'}>{'Current Tags'}</Heading>
|
||||
{this.renderPackageList(distTags)}
|
||||
{this.renderPackageList(distTags, false, timeMap)}
|
||||
</>
|
||||
)}
|
||||
{versions && (
|
||||
<>
|
||||
<Heading variant={'subheading'}>{'Version History'}</Heading>
|
||||
{this.renderPackageList(versions, true)}
|
||||
{this.renderPackageList(versions, true, timeMap)}
|
||||
</>
|
||||
)}
|
||||
</>
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`<Footer /> component should load the initial state of Footer component 1`] = `"<div class=\\"css-i0nj2g efsnl070\\"><div class=\\"css-hzfs9b efsnl071\\"><div class=\\"css-d8nsp7 efsnl072\\"> Made with<span class=\\"css-1so4oe0 efsnl077\\">♥</span>on<span class=\\"css-1ie354y efsnl074\\"><svg class=\\"efsnl075 css-1kgp95j ej4jd2o0\\"><title>Earth</title><use xlink:href=\\"[object Object]#earth\\"></use></svg><span class=\\"css-e8kfuf efsnl076\\"><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>Spain</title><use xlink:href=\\"[object Object]#spain\\"></use></svg><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>Nicaragua</title><use xlink:href=\\"[object Object]#nicaragua\\"></use></svg><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>India</title><use xlink:href=\\"[object Object]#india\\"></use></svg><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>Brazil</title><use xlink:href=\\"[object Object]#brazil\\"></use></svg><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>Pakistan</title><use xlink:href=\\"[object Object]#pakistan\\"></use></svg><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>China</title><use xlink:href=\\"[object Object]#china\\"></use></svg><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>Austria</title><use xlink:href=\\"[object Object]#austria\\"></use></svg></span></span></div><div class=\\"css-1wbzdyy efsnl073\\">Powered by<span class=\\"efsnl078 css-i15wza ej4jd2o1\\" title=\\"Verdaccio\\"><img alt=\\"Verdaccio\\" src=\\"[object Object]\\" class=\\"css-1ncdhax ej4jd2o2\\"></span>/ 4.0.0-alpha.3</div></div></div>"`;
|
||||
exports[`<Footer /> component should load the initial state of Footer component 1`] = `"<div class=\\"css-i0nj2g efsnl070\\"><div class=\\"css-hzfs9b efsnl071\\"><div class=\\"css-d8nsp7 efsnl072\\"> Made with<span class=\\"css-1so4oe0 efsnl077\\">♥</span>on<span class=\\"css-1ie354y efsnl074\\"><svg class=\\"efsnl075 css-1kgp95j ej4jd2o0\\"><title>Earth</title><use xlink:href=\\"[object Object]#earth\\"></use></svg><span class=\\"css-e8kfuf efsnl076\\"><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>Spain</title><use xlink:href=\\"[object Object]#spain\\"></use></svg><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>Nicaragua</title><use xlink:href=\\"[object Object]#nicaragua\\"></use></svg><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>India</title><use xlink:href=\\"[object Object]#india\\"></use></svg><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>Brazil</title><use xlink:href=\\"[object Object]#brazil\\"></use></svg><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>China</title><use xlink:href=\\"[object Object]#china\\"></use></svg><svg class=\\"efsnl078 css-f1ndto ej4jd2o0\\"><title>Austria</title><use xlink:href=\\"[object Object]#austria\\"></use></svg></span></span></div><div class=\\"css-1wbzdyy efsnl073\\">Powered by<span class=\\"efsnl078 css-i15wza ej4jd2o1\\" title=\\"Verdaccio\\"><img alt=\\"Verdaccio\\" src=\\"[object Object]\\" class=\\"css-1ncdhax ej4jd2o2\\"></span>/ 4.0.0-alpha.3</div></div></div>"`;
|
||||
|
|
Loading…
Reference in a new issue