0
Fork 0
mirror of https://github.com/verdaccio/verdaccio.git synced 2025-03-25 02:32:52 -05:00

refactor: package list

This commit is contained in:
Ayush Sharma 2019-03-03 21:40:41 +01:00
parent c9858c85e3
commit 5aff7bc1a8
11 changed files with 88 additions and 86 deletions

View file

@ -1,3 +1,7 @@
/**
* @prettier
*/
import React, { Component, Fragment } from 'react';
import isNil from 'lodash/isNil';
@ -16,7 +20,6 @@ import 'normalize.css';
import Footer from './components/Footer';
export const AppContext = React.createContext();
export const AppContextProvider = AppContext.Provider;
export const AppContextConsumer = AppContext.Consumer;
@ -25,12 +28,12 @@ export default class App extends Component {
error: {},
logoUrl: window.VERDACCIO_LOGO,
user: {},
scope: (window.VERDACCIO_SCOPE) ? `${window.VERDACCIO_SCOPE}:` : '',
scope: window.VERDACCIO_SCOPE ? `${window.VERDACCIO_SCOPE}:` : '',
showLoginModal: false,
isUserLoggedIn: false,
packages: [],
isLoading: true,
}
};
componentDidMount() {
this.isUserAlreadyLoggedIn();
@ -45,19 +48,36 @@ export default class App extends Component {
}
}
render() {
const { isLoading, isUserLoggedIn, packages, logoUrl, user, scope } = this.state;
return (
<Container isLoading={isLoading}>
{isLoading ? (
<Loading />
) : (
<Fragment>
<AppContextProvider value={{ isUserLoggedIn, packages, logoUrl, user, scope }}>{this.renderContent()}</AppContextProvider>
</Fragment>
)}
{this.renderLoginModal()}
</Container>
);
}
isUserAlreadyLoggedIn = () => {
// checks for token validity
const token = storage.getItem('token');
const username = storage.getItem('username');
if (isTokenExpire(token) || isNil(username)) {
this.handleLogout();
this.handleLogout();
} else {
this.setState({
user: { username, token },
isUserLoggedIn: true,
});
}
}
};
loadOnHandler = async () => {
try {
@ -74,34 +94,30 @@ export default class App extends Component {
});
this.setLoading(false);
}
}
};
setLoading = isLoading => (
setLoading = isLoading =>
this.setState({
isLoading,
})
)
});
/**
* Toggles the login modal
* Required by: <LoginModal /> <Header />
*/
handleToggleLoginModal = () => {
this.setState((prevState) => ({
this.setState(prevState => ({
showLoginModal: !prevState.showLoginModal,
error: {},
}));
}
};
/**
* handles login
* Required by: <Header />
*/
handleDoLogin = async (usernameValue, passwordValue) => {
const { username, token, error } = await makeLogin(
usernameValue,
passwordValue
);
const { username, token, error } = await makeLogin(usernameValue, passwordValue);
if (username && token) {
this.setLoggedUser(username, token);
@ -115,7 +131,7 @@ export default class App extends Component {
error,
});
}
}
};
setLoggedUser = (username, token) => {
this.setState({
@ -123,10 +139,11 @@ export default class App extends Component {
username,
token,
},
isUserLoggedIn: true, // close login modal after successful login
showLoginModal: false, // set isUserLoggedIn to true
isUserLoggedIn: true, // close login modal after successful login
showLoginModal: false, // set isUserLoggedIn to true
});
}
};
/**
* Logouts user
* Required by: <Header />
@ -138,25 +155,7 @@ export default class App extends Component {
user: {},
isUserLoggedIn: false,
});
}
render() {
const { isLoading, isUserLoggedIn, packages, logoUrl, user, scope } = this.state;
return (
<Container isLoading={isLoading}>
{isLoading ? (
<Loading />
) : (
<Fragment>
<AppContextProvider value={{isUserLoggedIn, packages, logoUrl, user, scope}}>
{this.renderContent()}
</AppContextProvider>
</Fragment>
)}
{this.renderLoginModal()}
</Container>
);
}
};
renderLoginModal = () => {
const { error, showLoginModal } = this.state;
@ -169,34 +168,24 @@ export default class App extends Component {
visibility={showLoginModal}
/>
);
}
};
renderContent = () => {
return (
<Fragment>
<Content>
<RouterApp
onLogout={this.handleLogout}
onToggleLoginModal={this.handleToggleLoginModal}>
<RouterApp onLogout={this.handleLogout} onToggleLoginModal={this.handleToggleLoginModal}>
{this.renderHeader()}
</RouterApp>
</Content>
<Footer />
</Fragment>
);
}
};
renderHeader = () => {
const { logoUrl, user, scope } = this.state;
const { logoUrl, user: { username } = {}, scope } = this.state;
return (
<Header
logo={logoUrl}
onLogout={this.handleLogout}
onToggleLoginModal={this.handleToggleLoginModal}
scope={scope}
username={user.username}
/>
);
}
return <Header logo={logoUrl} onLogout={this.handleLogout} onToggleLoginModal={this.handleToggleLoginModal} scope={scope} username={username} />;
};
}

View file

@ -1,3 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" id="fileBinary">
<svg xmlns="http://www.w3.org/2000/svg" id="filebinary">
<path d="M8.5 1H1c-.55 0-1 .45-1 1v12c0 .55.45 1 1 1h10c.55 0 1-.45 1-1V4.5L8.5 1zM11 14H1V2h7l3 3v9zM5 6.98L3.5 8.5 5 10l-.5 1L2 8.5 4.5 6l.5.98zM7.5 6L10 8.5 7.5 11l-.5-.98L8.5 8.5 7 7l.5-1z"></path>
</svg>

Before

Width:  |  Height:  |  Size: 265 B

After

Width:  |  Height:  |  Size: 265 B

View file

@ -19,7 +19,7 @@ import austria from './img/austria.svg';
import spain from './img/spain.svg';
import earth from './img/earth.svg';
import verdaccio from './img/verdaccio.svg';
import fileBinary from './img/fileBinary.svg';
import filebinary from './img/filebinary.svg';
import law from './img/law.svg';
import license from './img/license.svg';
import time from './img/time.svg';
@ -37,7 +37,7 @@ export const Icons: $Shape<IIconsMap> = {
earth,
verdaccio,
// other icons
fileBinary,
filebinary,
law,
license,
time,

View file

@ -19,7 +19,7 @@ export interface IIconsMap {
time: string;
law: string;
version: string;
fileBinary: string;
filebinary: string;
[key: string]: string;
}

View file

@ -69,7 +69,7 @@ const Package = ({
const renderFileSize = () =>
unpackedSize && (
<OverviewItem>
<Icon name={'fileBinary'} />
<Icon name={'filebinary'} />
{fileSizeSI(unpackedSize)}
</OverviewItem>
);
@ -157,4 +157,5 @@ const Package = ({
</PackageList>
);
};
export default Package;

View file

@ -1,24 +1,32 @@
/**
* @prettier
*/
import React from 'react';
export function asyncComponent(getComponent) {
return class AsyncComponent extends React.Component {
static Component = null;
state = {Component: AsyncComponent.Component};
state = { Component: AsyncComponent.Component };
componentDidMount() {
const {Component} = this.state;
const { Component } = this.state;
if (!Component) {
getComponent().then(({default: Component}) => {
AsyncComponent.Component = Component;
/* eslint react/no-did-mount-set-state:0 */
this.setState({Component});
});
getComponent()
.then(({ default: Component }) => {
AsyncComponent.Component = Component;
/* eslint react/no-did-mount-set-state:0 */
this.setState({ Component });
})
.catch(err => {
console.error(err);
});
}
}
render() {
const {Component} = this.state;
const { Component } = this.state;
if (Component) {
// eslint-disable-next-line verdaccio/jsx-spread
return <Component {...this.props} />;
}

View file

@ -2,7 +2,6 @@ import React from 'react';
import { mount } from 'enzyme';
import storage from '../../../src/webui/utils/storage';
import App from '../../../src/webui/app';
import { API_ERROR } from '../../../src/lib/constants';
import { generateTokenWithTimeRange } from './components/__mocks__/token';
@ -38,7 +37,7 @@ describe('App', () => {
wrapper = mount(<App />);
});
xtest('toggleLoginModal: should toggle the value in state', () => {
test('toggleLoginModal: should toggle the value in state', () => {
const { handleToggleLoginModal } = wrapper.instance();
expect(wrapper.state().showLoginModal).toBeFalsy();
handleToggleLoginModal();
@ -46,7 +45,7 @@ describe('App', () => {
expect(wrapper.state('error')).toEqual({});
});
xtest('isUserAlreadyLoggedIn: token already available in storage', async () => {
test('isUserAlreadyLoggedIn: token already available in storage', async () => {
storage.setItem('username', 'verdaccio');
storage.setItem('token', generateTokenWithTimeRange(24));
@ -57,7 +56,7 @@ describe('App', () => {
expect(wrapper.state('user').username).toEqual('verdaccio');
});
xtest('handleLogout - logouts the user and clear localstorage', async () => {
test('handleLogout - logouts the user and clear localstorage', async () => {
const { handleLogout } = wrapper.instance();
storage.setItem('username', 'verdaccio');
storage.setItem('token', 'xxxx.TOKEN.xxxx');
@ -67,7 +66,7 @@ describe('App', () => {
expect(wrapper.state('isUserLoggedIn')).toBeFalsy();
});
xtest('handleDoLogin - login the user successfully', async () => {
test('handleDoLogin - login the user successfully', async () => {
const { handleDoLogin } = wrapper.instance();
await handleDoLogin('sam', '1234');
const result = {
@ -81,10 +80,9 @@ describe('App', () => {
expect(wrapper.state('user')).toEqual(result);
});
xtest('handleDoLogin - authentication failure', async () => {
test('handleDoLogin - authentication failure', async () => {
const { handleDoLogin } = wrapper.instance();
await handleDoLogin('sam', '12345');
console.log(API_ERROR.BAD_USERNAME_PASSWORD);
const result = {
description: 'bad username/password, access denied',
title: 'Unable to login',

File diff suppressed because one or more lines are too long

View file

@ -21,7 +21,7 @@ describe('<PackageList /> component', () => {
});
xtest('should load the component with packages', () => {
test('should load the component with packages', () => {
const props = {
packages: [
{
@ -29,20 +29,20 @@ describe('<PackageList /> component', () => {
version: '1.0.0',
time: new Date(1532211072138).getTime(),
description: 'Private NPM repository',
author: { name: 'Sam' }
author: { name: 'Sam', avatar: 'test avatar' }
},
{
name: 'abc',
version: '1.0.1',
time: new Date(1532211072138).getTime(),
description: 'abc description',
author: { name: 'Rose' }
author: { name: 'Rose', avatar: 'test avatar' }
},
{
name: 'xyz',
version: '1.1.0',
description: 'xyz description',
author: { name: 'Martin' }
author: { name: 'Martin', avatar: 'test avatar' }
}
],
help: false

View file

@ -8,7 +8,8 @@ export const packageInformation = [
homepage: 'https://jquery.com',
author: {
name: 'JS Foundation and other contributors',
url: 'https://github.com/jquery/jquery/blob/master/AUTHORS.txt'
url: 'https://github.com/jquery/jquery/blob/master/AUTHORS.txt',
avatar: '',
},
repository: {
type: 'git',
@ -108,6 +109,11 @@ export const packageInformation = [
license: 'MIT',
private: true,
main: 'lodash.js',
author: {
name: 'John david dalton',
url: 'test url',
avatar: 'test avatar',
},
engines: {
node: '>=4.0.0'
},

View file

@ -50,15 +50,15 @@ describe('formatDate', () => {
});
});
xdescribe('formatDateDistance', () => {
describe('formatDateDistance', () => {
test('should calculate the distance', () => {
const dateOneMonthAgo = () => {
const dateTwoMonthsAgo = () => {
const date = new Date();
date.setMonth(date.getMonth() - 1);
date.setMonth(date.getMonth() - 2);
return date;
};
const date = dateOneMonthAgo();
expect(formatDateDistance(date)).toEqual('about 1 month');
const date = dateTwoMonthsAgo();
expect(formatDateDistance(date)).toEqual('about 2 months');
});
});