2019-06-20 19:37:28 +07:00
|
|
|
import React, { Component, ReactElement, Consumer, Provider } from 'react';
|
|
|
|
import Grid from '@material-ui/core/Grid';
|
|
|
|
import Loading from '../../components/Loading/Loading';
|
|
|
|
import DetailContainer from '../../components/DetailContainer/DetailContainer';
|
|
|
|
import DetailSidebar from '../../components/DetailSidebar/DetailSidebar';
|
2019-06-22 16:43:59 +07:00
|
|
|
import { callDetailPage } from '../../utils/calls';
|
2019-03-28 05:39:06 +07:00
|
|
|
import { getRouterPackageName } from '../../utils/package';
|
|
|
|
import NotFound from '../../components/NotFound';
|
2019-06-22 16:43:59 +07:00
|
|
|
import { PackageMetaInterface } from '../../../types/packageMeta';
|
2019-02-03 17:23:33 +07:00
|
|
|
|
2019-06-20 19:37:28 +07:00
|
|
|
export interface DetailContextProps {
|
2019-06-22 16:43:59 +07:00
|
|
|
packageMeta: PackageMetaInterface;
|
|
|
|
readMe: string;
|
2019-06-20 19:37:28 +07:00
|
|
|
packageName: string;
|
|
|
|
enableLoading: () => void;
|
|
|
|
}
|
|
|
|
|
2019-06-22 16:43:59 +07:00
|
|
|
export const DetailContext = React.createContext<Partial<DetailContextProps>>({});
|
2019-02-03 17:23:33 +07:00
|
|
|
|
2019-06-20 19:37:28 +07:00
|
|
|
export interface VersionPageConsumerProps {
|
2019-06-22 16:43:59 +07:00
|
|
|
packageMeta: PackageMetaInterface;
|
|
|
|
readMe: string;
|
|
|
|
packageName: string;
|
|
|
|
enableLoading: () => void;
|
2019-06-20 19:37:28 +07:00
|
|
|
}
|
|
|
|
|
2019-06-22 16:43:59 +07:00
|
|
|
export const DetailContextProvider: Provider<Partial<VersionPageConsumerProps>> = DetailContext.Provider;
|
|
|
|
export const DetailContextConsumer: Consumer<Partial<VersionPageConsumerProps>> = DetailContext.Consumer;
|
|
|
|
|
|
|
|
interface PropsInterface {
|
|
|
|
match: boolean;
|
|
|
|
}
|
|
|
|
|
|
|
|
interface StateInterface {
|
|
|
|
readMe: string;
|
|
|
|
packageName: string;
|
|
|
|
packageMeta: PackageMetaInterface | null;
|
|
|
|
isLoading: boolean;
|
|
|
|
notFound: boolean;
|
|
|
|
}
|
2019-02-03 17:23:33 +07:00
|
|
|
|
2019-06-24 02:50:30 +07:00
|
|
|
class VersionPage extends Component<PropsInterface, Partial<StateInterface>> {
|
2019-06-22 16:43:59 +07:00
|
|
|
constructor(props) {
|
2019-02-03 17:23:33 +07:00
|
|
|
super(props);
|
|
|
|
|
|
|
|
this.state = {
|
|
|
|
readMe: '',
|
|
|
|
packageName: getRouterPackageName(props.match),
|
|
|
|
packageMeta: null,
|
|
|
|
isLoading: true,
|
|
|
|
notFound: false,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2019-06-22 16:43:59 +07:00
|
|
|
public static getDerivedStateFromProps(nextProps, prevState): { packageName?: string; isLoading: boolean; notFound?: boolean } | null {
|
2019-03-28 05:39:06 +07:00
|
|
|
const { match } = nextProps;
|
2019-02-03 17:23:33 +07:00
|
|
|
const packageName = getRouterPackageName(match);
|
|
|
|
|
|
|
|
if (packageName !== prevState.packageName) {
|
|
|
|
try {
|
|
|
|
return {
|
|
|
|
packageName,
|
|
|
|
isLoading: false,
|
|
|
|
};
|
|
|
|
} catch (err) {
|
|
|
|
return {
|
|
|
|
notFound: true,
|
|
|
|
isLoading: false,
|
|
|
|
};
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-20 19:37:28 +07:00
|
|
|
public async componentDidMount(): Promise<void> {
|
|
|
|
await this.loadPackageInfo();
|
|
|
|
}
|
2019-02-03 17:23:33 +07:00
|
|
|
|
2019-06-20 19:37:28 +07:00
|
|
|
/* eslint no-unused-vars: 0 */
|
2019-06-22 16:43:59 +07:00
|
|
|
public async componentDidUpdate(nextProps, prevState: StateInterface): Promise<void> {
|
2019-06-20 19:37:28 +07:00
|
|
|
const { packageName } = this.state;
|
|
|
|
if (packageName !== prevState.packageName) {
|
2019-06-24 02:50:30 +07:00
|
|
|
const { readMe, packageMeta } = (await callDetailPage(packageName)) as Partial<StateInterface>;
|
2019-02-03 17:23:33 +07:00
|
|
|
this.setState({
|
|
|
|
readMe,
|
|
|
|
packageMeta,
|
|
|
|
packageName,
|
|
|
|
notFound: false,
|
|
|
|
isLoading: false,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-20 19:37:28 +07:00
|
|
|
public render(): ReactElement<HTMLElement> {
|
2019-03-28 05:39:06 +07:00
|
|
|
const { isLoading, packageMeta, readMe, packageName } = this.state;
|
2019-02-03 17:23:33 +07:00
|
|
|
|
2019-03-28 05:39:06 +07:00
|
|
|
if (isLoading) {
|
|
|
|
return <Loading />;
|
|
|
|
} else if (!packageMeta) {
|
|
|
|
return <NotFound />;
|
|
|
|
} else {
|
2019-02-03 17:23:33 +07:00
|
|
|
return (
|
2019-03-28 05:39:06 +07:00
|
|
|
<DetailContextProvider value={{ packageMeta, readMe, packageName, enableLoading: this.enableLoading }}>
|
2019-02-03 17:23:33 +07:00
|
|
|
<Grid className={'container content'} container={true} spacing={0}>
|
|
|
|
<Grid item={true} xs={8}>
|
|
|
|
{this.renderDetail()}
|
|
|
|
</Grid>
|
|
|
|
<Grid item={true} xs={4}>
|
|
|
|
{this.renderSidebar()}
|
|
|
|
</Grid>
|
|
|
|
</Grid>
|
|
|
|
</DetailContextProvider>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-06-20 19:37:28 +07:00
|
|
|
public async loadPackageInfo(): Promise<void> {
|
|
|
|
const { packageName } = this.state;
|
|
|
|
// FIXME: use utility
|
|
|
|
document.title = `Verdaccio - ${packageName}`;
|
|
|
|
|
|
|
|
this.setState({
|
|
|
|
readMe: '',
|
|
|
|
});
|
|
|
|
|
|
|
|
try {
|
2019-06-24 02:50:30 +07:00
|
|
|
const { readMe, packageMeta } = (await callDetailPage(packageName)) as Partial<StateInterface>;
|
2019-06-20 19:37:28 +07:00
|
|
|
this.setState({
|
|
|
|
readMe,
|
|
|
|
packageMeta,
|
|
|
|
packageName,
|
|
|
|
notFound: false,
|
|
|
|
isLoading: false,
|
|
|
|
});
|
|
|
|
} catch (err) {
|
|
|
|
this.setState({
|
|
|
|
notFound: true,
|
|
|
|
packageName,
|
|
|
|
isLoading: false,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public enableLoading = () => {
|
|
|
|
this.setState({
|
|
|
|
isLoading: true,
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
public renderDetail(): ReactElement<HTMLElement> {
|
2019-02-03 17:23:33 +07:00
|
|
|
return <DetailContainer />;
|
|
|
|
}
|
|
|
|
|
2019-06-20 19:37:28 +07:00
|
|
|
public renderSidebar(): ReactElement<HTMLElement> {
|
2019-02-03 17:23:33 +07:00
|
|
|
return <DetailSidebar />;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default VersionPage;
|