Skip to content

Commit acadaf4

Browse files
committed
base code
0 parents  commit acadaf4

14 files changed

+9976
-0
lines changed

babel.config.json

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
{
2+
"presets": [
3+
"@babel/preset-env",
4+
"@babel/preset-react",
5+
],
6+
"plugins": [
7+
[
8+
"@babel/plugin-transform-runtime",
9+
{
10+
"useESModules": true,
11+
"regenerator": false
12+
}
13+
]
14+
],
15+
"env": {
16+
"test": {
17+
"presets": [
18+
["@babel/preset-env", {
19+
"targets": "current node"
20+
}]
21+
]
22+
}
23+
}
24+
}

jest.config.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
module.exports = {
2+
rootDir: "src",
3+
transform: {
4+
"^.+\\.(j|t)sx?$": "babel-jest",
5+
},
6+
moduleNameMapper: {
7+
"\\.(css)$": "identity-obj-proxy",
8+
},
9+
setupFilesAfterEnv: [
10+
"../node_modules/@testing-library/jest-dom/dist/index.js",
11+
],
12+
};

package.json

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
{
2+
"name": "@mt/navbar",
3+
"scripts": {
4+
"start": "webpack-dev-server",
5+
"start:standalone": "webpack-dev-server --env.standalone",
6+
"build": "webpack --mode=production",
7+
"analyze": "webpack --mode=production --env.analyze=true",
8+
"lint": "eslint src --ext js",
9+
"format": "prettier --write \"./**\"",
10+
"test": "cross-env BABEL_ENV=test jest",
11+
"watch-tests": "cross-env BABEL_ENV=test jest --watch",
12+
"coverage": "cross-env BABEL_ENV=test jest --coverage"
13+
},
14+
"husky": {
15+
"hooks": {
16+
"pre-commit": "pretty-quick --staged && concurrently yarn:test yarn:lint"
17+
}
18+
},
19+
"devDependencies": {
20+
"@babel/core": "^7.7.5",
21+
"@babel/plugin-transform-runtime": "^7.8.3",
22+
"@babel/preset-env": "^7.7.6",
23+
"@babel/preset-react": "^7.7.4",
24+
"@babel/runtime": "^7.8.7",
25+
"@reach/router": "^1.3.4",
26+
"@testing-library/jest-dom": "^5.11.6",
27+
"@testing-library/react": "^11.2.2",
28+
"@types/jest": "^25.2.1",
29+
"@types/systemjs": "^6.1.0",
30+
"antd": "^4.8.6",
31+
"babel-eslint": "^11.0.0-beta.2",
32+
"babel-jest": "^24.9.0",
33+
"babel-plugin-import": "^1.13.3",
34+
"concurrently": "^5.0.1",
35+
"cross-env": "^7.0.2",
36+
"css-loader": "^5.0.1",
37+
"eslint": "^6.7.2",
38+
"eslint-config-prettier": "^6.7.0",
39+
"eslint-config-react-important-stuff": "^2.0.0",
40+
"eslint-plugin-prettier": "^3.1.1",
41+
"husky": "^3.1.0",
42+
"identity-obj-proxy": "^3.0.0",
43+
"jest": "^25.2.7",
44+
"jest-cli": "^25.2.7",
45+
"prettier": "^2.0.4",
46+
"pretty-quick": "^2.0.1",
47+
"single-spa-react": "^2.14.0",
48+
"systemjs-webpack-interop": "^2.1.2",
49+
"webpack": "^4.41.2",
50+
"webpack-cli": "^3.3.10",
51+
"webpack-config-single-spa-react": "^1.0.3",
52+
"webpack-dev-server": "^3.9.0",
53+
"webpack-merge": "^4.2.2"
54+
},
55+
"dependencies": {
56+
"react": "^16.12.0",
57+
"react-dom": "^16.12.0"
58+
}
59+
}

src/container/layout/index.js

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import React from 'react';
2+
import { Layout, Menu, Breadcrumb } from 'antd';
3+
import Navbar from '../navbar/index.js'
4+
5+
const { Header, Content, Footer, Sider } = Layout;
6+
const { SubMenu } = Menu;
7+
export default class LayoutGuide extends React.Component {
8+
constructor(props) {
9+
super(props);
10+
this.state = {
11+
collapsed: false,
12+
}
13+
}
14+
rootPath() {
15+
16+
}
17+
onCollapse (collapsed){
18+
const dom = document.getElementById("containerPanel");
19+
this.setState({ collapsed },()=>{
20+
if (collapsed) {
21+
setTimeout(function(){
22+
dom.style.marginLeft = '80px';
23+
}, 220)
24+
25+
} else {
26+
dom.style.marginLeft = '200px';
27+
}
28+
});
29+
};
30+
31+
render() {
32+
const { collapsed } = this.state;
33+
return (
34+
<Layout style={{ minHeight: '100vh' }}>
35+
<Sider collapsible collapsed={collapsed} onCollapse={this.onCollapse.bind(this)}>
36+
<div className="logo" />
37+
<Menu theme="dark" defaultSelectedKeys={['top4']} mode="inline">
38+
<Navbar />
39+
</Menu>
40+
</Sider>
41+
</Layout>
42+
);
43+
}
44+
}

src/container/main.js

Whitespace-only changes.

src/container/navbar/index.js

+91
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import React, {Fragment} from "react";
2+
import { links } from "../../root.helper.js";
3+
import { Link } from "@reach/router";
4+
import '../../index.css'
5+
import {Menu, Button} from 'antd';
6+
7+
import {
8+
AppstoreOutlined,
9+
MenuUnfoldOutlined,
10+
MenuFoldOutlined,
11+
PieChartOutlined,
12+
DesktopOutlined,
13+
ContainerOutlined,
14+
MailOutlined,
15+
} from '@ant-design/icons';
16+
17+
const { SubMenu } = Menu;
18+
export default class Navbar extends React.Component {
19+
constructor(props) {
20+
super(props);
21+
this.state = {
22+
defaultOpenItemIndex: 'top4'
23+
}
24+
}
25+
26+
autoGenerateNavItem(itemlinks) {
27+
let itemOptons = [];
28+
if (!itemlinks.type) {
29+
return;
30+
} else if (itemlinks.type === "toplevel") {
31+
itemOptons.push(
32+
<Menu.Item key={itemlinks.index} icon={this.setItemIcon(itemlinks.icon)} key={itemlinks.index}>
33+
<Link key={itemlinks.href} className="p-6" to={itemlinks.href} key={itemlinks.index}>
34+
{itemlinks.name}
35+
</Link>
36+
</Menu.Item>
37+
)
38+
} else {
39+
itemOptons.push(
40+
<SubMenu key={itemlinks.index} icon={<MailOutlined />} title={itemlinks.name} key={itemlinks.index}>
41+
{itemlinks["subItem"].map((seclink) => {
42+
return (
43+
<Menu.Item key={seclink.secindex} key={itemlinks.seclink}>{seclink.secName}</Menu.Item>
44+
)
45+
})}
46+
</SubMenu>
47+
);
48+
49+
}
50+
return itemOptons;
51+
}
52+
53+
setItemIcon(iconName) {
54+
let icon = <ContainerOutlined />;
55+
switch(iconName) {
56+
case 'AppstoreOutlined':
57+
icon = <AppstoreOutlined />;
58+
break;
59+
case 'PieChartOutlined':
60+
icon = <PieChartOutlined />;
61+
break;
62+
case 'MenuFoldOutlined':
63+
icon = <MenuFoldOutlined />;
64+
break;
65+
case "MailOutlined":
66+
icon = <MailOutlined />
67+
break;
68+
default:
69+
return icon;
70+
}
71+
return icon;
72+
}
73+
render() {
74+
return(
75+
<Fragment>
76+
<Menu
77+
defaultSelectedKeys={['1']}
78+
defaultOpenKeys={[this.state.defaultOpenItemIndex]}
79+
mode="inline"
80+
theme="dark"
81+
>
82+
{links.map((link) => {
83+
return this.autoGenerateNavItem(link);
84+
})}
85+
</Menu>
86+
</Fragment>
87+
)
88+
}
89+
90+
}
91+

src/index.css

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.colorName {
2+
/* color: blue */
3+
}

src/mt-navbar.js

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import "./set-public-path";
2+
import React from "react";
3+
import ReactDOM from "react-dom";
4+
import singleSpaReact from "single-spa-react";
5+
import RootLayout from "./root.component";
6+
7+
const lifecycles = singleSpaReact({
8+
React,
9+
ReactDOM,
10+
rootComponent: RootLayout,
11+
errorBoundary(err, info, props) {
12+
// Customize the root error boundary for your microfrontend here.
13+
return (
14+
<div className="h-16 flex items-center justify-between px-6 bg-primary text-white">
15+
Error Evan
16+
</div>
17+
);
18+
},
19+
domElementGetter
20+
});
21+
function domElementGetter() {
22+
let el = document.getElementById("menuPanel");
23+
if (!el) {
24+
el = document.createElement('div');
25+
el.id = 'menuPanel';
26+
document.body.appendChild(el);
27+
}
28+
return el;
29+
}
30+
31+
export const { bootstrap, mount, unmount } = lifecycles;

src/root.component.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import React from 'react'
2+
import LayoutGuide from './container/layout/index.js'
3+
4+
export default function RootLayout (props) {
5+
return(
6+
<LayoutGuide />
7+
)
8+
}

src/root.component.test.js

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import React from "react";
2+
import { render } from "@testing-library/react";
3+
import Root from "./root.component";
4+
5+
describe("Root component", () => {
6+
it("should be in the document", () => {
7+
const { getByText } = render(<Root name="Testapp" />);
8+
expect(getByText(/Testapp is mounted!/i)).toBeInTheDocument();
9+
});
10+
});

src/root.helper.js

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
export const links = [
2+
{
3+
index: 'top1',
4+
name: "home",
5+
href: "/",
6+
type: "toplevel",
7+
icon:'AppstoreOutlined',
8+
},
9+
{
10+
index: 'top2',
11+
name: "opp",
12+
href: "/oppReact",
13+
type: "toplevel",
14+
icon: "PieChartOutlined"
15+
},
16+
{
17+
index: 'top3',
18+
name: "testSingle",
19+
href: "/testSingle",
20+
type: "toplevel",
21+
icon: "MenuFoldOutlined"
22+
},
23+
{
24+
index: 'top4',
25+
name: "tmp",
26+
href: "/tmp",
27+
type: "sublevel",
28+
icon: "MailOutlined",
29+
subItem:[
30+
{
31+
secIndex:"4_1",
32+
secName: "test1"
33+
},
34+
{
35+
secIndex:"4_2",
36+
secName: "test2"
37+
},
38+
{
39+
secIndex:"4_3",
40+
secName: "test3"
41+
},
42+
]
43+
44+
},
45+
];

src/set-public-path.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { setPublicPath } from "systemjs-webpack-interop";
2+
/* This dynamically sets the webpack public path so that code splits work properly. See related:
3+
* https://github.com/joeldenning/systemjs-webpack-interop#what-is-this
4+
* https://webpack.js.org/guides/public-path/#on-the-fly
5+
* https://single-spa.js.org/docs/faq/#code-splits
6+
*/
7+
8+
setPublicPath("@mt/navbar");

webpack.config.js

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
const webpackMerge = require("webpack-merge");
2+
const singleSpaDefaults = require("webpack-config-single-spa-react");
3+
4+
module.exports = (webpackConfigEnv, argv) => {
5+
const defaultConfig = singleSpaDefaults({
6+
orgName: "mt",
7+
projectName: "navbar",
8+
webpackConfigEnv,
9+
argv,
10+
});
11+
12+
return webpackMerge.smart(defaultConfig, {
13+
module:{
14+
rules:[
15+
{
16+
test: `/\.css$/`,
17+
use: [ 'style-loader', 'css-loader' ]
18+
}
19+
]
20+
}
21+
// modify the webpack config however you'd like to by adding to this object
22+
});
23+
};

0 commit comments

Comments
 (0)