diff --git a/config/config.ts b/config/config.ts
index 2f794d2e..d6874c03 100644
--- a/config/config.ts
+++ b/config/config.ts
@@ -65,6 +65,7 @@ export default defineConfig({
}
: {}),
// esbuildMinifyIIFE: true,
+ favicons: ['/static/favicon.ico'],
jsMinifier: 'terser',
cssMinifier: 'cssnano',
presets: ['umi-presets-pro'],
diff --git a/src/favicon.ico b/public/static/favicon.ico
similarity index 100%
rename from src/favicon.ico
rename to public/static/favicon.ico
diff --git a/src/assets/images/bg-5.png b/src/assets/images/bg-5.png
new file mode 100644
index 00000000..a494136a
Binary files /dev/null and b/src/assets/images/bg-5.png differ
diff --git a/src/assets/images/bg-6.png b/src/assets/images/bg-6.png
new file mode 100644
index 00000000..b5c82747
Binary files /dev/null and b/src/assets/images/bg-6.png differ
diff --git a/src/assets/images/bg-7.png b/src/assets/images/bg-7.png
new file mode 100644
index 00000000..03367dac
Binary files /dev/null and b/src/assets/images/bg-7.png differ
diff --git a/src/assets/images/bg-8.png b/src/assets/images/bg-8.png
new file mode 100644
index 00000000..09d62af9
Binary files /dev/null and b/src/assets/images/bg-8.png differ
diff --git a/src/assets/images/bg.png b/src/assets/images/bg.png
new file mode 100644
index 00000000..de7f0623
Binary files /dev/null and b/src/assets/images/bg.png differ
diff --git a/src/assets/images/favicon.ico b/src/assets/images/favicon.ico
new file mode 100644
index 00000000..76597bea
Binary files /dev/null and b/src/assets/images/favicon.ico differ
diff --git a/src/components/card-wrapper/index.less b/src/components/card-wrapper/index.less
new file mode 100644
index 00000000..a5e2de39
--- /dev/null
+++ b/src/components/card-wrapper/index.less
@@ -0,0 +1,6 @@
+.cardWrapper {
+ border-radius: var(--border-radius-middle);
+ background-color: var(--color-white-1);
+ box-shadow: var(--box-shadow-base);
+ padding: 10px;
+}
diff --git a/src/components/card-wrapper/index.tsx b/src/components/card-wrapper/index.tsx
new file mode 100644
index 00000000..90c076b3
--- /dev/null
+++ b/src/components/card-wrapper/index.tsx
@@ -0,0 +1,12 @@
+import styles from './index.less';
+
+const CardWrapper = (props: any) => {
+ const { children, style } = props;
+ return (
+
+ {children}
+
+ );
+};
+
+export default CardWrapper;
diff --git a/src/components/charts/column-bar.tsx b/src/components/charts/column-bar.tsx
index cee60d98..d9200054 100644
--- a/src/components/charts/column-bar.tsx
+++ b/src/components/charts/column-bar.tsx
@@ -6,34 +6,69 @@ interface BarChartProps {
yField: string;
title?: string;
height?: number;
+ group?: boolean;
+ colorField?: string;
+ seriesField?: string;
+ stack?: boolean;
+ legend?: any;
}
const BarChart: React.FC = (props) => {
- const { data, xField, yField, title, height = 260 } = props;
+ const {
+ data,
+ xField,
+ yField,
+ title,
+ height = 260,
+ group,
+ colorField,
+ seriesField,
+ stack,
+ legend = undefined
+ } = props;
const config = {
data,
xField,
yField,
- // colorField: 'name',
+ colorField: colorField || 'name',
direction: 'vertical',
+ stack,
+ seriesField,
height,
- group: true,
- legend: {
- color: {
- position: 'top',
- layout: {
- justifyContent: 'center'
- }
+ group,
+ scale: {
+ x: {
+ type: 'band',
+ padding: 0.5
}
},
+ legend:
+ legend === 'undefined'
+ ? {
+ color: {
+ position: 'top',
+ layout: {
+ justifyContent: 'center'
+ }
+ }
+ }
+ : legend,
axis: {
x: {
- xAxis: true
+ xAxis: true,
+ tick: false
+ },
+ y: {
+ tick: false,
+ labelAutoWrap: true
}
},
title: {
title,
style: {
- align: 'center'
+ align: 'center',
+ titleFontSize: 14,
+ titleFill: 'rgba(0,0,0,0.88)',
+ titleFontWeight: 500
}
},
split: {
@@ -48,10 +83,16 @@ const BarChart: React.FC = (props) => {
},
style: {
- fill: '#54cc98',
- radiusTopLeft: 8,
- radiusTopRight: 8,
- width: 30
+ fill: (params: any) => {
+ return (
+ params.color ||
+ 'linear-gradient(90deg,rgba(84, 204, 152,0.8) 0%,rgb(0, 168, 143,.7) 100%)'
+ );
+ },
+ radiusTopLeft: 12,
+ radiusTopRight: 12,
+ align: 'center',
+ width: 20
}
};
diff --git a/src/components/charts/gauge.tsx b/src/components/charts/gauge.tsx
index 1b6cca2e..e226e247 100644
--- a/src/components/charts/gauge.tsx
+++ b/src/components/charts/gauge.tsx
@@ -16,6 +16,19 @@ const GaugeChart: React.FC = (props) => {
const config = {
width,
height,
+ box: {
+ padding: [0, 0, 0, 0],
+ style: {
+ padding: [0, 0, 0, 0]
+ }
+ },
+ guide: {
+ arc: {
+ style: {
+ lineWidth: 30
+ }
+ }
+ },
autoFit: true,
data: {
target,
@@ -34,9 +47,11 @@ const GaugeChart: React.FC = (props) => {
title: {
title,
size: 0,
- titleFontSize: 14,
style: {
- align: 'center'
+ align: 'center',
+ titleFontSize: 14,
+ titleFill: 'rgba(0,0,0,0.88)',
+ titleFontWeight: 500
}
},
style: {
diff --git a/src/components/charts/h-bar.tsx b/src/components/charts/h-bar.tsx
index 12edd9fc..4d6c9d15 100644
--- a/src/components/charts/h-bar.tsx
+++ b/src/components/charts/h-bar.tsx
@@ -6,52 +6,89 @@ interface BarChartProps {
yField: string;
title?: string;
height?: number;
+ group?: boolean;
+ colorField?: string;
+ seriesField?: string;
+ stack?: boolean;
+ legend?: any;
}
const BarChart: React.FC = (props) => {
- const { data, xField, yField, title, height = 300 } = props;
+ const {
+ data,
+ xField,
+ yField,
+ title,
+ height,
+ group,
+ colorField,
+ seriesField,
+ stack,
+ legend = undefined
+ } = props;
const config = {
data,
xField,
yField,
- // colorField: 'name',
+ colorField: colorField || 'name',
direction: 'vertical',
+ seriesField,
height,
- group: true,
- legend: {
- color: {
- position: 'top',
- layout: {
- justifyContent: 'center'
- }
+ group,
+ stack,
+ legend:
+ legend === 'undefined'
+ ? {
+ color: {
+ position: 'top',
+ layout: {
+ justifyContent: 'center'
+ }
+ }
+ }
+ : legend,
+ scale: {
+ x: {
+ type: 'band',
+ padding: 0.5
}
},
axis: {
x: {
- xAxis: true
+ xAxis: true,
+ tick: false
+ },
+ y: {
+ tick: false
}
},
title: {
title,
style: {
- align: 'center'
+ align: 'center',
+ titleFontSize: 14,
+ titleFill: 'rgba(0,0,0,0.88)',
+ titleFontWeight: 500
}
},
split: {
type: 'line',
line: {
- color: 'red',
style: {
- color: 'red',
lineDash: [4, 5]
}
}
},
-
+ markBackground: {},
style: {
- fill: '#54cc98',
- radiusTopLeft: 8,
- radiusTopRight: 8,
- height: 30
+ fill: (params: any) => {
+ return (
+ params.color ||
+ 'linear-gradient(90deg,rgba(84, 204, 152,0.8) 0%,rgb(0, 168, 143,.7) 100%)'
+ );
+ },
+ radiusTopLeft: 12,
+ radiusTopRight: 12,
+ height: 20
}
};
diff --git a/src/components/charts/line-chart.tsx b/src/components/charts/line-chart.tsx
index aea2ec27..f93ba481 100644
--- a/src/components/charts/line-chart.tsx
+++ b/src/components/charts/line-chart.tsx
@@ -7,16 +7,18 @@ interface LineChartProps {
color?: string[];
xField?: string;
yField?: string;
- slider?: boolean;
+ labelFormatter?: (v: any) => string;
+ slider?: any;
}
const LineChart: React.FC = (props) => {
- const { data, title, color, xField, yField, slider, height } = props;
+ const { data, title, color, xField, yField, slider, height, labelFormatter } =
+ props;
const config = {
title,
height,
xField: xField || 'time',
yField: yField || 'value',
- color: color || ['red', 'blue', 'green'],
+ // color: color || ['red', 'blue', 'green', 'yellow'],
colorField: 'type',
autoFit: true,
slider,
@@ -26,21 +28,31 @@ const LineChart: React.FC = (props) => {
textStyle: {
autoRoate: true
}
+ },
+ y: {
+ tick: false,
+ // size: 14,
+ // title: '%',
+ titlePosition: 'top',
+ titleFontSize: 12,
+ labelFormatter
}
},
- point: {
- shapeField: 'circle',
- sizeField: 2
- },
+ // point: {
+ // shapeField: 'circle',
+ // sizeField: 2
+ // },
style: {
- lineWidth: 1.5
+ lineWidth: 1.5,
+ opacity: 0.8
},
legend: {
- itemMarker: {
- symbol: 'circle'
- },
color: {
layout: { justifyContent: 'center' }
+ },
+ size: {
+ itemLabelFontSize: 14,
+ itemLabelFontWeight: 500
}
},
tooltip: {
diff --git a/src/components/charts/liquid.tsx b/src/components/charts/liquid.tsx
new file mode 100644
index 00000000..3b7a0513
--- /dev/null
+++ b/src/components/charts/liquid.tsx
@@ -0,0 +1,79 @@
+import { Liquid } from '@ant-design/plots';
+import { useEffect, useState } from 'react';
+
+interface LiquidChartProps {
+ percent: number;
+ color?: string;
+ title?: string;
+ height?: number;
+ width?: number;
+ thresholds?: number[];
+ rangColor?: string[];
+}
+const LiquidChart: React.FC = (props) => {
+ const {
+ percent = 0,
+ color,
+ title,
+ width,
+ height,
+ thresholds = [],
+ rangColor = []
+ } = props;
+
+ const primaryColor = 'rgba(84, 204, 152,0.8)';
+ const [fillColor, setFillColor] = useState(primaryColor);
+
+ const calcColorByPercent = () => {
+ if (color) {
+ return color;
+ }
+ if (!rangColor.length) {
+ return primaryColor;
+ }
+
+ if (rangColor.length && thresholds.length) {
+ let index = 0;
+ for (let i = 0; i < thresholds.length; i++) {
+ if (percent <= thresholds[i]) {
+ index = i;
+ break;
+ }
+ }
+ return rangColor[index];
+ }
+ return primaryColor;
+ };
+
+ useEffect(() => {
+ const fc = calcColorByPercent();
+ setFillColor(fc);
+ }, [percent]);
+
+ const config = {
+ percent,
+ textAlign: 'center',
+ autoFit: true,
+ title: {
+ title,
+ size: 0,
+ style: {
+ align: 'center',
+ titleFontSize: 12,
+ titleFill: 'rgba(0,0,0,0.88)',
+ titleFontWeight: 500
+ }
+ },
+
+ style: {
+ textAlign: 'center',
+ outlineBorder: 2,
+ waveLength: 128,
+ stroke: fillColor,
+ fill: fillColor
+ }
+ };
+ return ;
+};
+
+export default LiquidChart;
diff --git a/src/components/glass-bg/index.less b/src/components/glass-bg/index.less
new file mode 100644
index 00000000..5b338e4a
--- /dev/null
+++ b/src/components/glass-bg/index.less
@@ -0,0 +1,39 @@
+.g-polygon {
+ position: absolute;
+ opacity: 0.5;
+}
+
+.g-polygon-1 {
+ // 定位代码,容器高宽随意
+ background: #fe5;
+ clip-path: polygon(0 10%, 30% 0, 100% 40%, 70% 100%, 20% 90%);
+ width: 50%;
+ height: 50%;
+}
+
+.g-polygon-2 {
+ // 定位代码,容器高宽随意
+ background: #e950d1;
+ clip-path: polygon(10% 0, 100% 70%, 100% 100%, 20% 90%);
+ width: 50%;
+ height: 50%;
+}
+
+.g-polygon-3 {
+ // 定位代码,容器高宽随意
+ background: rgba(87, 80, 233);
+ clip-path: polygon(80% 0, 100% 70%, 100% 100%, 20% 90%);
+ width: 50%;
+ height: 50%;
+}
+
+.g-bg::before {
+ content: '';
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ backdrop-filter: blur(150px);
+ z-index: 1;
+}
diff --git a/src/components/glass-bg/index.tsx b/src/components/glass-bg/index.tsx
new file mode 100644
index 00000000..0dd4374e
--- /dev/null
+++ b/src/components/glass-bg/index.tsx
@@ -0,0 +1,13 @@
+import './index.less';
+
+const GlassBg = () => {
+ return (
+
+ );
+};
+
+export default GlassBg;
diff --git a/src/components/seal-table/styles/index.less b/src/components/seal-table/styles/index.less
index 642814eb..c6c05b5f 100644
--- a/src/components/seal-table/styles/index.less
+++ b/src/components/seal-table/styles/index.less
@@ -2,57 +2,69 @@
display: flex;
flex-direction: column;
width: 100%;
+
.header-row-wrapper {
height: 40px;
margin-bottom: 10px;
display: flex;
justify-content: flex-start;
align-items: center;
+
.header-row-prefix-wrapper {
padding-left: var(--ant-table-cell-padding-inline);
}
+
.row {
flex: 1;
}
}
+
.row-box {
margin-bottom: 20px;
border-radius: var(--ant-table-header-border-radius);
overflow: hidden;
}
+
.expanded-row {
background-color: var(--color-white-1);
- padding: 16px 16px;
+ padding: 16px;
border: 1px solid var(--color-fill-1);
border-top: 0;
border-radius: 0 0 var(--ant-table-header-border-radius)
var(--ant-table-header-border-radius);
}
+
.row-wrapper {
display: flex;
justify-content: flex-start;
align-items: center;
- background-color: var(--color-fill-1);
+ background-color: var(--color-white-1);
transition: all 0.2s ease;
+
&:hover {
background-color: var(--ant-table-row-hover-bg);
transition: all 0.2s ease;
}
+
&-selected {
background-color: var(--ant-table-row-selected-bg);
transition: all 0.2s ease;
+
&:hover {
background-color: var(--ant-table-row-selected-hover-bg);
transition: all 0.2s ease;
}
}
+
.row-prefix-wrapper {
padding-left: var(--ant-table-cell-padding-inline);
}
}
+
.seal-table-row {
flex: 1;
}
+
.spin {
text-align: center;
display: flex;
diff --git a/src/config/breakpoints.ts b/src/config/breakpoints.ts
new file mode 100644
index 00000000..38cf41dc
--- /dev/null
+++ b/src/config/breakpoints.ts
@@ -0,0 +1,8 @@
+export default {
+ xs: 0,
+ sm: 576,
+ md: 768,
+ lg: 992,
+ xl: 1200,
+ xxl: 1600
+};
diff --git a/src/global.less b/src/global.less
index 872239da..b21d96e4 100644
--- a/src/global.less
+++ b/src/global.less
@@ -4,13 +4,14 @@
html {
--ant-color-fill-tertiary: rgba(0, 0, 0, 4%);
--color-fill-1: var(--ant-color-fill-tertiary);
- // --color-fill-1: #f3f6fa;
+ // --color-fill-1: #fff;
--color-fill-2: #fff;
--color-fill-3: #f3f6fa;
- --menu-border-radius-base: 32px;
+ --menu-border-radius-base: 20px;
--border-radius-base: 16px;
+ --border-radius-middle: 20px;
--border-radius-small: 8px;
- --color-white-1: #fff;
+ --color-white-1: rgba(255, 255, 255, 100%);
--font-weight-normal: 500;
--font-weight-bold: 700;
--color-text-1: var(--ant-color-text);
@@ -19,7 +20,7 @@ html {
--font-size-large: 16px;
--font-size-middle: 14px;
--ant-color-fill-secondary: rgba(0, 0, 0, 6%);
- --table-td-radius: 24px;
+ --table-td-radius: 20px;
--checkbox-border-radius: 4px;
--ant-table-cell-padding-inline: 16px;
--ant-table-cell-padding-block: 16px;
@@ -27,7 +28,7 @@ html {
--ant-table-header-split-color: #f0f0f0;
--ant-table-row-selected-bg: #f0fff6;
--ant-table-row-selected-hover-bg: #d8f2e4;
- --ant-table-row-hover-bg: #e6e6e6;
+ --ant-table-row-hover-bg: rgba(230, 230, 230, 70%);
--color-chart-red: #ff7875;
--color-chart-green: #54cc98;
--color-chart-glod: #ffd666;
@@ -36,6 +37,7 @@ html {
--ant-input-active-shadow: 0 0 0 2px rgba(5, 255, 105, 6%);
--ant-input-active-border-color: #2fbf85;
--ant-input-hover-border-color: #54cc98;
+ --box-shadow-base: 0 4px 12px rgb(227, 232, 240);
.css-var-rf {
--ant-font-size: var(--font-size-base);
@@ -49,7 +51,7 @@ html {
&.ant-menu-css-var {
--ant-menu-item-height: 46px;
--ant-menu-item-selected-bg: var(--color-white-1);
- --ant-menu-item-border-radius: 24px;
+ --ant-menu-item-border-radius: 16px;
--ant-menu-item-selected-color: var(--ant-color-primary);
--ant-menu-item-hover-bg: var(--color-white-1);
--ant-menu-item-color: var(--color-text-1);
@@ -67,6 +69,7 @@ html {
--ant-border-radius-lg: 16px;
--ant-color-error: #ff4d4f;
--ant-color-bg-mask: rgba(0, 0, 0, 35%);
+ --ant-color-border: rgb(217 217 217 / 50%);
&.ant-popover {
--ant-popover-inner-padding: 26px;
@@ -95,7 +98,7 @@ html {
.css-var-rh.ant-menu-css-var {
--ant-menu-item-height: 46px;
--ant-menu-item-selected-bg: var(--color-white-1);
- --ant-menu-item-border-radius: 24px;
+ --ant-menu-item-border-radius: 20px;
--ant-menu-item-selected-color: var(--ant-color-primary);
--ant-menu-item-hover-bg: var(--color-white-1);
--ant-menu-item-color: var(--color-text-1);
@@ -161,7 +164,7 @@ body {
}
tr > td {
- background-color: var(--color-fill-1);
+ // background-color: var(--color-fill-1);
border-bottom: none;
height: 70px;
@@ -222,12 +225,43 @@ body {
font-size: 16px;
}
}
+
+ // ============== new theme style start ===============
+ .ant-pro-layout {
+ background-color: var(--color-fill-1);
+ height: 100%;
+
+ .ant-pro-sider .ant-layout-sider-children {
+ background-color: var(--color-white-1);
+ box-shadow: var(--box-shadow-base);
+ }
+ }
+
+ .ant-table-wrapper .ant-table {
+ background-color: unset;
+ }
+
+ .ant-table-content table {
+ .ant-table-thead > tr > th {
+ background-color: unset;
+ }
+
+ .ant-table-tbody {
+ .ant-table-row {
+ border-radius: var(--table-td-radius);
+ background-color: var(--color-white-1);
+ box-shadow: var(--box-shadow-base);
+
+ > td {
+ background-color: unset;
+ }
+ }
+ }
+ }
+
+ // ============== new theme style end =================
}
-// ======== basic layout style start============
-
-// ======== basic layout style end ============
-
// ======== menu style start ============
.ant-pro-sider-collapsed-button {
display: none;
@@ -250,11 +284,19 @@ body {
}
.ant-pro-layout-container {
- background-color: var(--color-fill-2);
+ // background-color: var(--color-fill-2);
}
.ant-pro-sider {
.ant-menu {
+ .ant-menu-item {
+ border-radius: 16px;
+
+ &:active {
+ background-color: var(--ant-menu-item-selected-bg);
+ }
+ }
+
.ant-menu-item:not(.ant-menu-item-selected) {
color: var(--ant-color-text);
}
@@ -266,6 +308,11 @@ body {
.ant-menu-item.ant-menu-item-selected:hover {
color: var(--ant-color-primary);
}
+
+ .ant-menu-item.ant-menu-item-selected {
+ color: var(--ant-color-primary);
+ background-color: unset;
+ }
}
}
}
@@ -275,20 +322,35 @@ body {
.monaco-editor {
border-radius: 16px;
}
-// .background {
-// position: fixed;
-// top: 0;
-// left: 0;
-// bottom: 0;
-// right: 0;
-// background: radial-gradient(
-// circle,
-// rgba(47, 191, 133, 0.02),
-// rgba(55, 125, 184, 0.2)
-// );
-// filter: blur(100px);
-// height: 100%;
-// }
+
+.background {
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ // background: radial-gradient(
+ // circle,
+ // rgba(47, 191, 133, 0.02),
+ // rgba(55, 125, 184, 0.2)
+ // );
+ background: url('./assets/images/bg.png') center center no-repeat;
+ background-size: cover;
+
+ &::after {
+ content: '';
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ right: 0;
+ z-index: 1;
+ backdrop-filter: blur(100px);
+ filter: blur(100px);
+ height: 100%;
+ }
+}
+
.ant-pro-page-container {
background: transparent;
}
@@ -308,7 +370,7 @@ body {
background: linear-gradient(
90deg,
rgba(255, 255, 255, 4%) 25%,
- rgba(0, 0, 0, 10%) 37%,
+ rgba(0, 0, 0, 8%) 37%,
rgba(255, 255, 255, 4%) 63%
);
background-size: 400% 100%;
diff --git a/src/hooks/use-window-resize.ts b/src/hooks/use-window-resize.ts
new file mode 100644
index 00000000..9bcebb98
--- /dev/null
+++ b/src/hooks/use-window-resize.ts
@@ -0,0 +1,60 @@
+import breakpoints from '@/config/breakpoints';
+import { useEffect, useState } from 'react';
+
+export default function useWindowResize() {
+ const [size, setSize] = useState<{ width: number; height: number }>({
+ width: window.innerWidth,
+ height: window.innerHeight
+ });
+ const [isMobile, setIsMobile] = useState(false);
+ const [isTablet, setIsTablet] = useState(false);
+ const [isDesktop, setIsDesktop] = useState(false);
+ const [currentPoint, setCurrentPoint] = useState('');
+
+ const checkBreakpoint = (width: number) => {
+ if (width < breakpoints.sm) {
+ setIsMobile(true);
+ setIsTablet(false);
+ setIsDesktop(false);
+ setCurrentPoint('sm');
+ return;
+ }
+ if (width < breakpoints.md) {
+ setIsMobile(false);
+ setIsTablet(true);
+ setIsDesktop(false);
+ setCurrentPoint('md');
+ return;
+ }
+ if (width < breakpoints.lg) {
+ setIsMobile(false);
+ setIsTablet(false);
+ setIsDesktop(true);
+ setCurrentPoint('lg');
+ return;
+ }
+ setIsMobile(false);
+ setIsTablet(false);
+ setIsDesktop(true);
+ setCurrentPoint('xl');
+ };
+
+ useEffect(() => {
+ const handleResize = () => {
+ setSize({
+ width: window.innerWidth,
+ height: window.innerHeight
+ });
+ };
+ window.addEventListener('resize', handleResize);
+ return () => {
+ window.removeEventListener('resize', handleResize);
+ };
+ }, []);
+
+ useEffect(() => {
+ checkBreakpoint(size.width);
+ }, [size.width]);
+
+ return { size, isMobile, isTablet, isDesktop, currentPoint };
+}
diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx
index 3ed73779..edb88887 100644
--- a/src/layouts/index.tsx
+++ b/src/layouts/index.tsx
@@ -144,7 +144,7 @@ export default (props: any) => {
location={location}
title={userConfig.title}
navTheme="light"
- siderWidth={270}
+ siderWidth={220}
onMenuHeaderClick={(e) => {
e.stopPropagation();
e.preventDefault();
diff --git a/src/pages/dashboard/apis/index.ts b/src/pages/dashboard/apis/index.ts
new file mode 100644
index 00000000..bb2d0661
--- /dev/null
+++ b/src/pages/dashboard/apis/index.ts
@@ -0,0 +1,7 @@
+import { request } from '@umijs/max';
+
+export const DASHBOARD_API = '/dashboard';
+
+export async function queryDashboardData() {
+ return request(DASHBOARD_API);
+}
diff --git a/src/pages/dashboard/components/active-table.tsx b/src/pages/dashboard/components/active-table.tsx
index 6c4b40e6..ea065d84 100644
--- a/src/pages/dashboard/components/active-table.tsx
+++ b/src/pages/dashboard/components/active-table.tsx
@@ -1,6 +1,9 @@
-import ContentWrapper from '@/components/content-wrapper';
import PageTools from '@/components/page-tools';
+import ProgressBar from '@/components/progress-bar';
import { Col, Row, Table } from 'antd';
+import _ from 'lodash';
+import { useContext } from 'react';
+import { DashboardContext } from '../config/dashboard-context';
const modelColumns = [
{
@@ -9,28 +12,30 @@ const modelColumns = [
key: 'name'
},
{
- title: 'Allocated GPUs',
- dataIndex: 'allocated',
- key: 'allocated',
- render: (text: any, record: any) => {record.gpu.allocated}
+ title: 'GPU Utilization',
+ dataIndex: 'gpu_utilization',
+ key: 'gpu_utilization',
+ render: (text: any, record: any) => (
+
+ )
},
{
- title: 'GPU Utilization',
- dataIndex: 'utilization',
- key: 'utilization',
- render: (text: any, record: any) => {record.gpu.utilization}
+ title: 'VRAM Utilization',
+ dataIndex: 'gpu_memory_utilization',
+ key: 'gpu_memory_utilization',
+ render: (text: any, record: any) => (
+
+ )
},
{
title: 'Running Instances',
- dataIndex: 'running',
- key: 'running',
- render: (text: any, record: any) => {record.instances.running}
+ dataIndex: 'instance_count',
+ key: 'instance_count'
},
{
- title: 'Pending Instances',
- dataIndex: 'pending',
- key: 'pending',
- render: (text: any, record: any) => {record.instances.pending}
+ title: 'Tokens',
+ dataIndex: 'token_count',
+ key: 'token_count'
}
];
@@ -59,39 +64,6 @@ const projectColumns = [
}
];
-const modelData = [
- {
- id: 1,
- name: 'qwen2',
- gpu: { allocated: 4, utilization: '50%' },
- instances: { running: 1, pending: 0 }
- },
- {
- id: 2,
- name: 'llama3:70b',
- gpu: { allocated: 3, utilization: '70%' },
- instances: { running: 1, pending: 0 }
- },
- {
- id: 3,
- name: 'llama3',
- gpu: { allocated: 5, utilization: '20%' },
- instances: { running: 1, pending: 0 }
- },
- {
- id: 4,
- name: 'gemma',
- gpu: { allocated: 1, utilization: '25%' },
- instances: { running: 1, pending: 0 }
- },
- {
- id: 5,
- name: 'phi3',
- gpu: { allocated: 2, utilization: '46%' },
- instances: { running: 1, pending: 0 }
- }
-];
-
const projectData = [
{
id: 1,
@@ -130,11 +102,12 @@ const projectData = [
}
];
const ActiveTable = () => {
+ const data = useContext(DashboardContext).active_models || [];
return (
-
-
+
+
{
}
right={false}
/>
-
+
-
-
-
-
- Active Projects
-
- }
- right={false}
- />
-
-
-
+
);
diff --git a/src/pages/dashboard/components/over-view.less b/src/pages/dashboard/components/over-view.less
index 67bdaae2..b0fe020e 100644
--- a/src/pages/dashboard/components/over-view.less
+++ b/src/pages/dashboard/components/over-view.less
@@ -3,6 +3,8 @@
height: 110px;
display: flex;
justify-content: space-around;
+ box-shadow: var(--box-shadow-base);
+ border-radius: var(--ant-border-radius-lg);
}
}
diff --git a/src/pages/dashboard/components/over-view.tsx b/src/pages/dashboard/components/over-view.tsx
index ddd22dec..46cf5de0 100644
--- a/src/pages/dashboard/components/over-view.tsx
+++ b/src/pages/dashboard/components/over-view.tsx
@@ -1,7 +1,8 @@
-import ContentWrapper from '@/components/content-wrapper';
import { Card, Col, Row, Space } from 'antd';
-import React from 'react';
+import _ from 'lodash';
+import React, { useContext } from 'react';
import { overviewConfigs } from '../config';
+import { DashboardContext } from '../config/dashboard-context';
import '../styles/index.less';
import styles from './over-view.less';
@@ -24,23 +25,8 @@ const renderCardItem = (data: {
);
};
-const Overview: React.FC = (props) => {
- // const { data = {} } = props;
- const data = {
- workers: 8,
- models: {
- healthy: 10,
- warning: 2,
- error: 1
- },
- gpus: 30,
- allocatedGpus: 12,
- instances: {
- healthy: 32,
- warning: 3,
- error: 2
- }
- };
+const Overview: React.FC = () => {
+ const data = useContext(DashboardContext).resource_counts || {};
const renderValue = (
value:
@@ -63,19 +49,26 @@ const Overview: React.FC = (props) => {
);
};
return (
-
+
{overviewConfigs.map((config, index) => (
-
+
{renderCardItem({
label: config.label,
- value: renderValue(data[config.key] || 0),
+ value: renderValue(_.get(data, config.key, 0)),
bgColor: config.backgroundColor
})}
))}
-
+
);
};
diff --git a/src/pages/dashboard/components/resource-utilization.tsx b/src/pages/dashboard/components/resource-utilization.tsx
index 3b7c94b2..33cbb2b8 100644
--- a/src/pages/dashboard/components/resource-utilization.tsx
+++ b/src/pages/dashboard/components/resource-utilization.tsx
@@ -1,68 +1,68 @@
import LineChart from '@/components/charts/line-chart';
-import { generateFluctuatingData } from '@/utils';
+import dayjs from 'dayjs';
import _ from 'lodash';
+import { useContext, useEffect, useState } from 'react';
+import { DashboardContext } from '../config/dashboard-context';
-const mockData = {
- GPU: generateFluctuatingData({
- total: 17,
- max: 80,
- min: 20
- }),
- CPU: generateFluctuatingData({
- total: 17,
- max: 70,
- min: 10
- }),
- Memory: generateFluctuatingData({
- total: 17,
- max: 60,
- min: 20
- }),
- VRAM: generateFluctuatingData({
- total: 17,
- max: 90,
- min: 15
- })
+const TypeKeyMap = {
+ cpu: 'CPU',
+ memory: 'Memory',
+ gpu: 'GPU',
+ gpu_memory: 'VRAM'
};
+
const UtilizationOvertime: React.FC = () => {
- const timeList = [
- '08:00:00',
- '09:00:00',
- '10:00:00',
- '11:00:00',
- '12:00:00',
- '13:00:00',
- '14:00:00',
- '15:00:00',
- '16:00:00',
- '17:00:00',
- '18:00:00',
- '19:00:00',
- '20:00:00',
- '21:00:00',
- '22:00:00',
- '23:00:00',
- '24:00:00'
- ];
- const typeList = ['GPU', 'CPU', 'Memory', 'VRAM'];
- const generateData = () => {
- const data = [];
- for (let i = 0; i < timeList.length; i++) {
- for (let j = 0; j < typeList.length; j++) {
- data.push({
- time: timeList[i],
- type: typeList[j],
- value: _.get(mockData, typeList[j])[i]
- });
- }
+ const data = useContext(DashboardContext)?.system_load?.history || {};
+ const [result, setResult] = useState<
+ { time: string; value: number; type: string }[]
+ >([]);
+
+ const typeList = ['gpu', 'cpu', 'memory', 'gpu_memory'];
+ const sliderConfig = {
+ y: false,
+ x: {
+ style: {
+ selectionFill: 'rgb(84, 204, 152)',
+ selectionFillOpacity: 0.1,
+ handleIconFill: 'rgb(84, 204, 152)',
+ handleIconFillOpacity: 0.15,
+ handleIconStrokeOpacity: 0,
+ sparklineType: 'line',
+ sparkline: true
+ },
+ sparkline: true
}
- return data;
};
- const data = generateData();
+
+ const labelFormatter = (value: any) => {
+ return `${value}%`;
+ };
+ const generateData = () => {
+ const list: { value: number; time: string; type: string }[] = [];
+ _.each(typeList, (type: any) => {
+ const dataList = _.map(_.get(data, type, []), (item: any) => {
+ return {
+ value: _.round(item.value, 2) || 0,
+ time: dayjs(item.timestamp * 1000).format('HH:mm:ss'),
+ type: _.get(TypeKeyMap, type, '')
+ };
+ });
+ list.push(...dataList);
+ });
+ setResult(list);
+ };
+
+ useEffect(() => {
+ generateData();
+ }, [data]);
return (
<>
-
+
>
);
};
diff --git a/src/pages/dashboard/components/system-load.tsx b/src/pages/dashboard/components/system-load.tsx
index d93a9481..3a2a541e 100644
--- a/src/pages/dashboard/components/system-load.tsx
+++ b/src/pages/dashboard/components/system-load.tsx
@@ -1,20 +1,43 @@
-import GaugeChart from '@/components/charts/gauge';
+import CardWrapper from '@/components/card-wrapper';
+import LiquidChart from '@/components/charts/liquid';
import PageTools from '@/components/page-tools';
-import { PageContainer } from '@ant-design/pro-components';
+import breakpoints from '@/config/breakpoints';
+import useWindowResize from '@/hooks/use-window-resize';
import { Col, DatePicker, Row } from 'antd';
+import _ from 'lodash';
+import { useContext, useEffect, useState } from 'react';
+import { DashboardContext } from '../config/dashboard-context';
import ResourceUtilization from './resource-utilization';
const SystemLoad = () => {
- const handleSelectDate = (date: string) => {
- console.log('dateString============', date);
- };
+ const colors = [
+ 'linear-gradient(90deg, rgba(84, 204, 152,.8) 0%, rgba(84, 204, 152,0.5) 50%, rgba(84, 204, 152,.8) 100%)',
+ 'linear-gradient(90deg, rgba(255, 214, 102,.8) 0%, rgba(255, 214, 102,0.5) 50%, rgba(255, 214, 102,.8) 100%)',
+ 'linear-gradient(90deg, rgba(255, 120, 117,.8) 0%, rgba(255, 120, 117,0.5) 50%, rgba(255, 120, 117,.8) 100%)'
+ ];
+ const data = useContext(DashboardContext)?.system_load?.current || {};
+ const { size } = useWindowResize();
+ const [paddingRight, setPaddingRight] = useState('20px');
+ const [smallChartHeight, setSmallChartHeight] = useState(190);
+ const [largeChartHeight, setLargeChartHeight] = useState(400);
+ const thresholds = [0.5, 0.7, 1];
+ const height = 400;
+
+ const handleSelectDate = (date: string) => {};
+
+ useEffect(() => {
+ if (size.width < breakpoints.xl) {
+ setPaddingRight('0');
+ } else {
+ setPaddingRight('20px');
+ }
+ }, [size.width]);
return (
-
+
System Load
@@ -24,51 +47,64 @@ const SystemLoad = () => {
}
/>
-
-
-
-
+
+
+
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
);
};
diff --git a/src/pages/dashboard/components/usage.tsx b/src/pages/dashboard/components/usage.tsx
index 7a89476e..77245dd1 100644
--- a/src/pages/dashboard/components/usage.tsx
+++ b/src/pages/dashboard/components/usage.tsx
@@ -1,10 +1,17 @@
+import CardWrapper from '@/components/card-wrapper';
import ColumnBar from '@/components/charts/column-bar';
import HBar from '@/components/charts/h-bar';
-import ContentWrapper from '@/components/content-wrapper';
import PageTools from '@/components/page-tools';
+import breakpoints from '@/config/breakpoints';
+import useWindowResize from '@/hooks/use-window-resize';
import { generateRandomArray } from '@/utils';
import { Col, DatePicker, Row } from 'antd';
+import dayjs from 'dayjs';
+import _ from 'lodash';
+import { useContext, useEffect, useState } from 'react';
+import { DashboardContext } from '../config/dashboard-context';
+const { RangePicker } = DatePicker;
const times = [
'june 1',
'june 2',
@@ -86,64 +93,154 @@ const tokenUsage = TokensData.map((val, i) => {
});
const Usage = () => {
- const handleSelectDate = (dateString: string) => {
- console.log('dateString============', dateString);
+ const { size } = useWindowResize();
+ const [paddingRight, setPaddingRight] = useState('20px');
+ const [requestData, setRequestData] = useState<
+ { time: string; value: number }[]
+ >([]);
+ const [tokenData, setTokenData] = useState<{ time: string; value: number }[]>(
+ []
+ );
+ const [userData, setUserData] = useState<{ name: string; value: number }[]>(
+ []
+ );
+ const data = useContext(DashboardContext)?.model_usage || {};
+
+ const handleSelectDate = (dateString: string) => {};
+
+ const generateData = () => {
+ const requestList: { time: string; value: number }[] = [];
+ const tokenList: {
+ time: string;
+ value: number;
+ name: string;
+ color: string;
+ }[] = [];
+ const userList: {
+ name: string;
+ value: number;
+ type: string;
+ color: string;
+ }[] = [];
+
+ _.each(data.api_request_history, (item: any) => {
+ requestList.push({
+ time: dayjs(item.timestamp * 1000).format('YYYY-MM-DD'),
+ value: item.value
+ });
+ });
+
+ _.each(data.completion_token_history, (item: any) => {
+ tokenList.push({
+ time: dayjs(item.timestamp * 1000).format('YYYY-MM-DD'),
+ name: 'completion_token',
+ color:
+ 'linear-gradient(90deg,rgba(84, 204, 152,0.8) 0%,rgb(0, 168, 143,.7) 100%)',
+ value: item.value
+ });
+ });
+ _.each(data.prompt_token_history, (item: any) => {
+ tokenList.push({
+ time: dayjs(item.timestamp * 1000).format('YYYY-MM-DD'),
+ name: 'prompt_token',
+ color:
+ 'linear-gradient(90deg,rgba(0, 170, 173, 0.8) 0%,rgba(0, 109, 193, 0.7) 100%)',
+ value: item.value
+ });
+ });
+
+ _.each(data.top_users, (item: any) => {
+ userList.push({
+ name: item.username,
+ type: 'completion_token',
+ color:
+ 'linear-gradient(90deg,rgba(84, 204, 152,0.8) 0%,rgb(0, 168, 143,.7) 100%)',
+ value: item.completion_token_count
+ });
+ userList.push({
+ name: item.username,
+ type: 'prompt_token',
+ color:
+ 'linear-gradient(90deg,rgba(0, 170, 173, 0.8) 0%,rgba(0, 109, 193, 0.7) 100%)',
+ value: item.prompt_token_count
+ });
+ });
+
+ setRequestData(requestList);
+ setTokenData(tokenList);
+ setUserData(userList);
};
+
+ useEffect(() => {
+ if (size.width < breakpoints.xl) {
+ setPaddingRight('0');
+ } else {
+ setPaddingRight('20px');
+ }
+ }, [size.width]);
+
+ useEffect(() => {
+ generateData();
+ }, [data]);
+
return (
<>
Usage}
right={
-
+
}
/>
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
+
+
-
-
-
-
-
-
+
>
diff --git a/src/pages/dashboard/config/dashboard-context.ts b/src/pages/dashboard/config/dashboard-context.ts
new file mode 100644
index 00000000..6d18d54e
--- /dev/null
+++ b/src/pages/dashboard/config/dashboard-context.ts
@@ -0,0 +1,8 @@
+import { createContext } from 'react';
+import { DashboardProps } from './types';
+
+export const DashboardContext = createContext(
+ {} as DashboardProps
+);
+
+export default DashboardContext;
diff --git a/src/pages/dashboard/config/index.ts b/src/pages/dashboard/config/index.ts
index b524fc4a..56aec962 100644
--- a/src/pages/dashboard/config/index.ts
+++ b/src/pages/dashboard/config/index.ts
@@ -1,32 +1,32 @@
export const overviewConfigs = [
{
- key: 'workers',
+ key: 'workworker_count',
label: 'Workers',
- backgroundColor:
- 'linear-gradient(180deg, rgb(0 139 188 / 20%) 0%, rgba(40,207,181,.2) 100%)'
+ // backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))'
+ backgroundColor: 'var(--color-white-1)'
},
{
- key: 'gpus',
+ key: 'gpu_count',
label: 'Total GPUs',
- backgroundColor:
- 'linear-gradient(180deg, rgb(0 139 188 / 20%) 0%, rgba(40,207,181,.2) 100%)'
+ backgroundColor: 'var(--color-white-1)'
+ // backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))'
},
{
key: 'allocatedGpus',
label: 'Allocated GPUs',
- backgroundColor:
- 'linear-gradient(180deg, rgb(0 139 188 / 20%) 0%, rgba(40,207,181,.2) 100%)'
+ backgroundColor: 'var(--color-white-1)'
+ // backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))'
},
{
- key: 'models',
+ key: 'model_count',
label: 'Models',
- backgroundColor:
- 'linear-gradient(180deg, rgb(0 139 188 / 20%) 0%, rgba(40,207,181,.2) 100%)'
+ backgroundColor: 'var(--color-white-1)'
+ // backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))'
},
{
- key: 'instances',
+ key: 'model_instance_count',
label: 'Instances',
- backgroundColor:
- 'linear-gradient(180deg, rgb(0 139 188 / 20%) 0%, rgba(40,207,181,.2) 100%)'
+ backgroundColor: 'var(--color-white-1)'
+ // backgroundColor: 'linear-gradient(135deg, #ffffff, rgb(232 249 240 / 60%))'
}
];
diff --git a/src/pages/dashboard/config/types.ts b/src/pages/dashboard/config/types.ts
new file mode 100644
index 00000000..8080b65b
--- /dev/null
+++ b/src/pages/dashboard/config/types.ts
@@ -0,0 +1,62 @@
+export interface DashboardProps {
+ resource_counts: {
+ worker_count: number;
+ gpu_count: number;
+ model_count: number;
+ model_instance_count: number;
+ };
+ system_load: {
+ current: {
+ cpu: {
+ total: number;
+ used: number;
+ utilization_rate: number;
+ };
+ memory: {
+ total: number;
+ used: number;
+ utilization_rate: number;
+ };
+ gpu: {
+ total: number;
+ used: number;
+ utilization_rate: number;
+ };
+ gpu_memory: {
+ total: number;
+ used: number;
+ utilization_rate: number;
+ };
+ };
+ history: {
+ cpu: {
+ timestamp: number;
+ value: number;
+ }[];
+ memory: {
+ timestamp: number;
+ value: number;
+ }[];
+ gpu: {
+ timestamp: number;
+ value: number;
+ }[];
+ gpu_memory: {
+ timestamp: number;
+ value: number;
+ }[];
+ };
+ };
+ model_usage: {
+ api_request_history: any[];
+ completion_token_history: any[];
+ prompt_token_history: any[];
+ top_users: {
+ user_id: number;
+ username: string;
+ prompt_token_count: number;
+ completion_token_count: number;
+ }[];
+ };
+ active_models: any[];
+}
diff --git a/src/pages/dashboard/index.tsx b/src/pages/dashboard/index.tsx
index 6ebc44ce..8edbaf48 100644
--- a/src/pages/dashboard/index.tsx
+++ b/src/pages/dashboard/index.tsx
@@ -1,20 +1,40 @@
-import DividerLine from '@/components/divider-line';
+import { Spin } from 'antd';
+import { useEffect, useState } from 'react';
+import { queryDashboardData } from './apis';
import ActiveTable from './components/active-table';
import Overview from './components/over-view';
import SystemLoad from './components/system-load';
import Usage from './components/usage';
+import DashboardContext from './config/dashboard-context';
+import { DashboardProps } from './config/types';
const Dashboard: React.FC = () => {
+ const [data, setData] = useState({} as DashboardProps);
+ const [loading, setLoading] = useState(false);
+
+ const getDashboardData = async () => {
+ try {
+ setLoading(true);
+ const res = await queryDashboardData();
+ setData(res);
+ setLoading(false);
+ } catch (error) {
+ setLoading(false);
+ setData({} as DashboardProps);
+ }
+ };
+ useEffect(() => {
+ getDashboardData();
+ }, []);
return (
- <>
-
-
-
-
-
-
-
- >
+
+
+
+
+
+
+
+
);
};
diff --git a/src/pages/llmodels/components/add-modal.tsx b/src/pages/llmodels/components/add-modal.tsx
index 75eefcfd..16714687 100644
--- a/src/pages/llmodels/components/add-modal.tsx
+++ b/src/pages/llmodels/components/add-modal.tsx
@@ -26,8 +26,7 @@ type AddModalProps = {
const sourceOptions = [
{ label: 'Huggingface', value: 'huggingface', key: 'huggingface' },
- { label: 'Ollama', value: 'ollama_library', key: 'ollama_library' },
- { label: 'S3', value: 's3', key: 's3' }
+ { label: 'Ollama Library', value: 'ollama_library', key: 'ollama_library' }
];
const AddModal: React.FC = (props) => {
diff --git a/src/pages/llmodels/index.tsx b/src/pages/llmodels/index.tsx
index d7d1fa86..ff0b0f67 100644
--- a/src/pages/llmodels/index.tsx
+++ b/src/pages/llmodels/index.tsx
@@ -114,7 +114,7 @@ const Models: React.FC = () => {
clearInterval(timer.current);
timer.current = setInterval(() => {
fetchData(true);
- }, 3000);
+ }, 5000);
};
const handleShowSizeChange = (page: number, size: number) => {
diff --git a/src/pages/playground/components/chat-footer.tsx b/src/pages/playground/components/chat-footer.tsx
index fa3cf394..d1e02365 100644
--- a/src/pages/playground/components/chat-footer.tsx
+++ b/src/pages/playground/components/chat-footer.tsx
@@ -18,11 +18,20 @@ interface ChatFooterProps {
onView: () => void;
disabled?: boolean;
feedback?: React.ReactNode;
+ hasTokenResult?: boolean;
}
const ChatFooter: React.FC = (props) => {
const intl = useIntl();
- const { onSubmit, onClear, onNewMessage, onView, feedback, disabled } = props;
+ const {
+ onSubmit,
+ onClear,
+ onNewMessage,
+ onView,
+ feedback,
+ disabled,
+ hasTokenResult
+ } = props;
useHotkeys(
HotKeys.SUBMIT.join(','),
() => {
@@ -34,7 +43,7 @@ const ChatFooter: React.FC = (props) => {
return (
-
+
- {feedback}
-
+ {feedback}
+
diff --git a/src/pages/playground/index.tsx b/src/pages/playground/index.tsx
index 52605e12..12daf45d 100644
--- a/src/pages/playground/index.tsx
+++ b/src/pages/playground/index.tsx
@@ -1,3 +1,4 @@
+import CardWrapper from '@/components/card-wrapper';
import { useSearchParams } from '@umijs/max';
import { Divider } from 'antd';
import { useState } from 'react';
@@ -26,20 +27,25 @@ const Playground: React.FC = () => {
};
return (
-
-
-
-
-
-
+
);
};
diff --git a/src/pages/playground/style/ground-left.less b/src/pages/playground/style/ground-left.less
index a9201798..f1a8760d 100644
--- a/src/pages/playground/style/ground-left.less
+++ b/src/pages/playground/style/ground-left.less
@@ -1,11 +1,17 @@
.ground-left {
position: relative;
- height: 100vh;
+ height: calc(100vh - 84px);
padding-bottom: 120px;
+
.message-list-wrap {
max-height: calc(100vh - 152px);
overflow-y: auto;
+
+ .ant-pro-page-container-children-container {
+ padding-inline: 26px;
+ }
}
+
.ground-left-footer {
position: absolute;
bottom: 20px;
diff --git a/src/pages/playground/style/play-ground.less b/src/pages/playground/style/play-ground.less
index 9819f80f..9415c724 100644
--- a/src/pages/playground/style/play-ground.less
+++ b/src/pages/playground/style/play-ground.less
@@ -1,20 +1,24 @@
.play-ground {
display: flex;
align-items: flex-start;
+
.chat {
flex: 1;
display: flex;
flex-direction: column;
}
+
.params {
// width: 465px;
padding: 20px;
}
+
.divider-line {
width: 1px;
+
.ant-divider {
margin: 0;
- min-height: 100vh;
+ min-height: calc(100vh - 84px);
}
}
}
diff --git a/src/pages/profile/index.tsx b/src/pages/profile/index.tsx
index 2b0b50a9..0a2fcc40 100644
--- a/src/pages/profile/index.tsx
+++ b/src/pages/profile/index.tsx
@@ -1,3 +1,4 @@
+import CardWrapper from '@/components/card-wrapper';
import FormButtons from '@/components/form-buttons';
import SealInput from '@/components/seal-form/seal-input';
import { PasswordReg } from '@/config';
@@ -42,14 +43,17 @@ const Profile: React.FC = () => {
}}
extra={[]}
>
-
+
name="username"
rules={[
{
@@ -69,50 +73,53 @@ const Profile: React.FC = () => {
style={{ width: INPUT_WIDTH.default }}
>
*/}
-
- name="current_password"
- rules={[
- {
- required: true,
- message: intl.formatMessage(
- { id: 'common.form.rule.input' },
- {
- name: intl.formatMessage({
- id: 'users.form.currentpassword'
- })
- }
- )
- }
- ]}
- >
-
-
-
- name="new_password"
- rules={[
- {
- required: true,
- pattern: PasswordReg,
- message: intl.formatMessage({ id: 'users.form.rule.password' })
- }
- ]}
- >
-
-
-
-
+
+ name="current_password"
+ rules={[
+ {
+ required: true,
+ message: intl.formatMessage(
+ { id: 'common.form.rule.input' },
+ {
+ name: intl.formatMessage({
+ id: 'users.form.currentpassword'
+ })
+ }
+ )
+ }
+ ]}
+ >
+
+
+
+ name="new_password"
+ rules={[
+ {
+ required: true,
+ pattern: PasswordReg,
+ message: intl.formatMessage({
+ id: 'users.form.rule.password'
+ })
+ }
+ ]}
+ >
+
+
+
+
+
);
diff --git a/src/pages/resources/components/workers.tsx b/src/pages/resources/components/workers.tsx
index cfa09811..2c5e9ea6 100644
--- a/src/pages/resources/components/workers.tsx
+++ b/src/pages/resources/components/workers.tsx
@@ -201,14 +201,7 @@ const Models: React.FC = () => {
);
}}
/>
- {
- return ;
- }}
- />
+
{
);
}}
/>
+ {
+ return ;
+ }}
+ />
>
);
diff --git a/src/utils/index.ts b/src/utils/index.ts
index e805792e..55b69441 100644
--- a/src/utils/index.ts
+++ b/src/utils/index.ts
@@ -1,3 +1,4 @@
+import _ from 'lodash';
export const isNotEmptyValue = (value: any) => {
if (Array.isArray(value)) {
return value.length > 0;