From 82d1cefcb5b27b776ae239671bfaf23a328b2374 Mon Sep 17 00:00:00 2001 From: xucz Date: Thu, 2 Jun 2022 20:13:31 +0800 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=E4=B8=BB=E9=A2=98=E9=A2=9C?= =?UTF-8?q?=E8=89=B2=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/configs/color.ts | 226 ++---------------- src/{utils => }/hooks/useDynamicChart.ts | 25 +- src/layouts/components/Footer.tsx | 10 +- src/layouts/components/Header.module.less | 2 +- src/layouts/components/Header.tsx | 4 +- .../components/Setting/RadioColor.module.less | 6 +- src/layouts/components/Setting/RadioColor.tsx | 43 ++-- src/layouts/components/Setting/RadioRect.tsx | 3 +- src/layouts/components/Setting/index.tsx | 5 +- src/layouts/index.module.less | 2 +- src/layouts/index.tsx | 4 +- src/modules/global/index.ts | 26 +- .../Dashboard/Base/components/MiddleChart.tsx | 2 +- .../Dashboard/Base/components/Overview.tsx | 2 +- .../Dashboard/Base/components/TopPanel.tsx | 2 +- src/pages/Dashboard/Detail/chart.ts | 4 +- .../Detail/components/PurchaseTrend.tsx | 2 +- .../Detail/components/Satisfaction.tsx | 2 +- src/pages/Detail/Deploy/chart.ts | 12 +- .../Deploy/components/DynamicLineChart.tsx | 2 +- .../Detail/Deploy/components/TopChart.tsx | 2 +- src/pages/User/index.tsx | 2 +- src/types/index.d.ts | 4 + src/utils/chart.ts | 1 - src/utils/color.ts | 41 ++++ vite.config.js | 2 + 26 files changed, 133 insertions(+), 303 deletions(-) rename src/{utils => }/hooks/useDynamicChart.ts (50%) create mode 100644 src/types/index.d.ts create mode 100644 src/utils/color.ts diff --git a/src/configs/color.ts b/src/configs/color.ts index cd72db0..ed37371 100644 --- a/src/configs/color.ts +++ b/src/configs/color.ts @@ -1,216 +1,22 @@ -import { useAppSelector } from 'modules/store'; -import { selectGlobal } from 'modules/global'; +import { ETheme } from 'types/index.d'; -import { Color } from 'tvision-color'; +export const defaultColor = ['#0052d9', '#0594fa', '#00a870', '#ebb105', '#ed7b2f', '#e34d59', '#ed49b4', '#834ec2']; +// export const defaultColor = ['#334455', '#0594fa', '#00a870', '#ebb105', '#ed7b2f', '#e34d59', '#ed49b4', '#834ec2']; -/* eslint-disable indent */ -export type TColorToken = Record; -export type TColorSeries = Record; +export const darkColor = ['#4582e6', '#29a4fb', '#03a56f', '#ca8d03', '#ed7b2f', '#ea7b84', '#f172c5', '#ab87d5']; +// export const darkColor = ['#ca8d03', '#29a4fb', '#03a56f', '#ca8d03', '#ed7b2f', '#ea7b84', '#f172c5', '#ab87d5']; -export const defaultLightColor = [ - '#0052d9', - '#0594fa', - '#00a870', - '#ebb105', - '#ed7b2f', - '#e34d59', - '#ed49b4', - '#834ec2', -]; -export const defaultDarkColor = [ - '#4582e6', - '#29a4fb', - '#03a56f', - '#ca8d03', - '#ed7b2f', - '#ea7b84', - '#f172c5', - '#ab87d5', -]; - -export const COLOR_TOKEN: TColorSeries = { - '#0052D9': { - '@brand-color': '#0052D9', - '@brand-color-1': '#e0ebff', - '@brand-color-2': '#c0d8ff', - '@brand-color-3': '#a1c4ff', - '@brand-color-4': '#81b1ff', - '@brand-color-5': '#5f9bff', - '@brand-color-6': '#3d87ff', - '@brand-color-7': '#176eff', - '@brand-color-8': '#0052D9', - '@brand-color-9': '#0048cd', - '@brand-color-10': '#0035b5', - }, - - '#0594FA': { - '@brand-color': '#0594FA', - '@brand-color-1': '#d7eefe', - '@brand-color-2': '#aeddfd', - '@brand-color-3': '#84cafd', - '@brand-color-4': '#58b8fc', - '@brand-color-5': '#29a4fb', - '@brand-color-6': '#0594FA', - '@brand-color-7': '#29a4fb', - '@brand-color-8': '#0594FA', - '@brand-color-9': '#0378df', - '@brand-color-10': '#01409b', - }, - '#00A870': { - '@brand-color': '#00A870', - '@brand-color-1': '#8dffd9', - '@brand-color-2': '#00f2a2', - '@brand-color-3': '#00dc92', - '@brand-color-4': '#00c583', - '@brand-color-5': '#00A870', - '@brand-color-6': '#009a5d', - '@brand-color-7': '#00c583', - '@brand-color-8': '#00A870', - '@brand-color-9': '#009a5d', - '@brand-color-10': '#004a14', - }, - '#ED7B2F': { - '@brand-color': '#ED7B2F', - '@brand-color-1': '#fce5d7', - '@brand-color-2': '#f8cdaf', - '@brand-color-3': '#f4b285', - '@brand-color-4': '#f19659', - '@brand-color-5': '#ED7B2F', - '@brand-color-6': '#e75510', - '@brand-color-7': '#f19659', - '@brand-color-8': '#ED7B2F', - '@brand-color-9': '#e75510', - '@brand-color-10': '#7f0a02', - }, - '#E34D59': { - '@brand-color': '#E34D59', - '@brand-color-1': '#fbe5e7', - '@brand-color-2': '#f7ccd0', - '@brand-color-3': '#f3b2b8', - '@brand-color-4': '#ef989f', - '@brand-color-5': '#ea7b84', - '@brand-color-6': '#E34D59', - '@brand-color-7': '#ea7b84', - '@brand-color-8': '#E34D59', - '@brand-color-9': '#e42c3a', - '@brand-color-10': '#8d0309', +export const CHART_COLORS = { + [ETheme.light]: { + textColor: 'rgba(0, 0, 0, 0.9)', + placeholderColor: 'rgba(0, 0, 0, 0.35)', + borderColor: '#dcdcdc', + containerColor: '#fff', }, - '#ED49B4': { - '@brand-color': '#ED49B4', - '@brand-color-1': '#fce5f4', - '@brand-color-2': '#facae9', - '@brand-color-3': '#f7aede', - '@brand-color-4': '#f491d2', - '@brand-color-5': '#f172c5', - '@brand-color-6': '#ED49B4', - '@brand-color-7': '#f172c5', - '@brand-color-8': '#ED49B4', - '@brand-color-9': '#e80f9d', - '@brand-color-10': '#8f025e', + [ETheme.dark]: { + textColor: 'rgba(255, 255, 255, 0.9)', + placeholderColor: 'rgba(255, 255, 255, 0.35)', + borderColor: '#5e5e5e', + containerColor: '#242424', }, - '#834EC2': { - '@brand-color': '#834EC2', - '@brand-color-1': '#eee6f7', - '@brand-color-2': '#ddceee', - '@brand-color-3': '#ccb6e6', - '@brand-color-4': '#bb9ede', - '@brand-color-5': '#ab87d5', - '@brand-color-6': '#9a6fce', - '@brand-color-7': '#9a6fce', - '@brand-color-8': '#834EC2', - '@brand-color-9': '#783ac3', - '@brand-color-10': '#4c1397', - }, - '#EBB105': { - '@brand-color': '#EBB105', - '@brand-color-1': '#fde9ab', - '@brand-color-2': '#fbd152', - '@brand-color-3': '#EBB105', - '@brand-color-4': '#dda204', - '@brand-color-5': '#ca8d03', - '@brand-color-6': '#b67803', - '@brand-color-7': '#fbd152', - '@brand-color-8': '#EBB105', - '@brand-color-9': '#dda204', - '@brand-color-10': '#603100', - }, -}; - -export const LIGHT_CHART_COLORS = { - textColor: 'rgba(0, 0, 0, 0.9)', - placeholderColor: 'rgba(0, 0, 0, 0.35)', - borderColor: '#dcdcdc', - containerColor: '#fff', -}; - -export const DARK_CHART_COLORS = { - textColor: 'rgba(255, 255, 255, 0.9)', - placeholderColor: 'rgba(255, 255, 255, 0.35)', - borderColor: '#5e5e5e', - containerColor: '#242424', }; - -function toUnderline(name: string): string { - return name.replace(/([A-Z])/g, '_$1').toUpperCase(); -} - -export function getBrandColor(type: string, colorList: TColorSeries): TColorToken { - const name = /^#[A-F\d]{6}$/i.test(type) ? type : toUnderline(type); - return colorList[name || 'DEFAULT']; -} - -export function getColorList(colorArray: Array): Array { - const pureColorList: Array = []; - colorArray.map((colorToken) => Object.keys(colorToken).map((key) => pureColorList.push(colorToken[key]))); - - return pureColorList; -} - -/** - * 依据主题类型获取颜色 - * - * @export - * @param {string} theme - * @returns {string[]} - */ -export function getColorFromTheme(theme: string): Array { - const state = useAppSelector(selectGlobal); - - const { colorList, theme: mode } = state; - - const isDarkMode = mode === 'dark'; - let themeColorList = []; - const themeColor = getBrandColor(theme, colorList); - if (!/^#[A-F\d]{6}$/i.test(theme) || defaultLightColor.includes(theme.toLocaleLowerCase())) { - // eslint-disable-next-line no-param-reassign - theme = themeColor?.['@brand-color'] || '#0052D9'; - const themIdx = defaultLightColor.indexOf(theme.toLocaleLowerCase()); - const defaultGradients = !isDarkMode ? defaultLightColor : defaultDarkColor; - - const spliceThemeList = defaultGradients.slice(0, themIdx); - themeColorList = defaultGradients.slice(themIdx, defaultGradients.length).concat(spliceThemeList); - } else { - // eslint-disable-next-line no-param-reassign - theme = themeColor?.['@brand-color']; - themeColorList = Color.getRandomPalette({ - color: theme, - colorGamut: 'bright', - number: 8, - }); - } - - return themeColorList; -} - -export function getChartColor(color: string) { - const finalColor = getColorFromTheme(color); - const state = useAppSelector(selectGlobal); - const { theme } = state; - if (theme === 'dark') { - return { - ...DARK_CHART_COLORS, - colorList: finalColor, - }; - } - return { ...LIGHT_CHART_COLORS, colorList: finalColor }; -} diff --git a/src/utils/hooks/useDynamicChart.ts b/src/hooks/useDynamicChart.ts similarity index 50% rename from src/utils/hooks/useDynamicChart.ts rename to src/hooks/useDynamicChart.ts index c737012..49bee77 100644 --- a/src/utils/hooks/useDynamicChart.ts +++ b/src/hooks/useDynamicChart.ts @@ -1,11 +1,13 @@ -/* eslint-disable no-param-reassign */ +import { useMemo } from 'react'; import { useAppSelector } from 'modules/store'; import { selectGlobal } from 'modules/global'; -import { getChartColor, LIGHT_CHART_COLORS } from 'configs/color'; +import { getChartColor } from 'utils/color'; +import { CHART_COLORS } from 'configs/color'; import lodashSet from 'lodash/set'; import lodashMap from 'lodash/map'; +import { ETheme } from '../types'; -export type TChartColorKey = keyof typeof LIGHT_CHART_COLORS; +export type TChartColorKey = keyof typeof CHART_COLORS[ETheme.light]; /** * 根据当前主题色返回动态的图表颜色列表 * @param options 图表的固定配置 @@ -16,16 +18,17 @@ export default function useDynamicChart( options: Record, configs?: Partial>>, ) { - const { color } = useAppSelector(selectGlobal); - const dynamicColor = getChartColor(color); - + const { theme, color } = useAppSelector(selectGlobal); + const dynamicColor = useMemo(() => getChartColor(theme, color), [theme, color]); if (options) { - options = lodashSet(options, 'color', dynamicColor.colorList); // 设置动态的图表颜色 + // 设置动态的图表颜色 + lodashSet(options, 'color', dynamicColor.colorList); lodashMap(configs, (config, configKey: TChartColorKey) => { - // eslint-disable-next-line no-return-assign - config?.map((v) => (options = lodashSet(options, `${v}`, dynamicColor[configKey]))); + config?.map((val) => lodashSet(options, val, dynamicColor[configKey])); }); - return { ...options }; } - return {}; + + return { + ...options, + }; } diff --git a/src/layouts/components/Footer.tsx b/src/layouts/components/Footer.tsx index 8b705bc..4bafe05 100644 --- a/src/layouts/components/Footer.tsx +++ b/src/layouts/components/Footer.tsx @@ -3,19 +3,19 @@ import { Layout, Row } from 'tdesign-react'; import { useAppSelector } from 'modules/store'; import { selectGlobal } from 'modules/global'; -const { Footer } = Layout; +const { Footer: TFooter } = Layout; -const LFooter = () => { +const Footer = () => { const globalState = useAppSelector(selectGlobal); if (!globalState.showFooter) { return null; } return ( -
+ Copyright @ 2022-2022 Tencent. All Rights Reserved -
+ ); }; -export default React.memo(LFooter); +export default React.memo(Footer); diff --git a/src/layouts/components/Header.module.less b/src/layouts/components/Header.module.less index efb0b56..9592552 100644 --- a/src/layouts/components/Header.module.less +++ b/src/layouts/components/Header.module.less @@ -1,4 +1,4 @@ -.headerPanel { +.panel { padding-left: 20px; padding-right: 20px; position: sticky; diff --git a/src/layouts/components/Header.tsx b/src/layouts/components/Header.tsx index ac16d76..b7261d6 100644 --- a/src/layouts/components/Header.tsx +++ b/src/layouts/components/Header.tsx @@ -37,14 +37,14 @@ export default memo((props: IHeaderProps) => { - } placeholder='请输入内容' /> + } placeholder='请输入内容1' /> ); } return ( -
+
{HeaderLeft}
diff --git a/src/layouts/components/Setting/RadioColor.module.less b/src/layouts/components/Setting/RadioColor.module.less index 5571141..7e1faaf 100644 --- a/src/layouts/components/Setting/RadioColor.module.less +++ b/src/layouts/components/Setting/RadioColor.module.less @@ -1,16 +1,16 @@ -.radioColorPanel { +.panel { display: flex; justify-content: space-between; } -.colorItemBox { +.box { cursor: pointer; border: 2px solid; padding: 4px; border-radius: 50%; } -.colorItem { +.item { width: 24px; height: 24px; border-radius: 50%; diff --git a/src/layouts/components/Setting/RadioColor.tsx b/src/layouts/components/Setting/RadioColor.tsx index 444aa09..ab84047 100644 --- a/src/layouts/components/Setting/RadioColor.tsx +++ b/src/layouts/components/Setting/RadioColor.tsx @@ -1,34 +1,25 @@ -import React, { memo, useState } from 'react'; +import React from 'react'; +import { defaultColor } from 'configs/color'; import Style from './RadioColor.module.less'; interface IProps { defaultValue?: number | string; - options?: any; onChange: (color: string) => void; } -const colors = ['#0052D9', '#0594FA', '#00A870', '#EBB105', '#ED7B2F', '#E34D59', '#ED49B4', '#834EC2']; +const RadioColor = (props: IProps) => ( +
+ {defaultColor.map((color, index) => ( +
props?.onChange(color)} + className={Style.box} + style={{ borderColor: props.defaultValue === color ? color : 'transparent' }} + > +
+
+ ))} +
+); -export default memo((props: IProps) => { - const [selectedColor, setSelectedColor] = useState(props.defaultValue); - - const handleClick = (color: string) => { - setSelectedColor(color); - props?.onChange(color); - }; - - return ( -
- {colors.map((color, index) => ( -
handleClick(color)} - className={Style.colorItemBox} - style={{ borderColor: selectedColor === color ? color : 'rgba(0,0,0,0)' }} - > -
-
- ))} -
- ); -}); +export default React.memo(RadioColor); diff --git a/src/layouts/components/Setting/RadioRect.tsx b/src/layouts/components/Setting/RadioRect.tsx index 0dafc96..9841fdb 100644 --- a/src/layouts/components/Setting/RadioRect.tsx +++ b/src/layouts/components/Setting/RadioRect.tsx @@ -1,6 +1,7 @@ import React, { memo, useState } from 'react'; import classname from 'classnames'; -import { ETheme, ELayout } from 'modules/global'; +import { ELayout } from 'modules/global'; +import { ETheme } from 'types/index.d'; import Style from './RadioRect.module.less'; interface IOption { diff --git a/src/layouts/components/Setting/index.tsx b/src/layouts/components/Setting/index.tsx index 9d9ee77..208ccc1 100644 --- a/src/layouts/components/Setting/index.tsx +++ b/src/layouts/components/Setting/index.tsx @@ -10,8 +10,8 @@ import { switchColor, switchLayout, ELayout, - ETheme, } from 'modules/global'; +import { ETheme } from 'types/index.d'; import RadioColor from './RadioColor'; import RadioRect from './RadioRect'; @@ -31,7 +31,6 @@ const themeList = [ name: '黑暗', }, { - // 跟随系统 value = undefined image: System, name: '跟随系统', }, @@ -61,7 +60,7 @@ export default memo(() => {
主题模式
dispatch(switchTheme(value))} + onChange={(value) => dispatch(switchTheme(value as ETheme))} options={themeList} /> diff --git a/src/layouts/index.module.less b/src/layouts/index.module.less index 7f4735b..82b72c9 100644 --- a/src/layouts/index.module.less +++ b/src/layouts/index.module.less @@ -1,4 +1,4 @@ -.mainPanel { +.panel { height: 100%; :global { .t-menu--scroll::-webkit-scrollbar { diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index 17868c7..1360019 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -28,14 +28,14 @@ export default memo(() => { }, []); return ( - + 页面配置
} + header='页面配置' onClose={() => dispatch(toggleSetting())} > diff --git a/src/modules/global/index.ts b/src/modules/global/index.ts index b7205af..2e59c0a 100644 --- a/src/modules/global/index.ts +++ b/src/modules/global/index.ts @@ -1,15 +1,11 @@ -import { createSlice } from '@reduxjs/toolkit'; -import { COLOR_TOKEN, TColorSeries, TColorToken, LIGHT_CHART_COLORS, DARK_CHART_COLORS } from 'configs/color'; +import { createSlice, PayloadAction } from '@reduxjs/toolkit'; +import { ETheme } from 'types/index.d'; +import { CHART_COLORS, defaultColor } from 'configs/color'; import { RootState } from '../store'; import { version } from '../../../package.json'; const namespace = 'global'; -export enum ETheme { - light = 'light', - dark = 'dark', -} - export enum ELayout { side = 1, top, @@ -29,24 +25,24 @@ export interface IGlobalState { showHeader: boolean; showBreadcrumbs: boolean; showFooter: boolean; - colorList: TColorSeries; - chartColors: TColorToken; + chartColors: Record; } +const defaultTheme = ETheme.light; + const initialState: IGlobalState = { loading: true, collapsed: window.innerWidth < 1000, // 宽度小于1000 菜单闭合 setting: false, version, - theme: ETheme.light, + theme: defaultTheme, layout: ELayout.side, isFullPage: false, - color: '#0052D9', + color: defaultColor?.[0], showHeader: true, showBreadcrumbs: false, showFooter: true, - colorList: COLOR_TOKEN, - chartColors: LIGHT_CHART_COLORS, + chartColors: CHART_COLORS[defaultTheme], }; // 创建带有命名空间的reducer @@ -73,7 +69,7 @@ const globalSlice = createSlice({ toggleShowFooter: (state) => { state.showFooter = !state.showFooter; }, - switchTheme: (state, action) => { + switchTheme: (state, action: PayloadAction) => { let finalTheme = action?.payload; if (!finalTheme) { // 跟随系统 @@ -83,7 +79,7 @@ const globalSlice = createSlice({ } } // 切换 chart 颜色 - state.chartColors = finalTheme === ETheme.dark ? DARK_CHART_COLORS : LIGHT_CHART_COLORS; + state.chartColors = CHART_COLORS[finalTheme]; // 切换主题颜色 state.theme = finalTheme; document.documentElement.setAttribute('theme-mode', finalTheme); diff --git a/src/pages/Dashboard/Base/components/MiddleChart.tsx b/src/pages/Dashboard/Base/components/MiddleChart.tsx index 728e691..fc72593 100644 --- a/src/pages/Dashboard/Base/components/MiddleChart.tsx +++ b/src/pages/Dashboard/Base/components/MiddleChart.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { Col, Row, Card } from 'tdesign-react'; import ReactEcharts from 'echarts-for-react'; -import useDynamicChart from 'utils/hooks/useDynamicChart'; +import useDynamicChart from 'hooks/useDynamicChart'; import LastWeekDatePicker from 'components/DatePicker'; import { getLineChartOptions, getPieChartOptions } from '../chart'; import Style from './MiddleChart.module.less'; diff --git a/src/pages/Dashboard/Base/components/Overview.tsx b/src/pages/Dashboard/Base/components/Overview.tsx index 34c7d26..1dace46 100644 --- a/src/pages/Dashboard/Base/components/Overview.tsx +++ b/src/pages/Dashboard/Base/components/Overview.tsx @@ -1,7 +1,7 @@ import React, { useState } from 'react'; import { Button, Col, Row, Card } from 'tdesign-react'; import ReactEcharts from 'echarts-for-react'; -import useDynamicChart from 'utils/hooks/useDynamicChart'; +import useDynamicChart from 'hooks/useDynamicChart'; import Board, { ETrend } from 'components/Board'; import LastWeekDatePicker from 'components/DatePicker'; import { getBarChartOptions } from '../chart'; diff --git a/src/pages/Dashboard/Base/components/TopPanel.tsx b/src/pages/Dashboard/Base/components/TopPanel.tsx index 438748a..3ead175 100644 --- a/src/pages/Dashboard/Base/components/TopPanel.tsx +++ b/src/pages/Dashboard/Base/components/TopPanel.tsx @@ -3,7 +3,7 @@ import { Col, Row } from 'tdesign-react'; import { UsergroupIcon, FileIcon } from 'tdesign-icons-react'; import ReactEcharts from 'echarts-for-react'; import Board, { ETrend, IBoardProps } from 'components/Board'; -import useDynamicChart from 'utils/hooks/useDynamicChart'; +import useDynamicChart from 'hooks/useDynamicChart'; import { MICRO_CHART_OPTIONS_BAR, MICRO_CHART_OPTIONS_LINE } from '../chart'; import Style from './TopPanel.module.less'; diff --git a/src/pages/Dashboard/Detail/chart.ts b/src/pages/Dashboard/Detail/chart.ts index 65f587c..68b5790 100644 --- a/src/pages/Dashboard/Detail/chart.ts +++ b/src/pages/Dashboard/Detail/chart.ts @@ -1,6 +1,6 @@ import type { EChartOption } from 'echarts'; -import { ONE_WEEK_LIST, CHART_LIST_COLOR, getChartDataSet, getTimeArray, getRandomInt } from 'utils/chart'; +import { ONE_WEEK_LIST, getChartDataSet, getTimeArray, getRandomInt } from 'utils/chart'; // line chart options export const getLineChartOptions = (dateTime: Array = []): EChartOption => { @@ -11,7 +11,6 @@ export const getLineChartOptions = (dateTime: Array = []): EChartOption } return { - color: CHART_LIST_COLOR, grid: { top: '5%', right: '10px', @@ -140,7 +139,6 @@ export const getScatterChartOptions = (dateTime: Array = []): EChartOpti const [timeArray, inArray, outArray] = getChartDataSet(dateTime); return { - color: CHART_LIST_COLOR, xAxis: { data: timeArray, axisLabel: { diff --git a/src/pages/Dashboard/Detail/components/PurchaseTrend.tsx b/src/pages/Dashboard/Detail/components/PurchaseTrend.tsx index 519b089..126f945 100644 --- a/src/pages/Dashboard/Detail/components/PurchaseTrend.tsx +++ b/src/pages/Dashboard/Detail/components/PurchaseTrend.tsx @@ -3,7 +3,7 @@ import { Button, Col, Dropdown, Row, Tag, Card } from 'tdesign-react'; import { Icon } from 'tdesign-icons-react'; import ReactEcharts from 'echarts-for-react'; import LastWeekDatePicker from 'components/DatePicker'; -import useDynamicChart from 'utils/hooks/useDynamicChart'; +import useDynamicChart from 'hooks/useDynamicChart'; import { PRODUCT_LIST } from '../constant'; import { getLineChartOptions } from '../chart'; import Style from './PurchaseThrend.module.less'; diff --git a/src/pages/Dashboard/Detail/components/Satisfaction.tsx b/src/pages/Dashboard/Detail/components/Satisfaction.tsx index b634776..d181316 100644 --- a/src/pages/Dashboard/Detail/components/Satisfaction.tsx +++ b/src/pages/Dashboard/Detail/components/Satisfaction.tsx @@ -2,7 +2,7 @@ import React, { useState } from 'react'; import { Button, Card } from 'tdesign-react'; import ReactEcharts from 'echarts-for-react'; import LastWeekDatePicker from 'components/DatePicker'; -import useDynamicChart from 'utils/hooks/useDynamicChart'; +import useDynamicChart from 'hooks/useDynamicChart'; import { getScatterChartOptions } from '../chart'; import Style from './Satisfaction.module.less'; diff --git a/src/pages/Detail/Deploy/chart.ts b/src/pages/Detail/Deploy/chart.ts index 7ead360..908cc82 100644 --- a/src/pages/Detail/Deploy/chart.ts +++ b/src/pages/Detail/Deploy/chart.ts @@ -1,5 +1,5 @@ import type { EChartOption } from 'echarts'; -import { CHART_LIST_COLOR, getTimeArray, getRandomInt } from 'utils/chart'; +import { getTimeArray, getRandomInt } from 'utils/chart'; export function getLineOptions(dateTime: any = []): EChartOption { let dateArray: Array = ['00:00', '02:00', '04:00', '06:00']; @@ -95,7 +95,6 @@ export function getBarOptions(isMonth = false): EChartOption { } return { - color: CHART_LIST_COLOR, tooltip: { trigger: 'item', }, @@ -153,15 +152,6 @@ export function getBarOptions(isMonth = false): EChartOption { type: 'bar', barWidth: '30%', data: thisYearListCopy, - itemStyle: { - // color: (param) => { - // // console.log('chartListColor', CHART_LIST_COLOR); - // if (params.value >= 200) { - // return '#E34D59'; - // } - // return '#0052D9'; - // }, - }, }, ], }; diff --git a/src/pages/Detail/Deploy/components/DynamicLineChart.tsx b/src/pages/Detail/Deploy/components/DynamicLineChart.tsx index aa18675..3406e37 100644 --- a/src/pages/Detail/Deploy/components/DynamicLineChart.tsx +++ b/src/pages/Detail/Deploy/components/DynamicLineChart.tsx @@ -1,7 +1,7 @@ import React, { useEffect, useState } from 'react'; import { EChartOption } from 'echarts'; import ReactEcharts from 'echarts-for-react'; -import useDynamicChart from 'utils/hooks/useDynamicChart'; +import useDynamicChart from 'hooks/useDynamicChart'; import { getLineOptions } from '../chart'; const DynamicLineChart = () => { diff --git a/src/pages/Detail/Deploy/components/TopChart.tsx b/src/pages/Detail/Deploy/components/TopChart.tsx index ff45043..de69c3a 100644 --- a/src/pages/Detail/Deploy/components/TopChart.tsx +++ b/src/pages/Detail/Deploy/components/TopChart.tsx @@ -3,7 +3,7 @@ import { Col, Radio, Row, Card } from 'tdesign-react'; import { EChartOption } from 'echarts'; import ReactEcharts from 'echarts-for-react'; import { getBarOptions } from '../chart'; -import useDynamicChart from 'utils/hooks/useDynamicChart'; +import useDynamicChart from 'hooks/useDynamicChart'; import DynamicLineChart from './DynamicLineChart'; import Style from './TopChart.module.less'; diff --git a/src/pages/User/index.tsx b/src/pages/User/index.tsx index 4c4c6a3..25136d0 100644 --- a/src/pages/User/index.tsx +++ b/src/pages/User/index.tsx @@ -10,7 +10,7 @@ import ProductA from 'assets/svg/assets-product-1.svg?component'; import ProductB from 'assets/svg/assets-product-2.svg?component'; import ProductC from 'assets/svg/assets-product-3.svg?component'; import ProductD from 'assets/svg/assets-product-4.svg?component'; -import useDynamicChart from 'utils/hooks/useDynamicChart'; +import useDynamicChart from 'hooks/useDynamicChart'; import styles from './index.module.less'; diff --git a/src/types/index.d.ts b/src/types/index.d.ts new file mode 100644 index 0000000..b6a872b --- /dev/null +++ b/src/types/index.d.ts @@ -0,0 +1,4 @@ +export enum ETheme { + light = 'light', + dark = 'dark', +} diff --git a/src/utils/chart.ts b/src/utils/chart.ts index 5ed39be..c8949b6 100644 --- a/src/utils/chart.ts +++ b/src/utils/chart.ts @@ -2,7 +2,6 @@ import dayjs, { Dayjs } from 'dayjs'; const RECENT_7_DAYS: [Dayjs, Dayjs] = [dayjs().subtract(7, 'day'), dayjs().subtract(1, 'day')]; -export const CHART_LIST_COLOR = ['#0052D9', '#BCC4D0', '#7D46BD', '#0594FA', '#ED7B2F']; export const ONE_WEEK_LIST = ['周一', '周二', '周三', '周四', '周五', '周六', '周日']; export const getRandomInt = (num = 100): number => { diff --git a/src/utils/color.ts b/src/utils/color.ts new file mode 100644 index 0000000..20e7092 --- /dev/null +++ b/src/utils/color.ts @@ -0,0 +1,41 @@ +import { Color } from 'tvision-color'; +import { defaultColor, darkColor, CHART_COLORS } from 'configs/color'; +import { ETheme } from 'types/index.d'; + +/** + * 依据主题颜色获取 ColorList + * @param theme + * @param themeColor + */ +function getColorFromThemeColor(theme: string, themeColor: string): Array { + let themeColorList = []; + const isDarkMode = theme === ETheme.dark; + const colorLowerCase = themeColor.toLocaleLowerCase(); + + if (defaultColor.includes(colorLowerCase)) { + const colorIdx = defaultColor.indexOf(colorLowerCase); + const defaultGradients = !isDarkMode ? defaultColor : darkColor; + const spliceThemeList = defaultGradients.slice(0, colorIdx); + themeColorList = defaultGradients.slice(colorIdx, defaultGradients.length).concat(spliceThemeList); + } else { + themeColorList = Color.getRandomPalette({ + color: themeColor, + colorGamut: 'bright', + number: 8, + }); + } + + return themeColorList; +} + +/** + * + * @param theme 当前主题 + * @param themeColor 当前主题色 + */ +export function getChartColor(theme: ETheme, themeColor: string) { + const colorList = getColorFromThemeColor(theme, themeColor); + // 图表颜色 + const chartColors = CHART_COLORS[theme]; + return { ...chartColors, colorList }; +} diff --git a/vite.config.js b/vite.config.js index 51cb142..ca52391 100644 --- a/vite.config.js +++ b/vite.config.js @@ -17,6 +17,8 @@ export default (params) => ({ utils: path.resolve(__dirname, './src/utils'), services: path.resolve(__dirname, './src/services'), router: path.resolve(__dirname, './src/router'), + hooks: path.resolve(__dirname, './src/hooks'), + types: path.resolve(__dirname, './src/types'), }, }, From e475221ccf7bfb47f1567f676138384ac8029d6f Mon Sep 17 00:00:00 2001 From: xucz Date: Sat, 4 Jun 2022 19:04:56 +0800 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=E5=9B=BE=E8=A1=A8=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useDynamicChart.ts | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/src/hooks/useDynamicChart.ts b/src/hooks/useDynamicChart.ts index 49bee77..d09a1d2 100644 --- a/src/hooks/useDynamicChart.ts +++ b/src/hooks/useDynamicChart.ts @@ -19,16 +19,18 @@ export default function useDynamicChart( configs?: Partial>>, ) { const { theme, color } = useAppSelector(selectGlobal); - const dynamicColor = useMemo(() => getChartColor(theme, color), [theme, color]); - if (options) { - // 设置动态的图表颜色 - lodashSet(options, 'color', dynamicColor.colorList); - lodashMap(configs, (config, configKey: TChartColorKey) => { - config?.map((val) => lodashSet(options, val, dynamicColor[configKey])); - }); - } - - return { - ...options, - }; + return useMemo(() => { + const dynamicColor = getChartColor(theme, color); + const newOptions = { + ...options, + }; + if (newOptions) { + // 设置动态的图表颜色 + lodashSet(newOptions, 'color', dynamicColor.colorList); + lodashMap(configs, (config, configKey: TChartColorKey) => { + config?.map((val) => lodashSet(newOptions, val, dynamicColor[configKey])); + }); + } + return newOptions; + }, [theme, color, options]); } From 837fc505323166e6c5e30368dc9ad8d418c706a2 Mon Sep 17 00:00:00 2001 From: xucz Date: Sat, 4 Jun 2022 19:06:17 +0800 Subject: [PATCH 3/8] =?UTF-8?q?feat:=20=E5=9B=BE=E8=A1=A8=E4=B8=BB?= =?UTF-8?q?=E9=A2=98=E5=8A=9F=E8=83=BD=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/hooks/useDynamicChart.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/hooks/useDynamicChart.ts b/src/hooks/useDynamicChart.ts index d09a1d2..e132d58 100644 --- a/src/hooks/useDynamicChart.ts +++ b/src/hooks/useDynamicChart.ts @@ -24,9 +24,9 @@ export default function useDynamicChart( const newOptions = { ...options, }; - if (newOptions) { - // 设置动态的图表颜色 - lodashSet(newOptions, 'color', dynamicColor.colorList); + // 设置动态的图表颜色 + lodashSet(newOptions, 'color', dynamicColor.colorList); + if (configs) { lodashMap(configs, (config, configKey: TChartColorKey) => { config?.map((val) => lodashSet(newOptions, val, dynamicColor[configKey])); }); From b6263856b1827709711b35f80c7c5f364e987d6a Mon Sep 17 00:00:00 2001 From: xucz Date: Sat, 4 Jun 2022 19:06:52 +0800 Subject: [PATCH 4/8] =?UTF-8?q?feat:=20=E5=88=A0=E9=99=A4=E6=B3=A8?= =?UTF-8?q?=E9=87=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/configs/color.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/configs/color.ts b/src/configs/color.ts index ed37371..46b4fff 100644 --- a/src/configs/color.ts +++ b/src/configs/color.ts @@ -1,10 +1,8 @@ import { ETheme } from 'types/index.d'; export const defaultColor = ['#0052d9', '#0594fa', '#00a870', '#ebb105', '#ed7b2f', '#e34d59', '#ed49b4', '#834ec2']; -// export const defaultColor = ['#334455', '#0594fa', '#00a870', '#ebb105', '#ed7b2f', '#e34d59', '#ed49b4', '#834ec2']; export const darkColor = ['#4582e6', '#29a4fb', '#03a56f', '#ca8d03', '#ed7b2f', '#ea7b84', '#f172c5', '#ab87d5']; -// export const darkColor = ['#ca8d03', '#29a4fb', '#03a56f', '#ca8d03', '#ed7b2f', '#ea7b84', '#f172c5', '#ab87d5']; export const CHART_COLORS = { [ETheme.light]: { From 4a906c7f7f8a6b9c33b7a14f5413054cd02e9b5d Mon Sep 17 00:00:00 2001 From: xucz Date: Sat, 4 Jun 2022 19:44:58 +0800 Subject: [PATCH 5/8] =?UTF-8?q?feat:=20=E5=8D=87=E7=BA=A7tdesign?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package-lock.json | 39 +++++++++++++++------------------------ package.json | 4 ++-- 2 files changed, 17 insertions(+), 26 deletions(-) diff --git a/package-lock.json b/package-lock.json index e848553..e794e10 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1736,13 +1736,13 @@ "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "@types/sortablejs": { - "version": "1.10.7", - "resolved": "https://mirrors.tencent.com/npm/@types%2fsortablejs/-/sortablejs-1.10.7.tgz", - "integrity": "sha512-lGCwwgpj8zW/ZmaueoPVSP7nnc9t8VqVWXS+ASX3eoUUENmiazv0rlXyTRludXzuX9ALjPsMqBu85TgJNWbTOg==" + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/@types/sortablejs/-/sortablejs-1.13.0.tgz", + "integrity": "sha512-C3064MH72iEfeGCYEGCt7FCxXoAXaMPG0QPnstcxvPmbl54erpISu06d++FY37Smja64iWy5L8wOyHHBghWbJQ==" }, "@types/tinycolor2": { "version": "1.4.3", - "resolved": "https://mirrors.tencent.com/npm/@types%2ftinycolor2/-/tinycolor2-1.4.3.tgz", + "resolved": "https://registry.npmjs.org/@types/tinycolor2/-/tinycolor2-1.4.3.tgz", "integrity": "sha512-Kf1w9NE5HEgGxCRyIcRXR/ZYtDv0V8FVPtYHwLxl0O+maGX0erE77pQlD0gpP+/KByMZ87mOA79SjifhSB3PjQ==" }, "@types/zrender": { @@ -2370,9 +2370,9 @@ "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" }, "clipboard": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.10.tgz", - "integrity": "sha512-cz3m2YVwFz95qSEbCDi2fzLN/epEN9zXBvfgAoGkvGOJZATMl9gtTDVOtBYkx2ODUJl2kvmud7n32sV2BpYR4g==", + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/clipboard/-/clipboard-2.0.11.tgz", + "integrity": "sha512-C+0bbOqkezLIsmWSvlsXS0Q0bmkugu7jcfMIACB+RDEntIzQIkdr148we28AfSloQLRdZlYL/QYyrq05j/3Faw==", "requires": { "good-listener": "^1.2.2", "select": "^1.1.2", @@ -3528,7 +3528,7 @@ "good-listener": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/good-listener/-/good-listener-1.2.2.tgz", - "integrity": "sha1-1TswzfkxPf+33JoNR3CWqm0UXFA=", + "integrity": "sha512-goW1b+d9q/HIwbVYZzZ6SsTr4IgE+WA44A0GmPIQstuOrgsFcT7VEJ48nmr9GaRtNu0XTKacFLGnBPAM6Afouw==", "requires": { "delegate": "^3.1.2" } @@ -4297,7 +4297,7 @@ "performance-now": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", - "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" + "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, "picocolors": { "version": "1.0.0", @@ -4722,7 +4722,7 @@ }, "sortablejs": { "version": "1.15.0", - "resolved": "https://mirrors.tencent.com/npm/sortablejs/-/sortablejs-1.15.0.tgz", + "resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.15.0.tgz", "integrity": "sha512-bv9qgVMjUMf89wAvM6AxVvS/4MX3sPeN0+agqShejLU5z5GX4C75ow1O2e5k4L6XItUyAK3gH6AxSbXrOM5e8w==" }, "source-map": { @@ -4837,9 +4837,9 @@ } }, "tdesign-react": { - "version": "0.32.2", - "resolved": "https://mirrors.tencent.com/npm/tdesign-react/-/tdesign-react-0.32.2.tgz", - "integrity": "sha512-dORzKN0nmEVh/AlCdzJF4g5/rSWUbW51cNj50wMnGsAonCkixCewVUKHeK6XWQFoIbau+2GQXSTky/qdDoDKDA==", + "version": "0.34.4", + "resolved": "https://registry.npmjs.org/tdesign-react/-/tdesign-react-0.34.4.tgz", + "integrity": "sha512-yAmwpqdPJP3XwnEKazkb9bS7rR8C8HB8UtR3t19wZG4s5YW9cC0PGNFedLfhUqefFRbrIwZZZWoKoUAeir5xXQ==", "requires": { "@babel/runtime": "~7.17.2", "@popperjs/core": "~2.11.2", @@ -4854,7 +4854,7 @@ "react-popper": "~2.2.5", "react-transition-group": "~4.4.1", "sortablejs": "^1.15.0", - "tdesign-icons-react": "^0.0.10", + "tdesign-icons-react": "~0.1.0", "tinycolor2": "^1.4.2", "tslib": "~2.3.1", "use-resize-observer": "^8.0.0", @@ -4867,15 +4867,6 @@ "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.10.8.tgz", "integrity": "sha512-wbNwDfBHHur9UOzNUjeKUOJ0fCb0a52Wx0xInmQ7Y8FstyajiV1NmK1e00cxsr9YrE9r7yAChE0VvpuY5Rnlow==" }, - "tdesign-icons-react": { - "version": "0.0.10", - "resolved": "https://mirrors.tencent.com/npm/tdesign-icons-react/-/tdesign-icons-react-0.0.10.tgz", - "integrity": "sha512-azFKwQ09rj1MXIgfJlTNpkvjXvFmPFhbb1FLkL2qbn+1IQ0IpCFV48C1TIWkANsmvMNIo3YxApOrBtcLB9fV0g==", - "requires": { - "@babel/runtime": "^7.16.5", - "classnames": "^2.2.6" - } - }, "tslib": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.3.1.tgz", @@ -4896,7 +4887,7 @@ }, "tinycolor2": { "version": "1.4.2", - "resolved": "https://mirrors.tencent.com/npm/tinycolor2/-/tinycolor2-1.4.2.tgz", + "resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.2.tgz", "integrity": "sha512-vJhccZPs965sV/L2sU4oRQVAos0pQXwsvTLkWYdqJ+a8Q5kPFzJTuOFwy7UniPli44NKQGAglksjvOcpo95aZA==" }, "to-fast-properties": { diff --git a/package.json b/package.json index 7875ebf..89f7c0e 100644 --- a/package.json +++ b/package.json @@ -56,8 +56,8 @@ "react-dom": "^17.0.2", "react-redux": "^7.2.4", "react-router-dom": "^6.3.0", - "tdesign-icons-react": "0.1.0", - "tdesign-react": "^0.32.2", + "tdesign-icons-react": "^0.1.0", + "tdesign-react": "^0.34.4", "tvision-color": "^1.3.1" }, "browserslist": { From 9d7544d06597c5292ef739e55079cb421e2d278a Mon Sep 17 00:00:00 2001 From: xucz Date: Sat, 4 Jun 2022 21:41:37 +0800 Subject: [PATCH 6/8] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E9=9D=A2?= =?UTF-8?q?=E5=8C=85=E5=B1=91=E5=AF=BC=E8=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/PageBox/index.module.less | 15 ------ src/components/PageBox/index.tsx | 36 --------------- src/layouts/components/Content.module.less | 3 ++ src/layouts/components/Content.tsx | 54 +++++++++------------- src/layouts/components/Page.module.less | 9 ++++ src/layouts/components/Page.tsx | 39 ++++++++++++++++ src/layouts/components/Setting/index.tsx | 2 +- src/modules/global/index.ts | 5 +- src/pages/Dashboard/Base/index.tsx | 5 +- src/pages/Dashboard/Detail/index.tsx | 5 +- src/pages/Detail/Advanced/index.tsx | 5 +- src/pages/Detail/Base/index.tsx | 5 +- src/pages/Detail/Deploy/index.tsx | 5 +- src/pages/Detail/Secondary/index.tsx | 5 +- src/pages/Form/Base/index.tsx | 7 +-- src/pages/Form/Step/index.tsx | 7 +-- src/pages/List/Base/index.tsx | 7 +-- src/pages/List/Select/index.tsx | 7 +-- src/pages/List/Tree/index.tsx | 7 +-- src/pages/User/index.tsx | 5 +- src/styles/common.module.less | 9 ++++ 21 files changed, 121 insertions(+), 121 deletions(-) delete mode 100644 src/components/PageBox/index.module.less delete mode 100644 src/components/PageBox/index.tsx create mode 100644 src/layouts/components/Page.module.less create mode 100644 src/layouts/components/Page.tsx create mode 100644 src/styles/common.module.less diff --git a/src/components/PageBox/index.module.less b/src/components/PageBox/index.module.less deleted file mode 100644 index 953a29a..0000000 --- a/src/components/PageBox/index.module.less +++ /dev/null @@ -1,15 +0,0 @@ -.pageBox { - margin: 24px; - padding: 0; - overflow: auto; -} - -.pageBoxWithPadding { - padding: 30px 32px; -} - -.pageBoxWithColor { - background: var(--td-bg-color-container); - box-shadow: 0px 2px 3px rgba(0, 0, 0, 0.1); - border-radius: 3px; -} diff --git a/src/components/PageBox/index.tsx b/src/components/PageBox/index.tsx deleted file mode 100644 index 0d22b48..0000000 --- a/src/components/PageBox/index.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from 'react'; -import { Layout } from 'tdesign-react'; -import classnames from 'classnames'; -import Style from './index.module.less'; - -const { Content } = Layout; - -export interface IPageBoxProps { - withColor?: boolean; - withPadding?: boolean; - className?: string; -} - -const PageBox: React.FC> = ({ - children, - withColor, - withPadding, - className, - ...others -}) => ( - - {children} - -); - -export default React.memo(PageBox); diff --git a/src/layouts/components/Content.module.less b/src/layouts/components/Content.module.less index 53fd177..01206ba 100644 --- a/src/layouts/components/Content.module.less +++ b/src/layouts/components/Content.module.less @@ -1,3 +1,6 @@ +.panel { + height: 0; +} .loading { height: 100%; width: 100%; diff --git a/src/layouts/components/Content.tsx b/src/layouts/components/Content.tsx index 8c5aa49..2fd7add 100644 --- a/src/layouts/components/Content.tsx +++ b/src/layouts/components/Content.tsx @@ -1,41 +1,34 @@ -import React, { Suspense, useEffect, memo } from 'react'; +import React, { Suspense, memo } from 'react'; import { Routes, Route, Navigate } from 'react-router-dom'; import { Layout, Loading } from 'tdesign-react'; import routers, { IRouter } from 'router'; import { resolve } from 'utils/path'; -import { useAppDispatch } from '../../modules/store'; -import { switchFullPage } from '../../modules/global'; +import Page from './Page'; import Style from './Content.module.less'; const { Content } = Layout; -const PageBox = memo( - ({ - children, - isFullPage, - }: React.PropsWithChildren<{ - isFullPage?: boolean; - }>) => { - const dispatch = useAppDispatch(); - - useEffect(() => { - dispatch(switchFullPage(isFullPage)); - }, [isFullPage]); - - return <>{children}; - }, -); - const PageLoading = memo(() => (
)); -const renderRoutes = (routes: IRouter[], parentPath = ''): React.ReactNode[] => +/** + * 渲染应用路由 + * @param routes + * @param parentPath + */ +type TRenderRoutes = (routes: IRouter[], parentPath?: string, breadcrumbs?: string[]) => React.ReactNode[]; +const renderRoutes: TRenderRoutes = (routes, parentPath = '', breadcrumb = []) => routes.map((route, index: number) => { - const { Component, children, redirect } = route; + const { Component, children, redirect, meta } = route; const currentPath = resolve(parentPath, route.path); + let currentBreadcrumb = breadcrumb; + + if (meta?.title) { + currentBreadcrumb = currentBreadcrumb.concat([meta?.title]); + } if (redirect) { // 重定向 @@ -43,28 +36,25 @@ const renderRoutes = (routes: IRouter[], parentPath = ''): React.ReactNode[] => } if (Component) { + // 有路由菜单 return ( + - + } - > - {children && renderRoutes(children, currentPath)} - + /> ); } - if (children) { - return renderRoutes(children, currentPath); - } - return null; + // 无路由菜单 + return children ? renderRoutes(children, currentPath, currentBreadcrumb) : null; }); export default memo(() => ( - + }> {renderRoutes(routers)} diff --git a/src/layouts/components/Page.module.less b/src/layouts/components/Page.module.less new file mode 100644 index 0000000..076937b --- /dev/null +++ b/src/layouts/components/Page.module.less @@ -0,0 +1,9 @@ +.panel { + margin: 24px; + padding: 0; + overflow: auto; +} + +.breadcrumb { + margin-bottom: 8px; +} diff --git a/src/layouts/components/Page.tsx b/src/layouts/components/Page.tsx new file mode 100644 index 0000000..b054d83 --- /dev/null +++ b/src/layouts/components/Page.tsx @@ -0,0 +1,39 @@ +import React, { useEffect } from 'react'; +import { useAppDispatch, useAppSelector } from '../../modules/store'; +import { selectGlobal, switchFullPage } from '../../modules/global'; +import { Layout, Breadcrumb } from 'tdesign-react'; +import Style from './Page.module.less'; + +const { Content } = Layout; +const { BreadcrumbItem } = Breadcrumb; + +const Page = ({ + children, + isFullPage, + breadcrumbs, +}: React.PropsWithChildren<{ isFullPage?: boolean; breadcrumbs?: string[] }>) => { + const globalState = useAppSelector(selectGlobal); + const dispatch = useAppDispatch(); + useEffect(() => { + dispatch(switchFullPage(isFullPage)); + }, [isFullPage]); + + if (isFullPage) { + return <>{children}; + } + + return ( + + {globalState.showBreadcrumbs && ( + + {breadcrumbs?.map((item, index) => ( + {item} + ))} + + )} + {children} + + ); +}; + +export default React.memo(Page); diff --git a/src/layouts/components/Setting/index.tsx b/src/layouts/components/Setting/index.tsx index 208ccc1..d65b55e 100644 --- a/src/layouts/components/Setting/index.tsx +++ b/src/layouts/components/Setting/index.tsx @@ -84,7 +84,7 @@ export default memo(() => { - +
显示 Breadcrumbs
diff --git a/src/modules/global/index.ts b/src/modules/global/index.ts index 2e59c0a..0fd056d 100644 --- a/src/modules/global/index.ts +++ b/src/modules/global/index.ts @@ -16,6 +16,9 @@ export enum ELayout { export interface IGlobalState { loading: boolean; collapsed: boolean; + /** + * 是否显示面包屑导航 + */ setting: boolean; version: string; color: string; @@ -40,7 +43,7 @@ const initialState: IGlobalState = { isFullPage: false, color: defaultColor?.[0], showHeader: true, - showBreadcrumbs: false, + showBreadcrumbs: true, showFooter: true, chartColors: CHART_COLORS[defaultTheme], }; diff --git a/src/pages/Dashboard/Base/index.tsx b/src/pages/Dashboard/Base/index.tsx index 01b30d0..2e422e0 100644 --- a/src/pages/Dashboard/Base/index.tsx +++ b/src/pages/Dashboard/Base/index.tsx @@ -1,17 +1,16 @@ import React, { memo } from 'react'; -import PageBox from 'components/PageBox'; import TopPanel from './components/TopPanel'; import MiddleChart from './components/MiddleChart'; import RankList from './components/RankList'; import Overview from './components/Overview'; const DashBoard = () => ( - +
- +
); export default memo(DashBoard); diff --git a/src/pages/Dashboard/Detail/index.tsx b/src/pages/Dashboard/Detail/index.tsx index 9b54da1..19c893f 100644 --- a/src/pages/Dashboard/Detail/index.tsx +++ b/src/pages/Dashboard/Detail/index.tsx @@ -1,13 +1,12 @@ import React, { memo } from 'react'; -import PageBox from 'components/PageBox'; import MonthPurchase from './components/MonthPurchase'; import PurchaseTrend from './components/PurchaseTrend'; import PurchaseSatisfaction from './components/Satisfaction'; export default memo(() => ( - +
- +
)); diff --git a/src/pages/Detail/Advanced/index.tsx b/src/pages/Detail/Advanced/index.tsx index 3a61cae..5a8ed4b 100644 --- a/src/pages/Detail/Advanced/index.tsx +++ b/src/pages/Detail/Advanced/index.tsx @@ -1,15 +1,14 @@ import React, { memo } from 'react'; -import PageBox from 'components/PageBox'; import Base from './components/Base'; import ProgressComp from './components/Progress'; import Product from './components/Product'; import Detail from './components/Detail'; export default memo(() => ( - +
- +
)); diff --git a/src/pages/Detail/Base/index.tsx b/src/pages/Detail/Base/index.tsx index 856c6fe..a5fb3cc 100644 --- a/src/pages/Detail/Base/index.tsx +++ b/src/pages/Detail/Base/index.tsx @@ -1,14 +1,13 @@ import React, { memo } from 'react'; import { Steps, Card } from 'tdesign-react'; import classnames from 'classnames'; -import PageBox from 'components/PageBox'; import { dataInfo, dataStep } from './consts'; import Style from './index.module.less'; const { StepItem } = Steps; export default memo(() => ( - +
{dataInfo.map((item) => ( @@ -36,5 +35,5 @@ export default memo(() => (
- +
)); diff --git a/src/pages/Detail/Deploy/index.tsx b/src/pages/Detail/Deploy/index.tsx index 34ceb2c..71de10d 100644 --- a/src/pages/Detail/Deploy/index.tsx +++ b/src/pages/Detail/Deploy/index.tsx @@ -1,13 +1,12 @@ import React, { memo } from 'react'; -import PageBox from 'components/PageBox'; import TopChart from './components/TopChart'; import BottomTable from './components/BottomTable'; const Deploy = () => ( - +
- +
); export default memo(Deploy); diff --git a/src/pages/Detail/Secondary/index.tsx b/src/pages/Detail/Secondary/index.tsx index 067acc2..72a48a4 100644 --- a/src/pages/Detail/Secondary/index.tsx +++ b/src/pages/Detail/Secondary/index.tsx @@ -2,7 +2,6 @@ import React, { memo, useState } from 'react'; import { Tabs, List, Tag, Row, Col, Popup } from 'tdesign-react'; import { AddRectangleIcon, DeleteIcon, ChatIcon } from 'tdesign-icons-react'; import classnames from 'classnames'; -import PageBox from 'components/PageBox'; import { dataItemList, IItem, TStatus } from './consts'; import Style from './index.module.less'; @@ -95,7 +94,7 @@ export default memo(() => { }; return ( - +
@@ -109,6 +108,6 @@ export default memo(() => {
- +
); }); diff --git a/src/pages/Form/Base/index.tsx b/src/pages/Form/Base/index.tsx index 74f0e35..509fc46 100644 --- a/src/pages/Form/Base/index.tsx +++ b/src/pages/Form/Base/index.tsx @@ -13,8 +13,9 @@ import { Upload, MessagePlugin, } from 'tdesign-react'; +import classnames from 'classnames'; import { SubmitContext, FormInstanceFunctions } from 'tdesign-react/es/form/type'; -import PageBox from 'components/PageBox'; +import CommonStyle from 'styles/common.module.less'; import Style from './index.module.less'; const { FormItem } = Form; @@ -50,7 +51,7 @@ export default memo(() => { }; return ( - +
@@ -173,6 +174,6 @@ export default memo(() => {
- +
); }); diff --git a/src/pages/Form/Step/index.tsx b/src/pages/Form/Step/index.tsx index f7608ec..f444a8b 100644 --- a/src/pages/Form/Step/index.tsx +++ b/src/pages/Form/Step/index.tsx @@ -1,7 +1,8 @@ import React, { memo } from 'react'; -import PageBox from 'components/PageBox'; +import classnames from 'classnames'; import { Steps } from 'tdesign-react'; import { StepOne, StepTwo, StepThree, StepFour } from './components'; +import CommonStyle from 'styles/common.module.less'; const { StepItem: Step } = Steps; interface IStep { @@ -62,7 +63,7 @@ export default memo(() => { }; return ( - +
<> {steps.map((item) => ( @@ -73,6 +74,6 @@ export default memo(() => {
-
+
); }); diff --git a/src/pages/List/Base/index.tsx b/src/pages/List/Base/index.tsx index 4493335..de53c57 100644 --- a/src/pages/List/Base/index.tsx +++ b/src/pages/List/Base/index.tsx @@ -1,9 +1,10 @@ import React, { useState, memo, useEffect } from 'react'; import { Table, Tag, Row, Col, Button, Input } from 'tdesign-react'; import { ChevronUpCircleIcon, SearchIcon, ChevronDownCircleIcon } from 'tdesign-icons-react'; -import PageBox from 'components/PageBox'; +import classnames from 'classnames'; import { useAppDispatch, useAppSelector } from 'modules/store'; import { selectListBase, getList, clearPageState } from 'modules/list/base'; +import CommonStyle from 'styles/common.module.less'; import style from './index.module.less'; export const PaymentTypeMap: { @@ -85,7 +86,7 @@ export default memo(() => { setSelectedRowKeys(value); } return ( - +
@@ -214,6 +215,6 @@ export default memo(() => { }, }} /> - +
); }); diff --git a/src/pages/List/Select/index.tsx b/src/pages/List/Select/index.tsx index 8fdf313..a705fa6 100644 --- a/src/pages/List/Select/index.tsx +++ b/src/pages/List/Select/index.tsx @@ -2,11 +2,12 @@ import React, { useState, memo, useEffect } from 'react'; import { Table, Dialog, Button, Row } from 'tdesign-react'; import { useAppDispatch, useAppSelector } from 'modules/store'; import { selectListSelect, getList, clearPageState } from 'modules/list/select'; -import PageBox from 'components/PageBox'; import SearchForm from './components/SearchForm'; import { StatusMap, ContractTypeMap, PaymentTypeMap } from '../Base'; import './index.module.less'; +import classnames from 'classnames'; +import CommonStyle from '../../../styles/common.module.less'; export const SelectTable = () => { const dispatch = useAppDispatch(); @@ -170,9 +171,9 @@ export const SelectTable = () => { }; const selectPage: React.FC = () => ( - +
- +
); export default memo(selectPage); diff --git a/src/pages/List/Tree/index.tsx b/src/pages/List/Tree/index.tsx index 7d0c0df..e92b90f 100644 --- a/src/pages/List/Tree/index.tsx +++ b/src/pages/List/Tree/index.tsx @@ -1,13 +1,14 @@ import React from 'react'; import { Input, Tree } from 'tdesign-react'; import { SearchIcon } from 'tdesign-icons-react'; -import PageBox from 'components/PageBox'; +import classnames from 'classnames'; import { SelectTable } from '../Select'; import { treeList } from './consts'; +import CommonStyle from 'styles/common.module.less'; import Style from './index.module.less'; const TreeTable: React.FC = () => ( - +
} placeholder='请输入关键词' /> @@ -15,7 +16,7 @@ const TreeTable: React.FC = () => (
- +
); export default TreeTable; diff --git a/src/pages/User/index.tsx b/src/pages/User/index.tsx index 25136d0..df630f4 100644 --- a/src/pages/User/index.tsx +++ b/src/pages/User/index.tsx @@ -3,7 +3,6 @@ import { Row, Col, Button, List, Card } from 'tdesign-react'; import { IconFont } from 'tdesign-icons-react'; import { BrowserRouterProps } from 'react-router-dom'; import ReactEcharts from 'echarts-for-react'; -import PageBox from 'components/PageBox'; import { TEAMS } from './consts'; import { visitData } from './chart'; import ProductA from 'assets/svg/assets-product-1.svg?component'; @@ -21,7 +20,7 @@ const User: React.FC = () => { placeholderColor: ['legend.textStyle.color', 'xAxis.axisLabel.color', 'yAxis.axisLabel.color'], }); return ( - +
@@ -144,7 +143,7 @@ const User: React.FC = () => { - +
); }; diff --git a/src/styles/common.module.less b/src/styles/common.module.less new file mode 100644 index 0000000..140ff85 --- /dev/null +++ b/src/styles/common.module.less @@ -0,0 +1,9 @@ +.pageWithPadding { + padding: 30px 32px; +} + +.pageWithColor { + background: var(--td-bg-color-container); + box-shadow: 0 2px 3px rgba(0, 0, 0, 0.1); + border-radius: 3px; +} From d860271972c227e5120b66dc08213d48ac8b9a0a Mon Sep 17 00:00:00 2001 From: xucz Date: Sat, 4 Jun 2022 21:55:25 +0800 Subject: [PATCH 7/8] =?UTF-8?q?feat:=20=E6=96=87=E4=BB=B6=E5=91=BD?= =?UTF-8?q?=E5=90=8D=E8=AF=AD=E4=B9=89=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ...iner.module.less => AppLayout.module.less} | 0 .../{Container.tsx => AppLayout.tsx} | 4 +-- ...tent.module.less => AppRouter.module.less} | 0 .../components/{Content.tsx => AppRouter.tsx} | 25 +++++++++++-------- src/layouts/components/Header.tsx | 6 +---- src/layouts/index.tsx | 6 ++--- 6 files changed, 20 insertions(+), 21 deletions(-) rename src/layouts/components/{Container.module.less => AppLayout.module.less} (100%) rename src/layouts/components/{Container.tsx => AppLayout.tsx} (92%) rename src/layouts/components/{Content.module.less => AppRouter.module.less} (100%) rename src/layouts/components/{Content.tsx => AppRouter.tsx} (86%) diff --git a/src/layouts/components/Container.module.less b/src/layouts/components/AppLayout.module.less similarity index 100% rename from src/layouts/components/Container.module.less rename to src/layouts/components/AppLayout.module.less diff --git a/src/layouts/components/Container.tsx b/src/layouts/components/AppLayout.tsx similarity index 92% rename from src/layouts/components/Container.tsx rename to src/layouts/components/AppLayout.tsx index bda83a3..350e403 100644 --- a/src/layouts/components/Container.tsx +++ b/src/layouts/components/AppLayout.tsx @@ -4,9 +4,9 @@ import { ELayout } from 'modules/global'; import Header from './Header'; import Footer from './Footer'; import Menu from './Menu'; -import Content from './Content'; +import Content from './AppRouter'; -import Style from './Container.module.less'; +import Style from './AppLayout.module.less'; const SideLayout = React.memo(() => ( diff --git a/src/layouts/components/Content.module.less b/src/layouts/components/AppRouter.module.less similarity index 100% rename from src/layouts/components/Content.module.less rename to src/layouts/components/AppRouter.module.less diff --git a/src/layouts/components/Content.tsx b/src/layouts/components/AppRouter.tsx similarity index 86% rename from src/layouts/components/Content.tsx rename to src/layouts/components/AppRouter.tsx index 2fd7add..d1136ea 100644 --- a/src/layouts/components/Content.tsx +++ b/src/layouts/components/AppRouter.tsx @@ -4,22 +4,17 @@ import { Layout, Loading } from 'tdesign-react'; import routers, { IRouter } from 'router'; import { resolve } from 'utils/path'; import Page from './Page'; -import Style from './Content.module.less'; +import Style from './AppRouter.module.less'; const { Content } = Layout; -const PageLoading = memo(() => ( -
- -
-)); - +type TRenderRoutes = (routes: IRouter[], parentPath?: string, breadcrumbs?: string[]) => React.ReactNode[]; /** * 渲染应用路由 * @param routes * @param parentPath + * @param breadcrumb */ -type TRenderRoutes = (routes: IRouter[], parentPath?: string, breadcrumbs?: string[]) => React.ReactNode[]; const renderRoutes: TRenderRoutes = (routes, parentPath = '', breadcrumb = []) => routes.map((route, index: number) => { const { Component, children, redirect, meta } = route; @@ -53,10 +48,18 @@ const renderRoutes: TRenderRoutes = (routes, parentPath = '', breadcrumb = []) = return children ? renderRoutes(children, currentPath, currentBreadcrumb) : null; }); -export default memo(() => ( +const AppRouter = () => ( - }> + + +
+ } + > {renderRoutes(routers)}
-)); +); + +export default memo(AppRouter); diff --git a/src/layouts/components/Header.tsx b/src/layouts/components/Header.tsx index b7261d6..1fbf79d 100644 --- a/src/layouts/components/Header.tsx +++ b/src/layouts/components/Header.tsx @@ -9,11 +9,7 @@ import Style from './Header.module.less'; const { Header } = Layout; -interface IHeaderProps { - showMenu?: boolean; -} - -export default memo((props: IHeaderProps) => { +export default memo((props: { showMenu?: boolean }) => { const globalState = useAppSelector(selectGlobal); const dispatch = useAppDispatch(); diff --git a/src/layouts/index.tsx b/src/layouts/index.tsx index 1360019..fc06ac7 100644 --- a/src/layouts/index.tsx +++ b/src/layouts/index.tsx @@ -4,14 +4,14 @@ import throttle from 'lodash/throttle'; import { useAppSelector, useAppDispatch } from 'modules/store'; import { selectGlobal, toggleSetting, toggleMenu, ELayout } from 'modules/global'; import Setting from './components/Setting'; -import LayoutMap from './components/Container'; +import AppLayout from './components/AppLayout'; import Style from './index.module.less'; export default memo(() => { const globalState = useAppSelector(selectGlobal); const dispatch = useAppDispatch(); - const Container = LayoutMap[globalState.isFullPage ? ELayout.fullPage : globalState.layout]; + const AppContainer = AppLayout[globalState.isFullPage ? ELayout.fullPage : globalState.layout]; useEffect(() => { const handleResize = throttle(() => { @@ -29,7 +29,7 @@ export default memo(() => { return ( - + Date: Sat, 4 Jun 2022 22:16:13 +0800 Subject: [PATCH 8/8] =?UTF-8?q?feat:=20=E6=90=9C=E7=B4=A2=E6=A1=86?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../components/{ => Header}/HeaderIcon.module.less | 0 src/layouts/components/{ => Header}/HeaderIcon.tsx | 0 src/layouts/components/Header/Search.module.less | 14 ++++++++++++++ src/layouts/components/Header/Search.tsx | 8 ++++++++ .../index.module.less} | 0 .../components/{Header.tsx => Header/index.tsx} | 11 ++++++----- 6 files changed, 28 insertions(+), 5 deletions(-) rename src/layouts/components/{ => Header}/HeaderIcon.module.less (100%) rename src/layouts/components/{ => Header}/HeaderIcon.tsx (100%) create mode 100644 src/layouts/components/Header/Search.module.less create mode 100644 src/layouts/components/Header/Search.tsx rename src/layouts/components/{Header.module.less => Header/index.module.less} (100%) rename src/layouts/components/{Header.tsx => Header/index.tsx} (77%) diff --git a/src/layouts/components/HeaderIcon.module.less b/src/layouts/components/Header/HeaderIcon.module.less similarity index 100% rename from src/layouts/components/HeaderIcon.module.less rename to src/layouts/components/Header/HeaderIcon.module.less diff --git a/src/layouts/components/HeaderIcon.tsx b/src/layouts/components/Header/HeaderIcon.tsx similarity index 100% rename from src/layouts/components/HeaderIcon.tsx rename to src/layouts/components/Header/HeaderIcon.tsx diff --git a/src/layouts/components/Header/Search.module.less b/src/layouts/components/Header/Search.module.less new file mode 100644 index 0000000..94f3518 --- /dev/null +++ b/src/layouts/components/Header/Search.module.less @@ -0,0 +1,14 @@ +.panel { + :global { + .t-input { + border: none; + } + .t-input:hover { + background: #EEE; + transition: background var(--tdvns-anim-duration-base) linear + } + .t-input--focused { + box-shadow: none; + } + } +} diff --git a/src/layouts/components/Header/Search.tsx b/src/layouts/components/Header/Search.tsx new file mode 100644 index 0000000..a50d7cb --- /dev/null +++ b/src/layouts/components/Header/Search.tsx @@ -0,0 +1,8 @@ +import React from 'react'; +import { Input } from 'tdesign-react'; +import { SearchIcon } from 'tdesign-icons-react'; +import Style from './Search.module.less'; + +const Search = () => } placeholder='请输入搜索内容' />; + +export default React.memo(Search); diff --git a/src/layouts/components/Header.module.less b/src/layouts/components/Header/index.module.less similarity index 100% rename from src/layouts/components/Header.module.less rename to src/layouts/components/Header/index.module.less diff --git a/src/layouts/components/Header.tsx b/src/layouts/components/Header/index.tsx similarity index 77% rename from src/layouts/components/Header.tsx rename to src/layouts/components/Header/index.tsx index 1fbf79d..8f4b99f 100644 --- a/src/layouts/components/Header.tsx +++ b/src/layouts/components/Header/index.tsx @@ -1,11 +1,12 @@ import React, { memo } from 'react'; -import { Layout, Button, Row, Col, Input } from 'tdesign-react'; -import { ViewListIcon, SearchIcon } from 'tdesign-icons-react'; +import { Layout, Button, Row, Col } from 'tdesign-react'; +import { ViewListIcon } from 'tdesign-icons-react'; import { useAppDispatch, useAppSelector } from 'modules/store'; import { selectGlobal, toggleMenu } from 'modules/global'; import HeaderIcon from './HeaderIcon'; -import { HeaderMenu } from './Menu'; -import Style from './Header.module.less'; +import { HeaderMenu } from '../Menu'; +import Search from './Search'; +import Style from './index.module.less'; const { Header } = Layout; @@ -33,7 +34,7 @@ export default memo((props: { showMenu?: boolean }) => { - } placeholder='请输入内容1' /> + );