mirror of
https://github.com/verdaccio/verdaccio.git
synced 2024-11-08 23:25:51 +01:00
feat: migrate react router from hash to history api #1013
This commit is contained in:
parent
8c06f968f9
commit
1a456fb8a6
@ -53,13 +53,7 @@ module.exports = function(config, auth, storage) {
|
||||
});
|
||||
});
|
||||
|
||||
router.get('/-/verdaccio/logo', function(req, res) {
|
||||
const installPath = _.get(config, 'url_prefix', '');
|
||||
|
||||
res.send(_.get(config, 'web.logo') || spliceURL(installPath, '/-/static/logo.png'));
|
||||
});
|
||||
|
||||
router.get('/', function(req, res) {
|
||||
function renderHTML(req, res) {
|
||||
const base = combineBaseUrl(getWebProtocol(req.get(HEADERS.FORWARDED_PROTO), req.protocol), req.get('host'), config.url_prefix);
|
||||
|
||||
const webPage = template
|
||||
@ -70,6 +64,20 @@ module.exports = function(config, auth, storage) {
|
||||
res.setHeader('Content-Type', 'text/html');
|
||||
|
||||
res.send(webPage);
|
||||
}
|
||||
|
||||
router.get('/-/web/:pkg', function(req, res) {
|
||||
renderHTML(req, res);
|
||||
});
|
||||
|
||||
router.get('/-/verdaccio/logo', function(req, res) {
|
||||
const installPath = _.get(config, 'url_prefix', '');
|
||||
|
||||
res.send(_.get(config, 'web.logo') || spliceURL(installPath, '/-/static/logo.png'));
|
||||
});
|
||||
|
||||
router.get('/', function(req, res) {
|
||||
renderHTML(req, res);
|
||||
});
|
||||
|
||||
return router;
|
||||
|
@ -5,16 +5,16 @@ import storage from './utils/storage';
|
||||
import logo from './utils/logo';
|
||||
import { makeLogin, isTokenExpire } from './utils/login';
|
||||
|
||||
import Footer from './components/Footer';
|
||||
import Loading from './components/Loading';
|
||||
import LoginModal from './components/Login';
|
||||
import Header from './components/Header';
|
||||
import { Container, Content } from './components/Layout';
|
||||
import Route from './router';
|
||||
import RouterApp from './router';
|
||||
import API from './utils/api';
|
||||
import './styles/typeface-roboto.scss';
|
||||
import './styles/main.scss';
|
||||
import 'normalize.css';
|
||||
import Footer from './components/Footer';
|
||||
|
||||
export const AppContext = React.createContext();
|
||||
|
||||
@ -143,15 +143,14 @@ export default class App extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { isLoading, isUserLoggedIn, packages } = this.state;
|
||||
const { isLoading, isUserLoggedIn, packages, logoUrl, user, scope } = this.state;
|
||||
return (
|
||||
<Container isLoading={isLoading}>
|
||||
{isLoading ? (
|
||||
<Loading />
|
||||
) : (
|
||||
<Fragment>
|
||||
<AppContextProvider value={{isUserLoggedIn, packages}}>
|
||||
{this.renderHeader()}
|
||||
<AppContextProvider value={{isUserLoggedIn, packages, logoUrl, user, scope}}>
|
||||
{this.renderContent()}
|
||||
</AppContextProvider>
|
||||
</Fragment>
|
||||
@ -178,7 +177,11 @@ export default class App extends Component {
|
||||
return (
|
||||
<Fragment>
|
||||
<Content>
|
||||
<Route></Route>
|
||||
<RouterApp
|
||||
onLogout={this.handleLogout}
|
||||
onToggleLoginModal={this.handleToggleLoginModal}>
|
||||
{this.renderHeader()}
|
||||
</RouterApp>
|
||||
</Content>
|
||||
<Footer />
|
||||
</Fragment>
|
||||
|
@ -34,14 +34,14 @@ class DepDetail extends Component<any, any> {
|
||||
const { onLoading, history } = this.props;
|
||||
|
||||
onLoading();
|
||||
history.push(`/version/${name}`);
|
||||
history.push(`/-/web/version/${name}`);
|
||||
};
|
||||
}
|
||||
|
||||
const WrappDepDetail = withRouter(DepDetail);
|
||||
|
||||
class DependencyBlock extends Component<any, any> {
|
||||
renderTags = (deps: object, enableLoading: boolean) =>
|
||||
renderTags = (deps: any, enableLoading: boolean) =>
|
||||
deps.map(dep => {
|
||||
const [name, version] = dep;
|
||||
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import type { Node } from 'react';
|
||||
import { Link } from 'react-router-dom';
|
||||
|
||||
import Button from '@material-ui/core/Button/index';
|
||||
import IconButton from '@material-ui/core/IconButton/index';
|
||||
@ -17,7 +18,7 @@ import AccountCircle from '@material-ui/icons/AccountCircle';
|
||||
import { default as IconSearch } from '@material-ui/icons/Search';
|
||||
|
||||
import { getRegistryURL } from '../../utils/url';
|
||||
import Link from '../Link';
|
||||
import ExternalLink from '../Link';
|
||||
import Logo from '../Logo';
|
||||
import RegistryInfoDialog from '../RegistryInfoDialog';
|
||||
import Label from '../Label';
|
||||
@ -128,7 +129,7 @@ class Header extends Component<IProps, IState> {
|
||||
switch (type) {
|
||||
case 'help':
|
||||
content = (
|
||||
<IconButton blank={true} color={'inherit'} component={Link} to={'https://verdaccio.org/docs/en/installation'}>
|
||||
<IconButton blank={true} color={'inherit'} component={ExternalLink} to={'https://verdaccio.org/docs/en/installation'}>
|
||||
<Help />
|
||||
</IconButton>
|
||||
);
|
||||
|
@ -80,7 +80,7 @@ const Package = ({ name: label, version, time, author: { name, avatar }, descrip
|
||||
);
|
||||
|
||||
return (
|
||||
<WrapperLink className={'package'} to={`version/${label}`}>
|
||||
<WrapperLink className={'package'} to={`/-/web/version/${label}`}>
|
||||
<Header>
|
||||
{renderMainInfo()}
|
||||
<Overview>
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
import React, { Component } from 'react';
|
||||
import type { Node } from 'react';
|
||||
import { withRouter } from 'react-router-dom';
|
||||
|
||||
import { default as IconSearch } from '@material-ui/icons/Search';
|
||||
import InputAdornment from '@material-ui/core/InputAdornment';
|
||||
@ -13,7 +14,6 @@ import debounce from 'lodash/debounce';
|
||||
import API from '../../utils/api';
|
||||
import AutoComplete from '../AutoComplete';
|
||||
import colors from '../../utils/styles/colors';
|
||||
import { getDetailPageURL } from '../../utils/url';
|
||||
|
||||
import { IProps, IState } from './types';
|
||||
import type { cancelAllSearchRequests, handlePackagesClearRequested, handleSearch, handleClickSearch, handleFetchPackages, onBlur } from './types';
|
||||
@ -92,13 +92,15 @@ class Search extends Component<IProps, IState> {
|
||||
* When an user select any package by clicking or pressing return key.
|
||||
*/
|
||||
handleClickSearch: handleClickSearch = (event, { suggestionValue, method }) => {
|
||||
const { history } = this.props;
|
||||
// stops event bubbling
|
||||
event.stopPropagation();
|
||||
switch (method) {
|
||||
case 'click':
|
||||
case 'enter':
|
||||
this.setState({ search: '' });
|
||||
window.location.assign(getDetailPageURL(suggestionValue));
|
||||
// $FlowFixMe
|
||||
history.push(`/-/web/version/${suggestionValue}`);
|
||||
break;
|
||||
}
|
||||
};
|
||||
@ -181,4 +183,4 @@ class Search extends Component<IProps, IState> {
|
||||
}
|
||||
}
|
||||
|
||||
export default Search;
|
||||
export default withRouter(Search);
|
||||
|
@ -3,7 +3,9 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
export interface IProps {}
|
||||
export interface IProps {
|
||||
history?: any;
|
||||
}
|
||||
|
||||
export interface IState {
|
||||
search: string;
|
||||
|
@ -2,9 +2,9 @@
|
||||
* @prettier
|
||||
*/
|
||||
|
||||
import { createHashHistory } from 'history';
|
||||
import { createBrowserHistory } from 'history';
|
||||
|
||||
const history = createHashHistory();
|
||||
const history = createBrowserHistory();
|
||||
|
||||
// Listen for changes to the current location.
|
||||
history.listen((location, action) => {
|
||||
|
@ -3,39 +3,50 @@
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React, { Component } from 'react';
|
||||
/* eslint react/jsx-max-depth:0 */
|
||||
|
||||
import React, { Component, Fragment } from 'react';
|
||||
import { Router, Route, Switch } from 'react-router-dom';
|
||||
import { AppContextConsumer } from './app';
|
||||
|
||||
import { asyncComponent } from './utils/asyncComponent';
|
||||
import history from './history';
|
||||
import Header from './components/Header';
|
||||
|
||||
const DetailPackage = asyncComponent(() => import('./pages/detail'));
|
||||
const VersionPackage = asyncComponent(() => import('./pages/version'));
|
||||
const HomePage = asyncComponent(() => import('./pages/home'));
|
||||
|
||||
interface IProps {
|
||||
isUserLoggedIn: boolean;
|
||||
packages: Array<Object>;
|
||||
}
|
||||
|
||||
interface IState {}
|
||||
|
||||
class RouterApp extends Component<IProps, IState> {
|
||||
class RouterApp extends Component<any, any> {
|
||||
render() {
|
||||
return (
|
||||
<Router history={history}>
|
||||
<Switch>
|
||||
<Route exact={true} path={'/'} render={this.renderHomePage} />
|
||||
<Route exact={true} path={'/detail/@:scope/:package'} render={this.renderDetailPage} />
|
||||
<Route exact={true} path={'/detail/:package'} render={this.renderDetailPage} />
|
||||
<Route exact={true} path={'/version/@:scope/:package'} render={this.renderVersionPage} />
|
||||
<Route exact={true} path={'/version/:package'} render={this.renderVersionPage} />
|
||||
</Switch>
|
||||
<Fragment>
|
||||
{this.renderHeader()}
|
||||
<Switch>
|
||||
<Route exact={true} path={'/'} render={this.renderHomePage} />
|
||||
<Route exact={true} path={'/-/web/detail/@:scope/:package'} render={this.renderDetailPage} />
|
||||
<Route exact={true} path={'/-/web/detail/:package'} render={this.renderDetailPage} />
|
||||
<Route exact={true} path={'/-/web/version/@:scope/:package'} render={this.renderVersionPage} />
|
||||
<Route exact={true} path={'/-/web/version/:package'} render={this.renderVersionPage} />
|
||||
</Switch>
|
||||
</Fragment>
|
||||
</Router>
|
||||
);
|
||||
}
|
||||
|
||||
renderHeader = () => {
|
||||
const { onLogout, onToggleLoginModal } = this.props;
|
||||
|
||||
return (
|
||||
<AppContextConsumer>
|
||||
{function renderConsumerVersionPage({ logoUrl, scope, user }) {
|
||||
return <Header logo={logoUrl} onLogout={onLogout} onToggleLoginModal={onToggleLoginModal} scope={scope} username={user.username} />;
|
||||
}}
|
||||
</AppContextConsumer>
|
||||
);
|
||||
};
|
||||
|
||||
renderHomePage = () => {
|
||||
return (
|
||||
<AppContextConsumer>
|
||||
|
Loading…
Reference in New Issue
Block a user