Skip to content

Commit

Permalink
feat: comprehensive upgrade dashboard UI (#260)
Browse files Browse the repository at this point in the history
## What type of PR is this?
/kind feature

## What this PR does / why we need it:
Comprehensive upgrade dashboard UI:
* Upgrade UI style.
* Add pages for multi cluster management, insights, search results, and
more.

Screenshots:

![image](https://github.com/KusionStack/karbour/assets/9360247/3d3db5c1-bfe2-4a21-a0d2-27a48c1e5403)

---------

Co-authored-by: hai-tian <[email protected]>
  • Loading branch information
elliotxx and hai-tian authored Jan 18, 2024
1 parent d8eba17 commit a510ed3
Show file tree
Hide file tree
Showing 170 changed files with 11,951 additions and 8,513 deletions.
8 changes: 4 additions & 4 deletions ui/craco.config.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const CracoLessPlugin = require("craco-less");
const CracoCSSModules = require("craco-css-modules");
const path = require("path");
const path = require("path");

module.exports = {
plugins: [
Expand All @@ -16,13 +16,13 @@ module.exports = {
},
},
{
plugin: CracoCSSModules
}
plugin: CracoCSSModules,
},
],
webpack: {
// 配置别名,设置别名是为了让后续引用的地方减少路径的复杂度
alias: {
"@": path.resolve(__dirname, "src"),
},
},
}
};
9,807 changes: 4,346 additions & 5,461 deletions ui/package-lock.json

Large diffs are not rendered by default.

24 changes: 18 additions & 6 deletions ui/package.json
Original file line number Diff line number Diff line change
@@ -1,27 +1,39 @@
{
"name": "karbour",
"version": "0.1.0",
"name": "Karbour-dashboard",
"version": "0.2.0",
"private": true,
"dependencies": {
"@ant-design/icons": "^5.0.1",
"@antv/g2": "^5.0.11",
"@antv/g6": "^4.8.13",
"@ant-design/icons": "^5.2.6",
"@antv/g2": "^5.1.13",
"@antv/g2plot": "^2.4.31",
"@antv/g6": "^4.8.23",
"@antv/g6-react-node": "^1.4.8",
"@codemirror/basic-setup": "^0.20.0",
"@codemirror/lang-sql": "^6.5.4",
"@codemirror/state": "^6.3.3",
"@codemirror/view": "^6.22.3",
"@testing-library/jest-dom": "^5.16.5",
"@testing-library/react": "^13.4.0",
"@testing-library/user-event": "^13.5.0",
"@types/jest": "^27.5.2",
"@types/node": "^16.18.23",
"@types/react": "^18.0.35",
"@types/react-dom": "^18.0.11",
"ahooks": "^3.7.8",
"ansi_up": "^5.2.1",
"antd": "^5.4.2",
"antd": "^5.11.3",
"axios": "^1.3.5",
"bignumber.js": "^9.1.2",
"bizcharts": "^4.1.22",
"classnames": "^2.3.2",
"dayjs": "^1.11.7",
"highlight.js": "^11.9.0",
"js-yaml": "^4.1.0",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"query-string": "^8.1.0",
"react": "^18.2.0",
"react-diff-viewer-continued": "^3.3.1",
"react-dom": "^18.2.0",
"react-grid-layout": "^1.3.4",
"react-router-dom": "^6.10.0",
Expand Down
2 changes: 1 addition & 1 deletion ui/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
~ limitations under the License.
-->

<!DOCTYPE html>
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
Expand Down
Binary file added ui/src/assets/labeled/c-role-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/cm-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/crb-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/crd-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/cronjob-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/deploy-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/ds-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/ep-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/group-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/hpa-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/ing-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/job-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/limits-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/netpol-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/node-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/ns-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/pod-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/psp-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/pv-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/pvc-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/quota-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/rb-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/role-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/rs-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/sa-128.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added ui/src/assets/labeled/sc-128.png
Binary file added ui/src/assets/labeled/secret-128.png
Binary file added ui/src/assets/labeled/sts-128.png
Binary file added ui/src/assets/labeled/svc-128.png
Binary file added ui/src/assets/labeled/user-128.png
Binary file added ui/src/assets/labeled/vol-128.png
Binary file added ui/src/assets/logo.jpg
Binary file added ui/src/assets/transfer.png
Binary file added ui/src/assets/unlabeled/c-role-128.png
Binary file added ui/src/assets/unlabeled/cm-128.png
Binary file added ui/src/assets/unlabeled/crb-128.png
Binary file added ui/src/assets/unlabeled/crd-128.png
Binary file added ui/src/assets/unlabeled/cronjob-128.png
Binary file added ui/src/assets/unlabeled/deploy-128.png
Binary file added ui/src/assets/unlabeled/ds-128.png
Binary file added ui/src/assets/unlabeled/ep-128.png
Binary file added ui/src/assets/unlabeled/group-128.png
Binary file added ui/src/assets/unlabeled/hpa-128.png
Binary file added ui/src/assets/unlabeled/ing-128.png
Binary file added ui/src/assets/unlabeled/job-128.png
Binary file added ui/src/assets/unlabeled/limits-128.png
Binary file added ui/src/assets/unlabeled/netpol-128.png
Binary file added ui/src/assets/unlabeled/node-128.png
Binary file added ui/src/assets/unlabeled/ns-128.png
Binary file added ui/src/assets/unlabeled/pod-128.png
Binary file added ui/src/assets/unlabeled/psp-128.png
Binary file added ui/src/assets/unlabeled/pv-128.png
Binary file added ui/src/assets/unlabeled/pvc-128.png
Binary file added ui/src/assets/unlabeled/quota-128.png
Binary file added ui/src/assets/unlabeled/rb-128.png
Binary file added ui/src/assets/unlabeled/role-128.png
Binary file added ui/src/assets/unlabeled/rs-128.png
Binary file added ui/src/assets/unlabeled/sa-128.png
Binary file added ui/src/assets/unlabeled/sc-128.png
Binary file added ui/src/assets/unlabeled/secret-128.png
Binary file added ui/src/assets/unlabeled/sts-128.png
Binary file added ui/src/assets/unlabeled/svc-128.png
Binary file added ui/src/assets/unlabeled/user-128.png
Binary file added ui/src/assets/unlabeled/vol-128.png
162 changes: 100 additions & 62 deletions ui/src/components/Layout/index.tsx
Original file line number Diff line number Diff line change
@@ -1,93 +1,131 @@
import React, { memo, useEffect, useMemo, useState } from "react";
import { Layout, Menu, MenuProps } from "antd";
import { HeatMapOutlined } from "@ant-design/icons";
import { matchRoutes, Outlet, useLocation, NavLink } from "react-router-dom";
import router, { RouteObject } from "../../router";
import React, { memo } from "react";
import { Divider, Menu } from "antd";
import {
ClusterOutlined,
FundOutlined,
QuestionCircleOutlined,
SearchOutlined,
} from "@ant-design/icons";
import type { MenuProps } from "antd";
import { Outlet, useLocation, useNavigate } from "react-router-dom";
import styles from "./style.module.less";

const { Content, Header } = Layout;

type MenuItem = Required<MenuProps>["items"][number];

function getItem(
label: React.ReactNode,
key: React.Key,
icon?: React.ReactNode,
children?: MenuItem[],
type?: "group"
type?: "group",
hidden?: boolean,
disabled?: boolean,
): MenuItem {
return {
key,
icon,
children,
label,
type,
hidden,
disabled,
} as MenuItem;
}

const LayoutPage = () => {
const [defaultSelectedKeys, setSelectKey] = useState<string[]>(["1"]);
const [defaultOpenKeys, setDefaultOpenKeys] = useState<string[]>(["1"]);
const [initial, setInitial] = useState(false);
const location = useLocation();
const navigate = useNavigate();
const { pathname } = useLocation();

const menuItems = [
getItem("搜索", "/search", <SearchOutlined />),
getItem("结果", "/search/result", <SearchOutlined />, null, null, true),
getItem("数据洞察", "/insight", <FundOutlined />, null, null, null, true),
getItem("集群列表", "/cluster", <ClusterOutlined />),
getItem("集群详情", "/insightDetail", <SearchOutlined />, null, null, true),
getItem(
"集群接入",
"/cluster/access",
<SearchOutlined />,
null,
null,
true,
),
getItem(
"更新证书",
"/cluster/certificate",
<SearchOutlined />,
null,
null,
true,
),
getItem("回流配置", "/reflux", <SearchOutlined />, null, null, true),
];

const items: MenuItem[] = useMemo(() => {
let menuItems = [];
router &&
(router[0]?.children || []).forEach((item: RouteObject) => {
// console.log(item, "===item===");
const navItem = getItem(
<NavLink to={item.path as string}>{item.title}</NavLink>,
item.path as string,
item.icon
);
if (item.istopmenu) {
menuItems.push(navItem);
}
});
return menuItems;
}, []);
function getKey() {
return [pathname];
}

useEffect(() => {
const routes = matchRoutes(router, { pathname: location.pathname });
// console.log('routes', routes, location.pathname);
const pathArr: string[] = [];
if (routes && routes.length) {
routes.forEach((item) => {
const path = item.route.path;
if (path === location.pathname) {
pathArr.push(path);
}
});
function getMenuItems() {
function loop(list) {
return list
?.filter((item) => !item?.hidden)
?.map((item) => {
if (item?.children) {
item.children = loop(item?.children);
}
return item;
});
}
setSelectKey(pathArr);
setDefaultOpenKeys(pathArr);
setInitial(true);
}, [location]);
return loop(menuItems);
}

if (!initial) {
return null;
function handleMenuClick(e) {
navigate(e.key);
}

function goHome() {
navigate("/search");
}

return (
<Layout>
<Header className={styles["top-container"]}>
<div className={styles.logo}>
<HeatMapOutlined />
<div className={styles.wrapper}>
<div className={styles.nav}>
<div className={styles.left}>
<div className={styles.title} onClick={goHome}>
<div className={styles.subLogo}>K</div>
<div className={styles.text}>Karbour 数据门户</div>
</div>
<div>
<Divider type="vertical" />
</div>
<Menu
style={{ flex: 1, border: "none" }}
mode="horizontal"
selectedKeys={getKey()}
items={getMenuItems()}
onClick={handleMenuClick}
/>
</div>
<div className={styles.right}>
<div className={styles.help}>
<a
target="_blank"
href="https://github.com/KusionStack/karbour"
rel="noreferrer"
>
<QuestionCircleOutlined style={{ color: "#999" }} />
</a>
</div>
</div>
</div>
<div className={styles.content}>
<div className={styles.right}>
<div className={styles.right_content}>
<Outlet />
</div>
</div>
<Menu
style={{ flex: 1, border: "none" }}
mode="horizontal"
defaultSelectedKeys={defaultSelectedKeys}
defaultOpenKeys={defaultOpenKeys}
selectedKeys={defaultSelectedKeys}
items={items}
/>
</Header>
<Content className={styles.container}>
<Outlet />
</Content>
</Layout>
</div>
</div>
);
};

Expand Down
111 changes: 99 additions & 12 deletions ui/src/components/Layout/style.module.less
Original file line number Diff line number Diff line change
@@ -1,16 +1,103 @@
.top-container {
.wrapper {
height: 100vh;
display: flex;
background: #fff;
padding: 0 20px;
.logo {
margin-right: 10px;
flex-direction: column;

.nav {
display: flex;
justify-content: space-between;
align-items: center;
background: #fff;
padding: 0 20px;
border-bottom: 1px solid #f5f5f5;

.left {
display: flex;
align-items: center;
flex: 1;

.logo {
margin-right: 30px;
}

.title {
font-weight: bold;
display: flex;
align-items: center;
cursor: pointer;

.subLogo {
display: inline-block;
width: 20px;
height: 20px;
line-height: 20px;
text-align: center;
color: #fff;
background: #2f54eb;
margin-right: 6px;
border-radius: 4px;
}

.text {
display: inline-block;
font-size: 14px;
margin-right: 10px;
}
}

.tenant {
padding-left: 10px;

.dropText {
color: #999;
font-size: 12px;
}
}
}

.right {
display: flex;
align-items: center;

.search {
margin-right: 10px;
}

.help {
margin: 0 10px;
}

.user {
display: flex;
align-items: center;
font-size: 12px;
margin-left: 10px;
color: #666;
}
}
}
}

.container {
margin: 10px;
padding: 20px;
background: #fff;
min-height: calc(100vh - 84px);
overflow: auto;
.content {
background: #fff;
flex: 1;
overflow: auto;
display: flex;

.left {
// height: 100%;
width: 160px;
border-right: 1px solid #f5f5f5;
}

.right {
flex: 1;
background: #fafafa;
padding: 32px;
overflow-y: scroll;

.right_content {
height: calc(100% - 30px);
}
}
}
}
Loading

0 comments on commit a510ed3

Please sign in to comment.