layout and navigation set up

This commit is contained in:
Sean Macfarlane
2020-03-12 18:06:11 -04:00
parent b619cfe8b0
commit 823470042f
15 changed files with 224 additions and 220 deletions

View File

@@ -9,14 +9,14 @@
right: 0;
z-index: 2000;
&.mobile {
left: 0;
}
&.collapsed {
left: $sidebar-collapsed-width;
}
&.mobile {
left: 0;
}
.row {
:global(.ant-row) {
margin-bottom: 10px;
&:last-child {
@@ -31,6 +31,10 @@
justify-content: center;
align-items: center;
padding: 0 0 0 24px;
img {
border-radius: 5px;
}
}
.MenuIcon {
@@ -39,3 +43,7 @@
line-height: 64px;
padding: 0 24px;
}
.RightMenu {
margin-left: auto;
}

View File

@@ -1,7 +1,8 @@
import React, { useState } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { Layout, Icon, Popover, Row } from 'antd';
import { Layout, Popover, Row } from 'antd';
import { MenuUnfoldOutlined, MenuFoldOutlined, SettingOutlined } from '@ant-design/icons';
import logoMobile from 'images/logoxmobile.jpg';
@@ -50,28 +51,30 @@ const GlobalHeader = ({ collapsed, onMenuButtonClick, isMobile }) => {
className={`${styles.GlobalHeader} ${collapsed ? styles.collapsed : ''} ${
isMobile ? styles.mobile : ''
}`}
collapsed={collapsed}
isMobile={isMobile}
>
{isMobile && [
<Link className={styles.LogoContainer} to="/" key="mobileLogo">
<img src={logoMobile} alt="logo" width="32" />
</Link>,
]}
<Icon
className={styles.MenuIcon}
type={collapsed ? 'menu-unfold' : 'menu-fold'}
onClick={onMenuButtonClick}
/>
<Popover
content={userOptions}
trigger="click"
getPopupContainer={e => e.parentElement}
visible={popoverVisible}
onVisibleChange={handleVisibleChange}
>
<Icon className={styles.MenuIcon} type="setting" />
</Popover>
{collapsed ? (
<MenuUnfoldOutlined className={styles.MenuIcon} onClick={onMenuButtonClick} />
) : (
<MenuFoldOutlined className={styles.MenuIcon} onClick={onMenuButtonClick} />
)}
<div className={styles.RightMenu}>
<Popover
content={userOptions}
trigger="click"
getPopupContainer={e => e.parentElement}
visible={popoverVisible}
onVisibleChange={handleVisibleChange}
placement="bottomRight"
arrowPointAtCenter
>
<SettingOutlined className={styles.MenuIcon} />
</Popover>
</div>
</Header>
);
};

View File

@@ -7,9 +7,11 @@
&.Mobile {
position: relative;
}
&.collapsed {
.Logo {
height: 32px;
width: 32px;
}
}
@@ -25,87 +27,11 @@
}
.Logo {
height: 44px;
width: 200px;
border-radius: 5px;
}
.MenuIcon {
margin-right: 10px;
}
:global(.sidemenu) {
border: none;
margin-top: 14px;
overflow-x: hidden;
overflow-y: auto;
display: flex;
flex-direction: column;
height: calc(100% - 78px);
width: auto;
.ant-menu-item {
display: flex;
min-height: 40px;
width: 100%;
align-items: center;
}
.ant-menu-submenu {
&.ant-menu-submenu-selected {
&.ant-menu-submenu-open {
.ant-menu-submenu-title {
color: rgba(0, 0, 0, 0.65);
background: transparent;
}
}
.ant-menu-submenu-title {
background: #e6f7ff;
color: #1890ff;
&::after {
content: '';
position: absolute;
right: 0;
top: 0;
bottom: 0;
border-right: 4px solid #1890ff;
transform: scaleY(0.0001);
opacity: 0;
transition: transform 0.15s cubic-bezier(0.215, 0.61, 0.355, 1),
opacity 0.15s cubic-bezier(0.215, 0.61, 0.355, 1);
}
}
}
.ant-menu-item {
padding-left: 24px !important;
}
}
&.ant-menu-inline {
.ant-menu-submenu {
&.ant-menu-submenu-selected {
&.ant-menu-submenu-open {
.ant-menu-submenu-title {
&::after {
transition: transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),
opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1);
opacity: 0;
transform: scaleY(0.0001);
}
}
}
.ant-menu-submenu-title {
&::after {
transition: transform 0.15s cubic-bezier(0.645, 0.045, 0.355, 1),
opacity 0.15s cubic-bezier(0.645, 0.045, 0.355, 1);
opacity: 1;
transform: scaleY(1);
}
}
}
}
}
margin-right: 10px!important;
}
}

View File

@@ -1,7 +1,19 @@
import React, { useState, useEffect } from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { Layout, Menu, Icon, Drawer } from 'antd';
import { Layout, Menu, Drawer } from 'antd';
import {
DashboardOutlined,
ProfileOutlined,
AreaChartOutlined,
MobileOutlined,
ApiOutlined,
NotificationOutlined,
CheckCircleOutlined,
SettingOutlined,
TeamOutlined,
LogoutOutlined,
} from '@ant-design/icons';
import logo from 'images/logo-light.png';
import logoMobile from 'images/logoxmobile.jpg';
@@ -36,63 +48,63 @@ const SideMenu = ({
const enocMenuItems = [
{
key: 'dashboard',
icon: 'dashboard',
path: '/dashboard',
icon: <DashboardOutlined className={styles.MenuIcon} />,
path: '/',
text: 'Dashboard',
onClick: onMenuItemClick,
},
{
key: 'profiles',
icon: 'profile',
icon: <ProfileOutlined className={styles.MenuIcon} />,
path: '/profiles',
text: 'Profiles',
onClick: onMenuItemClick,
},
{
key: 'reports',
icon: 'area-chart',
icon: <AreaChartOutlined className={styles.MenuIcon} />,
path: '/analytics/qoe',
text: 'Insights',
onClick: onMenuItemClick,
},
{
key: 'client-devices',
icon: 'mobile',
icon: <MobileOutlined className={styles.MenuIcon} />,
path: '/network/client-devices',
text: 'Client Devices',
onClick: onMenuItemClick,
},
{
key: 'network-elements',
icon: 'api',
icon: <ApiOutlined className={styles.MenuIcon} />,
path: '/network/elements',
text: 'Network Elements',
onClick: onMenuItemClick,
},
{
key: 'alarms',
icon: 'notification',
icon: <NotificationOutlined className={styles.MenuIcon} />,
path: '/network/alarms',
text: 'Alarms',
onClick: onMenuItemClick,
},
{
key: 'recommendations',
icon: 'check',
icon: <CheckCircleOutlined className={styles.MenuIcon} />,
path: '/recommendations',
text: 'Recommendations',
onClick: onMenuItemClick,
},
{
key: 'settings',
icon: 'setting',
icon: <SettingOutlined className={styles.MenuIcon} />,
path: '/settings',
text: 'Settings',
onClick: onMenuItemClick,
},
{
key: ACCOUNTS,
icon: 'team',
icon: <TeamOutlined className={styles.MenuIcon} />,
text: 'Customers',
path: '/accounts/customers',
onClick: onMenuItemClick,
@@ -102,7 +114,8 @@ const SideMenu = ({
const commonMenuItems = [
{
key: 'logout',
icon: 'logout',
icon: <LogoutOutlined className={styles.MenuIcon} />,
path: '/signout',
text: 'Sign Out',
onClick: onLogout,
},
@@ -141,7 +154,7 @@ const SideMenu = ({
key={item.key}
title={
<span>
<Icon type={item.icon} className={styles.MenuIcon} />
{item.icon}
<span>{item.text}</span>
</span>
}
@@ -176,7 +189,7 @@ const SideMenu = ({
items.push(
<ItemComponent key={item.key} className="ant-menu-item">
<LinkComponent onClick={item.onClick} to={item.path}>
<Icon type={item.icon} className={styles.MenuIcon} />
{item.icon}
<span>{item.text}</span>
</LinkComponent>
</ItemComponent>
@@ -204,8 +217,9 @@ const SideMenu = ({
width="234px"
collapsedWidth="80px"
breakpoint="lg"
isMobile={isMobile}
className={`${styles.Sider} ${isMobile || collapsed ? styles.Mobile : ''}`}
className={`${styles.Sider} ${collapsed ? styles.collapsed : ''} ${
isMobile ? styles.Mobile : ''
}`}
>
<div className={styles.TopArea}>
<Link
@@ -213,13 +227,7 @@ const SideMenu = ({
to="/"
// preserveParams={this.getPreservedParams('/', locationState)}
>
<img
className={styles.Logo}
alt="ConnectUs"
collapsed={collapsed}
isMobile={isMobile}
src={collapsed ? logoMobile : logo}
/>
<img className={styles.Logo} alt="ConnectUs" src={collapsed ? logoMobile : logo} />
</Link>
</div>
<Menu
@@ -228,7 +236,7 @@ const SideMenu = ({
defaultOpenKeys={menu.openKeys}
onOpenChange={onOpenChange}
mode="inline"
inlineCollapsed={collapsed}
theme="dark"
>
{menu.items}
</Menu>
@@ -238,11 +246,13 @@ const SideMenu = ({
if (isMobile) {
return (
<Drawer
getContainer={null}
level={null}
open={!collapsed}
handleChild={false}
onMaskClick={onMenuButtonClick}
zIndex={9999}
placement="left"
closable={false}
visible={!collapsed}
onClose={onMenuButtonClick}
bodyStyle={{ padding: 0 }}
width={256}
>
{sider}
</Drawer>

View File

@@ -2,9 +2,6 @@ import React from 'react';
import { Helmet } from 'react-helmet';
import { Switch } from 'react-router-dom';
import 'styles/antd.less';
import 'styles/index.scss';
import Dashboard from 'containers/Dashboard';
import RouteWithLayout from './components/RouteWithLayout';

View File

@@ -5,16 +5,16 @@
margin-left: $sidebar-width;
overflow: auto;
&.mobile {
margin-left: 0;
}
&.collapsed {
margin-left: $sidebar-collapsed-width;
}
&.mobile {
margin-left: 0;
}
}
.Content {
margin-top: $header-height;
margin-top: $header-height;
}
.Footer {

View File

@@ -1,6 +1,6 @@
import React, { useEffect } from 'react';
import React, { useEffect, memo } from 'react';
import PropTypes from 'prop-types';
import { Layout as AntdLayout } from 'antd';
import { Layout } from 'antd';
import { connect } from 'react-redux';
import { compose } from 'redux';
import { createStructuredSelector } from 'reselect';
@@ -14,16 +14,15 @@ import { makeSelectLocation, makeSelectError } from 'containers/App/selectors';
import { setMenu } from './actions';
import { STATE_KEY } from './constants';
import { makeSelectMenu } from './selectors';
import { makeSelectCollapsed, makeSelectIsMobile, makeSelectScreen } from './selectors';
import reducer from './reducer';
import styles from './MasterLayout.module.scss';
const { Content, Footer } = AntdLayout;
const { Content, Footer } = Layout;
const MasterLayout = ({ children, locationState, menu, onSetMenu }) => {
const MasterLayout = ({ children, locationState, collapsed, isMobile, screen, onSetMenu }) => {
useInjectReducer({ key: STATE_KEY, reducer });
const { collapsed, isMobile, screen } = menu;
const currentYear = new Date().getFullYear();
const handleResize = () => {
@@ -52,7 +51,8 @@ const MasterLayout = ({ children, locationState, menu, onSetMenu }) => {
const handleMenuToggle = () => {
onSetMenu({
...menu,
isMobile,
screen,
collapsed: !collapsed,
});
@@ -65,7 +65,8 @@ const MasterLayout = ({ children, locationState, menu, onSetMenu }) => {
const handleMenuItemClick = () => {
if (isMobile === true) {
onSetMenu({
...menu,
isMobile,
screen,
collapsed: true,
});
}
@@ -82,8 +83,13 @@ const MasterLayout = ({ children, locationState, menu, onSetMenu }) => {
return () => window.removeEventListener('resize', handleResize);
}, []);
useEffect(() => {
window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize);
}, [screen]);
return (
<AntdLayout>
<Layout>
<SideMenu
locationState={locationState}
collapsed={collapsed}
@@ -92,38 +98,40 @@ const MasterLayout = ({ children, locationState, menu, onSetMenu }) => {
onMenuItemClick={handleMenuItemClick}
onLogout={handleLogout}
/>
<AntdLayout
<Layout
className={`${styles.MainLayout} ${collapsed ? styles.collapsed : ''} ${
isMobile ? styles.mobile : ''
}`}
collapsed={collapsed}
isMobile={isMobile}
>
<GlobalHeader
collapsed={collapsed}
onMenuButtonClick={handleMenuToggle}
isMobile={isMobile}
onMenuButtonClick={handleMenuToggle}
/>
<Content>{children}</Content>
<Content className={styles.Content}>{children}</Content>
<Footer className={styles.Footer}>
Copyright © {currentYear} ConnectUs Inc. All Rights Reserved.
</Footer>
</AntdLayout>
</AntdLayout>
</Layout>
</Layout>
);
};
MasterLayout.propTypes = {
children: PropTypes.node.isRequired,
locationState: PropTypes.instanceOf(Object).isRequired,
menu: PropTypes.instanceOf(Object).isRequired,
collapsed: PropTypes.bool.isRequired,
isMobile: PropTypes.bool.isRequired,
screen: PropTypes.string.isRequired,
onSetMenu: PropTypes.func.isRequired,
};
export const mapStateToProps = createStructuredSelector({
locationState: makeSelectLocation(),
globalError: makeSelectError(),
menu: makeSelectMenu(),
collapsed: makeSelectCollapsed(),
isMobile: makeSelectIsMobile(),
screen: makeSelectScreen(),
});
export function mapDispatchToProps(dispatch) {
@@ -134,4 +142,4 @@ export function mapDispatchToProps(dispatch) {
const withConnect = connect(mapStateToProps, mapDispatchToProps);
export default compose(withConnect)(MasterLayout);
export default compose(withConnect, memo)(MasterLayout);

View File

@@ -3,11 +3,9 @@ import { SET_MENU } from './constants';
// The initial state of the App
export const initialState = {
menu: {
collapsed: false,
isMobile: false,
screen: 'lg',
},
collapsed: false,
isMobile: false,
screen: 'lg',
};
/* eslint-disable default-case, no-param-reassign */
@@ -15,8 +13,12 @@ const layoutReducer = (state = initialState, action) =>
produce(state, draft => {
switch (action.type) {
case SET_MENU:
draft.menu = action.menu;
break;
draft.collapsed = action.menu.collapsed;
draft.isMobile = action.menu.isMobile;
draft.screen = action.menu.screen;
return draft;
default:
return draft;
}
});

View File

@@ -5,6 +5,8 @@ import { initialState } from './reducer';
const selectLayout = state => state[STATE_KEY] || initialState;
const makeSelectMenu = () => createSelector(selectLayout, state => state.menu);
const makeSelectCollapsed = () => createSelector(selectLayout, state => state.collapsed);
const makeSelectIsMobile = () => createSelector(selectLayout, state => state.isMobile);
const makeSelectScreen = () => createSelector(selectLayout, state => state.screen);
export { selectLayout, makeSelectMenu };
export { selectLayout, makeSelectCollapsed, makeSelectIsMobile, makeSelectScreen };

View File

@@ -3,6 +3,9 @@ import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { ConnectedRouter } from 'connected-react-router';
import 'styles/antd.less';
import 'styles/index.scss';
import App from 'containers/App';
import configureStore from 'store';
import history from 'utils/history';

View File

@@ -1,3 +1,3 @@
@import '~antd/dist/antd.dark.less';
@primary-color: #35a649;
@primary-color: #35a649;

View File

@@ -1,4 +1,4 @@
$sidebar-width: 234px;
$sidebar-collapsed-width: 80;
$sidebar-collapsed-width: 80px;
$header-height: 64px;

137
package-lock.json generated
View File

@@ -1117,6 +1117,11 @@
"any-observable": "0.3.0"
}
},
"@types/anymatch": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz",
"integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA=="
},
"@types/color-name": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz",
@@ -1126,14 +1131,12 @@
"@types/events": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
"dev": true
"integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g=="
},
"@types/glob": {
"version": "7.1.1",
"resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
"integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
"dev": true,
"requires": {
"@types/events": "3.0.0",
"@types/minimatch": "3.0.3",
@@ -1143,14 +1146,12 @@
"@types/minimatch": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
"dev": true
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA=="
},
"@types/node": {
"version": "13.9.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.0.tgz",
"integrity": "sha512-0ARSQootUG1RljH2HncpsY2TJBfGQIKOOi7kxzUY6z54ePu/ZD+wJA8zI2Q6v8rol2qpG/rvqsReco8zNMPvhQ==",
"dev": true
"integrity": "sha512-0ARSQootUG1RljH2HncpsY2TJBfGQIKOOi7kxzUY6z54ePu/ZD+wJA8zI2Q6v8rol2qpG/rvqsReco8zNMPvhQ=="
},
"@types/parse-json": {
"version": "4.0.0",
@@ -1158,6 +1159,68 @@
"integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==",
"dev": true
},
"@types/source-list-map": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz",
"integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA=="
},
"@types/tapable": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.5.tgz",
"integrity": "sha512-/gG2M/Imw7cQFp8PGvz/SwocNrmKFjFsm5Pb8HdbHkZ1K8pmuPzOX4VeVoiEecFCVf4CsN1r3/BRvx+6sNqwtQ=="
},
"@types/uglify-js": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.0.4.tgz",
"integrity": "sha512-SudIN9TRJ+v8g5pTG8RRCqfqTMNqgWCKKd3vtynhGzkIIjxaicNAMuY5TRadJ6tzDu3Dotf3ngaMILtmOdmWEQ==",
"requires": {
"source-map": "0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
},
"@types/webpack": {
"version": "4.41.7",
"resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.7.tgz",
"integrity": "sha512-OQG9viYwO0V1NaNV7d0n79V+n6mjOV30CwgFPIfTzwmk8DHbt+C4f2aBGdCYbo3yFyYD6sjXfqqOjwkl1j+ulA==",
"requires": {
"@types/anymatch": "1.3.1",
"@types/node": "13.9.0",
"@types/tapable": "1.0.5",
"@types/uglify-js": "3.0.4",
"@types/webpack-sources": "0.1.6",
"source-map": "0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
},
"@types/webpack-sources": {
"version": "0.1.6",
"resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-0.1.6.tgz",
"integrity": "sha512-FtAWR7wR5ocJ9+nP137DV81tveD/ZgB1sadnJ/axUGM3BUVfRPx8oQNMtv3JNfTeHx3VP7cXiyfR/jmtEsVHsQ==",
"requires": {
"@types/node": "13.9.0",
"@types/source-list-map": "0.1.2",
"source-map": "0.6.1"
},
"dependencies": {
"source-map": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
}
}
},
"@webassemblyjs/ast": {
"version": "1.8.5",
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz",
@@ -1625,7 +1688,6 @@
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
"integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
"dev": true,
"requires": {
"array-uniq": "1.0.3"
}
@@ -1633,8 +1695,7 @@
"array-uniq": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
"integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
"dev": true
"integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY="
},
"array-unique": {
"version": "0.3.2",
@@ -2139,8 +2200,7 @@
"balanced-match": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
"dev": true
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
"base": {
"version": "0.11.2",
@@ -2311,7 +2371,6 @@
"version": "1.1.11",
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"dev": true,
"requires": {
"balanced-match": "1.0.0",
"concat-map": "0.0.1"
@@ -2668,6 +2727,15 @@
}
}
},
"clean-webpack-plugin": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-3.0.0.tgz",
"integrity": "sha512-MciirUH5r+cYLGCOL5JX/ZLzOZbVr1ot3Fw+KcvbhUb6PM+yycqd9ZhIlcigQ5gl+XhppNmw3bEFuaaMNyLj3A==",
"requires": {
"@types/webpack": "4.41.7",
"del": "4.1.1"
}
},
"cli-cursor": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
@@ -2873,8 +2941,7 @@
"concat-map": {
"version": "0.0.1",
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
"dev": true
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"concat-stream": {
"version": "1.6.2",
@@ -3345,7 +3412,6 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz",
"integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==",
"dev": true,
"requires": {
"@types/glob": "7.1.1",
"globby": "6.1.0",
@@ -4663,8 +4729,7 @@
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
"dev": true
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
},
"fsevents": {
"version": "1.2.11",
@@ -5343,7 +5408,6 @@
"version": "7.1.6",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz",
"integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==",
"dev": true,
"requires": {
"fs.realpath": "1.0.0",
"inflight": "1.0.6",
@@ -5419,7 +5483,6 @@
"version": "6.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz",
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
"dev": true,
"requires": {
"array-union": "1.0.2",
"glob": "7.1.6",
@@ -5431,8 +5494,7 @@
"pify": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
"dev": true
"integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
}
}
},
@@ -6091,7 +6153,6 @@
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"dev": true,
"requires": {
"once": "1.4.0",
"wrappy": "1.0.2"
@@ -6100,8 +6161,7 @@
"inherits": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
"dev": true
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"ini": {
"version": "1.3.5",
@@ -6459,14 +6519,12 @@
"is-path-cwd": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
"integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
"dev": true
"integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ=="
},
"is-path-in-cwd": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz",
"integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==",
"dev": true,
"requires": {
"is-path-inside": "2.1.0"
}
@@ -6475,7 +6533,6 @@
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz",
"integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==",
"dev": true,
"requires": {
"path-is-inside": "1.0.2"
}
@@ -7719,7 +7776,6 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"dev": true,
"requires": {
"brace-expansion": "1.1.11"
}
@@ -8344,7 +8400,6 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"dev": true,
"requires": {
"wrappy": "1.0.2"
}
@@ -8474,8 +8529,7 @@
"p-map": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz",
"integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==",
"dev": true
"integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw=="
},
"p-retry": {
"version": "3.0.1",
@@ -8589,14 +8643,12 @@
"path-is-absolute": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
"dev": true
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18="
},
"path-is-inside": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
"integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
"dev": true
"integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM="
},
"path-key": {
"version": "2.0.1",
@@ -8660,20 +8712,17 @@
"pify": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
"dev": true
"integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g=="
},
"pinkie": {
"version": "2.0.4",
"resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
"integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=",
"dev": true
"integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
},
"pinkie-promise": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
"integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
"dev": true,
"requires": {
"pinkie": "2.0.4"
}
@@ -10122,7 +10171,6 @@
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz",
"integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==",
"dev": true,
"requires": {
"glob": "7.1.6"
}
@@ -12488,8 +12536,7 @@
"wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
"dev": true
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
},
"write": {
"version": "1.0.3",

View File

@@ -16,8 +16,10 @@
},
"license": "MIT",
"dependencies": {
"@ant-design/icons": "^4.0.2",
"antd": "^4.0.2",
"axios": "^0.19.2",
"clean-webpack-plugin": "^3.0.0",
"connected-react-router": "^6.7.0",
"history": "^4.10.1",
"hoist-non-react-statics": "^3.3.2",

View File

@@ -1,6 +1,7 @@
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const path = require('path');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const HtmlWebPackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
module.exports = {
mode: process.env.NODE_ENV,
@@ -10,6 +11,7 @@ module.exports = {
publicPath: '/',
filename: 'bundle.js',
},
devtool: 'inline-source-map',
devServer: {
port: 3000,
},
@@ -36,19 +38,12 @@ module.exports = {
},
{
test: /\.less$/,
exclude: /node_modules/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
modules: {
localIdentName: '[name]__[local]___[hash:base64:5]',
},
sourceMap: true,
},
},
{
loader: 'less-loader',
@@ -91,6 +86,7 @@ module.exports = {
},
},
plugins: [
new CleanWebpackPlugin(),
new HtmlWebPackPlugin({
inject: true,
template: './app/index.html',