style: ui style

This commit is contained in:
jialin
2024-07-02 15:03:38 +08:00
parent 6989345088
commit 49efbd1a7f
38 changed files with 336 additions and 135 deletions
+20 -19
View File
@@ -1,4 +1,5 @@
import { defineConfig } from '@umijs/max'; import { defineConfig } from '@umijs/max';
import theme from './theme';
const CompressionWebpackPlugin = require('compression-webpack-plugin'); const CompressionWebpackPlugin = require('compression-webpack-plugin');
import proxy from './proxy'; import proxy from './proxy';
@@ -44,6 +45,24 @@ export default defineConfig({
minRatio: 0.8 minRatio: 0.8
} }
]); ]);
config.module
.rule('images')
.test(/\.(png|jpe?g|gif|svg|ico)(\?.*)?$/)
.use('url-loader')
.loader(require.resolve('url-loader'))
.tap((options: any) => {
console.log('iamges==options========', options);
return {
...options,
limit: 8192, // 小于8KB的图片会被转为base64
fallback: {
loader: require.resolve('file-loader'),
options: {
name: 'static/[name].[hash:8].[ext]' // 将所有图片输出到 static 目录
}
}
};
});
} }
} }
: {}), : {}),
@@ -58,25 +77,7 @@ export default defineConfig({
style: 'less', style: 'less',
configProvider: { configProvider: {
componentSize: 'large', componentSize: 'large',
theme: { theme
'root-entry-name': 'variable',
cssVar: true,
hashed: false,
components: {
Input: {
inputFontSize: 12
},
Table: {
cellFontSize: 12
}
},
token: {
colorPrimary: '#2fbf85',
borderRadius: 8,
fontSize: 12,
motion: true
}
}
} }
}, },
hash: true, hash: true,
+25
View File
@@ -0,0 +1,25 @@
export default {
'root-entry-name': 'variable',
cssVar: true,
hashed: false,
components: {
Input: {
inputFontSize: 12
},
Table: {
cellFontSize: 12,
rowSelectedHoverBg: '#e6f6ff'
},
Menu: {
iconSize: 16,
iconMarginInlineEnd: 12,
itemHeight: 44
}
},
token: {
colorPrimary: '#007BFF',
borderRadius: 8,
fontSize: 12,
motion: true
}
};
+1
View File
@@ -27,6 +27,7 @@
"dayjs": "^1.11.11", "dayjs": "^1.11.11",
"has-ansi": "^5.0.1", "has-ansi": "^5.0.1",
"jotai": "^2.8.4", "jotai": "^2.8.4",
"localforage": "^1.10.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"numeral": "^2.0.6", "numeral": "^2.0.6",
"query-string": "^9.0.0", "query-string": "^9.0.0",
+23 -28
View File
@@ -53,6 +53,9 @@ dependencies:
jotai: jotai:
specifier: ^2.8.4 specifier: ^2.8.4
version: 2.8.4(@types/react@18.3.1)(react@18.3.1) version: 2.8.4(@types/react@18.3.1)(react@18.3.1)
localforage:
specifier: ^1.10.0
version: 1.10.0
lodash: lodash:
specifier: ^4.17.21 specifier: ^4.17.21
version: 4.17.21 version: 4.17.21
@@ -4285,7 +4288,7 @@ packages:
dependencies: dependencies:
'@babel/core': 7.24.5 '@babel/core': 7.24.5
postcss: 7.0.39 postcss: 7.0.39
postcss-syntax: 0.36.2(postcss@7.0.39) postcss-syntax: 0.36.2(postcss@8.4.38)
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
dev: false dev: false
@@ -4312,7 +4315,7 @@ packages:
postcss-syntax: '>=0.36.2' postcss-syntax: '>=0.36.2'
dependencies: dependencies:
postcss: 7.0.39 postcss: 7.0.39
postcss-syntax: 0.36.2(postcss@7.0.39) postcss-syntax: 0.36.2(postcss@8.4.38)
remark: 13.0.0 remark: 13.0.0
unist-util-find-all-after: 3.0.2 unist-util-find-all-after: 3.0.2
transitivePeerDependencies: transitivePeerDependencies:
@@ -10176,6 +10179,10 @@ packages:
requiresBuild: true requiresBuild: true
optional: true optional: true
/immediate@3.0.6:
resolution: {integrity: sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==, tarball: https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz}
dev: false
/immer@8.0.4: /immer@8.0.4:
resolution: {integrity: sha512-jMfL18P+/6P6epANRvRk6q8t+3gGhqsJ9EuJ25AXE+9bNTYtssvzeYbEd0mXRYWCmmXSIbnlpz6vd6iJlmGGGQ==} resolution: {integrity: sha512-jMfL18P+/6P6epANRvRk6q8t+3gGhqsJ9EuJ25AXE+9bNTYtssvzeYbEd0mXRYWCmmXSIbnlpz6vd6iJlmGGGQ==}
dev: false dev: false
@@ -10999,6 +11006,12 @@ packages:
prelude-ls: 1.2.1 prelude-ls: 1.2.1
type-check: 0.4.0 type-check: 0.4.0
/lie@3.1.1:
resolution: {integrity: sha512-RiNhHysUjhrDQntfYSfY4MU24coXXdEOgw9WGcKHNeEwffDYbF//u87M1EWaMGzuFoSbqW0C9C6lEEhDOAswfw==, tarball: https://registry.npmjs.org/lie/-/lie-3.1.1.tgz}
dependencies:
immediate: 3.0.6
dev: false
/lightningcss-darwin-arm64@1.22.1: /lightningcss-darwin-arm64@1.22.1:
resolution: {integrity: sha512-ldvElu+R0QimNTjsKpaZkUv3zf+uefzLy/R1R19jtgOfSRM+zjUCUgDhfEDRmVqJtMwYsdhMI2aJtJChPC6Osg==, tarball: https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.22.1.tgz} resolution: {integrity: sha512-ldvElu+R0QimNTjsKpaZkUv3zf+uefzLy/R1R19jtgOfSRM+zjUCUgDhfEDRmVqJtMwYsdhMI2aJtJChPC6Osg==, tarball: https://registry.npmjs.org/lightningcss-darwin-arm64/-/lightningcss-darwin-arm64-1.22.1.tgz}
engines: {node: '>= 12.0.0'} engines: {node: '>= 12.0.0'}
@@ -11158,6 +11171,12 @@ packages:
engines: {node: '>=14'} engines: {node: '>=14'}
dev: false dev: false
/localforage@1.10.0:
resolution: {integrity: sha512-14/H1aX7hzBBmmh7sGPd+AOMkkIrHM3Z1PAyGgZigA1H1p5O5ANnMyWzvpAETtG68/dC4pC0ncy3+PPGzXZHPg==, tarball: https://registry.npmjs.org/localforage/-/localforage-1.10.0.tgz}
dependencies:
lie: 3.1.1
dev: false
/locate-path@5.0.0: /locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
engines: {node: '>=8'} engines: {node: '>=8'}
@@ -12460,7 +12479,7 @@ packages:
dependencies: dependencies:
htmlparser2: 3.10.1 htmlparser2: 3.10.1
postcss: 7.0.39 postcss: 7.0.39
postcss-syntax: 0.36.2(postcss@7.0.39) postcss-syntax: 0.36.2(postcss@8.4.38)
dev: false dev: false
/postcss-image-set-function@4.0.7(postcss@8.4.38): /postcss-image-set-function@4.0.7(postcss@8.4.38):
@@ -12750,30 +12769,6 @@ packages:
lodash: 4.17.21 lodash: 4.17.21
postcss: 8.4.38 postcss: 8.4.38
/postcss-syntax@0.36.2(postcss@7.0.39):
resolution: {integrity: sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==}
peerDependencies:
postcss: '>=5.0.0'
postcss-html: '*'
postcss-jsx: '*'
postcss-less: '*'
postcss-markdown: '*'
postcss-scss: '*'
peerDependenciesMeta:
postcss-html:
optional: true
postcss-jsx:
optional: true
postcss-less:
optional: true
postcss-markdown:
optional: true
postcss-scss:
optional: true
dependencies:
postcss: 7.0.39
dev: false
/postcss-syntax@0.36.2(postcss@8.4.38): /postcss-syntax@0.36.2(postcss@8.4.38):
resolution: {integrity: sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==} resolution: {integrity: sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==}
peerDependencies: peerDependencies:
@@ -15900,7 +15895,7 @@ packages:
postcss-sass: 0.4.4 postcss-sass: 0.4.4
postcss-scss: 2.1.1 postcss-scss: 2.1.1
postcss-selector-parser: 6.0.16 postcss-selector-parser: 6.0.16
postcss-syntax: 0.36.2(postcss@7.0.39) postcss-syntax: 0.36.2(postcss@8.4.38)
postcss-value-parser: 4.2.0 postcss-value-parser: 4.2.0
resolve-from: 5.0.0 resolve-from: 5.0.0
slash: 3.0.0 slash: 3.0.0
Binary file not shown.

After

Width:  |  Height:  |  Size: 44 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 896 KiB

+1 -1
View File
@@ -7,7 +7,7 @@
background-color: var(--color-fill-1); background-color: var(--color-fill-1);
border-inline: none; border-inline: none;
border-radius: 0; border-radius: 0;
padding-inline: 16px; // padding-inline: 16px;
padding-block-end: 12px; padding-block-end: 12px;
} }
+3 -1
View File
@@ -1,6 +1,8 @@
.cardWrapper { .cardWrapper {
border-radius: var(--border-radius-small); border-radius: var(--border-radius-small);
background-color: var(--color-white-1); background-color: var(--color-white-1);
box-shadow: var(--box-shadow-base); // box-shadow: var(--box-shadow-base);
box-shadow: none;
padding: 10px; padding: 10px;
border: 1px solid var(--ant-color-border);
} }
+3 -3
View File
@@ -35,15 +35,15 @@ const LineChart: React.FC<LineChartProps> = (props) => {
x: { x: {
textStyle: { textStyle: {
autoRoate: true autoRoate: true
} },
labelFormatter
}, },
y: { y: {
tick: false, tick: false,
// size: 14, // size: 14,
// title: '%', // title: '%',
titlePosition: 'top', titlePosition: 'top',
titleFontSize: 12, titleFontSize: 12
labelFormatter
} }
}, },
style: { style: {
+6 -6
View File
@@ -13,6 +13,7 @@ interface BarChartProps {
seriesField?: string; seriesField?: string;
stack?: boolean; stack?: boolean;
legend?: any; legend?: any;
labelFormatter?: (v: any) => string;
} }
const BarChart: React.FC<BarChartProps> = (props) => { const BarChart: React.FC<BarChartProps> = (props) => {
const { const {
@@ -25,7 +26,8 @@ const BarChart: React.FC<BarChartProps> = (props) => {
colorField, colorField,
seriesField, seriesField,
stack, stack,
legend = undefined legend = undefined,
labelFormatter
} = props; } = props;
const config = { const config = {
data, data,
@@ -57,7 +59,8 @@ const BarChart: React.FC<BarChartProps> = (props) => {
axis: { axis: {
x: { x: {
xAxis: true, xAxis: true,
tick: false tick: false,
labelFormatter
}, },
y: { y: {
tick: false, tick: false,
@@ -86,10 +89,7 @@ const BarChart: React.FC<BarChartProps> = (props) => {
style: { style: {
fill: (params: any) => { fill: (params: any) => {
return ( return params.color || 'rgba(84, 204, 152,0.8)';
params.color ||
'linear-gradient(90deg,rgba(84, 204, 152,0.8) 0%,rgb(0, 168, 143,.7) 100%)'
);
}, },
// radiusTopLeft: 12, // radiusTopLeft: 12,
// radiusTopRight: 12, // radiusTopRight: 12,
+9 -5
View File
@@ -1,21 +1,25 @@
.editor-wrap { .editor-wrap {
border-radius: 16px; border-radius: 8px;
overflow: hidden; overflow: hidden;
.editor-header { .editor-header {
display: flex; display: flex;
padding: 6px 10px; padding: 6px 10px;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
background-color: rgb(56, 56, 56); background-color: rgb(56, 56, 56);
.ant-select-selector { .ant-select-selector {
background-color: rgba(255, 255, 255, 0.09) !important; background-color: rgba(255, 255, 255, 9%) !important;
color: rgba(255, 255, 255, 0.7); color: rgba(255, 255, 255, 70%);
.ant-select-selection-item { .ant-select-selection-item {
color: rgba(255, 255, 255, 0.7); color: rgba(255, 255, 255, 70%);
} }
} }
.ant-select-arrow { .ant-select-arrow {
color: rgba(255, 255, 255, 0.7); color: rgba(255, 255, 255, 70%);
} }
} }
// set scrollbar style // set scrollbar style
+4 -2
View File
@@ -1,3 +1,4 @@
import { useIntl } from '@umijs/max';
import { Button, Space } from 'antd'; import { Button, Space } from 'antd';
type ModalFooterProps = { type ModalFooterProps = {
@@ -18,10 +19,11 @@ const ModalFooter: React.FC<ModalFooterProps> = ({
htmlType = 'button', htmlType = 'button',
form form
}) => { }) => {
const intl = useIntl();
return ( return (
<Space size={20}> <Space size={20}>
<Button onClick={onCancel} style={{ width: '88px' }} loading={loading}> <Button onClick={onCancel} style={{ width: '88px' }} loading={loading}>
{cancelText || '取消'} {cancelText || intl.formatMessage({ id: 'common.button.cancel' })}
</Button> </Button>
<Button <Button
type="primary" type="primary"
@@ -30,7 +32,7 @@ const ModalFooter: React.FC<ModalFooterProps> = ({
loading={loading} loading={loading}
htmlType={htmlType} htmlType={htmlType}
> >
{okText || '保存'} {okText || intl.formatMessage({ id: 'common.button.save' })}
</Button> </Button>
</Space> </Space>
); );
+1 -1
View File
@@ -14,7 +14,7 @@ const PageTools: React.FC<PageToolsProps> = (props) => {
left, left,
right, right,
marginBottom = 0, marginBottom = 0,
marginTop = 70, marginTop = 60,
style: pageStyle style: pageStyle
} = props; } = props;
+4 -4
View File
@@ -29,12 +29,12 @@ const RenderProgress = memo(
<Tooltip title={label}> <Tooltip title={label}>
<Progress <Progress
percentPosition={{ align: 'center', type: 'inner' }} percentPosition={{ align: 'center', type: 'inner' }}
size={[undefined, 12]} size={[undefined, 16]}
format={() => { format={() => {
return ( return (
<span <span
style={{ style={{
color: 'var(--ant-color-text)' color: '#fff'
}} }}
> >
{percent}% {percent}%
@@ -49,12 +49,12 @@ const RenderProgress = memo(
<Progress <Progress
type="line" type="line"
percentPosition={{ align: 'center', type: 'inner' }} percentPosition={{ align: 'center', type: 'inner' }}
size={[undefined, 12]} size={[undefined, 16]}
format={() => { format={() => {
return ( return (
<span <span
style={{ style={{
color: 'var(--ant-color-text)' color: '#fff'
}} }}
> >
{percent}% {percent}%
@@ -3,11 +3,12 @@
@inputheight: 32px; @inputheight: 32px;
@borderRadius: 8px; @borderRadius: 8px;
@input-inner-padding: 12px; @input-inner-padding: 12px;
@bgColor: transparent;
position: relative; position: relative;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
align-items: center; align-items: flex-start;
height: 54px; height: 54px;
border-width: var(--ant-line-width); border-width: var(--ant-line-width);
border-style: var(--ant-line-type); border-style: var(--ant-line-type);
@@ -15,6 +16,7 @@
border-radius: @borderRadius; border-radius: @borderRadius;
padding-inline: 12px; padding-inline: 12px;
padding-block: 20px 0; padding-block: 20px 0;
background-color: var(--color-white-1);
&.filled { &.filled {
border: none; border: none;
@@ -105,6 +107,7 @@
} }
// ==================== select ================== // ==================== select ==================
:global(.ant-select) { :global(.ant-select) {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -118,6 +121,7 @@
padding-block: 5px; padding-block: 5px;
padding-inline: @input-inner-padding !important; padding-inline: @input-inner-padding !important;
box-shadow: none !important; box-shadow: none !important;
background-color: @bgColor !important;
} }
:global(.ant-select-selection-item) { :global(.ant-select-selection-item) {
@@ -127,6 +131,10 @@
padding-inline-end: 0 !important; padding-inline-end: 0 !important;
} }
:global(.ant-select-auto-complete) :global(.ant-select-selector) {
padding-inline: 0 !important;
}
:global(.ant-select-arrow) { :global(.ant-select-arrow) {
top: 10px; top: 10px;
} }
@@ -144,6 +152,7 @@
// ==================== input ==================== // ==================== input ====================
:global(.ant-input), :global(.ant-input),
:global(.ant-input-password) { :global(.ant-input-password) {
width: 100%;
display: flex; display: flex;
align-items: center; align-items: center;
border: none; border: none;
@@ -151,6 +160,11 @@
padding-block: 5px; padding-block: 5px;
padding-inline: 12px; padding-inline: 12px;
height: @inputheight !important; height: @inputheight !important;
background-color: @bgColor;
}
:global(.ant-input.seal-textarea) {
width: 100%;
} }
:global(.ant-input-number) { :global(.ant-input-number) {
@@ -160,6 +174,7 @@
box-shadow: none; box-shadow: none;
padding: 0; padding: 0;
height: @inputheight !important; height: @inputheight !important;
background-color: @bgColor;
} }
:global(.ant-input-outlined) { :global(.ant-input-outlined) {
@@ -170,6 +185,7 @@
padding-block: 5px; padding-block: 5px;
padding-inline: @input-inner-padding; padding-inline: @input-inner-padding;
height: @inputheight !important; height: @inputheight !important;
background-color: transparent;
&.seal-textarea { &.seal-textarea {
min-height: 100px !important; min-height: 100px !important;
@@ -213,7 +229,7 @@
:global(.ant-input-search-button) { :global(.ant-input-search-button) {
position: absolute; position: absolute;
top: -20px; top: -20px;
right: -11px; right: 0;
border-radius: 0 @borderRadius @borderRadius 0 !important; border-radius: 0 @borderRadius @borderRadius 0 !important;
overflow: hidden; overflow: hidden;
border: none; border: none;
+1
View File
@@ -68,6 +68,7 @@ const SealPassword: React.FC<InputProps & SealFormItemProps> = (props) => {
{...rest} {...rest}
ref={inputRef} ref={inputRef}
autoComplete="off" autoComplete="off"
className="seal-input-password"
onFocus={handleOnFocus} onFocus={handleOnFocus}
onBlur={handleOnBlur} onBlur={handleOnBlur}
onChange={handleChange} onChange={handleChange}
+4 -1
View File
@@ -4,13 +4,16 @@
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: flex-start; justify-content: flex-start;
height: 70px; height: 68px;
&-left { &-left {
justify-content: flex-start; justify-content: flex-start;
} }
&-right { &-right {
justify-content: flex-end; justify-content: flex-end;
} }
&-center { &-center {
justify-content: center; justify-content: center;
} }
+2 -2
View File
@@ -23,7 +23,7 @@
margin-bottom: 20px; margin-bottom: 20px;
border-radius: var(--ant-table-header-border-radius); border-radius: var(--ant-table-header-border-radius);
overflow: hidden; overflow: hidden;
box-shadow: var(--box-shadow-base); // box-shadow: var(--box-shadow-base);
} }
.expanded-row { .expanded-row {
@@ -39,7 +39,7 @@
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
align-items: center; align-items: center;
background-color: var(--color-white-1); background-color: var(--color-fill-sider);
transition: all 0.2s ease; transition: all 0.2s ease;
&:hover { &:hover {
+1 -1
View File
@@ -1,5 +1,5 @@
.transition-wrapper { .transition-wrapper {
border-radius: 16px; border-radius: 8px;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
overflow: hidden; overflow: hidden;
+3 -3
View File
@@ -25,12 +25,12 @@ const UitilBar: React.FC<UitilBarProps> = (props) => {
const strokeColorFunc = (percent: number) => { const strokeColorFunc = (percent: number) => {
if (percent <= 50) { if (percent <= 50) {
return 'var(--ant-color-primary)'; return 'var(--color-chart-green)';
} }
if (percent <= 80) { if (percent <= 80) {
return 'var(--ant-color-warning)'; return 'var(--color-chart-glod)';
} }
return 'var(--ant-color-error)'; return 'var(--color-chart-red)';
}; };
return ( return (
<div className="util-bar-box"> <div className="util-bar-box">
+1 -1
View File
@@ -1,5 +1,5 @@
export default { export default {
CREATE: ['ctrl+n', 'meta+n'], CREATE: ['ctrl+shift+n', 'meta+shift+n'],
SAVE: ['ctrl+s', 'meta+s'], SAVE: ['ctrl+s', 'meta+s'],
SUBMIT: ['ctrl+enter', 'meta+enter'], SUBMIT: ['ctrl+enter', 'meta+enter'],
SAVEAS: ['ctrl+shift+s', 'meta+shift+s'], SAVEAS: ['ctrl+shift+s', 'meta+shift+s'],
+39 -19
View File
@@ -5,6 +5,7 @@ html {
--ant-color-fill-tertiary: rgba(0, 0, 0, 4%); --ant-color-fill-tertiary: rgba(0, 0, 0, 4%);
--color-fill-1: var(--ant-color-fill-tertiary); --color-fill-1: var(--ant-color-fill-tertiary);
// --color-fill-1: #fff; // --color-fill-1: #fff;
--ant-color-text: #000;
--color-fill-2: #fff; --color-fill-2: #fff;
--color-fill-3: #f3f6fa; --color-fill-3: #f3f6fa;
--color-logs-bg: #1e1e1e; --color-logs-bg: #1e1e1e;
@@ -16,11 +17,12 @@ html {
--border-radius-middle: 20px; --border-radius-middle: 20px;
--border-radius-small: 8px; --border-radius-small: 8px;
--color-white-1: rgba(255, 255, 255, 100%); --color-white-1: rgba(255, 255, 255, 100%);
--color-fill-sider: #f4f5f4;
--font-weight-normal: 500; --font-weight-normal: 500;
--font-weight-medium: 600; --font-weight-medium: 600;
--font-weight-bold: 700; --font-weight-bold: 700;
--color-text-1: var(--ant-color-text); --color-text-1: var(--ant-color-text);
--color-bg-light-1: #f0fff6; --color-bg-light-1: #e6f6ff;
--font-size-base: 12px; --font-size-base: 12px;
--font-size-large: 16px; --font-size-large: 16px;
--font-size-middle: 14px; --font-size-middle: 14px;
@@ -31,18 +33,19 @@ html {
--ant-table-cell-padding-block: 8px; --ant-table-cell-padding-block: 8px;
--ant-table-header-border-radius: 8px; --ant-table-header-border-radius: 8px;
--ant-table-header-split-color: #f0f0f0; --ant-table-header-split-color: #f0f0f0;
--ant-table-row-selected-bg: #f0fff6; --ant-table-row-selected-bg: #e6f6ff;
--ant-table-row-selected-hover-bg: #d8f2e4; --ant-table-row-selected-hover-bg: #e6f6ff;
--ant-table-row-hover-bg: rgba(230, 230, 230, 70%); --ant-table-row-hover-bg: rgba(230, 230, 230, 88%);
--color-chart-red: #ff7875; --color-chart-red: rgba(255, 77, 79, 80%);
--color-chart-green: #54cc98; --color-chart-green: rgb(84, 204, 152, 80%);
--color-chart-glod: #ffd666; --color-chart-glod: rgba(250, 173, 20, 80%);
--seal-transition-func: cubic-bezier(0, 0, 1, 1); --seal-transition-func: cubic-bezier(0, 0, 1, 1);
// ======== input ============ // ======== input ============
--ant-input-active-shadow: 0 0 0 2px rgba(5, 255, 105, 6%); --ant-input-active-shadow: 0 0 0 2px rgba(5, 255, 105, 6%);
--ant-input-active-border-color: #2fbf85; --ant-input-active-border-color: #007bff;
--ant-input-hover-border-color: #54cc98; --ant-input-hover-border-color: #2997ff;
--box-shadow-base: 0 4px 12px rgba(227, 232, 240, 70%); --box-shadow-base: 0 4px 6px rgba(227, 232, 240, 70%);
// --box-shadow-base: none;
.css-var-rf { .css-var-rf {
--ant-font-size: var(--font-size-base); --ant-font-size: var(--font-size-base);
@@ -54,7 +57,6 @@ html {
--ant-font-size: var(--font-size-base); --ant-font-size: var(--font-size-base);
&.ant-menu-css-var { &.ant-menu-css-var {
--ant-menu-item-height: 46px;
--ant-menu-item-selected-bg: var(--color-white-1); --ant-menu-item-selected-bg: var(--color-white-1);
--ant-menu-item-border-radius: 8px; --ant-menu-item-border-radius: 8px;
--ant-menu-item-selected-color: var(--ant-color-primary); --ant-menu-item-selected-color: var(--ant-color-primary);
@@ -72,6 +74,7 @@ html {
--ant-font-size: var(--font-size-base); --ant-font-size: var(--font-size-base);
--ant-padding-sm: 14px; --ant-padding-sm: 14px;
--ant-border-radius-lg: 8px; --ant-border-radius-lg: 8px;
--ant-color-text: #000;
--ant-color-error: #ff4d4f; --ant-color-error: #ff4d4f;
--ant-color-bg-mask: rgba(0, 0, 0, 35%); --ant-color-bg-mask: rgba(0, 0, 0, 35%);
--ant-color-border: rgb(217 217 217 / 50%); --ant-color-border: rgb(217 217 217 / 50%);
@@ -171,7 +174,7 @@ body {
tr > td { tr > td {
// background-color: var(--color-fill-1); // background-color: var(--color-fill-1);
border-bottom: none; border-bottom: none;
height: 70px; height: 68px;
&:first-child { &:first-child {
border-top-left-radius: var(--table-td-radius); border-top-left-radius: var(--table-td-radius);
@@ -237,8 +240,9 @@ body {
height: 100%; height: 100%;
.ant-pro-sider .ant-layout-sider-children { .ant-pro-sider .ant-layout-sider-children {
background-color: var(--color-white-1); background-color: var(--color-fill-sider);
box-shadow: var(--box-shadow-base); // box-shadow: var(--box-shadow-base);
border-right: 1px solid var(--ant-color-border);
} }
} }
@@ -254,8 +258,9 @@ body {
.ant-table-tbody { .ant-table-tbody {
.ant-table-row { .ant-table-row {
border-radius: var(--table-td-radius); border-radius: var(--table-td-radius);
background-color: var(--color-white-1); // background-color: var(--color-white-1);
box-shadow: var(--box-shadow-base); background-color: var(--color-fill-sider);
// box-shadow: var(--box-shadow-base);
> td { > td {
background-color: unset; background-color: unset;
@@ -297,10 +302,15 @@ body {
} }
.ant-pro-layout-container { .ant-pro-layout-container {
min-height: 100vh;
// background-color: var(--color-fill-2); // background-color: var(--color-fill-2);
} }
.ant-pro-sider { .ant-pro-sider {
.ant-pro-base-menu-inline-item-title {
gap: 12px;
}
.ant-menu { .ant-menu {
.ant-menu-item { .ant-menu-item {
border-radius: var(--border-radius-small); border-radius: var(--border-radius-small);
@@ -325,7 +335,7 @@ body {
.ant-menu-item.ant-menu-item-selected { .ant-menu-item.ant-menu-item-selected {
color: var(--ant-color-primary); color: var(--ant-color-primary);
background-color: unset; background-color: var(--ant-menu-item-selected-bg);
} }
} }
} }
@@ -343,8 +353,9 @@ body {
left: 0; left: 0;
bottom: 0; bottom: 0;
right: 0; right: 0;
background: url('./assets/images/bg-11.png') center center no-repeat; // background: url('@/assets/images/bg-11.png') center center no-repeat;
background-size: cover; // background-size: cover;
background-color: #fff;
&::after { &::after {
content: ''; content: '';
@@ -357,6 +368,15 @@ body {
height: 100%; height: 100%;
} }
} }
// .login-wrapper {
// position: fixed;
// top: 0;
// left: 0;
// bottom: 0;
// right: 0;
// background: url('@/assets/images/bg-2.png') center center no-repeat;
// background-size: cover;
// }
.ant-pro-page-container { .ant-pro-page-container {
background: transparent; background: transparent;
@@ -105,7 +105,7 @@ const ActiveTable = () => {
<Row gutter={[20, 0]}> <Row gutter={[20, 0]}>
<Col xs={24} sm={24} md={24} lg={24} xl={24}> <Col xs={24} sm={24} md={24} lg={24} xl={24}>
<PageTools <PageTools
style={{ margin: '32px 8px' }} style={{ margin: '26px 0px' }}
left={ left={
<span <span
style={{ fontSize: 'var(--font-size-large)', padding: '9px 0' }} style={{ fontSize: 'var(--font-size-large)', padding: '9px 0' }}
@@ -3,8 +3,9 @@
height: 110px; height: 110px;
display: flex; display: flex;
justify-content: space-around; justify-content: space-around;
box-shadow: var(--box-shadow-base); // box-shadow: var(--box-shadow-base);
border-radius: var(--ant-border-radius-lg); border-radius: var(--ant-border-radius-lg);
// border: 1px solid var(--ant-color-border);
} }
} }
+1 -1
View File
@@ -15,7 +15,7 @@ const renderCardItem = (data: {
const { label, value, bgColor } = data; const { label, value, bgColor } = data;
return ( return (
<Card <Card
bordered={false} bordered={true}
style={{ background: bgColor }} style={{ background: bgColor }}
className={styles['card-body']} className={styles['card-body']}
> >
@@ -11,11 +11,6 @@ import { DashboardContext } from '../config/dashboard-context';
import ResourceUtilization from './resource-utilization'; import ResourceUtilization from './resource-utilization';
const SystemLoad = () => { const SystemLoad = () => {
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 intl = useIntl(); const intl = useIntl();
const data = useContext(DashboardContext)?.system_load?.current || {}; const data = useContext(DashboardContext)?.system_load?.current || {};
const { size } = useWindowResize(); const { size } = useWindowResize();
@@ -39,7 +34,7 @@ const SystemLoad = () => {
<div> <div>
<div className="system-load"> <div className="system-load">
<PageTools <PageTools
style={{ margin: '32px 8px' }} style={{ margin: '26px 0px' }}
left={ left={
<span style={{ fontSize: 'var(--font-size-large)' }}> <span style={{ fontSize: 'var(--font-size-large)' }}>
{intl.formatMessage({ id: 'dashboard.systemload' })} {intl.formatMessage({ id: 'dashboard.systemload' })}
+7 -1
View File
@@ -225,6 +225,10 @@ const Usage = () => {
setUserData(userList); setUserData(userList);
}; };
const labelFormatter = (v: any) => {
return dayjs(v).format('MM-DD');
};
useEffect(() => { useEffect(() => {
if (size.width < breakpoints.xl) { if (size.width < breakpoints.xl) {
setPaddingRight('0'); setPaddingRight('0');
@@ -240,7 +244,7 @@ const Usage = () => {
return ( return (
<> <>
<PageTools <PageTools
style={{ margin: '32px 8px' }} style={{ margin: '26px 0px' }}
left={ left={
<span style={{ fontSize: 'var(--font-size-large)' }}> <span style={{ fontSize: 'var(--font-size-large)' }}>
{intl.formatMessage({ id: 'dashboard.usage' })} {intl.formatMessage({ id: 'dashboard.usage' })}
@@ -272,6 +276,7 @@ const Usage = () => {
xField="time" xField="time"
yField="value" yField="value"
height={360} height={360}
labelFormatter={labelFormatter}
></AreaChart> ></AreaChart>
</Col> </Col>
<Col span={12}> <Col span={12}>
@@ -285,6 +290,7 @@ const Usage = () => {
legend={false} legend={false}
yField="value" yField="value"
height={360} height={360}
labelFormatter={labelFormatter}
></ColumnBar> ></ColumnBar>
</Col> </Col>
</Row> </Row>
+57 -13
View File
@@ -1,13 +1,23 @@
import LogoIcon from '@/assets/images/logo.png'; import LogoIcon from '@/assets/images/logo.png';
import { initialPasswordAtom, userAtom } from '@/atoms/user'; import { initialPasswordAtom, userAtom } from '@/atoms/user';
import SealInput from '@/components/seal-form/seal-input'; import SealInput from '@/components/seal-form/seal-input';
import {
getRememberMe,
rememberMe,
removeRememberMe
} from '@/utils/localstore/index';
import { GlobalOutlined, LockOutlined, UserOutlined } from '@ant-design/icons'; import { GlobalOutlined, LockOutlined, UserOutlined } from '@ant-design/icons';
import { SelectLang, history, useIntl, useModel } from '@umijs/max'; import { SelectLang, history, useIntl, useModel } from '@umijs/max';
import { Button, Checkbox, Form } from 'antd'; import { Button, Checkbox, Form } from 'antd';
import CryptoJS from 'crypto-js';
import { useAtom } from 'jotai'; import { useAtom } from 'jotai';
import { useEffect } from 'react';
import { flushSync } from 'react-dom'; import { flushSync } from 'react-dom';
import { login } from '../apis'; import { login } from '../apis';
const REMEMBER_ME_KEY = 'r_m';
const CRYPT_TEXT = 'seal';
const renderLogo = () => { const renderLogo = () => {
return ( return (
<div <div
@@ -28,7 +38,6 @@ const LoginForm = () => {
const [userInfo, setUserInfo] = useAtom(userAtom); const [userInfo, setUserInfo] = useAtom(userAtom);
const [initialPassword, setInitialPassword] = useAtom(initialPasswordAtom); const [initialPassword, setInitialPassword] = useAtom(initialPasswordAtom);
const { initialState, setInitialState } = useModel('@@initialState'); const { initialState, setInitialState } = useModel('@@initialState');
const { globalState, setGlobalState } = useModel('global');
const intl = useIntl(); const intl = useIntl();
const [form] = Form.useForm(); const [form] = Form.useForm();
@@ -51,28 +60,65 @@ const LoginForm = () => {
return userInfo; return userInfo;
}; };
const encryptPassword = (password: string) => {
const psw = CryptoJS.AES?.encrypt?.(password, CRYPT_TEXT).toString();
return psw;
};
const decryptPassword = (password: string) => {
const bytes = CryptoJS.AES?.decrypt?.(password, CRYPT_TEXT);
const res = bytes.toString(CryptoJS.enc.Utf8);
return res;
};
const callRememberMe = async (values: any) => {
const { autoLogin } = values;
if (autoLogin) {
await rememberMe(REMEMBER_ME_KEY, {
um: encryptPassword(values.username),
pw: encryptPassword(values.password),
f: true
});
} else {
await removeRememberMe(REMEMBER_ME_KEY);
}
};
const callGetRememberMe = async () => {
const rememberMe = await getRememberMe(REMEMBER_ME_KEY);
if (rememberMe?.f) {
const username = decryptPassword(rememberMe?.um);
const password = decryptPassword(rememberMe?.pw);
form.setFieldsValue({ username, password, autoLogin: true });
}
};
const handleLogin = async (values: any) => { const handleLogin = async (values: any) => {
console.log('values', values, form);
try { try {
await login({ await login({
username: values.username, username: values.username,
password: values.password password: values.password
}); });
const userInfo = await fetchUserInfo(); const userInfo = await fetchUserInfo();
setGlobalState({
userInfo
});
setUserInfo(userInfo); setUserInfo(userInfo);
setInitialPassword(values.password); setInitialPassword(values.password);
if (values.autoLogin) {
await callRememberMe(values);
} else {
await removeRememberMe(REMEMBER_ME_KEY);
}
if (!userInfo?.require_password_change) { if (!userInfo?.require_password_change) {
gotoDefaultPage(userInfo); gotoDefaultPage(userInfo);
} }
// gotoDefaultPage(userInfo);
} catch (error) { } catch (error) {
console.log('error====', error); // to do something
} }
}; };
useEffect(() => {
callGetRememberMe();
}, []);
return ( return (
<div> <div>
<div style={{ position: 'fixed', right: 0, top: 0, padding: '0 20px' }}> <div style={{ position: 'fixed', right: 0, top: 0, padding: '0 20px' }}>
@@ -119,12 +165,10 @@ const LoginForm = () => {
label={intl.formatMessage({ id: 'common.form.password' })} label={intl.formatMessage({ id: 'common.form.password' })}
/> />
</Form.Item> </Form.Item>
<Form.Item name="autoLogin"> <Form.Item name="autoLogin" valuePropName="checked">
<div style={{ paddingLeft: 10 }}> <Checkbox style={{ marginLeft: 10 }}>
<Checkbox> {intl.formatMessage({ id: 'common.login.rember' })}
{intl.formatMessage({ id: 'common.login.rember' })} </Checkbox>
</Checkbox>
</div>
</Form.Item> </Form.Item>
<Button htmlType="submit" type="primary" block> <Button htmlType="submit" type="primary" block>
{intl.formatMessage({ id: 'menu.login' })} {intl.formatMessage({ id: 'menu.login' })}
+1 -1
View File
@@ -21,7 +21,7 @@ const Login = () => {
}, [userInfo]); }, [userInfo]);
return ( return (
<div> <div className="login-wrapper">
{userInfo?.require_password_change ? <PasswordForm /> : <LoginForm />} {userInfo?.require_password_change ? <PasswordForm /> : <LoginForm />}
</div> </div>
); );
@@ -39,6 +39,13 @@ const ChatFooter: React.FC<ChatFooterProps> = (props) => {
}, },
{ enabled: !disabled } { enabled: !disabled }
); );
useHotkeys(
HotKeys.CREATE.join(','),
(e) => {
onNewMessage();
},
{ enabled: !disabled }
);
return ( return (
<div className="chat-footer"> <div className="chat-footer">
@@ -52,6 +59,7 @@ const ChatFooter: React.FC<ChatFooterProps> = (props) => {
onClick={onNewMessage} onClick={onNewMessage}
> >
{intl.formatMessage({ id: 'playground.newMessage' })} {intl.formatMessage({ id: 'playground.newMessage' })}
<span className="m-l-5 opct-7">CTRL+SHIFT+ N</span>
</Button> </Button>
<Button <Button
icon={<DeleteOutlined></DeleteOutlined>} icon={<DeleteOutlined></DeleteOutlined>}
@@ -1,7 +1,4 @@
.chat-footer { .chat-footer {
display: flex; display: flex;
align-items: center; align-items: center;
padding-inline: 0 32px;
height: 100px;
// box-shadow: 0px -1px 2px 0px var(--ant-color-border);
} }
+2 -1
View File
@@ -9,8 +9,9 @@
top: -14px; top: -14px;
right: 26px; right: 26px;
width: 80px; width: 80px;
border-radius: var(--border-radius-small); border-radius: 8px;
text-align: center; text-align: center;
border: 1px solid var(--ant-color-border) !important;
:global(.ant-input-number-input) { :global(.ant-input-number-input) {
text-align: center !important; text-align: center !important;
+8 -5
View File
@@ -1,7 +1,10 @@
.ground-left { .ground-left {
display: flex;
justify-content: space-between;
flex-direction: column;
position: relative; position: relative;
height: calc(100vh - 84px); height: calc(100vh - 136px);
padding-bottom: 120px; // padding-bottom: 120px;
padding-right: 32px; padding-right: 32px;
.message-list-wrap { .message-list-wrap {
@@ -10,8 +13,8 @@
} }
.ground-left-footer { .ground-left-footer {
position: absolute; // position: absolute;
bottom: 20px; // bottom: 20px;
width: 100%; // width: 100%;
} }
} }
+2 -2
View File
@@ -9,8 +9,8 @@
} }
.params { .params {
// width: 465px;
padding: 20px; padding: 20px;
padding-top: 0;
} }
.divider-line { .divider-line {
@@ -18,7 +18,7 @@
.ant-divider { .ant-divider {
margin: 0; margin: 0;
min-height: calc(100vh - 84px); min-height: calc(100vh - 136px);
} }
} }
} }
+1 -1
View File
@@ -35,7 +35,7 @@ const Resources = () => {
}} }}
extra={[]} extra={[]}
> >
<div style={{ marginTop: 70 }}> <div style={{ marginTop: 60 }}>
<Tabs <Tabs
type="card" type="card"
defaultActiveKey="workers" defaultActiveKey="workers"
+25
View File
@@ -0,0 +1,25 @@
import localStore from './store';
const store = localStore.createInstance({ name: '_xWXJKJ_S1Sna_' });
const rememberMe = (key: string, data: any) => {
if (store) {
store.setItem(key, data);
}
};
const getRememberMe = (key: string) => {
if (store) {
return store.getItem(key);
}
};
const removeRememberMe = (key: string) => {
if (store) {
store.removeItem(key);
}
};
export { getRememberMe, rememberMe, removeRememberMe };
export default store;
+51
View File
@@ -0,0 +1,51 @@
import dayjs from 'dayjs';
import localForage from 'localforage';
import { get } from 'lodash';
class Localestore extends Object.getPrototypeOf(localForage).constructor {
constructor() {
super();
this.state = {};
}
public async removeValue(key: string) {
return localForage.removeItem(key);
}
public async setValue(
key: string,
value: any,
callback?: (args?: any) => void,
expire?: number
) {
if (!expire) {
return localForage.setItem(key, { value }, callback);
}
return localForage.setItem(
key,
{
value,
expire: {
expire,
createTime: dayjs().valueOf(),
expiration: dayjs().add(expire, 'day').valueOf()
}
},
callback
);
}
public async getValue(key: string, callback?: (args?: any) => void) {
const storeValue = await localForage.getItem(key, callback);
const expire = get(storeValue, 'expire');
if (!expire) return storeValue;
const expiration = get(expire, 'expiration');
return {
value: get(storeValue, 'value'),
isExpiration: dayjs().isAfter(expiration)
};
}
}
export default new Localestore();