From d6b2597f47e474b517d41b16563af727f746c301 Mon Sep 17 00:00:00 2001 From: nyqykk <1327719263@qq.com> Date: Fri, 13 Dec 2024 17:45:01 +0800 Subject: [PATCH] chore: refactor bundle alert --- .../Alert/package-relation.module.scss | 11 ++ .../src/components/Alert/package-relation.tsx | 125 ++++++------ .../Alerts/bundle-alert.module.scss | 16 ++ .../src/components/Alerts/bundle-alert.tsx | 108 +++++++++++ .../src/components/Alerts/bundle.tsx | 27 ++- .../components/Alerts/collapse.module.scss | 74 +++++++ .../src/components/Alerts/collapse.tsx | 180 ++++++++++++++++++ .../src/components/Alerts/common.tsx | 167 ---------------- .../src/components/Alerts/compile.tsx | 23 ++- .../src/components/Alerts/list.module.scss | 6 + .../components/src/components/Alerts/list.tsx | 26 +++ .../src/components/Overall/card.module.scss | 2 +- .../src/components/Overall/list.module.scss | 1 + .../components/Overall/overview.module.scss | 35 ++++ .../src/components/Overall/overview.tsx | 23 +++ .../components/Overall/project.module.scss | 4 + .../src/components/Overall/project.tsx | 132 +++++++++---- 17 files changed, 676 insertions(+), 284 deletions(-) create mode 100644 packages/components/src/components/Alert/package-relation.module.scss create mode 100644 packages/components/src/components/Alerts/bundle-alert.module.scss create mode 100644 packages/components/src/components/Alerts/bundle-alert.tsx create mode 100644 packages/components/src/components/Alerts/collapse.module.scss create mode 100644 packages/components/src/components/Alerts/collapse.tsx delete mode 100644 packages/components/src/components/Alerts/common.tsx create mode 100644 packages/components/src/components/Alerts/list.module.scss create mode 100644 packages/components/src/components/Alerts/list.tsx create mode 100644 packages/components/src/components/Overall/overview.module.scss create mode 100644 packages/components/src/components/Overall/overview.tsx create mode 100644 packages/components/src/components/Overall/project.module.scss diff --git a/packages/components/src/components/Alert/package-relation.module.scss b/packages/components/src/components/Alert/package-relation.module.scss new file mode 100644 index 00000000..65611ca2 --- /dev/null +++ b/packages/components/src/components/Alert/package-relation.module.scss @@ -0,0 +1,11 @@ +.dot { + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; +} + +.filePath { + display: flex; + justify-content: space-between; +} diff --git a/packages/components/src/components/Alert/package-relation.tsx b/packages/components/src/components/Alert/package-relation.tsx index fe54d755..575f32e1 100644 --- a/packages/components/src/components/Alert/package-relation.tsx +++ b/packages/components/src/components/Alert/package-relation.tsx @@ -15,18 +15,28 @@ import { Empty, Popover, Grid, + Badge, } from 'antd'; import { sumBy } from 'lodash-es'; -import { Rule, SDK } from '@rsdoctor/types'; -import { ExpandAltOutlined, InfoCircleOutlined } from '@ant-design/icons'; +import { + ExpandAltOutlined, + InfoCircleOutlined, + DoubleRightOutlined, +} from '@ant-design/icons'; + import { useRuleIndexNavigate, formatSize, useI18n } from '../../utils'; import { TextDrawer } from '../TextDrawer'; import { Title } from '../Title'; import { Size, Color } from '../../constants'; import { Badge as Bdg } from '../Badge'; -import { PackageRelationAlertProps } from './types'; import { withServerAPI } from '../Manifest'; +import { Rule, SDK } from '@rsdoctor/types'; + +import { PackageRelationAlertProps } from './types'; + +import styles from './package-relation.module.scss'; + const TextDrawerWidth = '60%'; export const PackageRelationReasons: React.FC<{ @@ -39,72 +49,55 @@ export const PackageRelationReasons: React.FC<{ return ( - - {t('DuplicatePakCodeExplain')} - - } - > - Explain - - } - bodyStyle={{ overflow: 'scroll' }} - > - {data.length ? ( - -
- - Click the file path below to show the reason in code viewer. - -
- - {data.map((e, i) => { - const { dependency, module, relativePath } = e!; - const { statements } = dependency; - const { start } = statements?.[0]?.position - ? module.isPreferSource - ? statements[0].position.source! - : statements[0].position.transformed - : { start: { line: 0, column: 0 } }; - const text = `${relativePath}:${start.line}:${ - start.column || 1 - }`; + {data.length ? ( + <> +
+ + Click the file path below to show the reason in code viewer. + +
+ + {data.map((e, i) => { + const { dependency, module, relativePath } = e!; + const { statements } = dependency; + const { start } = statements?.[0]?.position + ? module.isPreferSource + ? statements[0].position.source! + : statements[0].position.transformed + : { start: { line: 0, column: 0 } }; + const text = `${relativePath}:${start.line}:${ + start.column || 1 + }`; - return ( - + { + e.preventDefault(); + e.stopPropagation(); + setIndex(i); + }} + strong={i === index} + style={{ + color: i === index ? Color.Blue : 'inherit', + display: 'block', + }} > - { - e.preventDefault(); - e.stopPropagation(); - setIndex(i); - }} - strong={i === index} - style={{ - color: i === index ? Color.Blue : 'inherit', - display: 'block', - }} - > +
{text} - - - ); - })} - - - ) : ( - - )} - + +
+
+
+ ); + })} +
+ + ) : ( + + )}
); diff --git a/packages/components/src/components/Alerts/bundle-alert.module.scss b/packages/components/src/components/Alerts/bundle-alert.module.scss new file mode 100644 index 00000000..1f464ba6 --- /dev/null +++ b/packages/components/src/components/Alerts/bundle-alert.module.scss @@ -0,0 +1,16 @@ +.card { + :global { + .ant-card-body { + padding: 0; + } + + .ant-collapse { + border-radius: 0; + border: 0; + } + + .ant-collapse-content { + border-radius: 0 !important; + } + } +} diff --git a/packages/components/src/components/Alerts/bundle-alert.tsx b/packages/components/src/components/Alerts/bundle-alert.tsx new file mode 100644 index 00000000..ed5bc5ae --- /dev/null +++ b/packages/components/src/components/Alerts/bundle-alert.tsx @@ -0,0 +1,108 @@ +import { Typography, Tabs } from 'antd'; +import { Rule } from '@rsdoctor/types'; + +import { ViewMode } from '../../constants'; +import { Card } from '../Card'; +import { Overview } from '../Overall/overview'; +import { AlertCollapse } from './collapse'; +import { CommonList } from './list'; + +import { AlertProps } from '../Alert/types'; + +import styles from './bundle-alert.module.scss'; + +interface BundleAlertProps { + title: string; + cwd: string; + dataSource: Rule.RuleStoreDataItem[]; + extraData: Omit; + viewMode: ViewMode; + setViewMode(mode: ViewMode): void; + extraCom?: JSX.Element | undefined; +} + +export const BundleAlert: React.FC = ({ + title, + dataSource, + extraData, +}) => { + if (!dataSource.length) return null; + + const tabData: Array<{ + key: string; + label: string; + data: Array; + }> = [ + { + key: 'E1001', + label: 'Duplicate Packages', + data: [], + }, + { + key: 'E1002', + label: 'Default Import Check', + data: [], + }, + { + key: 'E1003', + label: 'Loader Performance Optimization', + data: [], + }, + { + key: 'E1004', + label: 'ECMA Version Check', + data: [], + }, + ]; + + dataSource.forEach((data) => { + const target = tabData.find((td) => td.key === data.code)?.data; + target?.push(data); + }); + + const tabItems = tabData.map((td) => { + const LabelComponent = () => ( + {td.key}} + /> + ); + + let children; + switch (td.key) { + case 'E1001': + children = ; + break; + case 'E1002': + children = ; + break; + case 'E1003': + children = ; + break; + case 'E1004': + children = <>1004; + break; + default: + children = null; + break; + } + + return { + key: td.key, + label: , + children: ( + + {children} + + ), + }; + }); + + return ( + + + + ); +}; diff --git a/packages/components/src/components/Alerts/bundle.tsx b/packages/components/src/components/Alerts/bundle.tsx index 8c51c82a..e7c21536 100644 --- a/packages/components/src/components/Alerts/bundle.tsx +++ b/packages/components/src/components/Alerts/bundle.tsx @@ -1,7 +1,11 @@ import React, { useEffect } from 'react'; import { Rule, SDK } from '@rsdoctor/types'; -import { hasViewModeFromStorage, useBundleAlertsByErrors, useViewMode } from '../../utils'; -import { CommonAlertsContainer } from './common'; +import { + hasViewModeFromStorage, + useBundleAlertsByErrors, + useViewMode, +} from '../../utils'; +import { BundleAlert } from './bundle-alert'; import { withServerAPI } from '../Manifest'; import { ViewMode } from '../../constants'; import { PackageRelationReasonsWithServer } from '../Alert/package-relation'; @@ -12,7 +16,10 @@ interface BundleAlertsProps { project: SDK.ServerAPI.InferResponseType; } -export const BundleAlertsBase: React.FC = ({ filter, project }) => { +export const BundleAlertsBase: React.FC = ({ + filter, + project, +}) => { const { errors, root: cwd } = project; const bundleAlerts = useBundleAlertsByErrors(errors); const { setBundleAlertsViewMode, viewMode, setViewMode } = useViewMode(); @@ -23,7 +30,8 @@ export const BundleAlertsBase: React.FC = ({ filter, project if (!hasViewModeFromStorage()) { setViewMode( { - bundleAlerts: bundleAlerts.length >= 5 ? ViewMode.Group : ViewMode.List, + bundleAlerts: + bundleAlerts.length >= 5 ? ViewMode.Group : ViewMode.List, }, false, ); @@ -37,17 +45,20 @@ export const BundleAlertsBase: React.FC = ({ filter, project Alert: { colorInfoBg: '#e6f4ff57', colorInfoBorder: 'none', - } - } + }, + }, }} > - ( - + ), }} viewMode={viewMode.bundleAlerts} diff --git a/packages/components/src/components/Alerts/collapse.module.scss b/packages/components/src/components/Alerts/collapse.module.scss new file mode 100644 index 00000000..2a2c01fc --- /dev/null +++ b/packages/components/src/components/Alerts/collapse.module.scss @@ -0,0 +1,74 @@ +.label { + display: flex; + justify-content: space-between; + + :global { + .ant-collapse-header { + background-color: white; + } + } + + .labelContent { + display: flex; + + & > * { + margin-right: 10px; + } + } +} + +.collapseContainer { + .collapseChild { + display: flex; + font-family: Roboto; + font-size: 14px; + font-weight: 400; + line-height: 20px; + text-align: left; + + & > * { + margin-right: 20px; + } + + .attribute { + font-family: Roboto; + font-size: 12px; + font-weight: 400; + line-height: 16px; + text-align: left; + color: #00000073; + } + + .copy { + position: relative; + left: 100%; + top: -50%; + } + } +} + +.dataIcon { + margin-right: 5px; +} + +.drawerLabelTitle { + min-width: 120px; + display: flex; + justify-content: space-evenly; + align-items: center; + + .drawerLabelSize { + font-family: Roboto Mono; + font-size: 12px; + font-weight: 400; + } +} + +.extraContainer { + display: flex; + align-items: center; + + .size { + margin-right: 20px; + } +} diff --git a/packages/components/src/components/Alerts/collapse.tsx b/packages/components/src/components/Alerts/collapse.tsx new file mode 100644 index 00000000..bf886b43 --- /dev/null +++ b/packages/components/src/components/Alerts/collapse.tsx @@ -0,0 +1,180 @@ +import { ReactNode } from 'react'; +import { Collapse, Typography, Divider, Space, Tabs, Tag } from 'antd'; +import { BorderOuterOutlined } from '@ant-design/icons'; +import { sumBy } from 'lodash-es'; + +import Overview from '../Overall/overview'; +import { TextDrawer } from '../TextDrawer'; +import { Title } from '../Title'; +import { Size } from '../../constants'; +import { formatSize } from '../../utils'; + +import { Rule } from '@rsdoctor/types'; + +import { AlertProps } from '../Alert/types'; + +import styles from './collapse.module.scss'; + +const { Paragraph } = Typography; + +const LabelComponent = (props: { + title: string; + description: string; + extra: ReactNode; +}) => { + const { title, description, extra } = props; + return ( +
+
+
{title}
+
{description}
+
+
{extra}
+
+ ); +}; + +export const AlertCollapse = (props: { + data: Array; + extraData: Omit; +}) => { + const { data, extraData } = props; + + const items = data.map((d) => { + const { packages } = d as Rule.PackageRelationDiffRuleStoreData; + const totalSize = sumBy(packages, (e) => e.targetSize.sourceSize); + const totalSizeStr = formatSize(totalSize); + const { name } = packages.find((e) => !!e.target.name)!.target; + const versions = packages.map((item) => item.target.version); + + const ChildComponent = () => { + return packages.map((pkg, idx) => { + const version = pkg.target.version; + const root = pkg.target.root; + const sizeStr = formatSize(pkg.targetSize.sourceSize); + // TODO add parsed size + // const parsedSizeStr = pkg.targetSize.parsedSize + // ? formatSize(pkg.targetSize.parsedSize) + // : null; + + return ( +
+ +
+
Version
+
+ + v.{version} +
+
+
+
Source size
+
+ + {sizeStr} +
+
+
+
Bundle size
+
+ + xxx +
+
+
+ } + icon={ + + } + /> + {idx !== packages.length - 1 ? ( + + ) : null} + + ); + }); + }; + + return { + key: d.code, + label: ( + +
+ + {totalSizeStr} +
+ {packages && packages.length > 0 ? ( + + + + + {name} + </Tag> + } + upperFirst={false} + /> + <Typography.Text strong> + {versions.length} + </Typography.Text> + <Typography.Text> versions was found</Typography.Text> + </Space> + <Tabs + size="middle" + items={ + packages.map((pkg) => { + const { target, targetSize } = pkg; + return { + label: ( + <Space className={styles.drawerLabelTitle}> + <div>v.{target.version}</div> + <Tag className={styles.drawerLabelSize}> + {formatSize(targetSize.sourceSize)} + </Tag> + </Space> + ), + key: `${target.root}${target.name}${target.version}`, + children: + extraData.getPackageRelationContentComponent({ + data: d as Rule.PackageRelationDiffRuleStoreData, + package: pkg, + }), + }; + })! + } + /> + </Space> + </TextDrawer> + ) : null} + </div> + } + /> + ), + children: <ChildComponent />, + }; + }); + + return ( + <Collapse + style={{ width: '100%' }} + defaultActiveKey={['E1001']} + items={items} + /> + ); +}; diff --git a/packages/components/src/components/Alerts/common.tsx b/packages/components/src/components/Alerts/common.tsx deleted file mode 100644 index 6005dd8e..00000000 --- a/packages/components/src/components/Alerts/common.tsx +++ /dev/null @@ -1,167 +0,0 @@ -import { Collapse, Space, Radio, Typography, Tooltip } from 'antd'; -import React, { useMemo } from 'react'; -import { AppstoreOutlined, UnorderedListOutlined } from '@ant-design/icons'; -import { Rule } from '@rsdoctor/types'; -import { groupBy, sumBy, values } from 'lodash-es'; -import { ViewMode } from '../../constants'; -import { Alert } from '../Alert'; -import { Card } from '../Card'; -import { Badge as Bdg } from '../Badge'; -import { AlertProps } from '../Alert/types'; -import { RuleErrorCodes } from '@rsdoctor/types/dist/rule'; - -interface CommonAlertsContainerProps { - title: string; - cwd: string; - dataSource: Rule.RuleStoreDataItem[]; - extraData: Omit<AlertProps, 'data'>; - viewMode: ViewMode; - setViewMode(mode: ViewMode): void; - extraCom?: JSX.Element | undefined; -} - -interface CommonAlertsContentProps - extends Pick<CommonAlertsContainerProps, 'dataSource' | 'extraData'> {} - -const LevelMap = { - warn: 1, - error: 2, -}; - -const CommonAlertsList: React.FC<CommonAlertsContentProps> = ({ - dataSource, - extraData, -}) => { - const _dataSource = useMemo( - () => - dataSource.slice().sort((a, b) => { - return LevelMap[b.level] - LevelMap[a.level]; - }), - [dataSource], - ); - - return ( - <Space - direction="vertical" - style={{ wordBreak: 'break-all', width: '100%' }} - > - {_dataSource.map((err, i) => { - return <Alert data={err} key={i} {...extraData} />; - })} - </Space> - ); -}; - -const CommonAlertsGroup: React.FC<CommonAlertsContentProps> = ({ - dataSource, - extraData, -}) => { - const _dataSource = useMemo(() => { - const sortedDataSource = dataSource.toSorted((a, b) => { - let sizeA = 0; - let sizeB = 0; - - if (a.type === 'package-relation') { - sizeA = sumBy(a.packages, (e) => e.targetSize.sourceSize); - } - - if (b.type === 'package-relation') { - sizeB = sumBy(b.packages, (e) => e.targetSize.sourceSize); - } - - return sizeB - sizeA; - }); - const groups = groupBy(sortedDataSource, (e) => e.code); - return values(groups); - }, [dataSource]); - - return ( - <Space - direction="vertical" - style={{ wordBreak: 'break-all', width: '100%' }} - > - <Collapse> - {_dataSource.map((el) => { - const [first] = el; - return ( - <Collapse.Panel - header={ - <Space> - <Typography.Text code strong style={{ cursor: 'pointer' }}> - {first.code} - </Typography.Text> - <Typography.Text strong> - {Rule.RuleErrorMap[first.code as keyof RuleErrorCodes] - ?.title || first.title} - </Typography.Text> - <Bdg label={'count'} value={el.length} type="error" /> - </Space> - } - key={first.code} - > - <Space direction="vertical" size={16} style={{ width: '100%' }}> - {el.map((err, i) => { - return <Alert data={err} key={i} {...extraData} />; - })} - </Space> - </Collapse.Panel> - ); - })} - </Collapse> - </Space> - ); -}; - -export const CommonAlertsContainer: React.FC<CommonAlertsContainerProps> = ({ - title, - dataSource, - extraData, - viewMode, - setViewMode, - extraCom, -}) => { - if (!dataSource.length) return null; - - return ( - <Card - title={title} - collapsable - extra={ - extraCom || ( - <Radio.Group - options={[ - { - label: ( - <Tooltip title="display by list"> - <UnorderedListOutlined /> - </Tooltip> - ), - value: ViewMode.List, - }, - { - label: ( - <Tooltip title="display by group"> - <AppstoreOutlined /> - </Tooltip> - ), - value: ViewMode.Group, - }, - ]} - value={viewMode} - optionType="button" - size="small" - onChange={(v) => { - setViewMode(v.target.value as ViewMode); - }} - /> - ) - } - > - {viewMode === ViewMode.List ? ( - <CommonAlertsList dataSource={dataSource} extraData={extraData} /> - ) : ( - <CommonAlertsGroup dataSource={dataSource} extraData={extraData} /> - )} - </Card> - ); -}; diff --git a/packages/components/src/components/Alerts/compile.tsx b/packages/components/src/components/Alerts/compile.tsx index 9ebae6d4..f6bab790 100644 --- a/packages/components/src/components/Alerts/compile.tsx +++ b/packages/components/src/components/Alerts/compile.tsx @@ -1,7 +1,11 @@ import React, { useEffect } from 'react'; import { Rule, SDK } from '@rsdoctor/types'; -import { hasViewModeFromStorage, useCompileAlertsByErrors, useViewMode } from '../../utils'; -import { CommonAlertsContainer } from './common'; +import { + hasViewModeFromStorage, + useCompileAlertsByErrors, + useViewMode, +} from '../../utils'; +import { BundleAlert } from './bundle-alert'; import { withServerAPI } from '../Manifest'; import { ViewMode } from '../../constants'; import { PackageRelationReasonsWithServer } from '../Alert/package-relation'; @@ -11,7 +15,10 @@ interface CompileAlertsProps { project: SDK.ServerAPI.InferResponseType<SDK.ServerAPI.API.GetProjectInfo>; } -const CompileAlertsBase: React.FC<CompileAlertsProps> = ({ filter, project }) => { +const CompileAlertsBase: React.FC<CompileAlertsProps> = ({ + filter, + project, +}) => { const { root: cwd, errors } = project; const compileAlerts = useCompileAlertsByErrors(errors); const { setCompileAlertsViewMode, viewMode, setViewMode } = useViewMode(); @@ -22,7 +29,8 @@ const CompileAlertsBase: React.FC<CompileAlertsProps> = ({ filter, project }) => if (!hasViewModeFromStorage()) { setViewMode( { - compileAlerts: compileAlerts.length >= 5 ? ViewMode.Group : ViewMode.List, + compileAlerts: + compileAlerts.length >= 5 ? ViewMode.Group : ViewMode.List, }, false, ); @@ -30,13 +38,16 @@ const CompileAlertsBase: React.FC<CompileAlertsProps> = ({ filter, project }) => }, []); return ( - <CommonAlertsContainer + <BundleAlert title="Compile Alerts" dataSource={dataSource} extraData={{ cwd, getPackageRelationContentComponent: (res) => ( - <PackageRelationReasonsWithServer body={{ id: res.data.id, target: res.package.target }} cwd={cwd} /> + <PackageRelationReasonsWithServer + body={{ id: res.data.id, target: res.package.target }} + cwd={cwd} + /> ), }} viewMode={viewMode.compileAlerts} diff --git a/packages/components/src/components/Alerts/list.module.scss b/packages/components/src/components/Alerts/list.module.scss new file mode 100644 index 00000000..0369844c --- /dev/null +++ b/packages/components/src/components/Alerts/list.module.scss @@ -0,0 +1,6 @@ +.description { + font-family: Roboto; + font-size: 14px; + font-weight: 400; + line-height: 16px; +} diff --git a/packages/components/src/components/Alerts/list.tsx b/packages/components/src/components/Alerts/list.tsx new file mode 100644 index 00000000..2a910328 --- /dev/null +++ b/packages/components/src/components/Alerts/list.tsx @@ -0,0 +1,26 @@ +import { Overview } from '../Overall/overview'; + +import { Rule } from '@rsdoctor/types'; + +import styles from './list.module.scss'; + +const data = [ + 'Racing car sprays burning fuel into crowd.', + 'Japanese princess to wed commoner.', + 'Australian walks 100km after outback crash.', + 'Man charged over missing wedding girl.', + 'Los Angeles battles huge wildfires.', +]; + +export const CommonList = (props: { data: Array<Rule.RuleStoreDataItem> }) => { + const { data } = props; + return ( + <Overview + style={{ + background: '#fff', + }} + description={<span className={styles.description}>aaa</span>} + icon={<span>more</span>} + /> + ); +}; diff --git a/packages/components/src/components/Overall/card.module.scss b/packages/components/src/components/Overall/card.module.scss index 825e442c..cabcc936 100644 --- a/packages/components/src/components/Overall/card.module.scss +++ b/packages/components/src/components/Overall/card.module.scss @@ -1,6 +1,6 @@ .card { width: 100%; - min-height: 334px; + padding-bottom: 10px; :global(.ant-card-body) { padding-bottom: 16px; diff --git a/packages/components/src/components/Overall/list.module.scss b/packages/components/src/components/Overall/list.module.scss index dd0d9934..0b29356a 100644 --- a/packages/components/src/components/Overall/list.module.scss +++ b/packages/components/src/components/Overall/list.module.scss @@ -2,6 +2,7 @@ :global(.ant-descriptions-item-label), :global(.ant-descriptions-item-content) { font-size: 13px; + color: #000000a6; } :global(.ant-descriptions-item) { diff --git a/packages/components/src/components/Overall/overview.module.scss b/packages/components/src/components/Overall/overview.module.scss new file mode 100644 index 00000000..b86caeb4 --- /dev/null +++ b/packages/components/src/components/Overall/overview.module.scss @@ -0,0 +1,35 @@ +:global { + .ant-tabs .ant-tabs-tab + .ant-tabs-tab { + margin-left: 7px; + } + + // .ant-collapse-content-box { + // background-color: #F6F8FA; + // } +} +.container { + width: 100%; + display: flex; + background: #f6f8fa; + align-items: center; + justify-content: space-between; + min-width: 210px; + padding: 10px 20px; + border-radius: 8px; + margin-right: 10px; + + .title { + font-family: Roboto; + font-size: 12px; + font-weight: 400; + line-height: 20px; + color: #000000a6; + } + + .description { + font-family: Roboto; + font-size: 24px; + font-weight: 500; + line-height: 32px; + } +} diff --git a/packages/components/src/components/Overall/overview.tsx b/packages/components/src/components/Overall/overview.tsx new file mode 100644 index 00000000..7c08463f --- /dev/null +++ b/packages/components/src/components/Overall/overview.tsx @@ -0,0 +1,23 @@ +import styles from './overview.module.scss'; + +interface OverviewProps { + title?: string | React.ReactNode; + description?: string | React.ReactNode; + icon?: React.ReactNode; + style?: React.CSSProperties; +} + +export const Overview = (props: OverviewProps) => { + const { title, description, icon, style } = props; + return ( + <div className={styles.container} style={style}> + <div> + <div className={styles.title}>{title}</div> + <div className={styles.description}>{description}</div> + </div> + {icon} + </div> + ); +}; + +export default Overview; diff --git a/packages/components/src/components/Overall/project.module.scss b/packages/components/src/components/Overall/project.module.scss new file mode 100644 index 00000000..b54d67bb --- /dev/null +++ b/packages/components/src/components/Overall/project.module.scss @@ -0,0 +1,4 @@ +.overview { + display: flex; + margin-bottom: 20px; +} diff --git a/packages/components/src/components/Overall/project.tsx b/packages/components/src/components/Overall/project.tsx index a8fde67a..e772ab5c 100644 --- a/packages/components/src/components/Overall/project.tsx +++ b/packages/components/src/components/Overall/project.tsx @@ -1,17 +1,23 @@ -import { Space, Row, Col, Descriptions, DescriptionsProps } from 'antd'; -import React from 'react'; +import { Descriptions, DescriptionsProps, Avatar } from 'antd'; +import { + CloseCircleFilled, + WarningFilled, + FileFilled, + ExperimentFilled, +} from '@ant-design/icons'; import { filter } from 'lodash-es'; -import { SDK } from '@rsdoctor/types'; -import { useI18n } from '../../utils'; + +import { ServerAPIProvider } from '../Manifest'; +import { useI18n, formatSize } from '../../utils'; import { WebpackConfigurationViewer } from '../Configuration'; import { Card } from '../Card'; +import { Overview } from './overview'; import listStyles from './list.module.scss'; import cardStyles from './card.module.scss'; -import numberButtonStyles from './NumberButton.module.scss'; -import { TextDrawer } from '../TextDrawer'; -import { BundleAlerts, CompileAlerts, OverlayAlertsWithTips } from '../Alerts'; -import { NumberButton } from './NumberButton'; +import projectStyles from './project.module.scss'; + +import { SDK } from '@rsdoctor/types'; export const ProjectOverall: React.FC<{ configs: SDK.ConfigData; @@ -53,34 +59,88 @@ export const ProjectOverall: React.FC<{ ]; return ( - <Card title={t('Project Overall')} extra={<WebpackConfigurationViewer />} className={cardStyles.card}> - <Row gutter={16}> - <Col span={12} className={numberButtonStyles.container}> - <TextDrawer - button={<NumberButton theme={errors === 0 ? 'success' : 'error'} number={errors} description="Errors" />} - drawerProps={{ title: 'Errors List' }} - > - <Space direction="vertical" style={{ width: '100%' }}> - <OverlayAlertsWithTips defaultOpen={false} /> - <BundleAlerts filter={(r) => r.level === 'error'} /> - <CompileAlerts filter={(r) => r.level === 'error'} /> - </Space> - </TextDrawer> - </Col> - <Col span={12} className={numberButtonStyles.container}> - <TextDrawer - button={<NumberButton theme={warns === 0 ? 'success' : 'warning'} number={warns} description="Warnings" />} - drawerProps={{ title: 'Warnings List' }} + <ServerAPIProvider + api={SDK.ServerAPI.API.GetAssetsSummary} + body={{ withFileContent: false }} + > + {(res) => { + const totalSizeStr = formatSize(res.all.total.size); + const totalFiles = res.all.total.count; + const [size, unit] = totalSizeStr.split(' '); + const overViewData = [ + { + title: 'Errors', + description: <span style={{ color: '#FF4D4F' }}>{errors}</span>, + icon: ( + <Avatar + style={{ background: '#FF4D4F' }} + shape="circle" + icon={<CloseCircleFilled style={{ fontSize: '18px' }} />} + /> + ), + }, + { + title: 'Warnings', + description: <span style={{ color: '#FAAD14' }}>{warns}</span>, + icon: ( + <Avatar + style={{ background: '#FAAD14' }} + shape="circle" + icon={<WarningFilled style={{ fontSize: '18px' }} />} + /> + ), + }, + { + title: 'Total Files', + description: <span>{totalFiles}</span>, + icon: ( + <Avatar + style={{ background: '#3874F6' }} + shape="circle" + icon={<FileFilled style={{ fontSize: '18px' }} />} + /> + ), + }, + { + title: 'Total Size', + description: ( + <> + <span style={{ fontSize: '20px' }}>{size}</span> + <span style={{ fontSize: '13px', marginLeft: '5px' }}> + {unit} + </span> + </> + ), + icon: ( + <Avatar + style={{ background: '#FF4D4F' }} + shape="circle" + icon={<ExperimentFilled style={{ fontSize: '18px' }} />} + /> + ), + }, + ]; + + return ( + <Card + title={t('Project Overall')} + extra={<WebpackConfigurationViewer />} + className={cardStyles.card} > - <Space direction="vertical" style={{ width: '100%' }}> - <OverlayAlertsWithTips defaultOpen={false} /> - <BundleAlerts filter={(r) => r.level === 'warn'} /> - <CompileAlerts filter={(r) => r.level === 'warn'} /> - </Space> - </TextDrawer> - </Col> - </Row> - <Descriptions className={listStyles.root} items={items} size="small" column={1} /> - </Card> + <div className={projectStyles.overview}> + {overViewData.map((data, idx) => ( + <Overview + key={idx} + title={data.title} + description={<span>{data.description}</span>} + icon={data.icon} + /> + ))} + </div> + <Descriptions className={listStyles.root} items={items} /> + </Card> + ); + }} + </ServerAPIProvider> ); };