diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Detail.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Detail.tsx index 0a10f169e..f436e1e13 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Detail.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Detail.tsx @@ -1,6 +1,6 @@ import { message } from 'antd'; import React, { useState, useEffect } from 'react'; -import { getMetricData } from '../service'; +import { getMetricData, getDimensionList, getDrillDownDimension } from '../service'; import { connect, useParams } from 'umi'; import type { StateType } from '../model'; import styles from './style.less'; @@ -9,29 +9,21 @@ import { ISemantic } from '../data'; import DimensionAndMetricRelationModal from '../components/DimensionAndMetricRelationModal'; import MetricInfoSider from './MetricInfoSider'; -type Props = { - metircData: any; - domainManger: StateType; - onNodeChange: (params?: { eventName?: string }) => void; - onEditBtnClick?: (metircData: any) => void; - [key: string]: any; -}; +type Props = Record; -const siderStyle: React.CSSProperties = { - backgroundColor: '#fff', - width: 450, - minHeight: '100vh', - boxShadow: - '6px 0 16px 0 rgba(0, 0, 0, 0.08), 3px 0 6px -4px rgba(0, 0, 0, 0.12), 9px 0 28px 8px rgba(0, 0, 0, 0.05)', -}; - -const MetricDetail: React.FC = ({ domainManger }) => { +const MetricDetail: React.FC = () => { const params: any = useParams(); const metricId = params.metricId; const [metricRelationModalOpenState, setMetricRelationModalOpenState] = useState(false); const [metircData, setMetircData] = useState(); + const [dimensionList, setDimensionList] = useState([]); + const [relationDimensionOptions, setRelationDimensionOptions] = useState< + { value: string; label: string; modelId: number }[] + >([]); + useEffect(() => { queryMetricData(metricId); + queryDrillDownDimension(metricId); }, [metricId]); const queryMetricData = async (metricId: string) => { @@ -43,15 +35,56 @@ const MetricDetail: React.FC = ({ domainManger }) => { message.error(msg); }; + const queryDrillDownDimension = async (metricId: number) => { + const { code, data, msg } = await getDrillDownDimension(metricId); + if (code === 200 && Array.isArray(data)) { + const ids = data.map((item) => item.dimensionId); + queryDimensionList(ids); + return data; + } else { + setDimensionList([]); + setRelationDimensionOptions([]); + } + if (code !== 200) { + message.error(msg); + } + return []; + }; + + const queryDimensionList = async (ids: number[]) => { + if (!(Array.isArray(ids) && ids.length > 0)) { + setRelationDimensionOptions([]); + return; + } + const { code, data, msg } = await getDimensionList({ ids }); + if (code === 200 && Array.isArray(data?.list)) { + setDimensionList(data.list); + setRelationDimensionOptions( + data.list.map((item: ISemantic.IMetricItem) => { + return { label: item.name, value: item.bizName, modelId: item.modelId }; + }), + ); + return data.list; + } + message.error(msg); + return []; + }; + return ( <>
- +
-
+
{ setMetricRelationModalOpenState(true); }} @@ -68,6 +101,7 @@ const MetricDetail: React.FC = ({ domainManger }) => { }} onSubmit={(relations) => { queryMetricData(metricId); + queryDrillDownDimension(metricId); setMetricRelationModalOpenState(false); }} /> diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Market.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Market.tsx index f43952892..57318e441 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Market.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/Market.tsx @@ -310,14 +310,16 @@ const ClassMetricTable: React.FC = ({ domainManger, dispatch }) => { const handleFilterChange = async (filterParams: { key: string; - sensitiveLevel: string; + sensitiveLevel: string[]; + showFilter: string[]; type: string; }) => { - const { sensitiveLevel, type } = filterParams; + const { sensitiveLevel, type, showFilter } = filterParams; const params: QueryMetricListParams = { ...filterParams }; const sensitiveLevelValue = sensitiveLevel?.[0]; + const showFilterValue = showFilter?.[0]; const typeValue = type?.[0]; - + showFilterValue ? (params[showFilterValue] = true) : null; params.sensitiveLevel = sensitiveLevelValue; params.type = typeValue; setFilterParams(params); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/MetricInfoSider.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/MetricInfoSider.tsx index 63c7b8f28..81d71110a 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/MetricInfoSider.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/MetricInfoSider.tsx @@ -1,15 +1,16 @@ -import { message, Tag, Space, Tooltip } from 'antd'; -import React, { useState, useEffect, ReactNode } from 'react'; -import { getMetricData } from '../service'; -import { connect, useParams } from 'umi'; +import { Tag, Space, Tooltip } from 'antd'; +import React from 'react'; +import { connect } from 'umi'; import type { StateType } from '../model'; +import { isArrayOfValues } from '@/utils/utils'; import dayjs from 'dayjs'; import { ExportOutlined, SolutionOutlined, ContainerOutlined, PartitionOutlined, - FallOutlined, + PlusOutlined, + AreaChartOutlined, DeleteOutlined, } from '@ant-design/icons'; import styles from './style.less'; @@ -18,38 +19,26 @@ import { ISemantic } from '../data'; import MetricStar from './components/MetricStar'; type Props = { - metircData: any; + metircData: ISemantic.IMetricItem; domainManger: StateType; + relationDimensionOptions: { value: string; label: string; modelId: number }[]; onNodeChange: (params?: { eventName?: string }) => void; onEditBtnClick?: (metircData: any) => void; onDimensionRelationBtnClick?: () => void; [key: string]: any; }; -const MetricInfoSider: React.FC = ({ onDimensionRelationBtnClick }) => { - const params: any = useParams(); - const metricId = params.metricId; - - const [metircData, setMetircData] = useState(); - useEffect(() => { - queryMetricData(metricId); - }, [metricId]); - - const queryMetricData = async (metricId: string) => { - const { code, data, msg } = await getMetricData(metricId); - if (code === 200) { - setMetircData(data); - return; - } - message.error(msg); - }; - +const MetricInfoSider: React.FC = ({ + metircData, + relationDimensionOptions, + onDimensionRelationBtnClick, +}) => { return (
- + {metircData?.name} {metircData?.alias && `[${metircData.alias}]`} {metircData?.hasAdminRes && ( @@ -64,20 +53,13 @@ const MetricInfoSider: React.FC = ({ onDimensionRelationBtnClick }) => { )} - - {metircData?.sensitiveLevel !== undefined && ( - - - {SENSITIVE_LEVEL_ENUM[metircData.sensitiveLevel]} - - - )}
{metircData?.bizName &&
{metircData.bizName}
}
+
@@ -88,6 +70,19 @@ const MetricInfoSider: React.FC = ({ onDimensionRelationBtnClick }) => {
+
+ 敏感度: + + {metircData?.sensitiveLevel !== undefined && ( + + + {SENSITIVE_LEVEL_ENUM[metircData.sensitiveLevel]} + + + )} + +
+
所属模型: @@ -115,7 +110,7 @@ const MetricInfoSider: React.FC = ({ onDimensionRelationBtnClick }) => { {metircData?.description}
- +
@@ -148,22 +143,61 @@ const MetricInfoSider: React.FC = ({ onDimensionRelationBtnClick }) => {

+ +
+
+ + + + 应用信息 + + +
+ + {isArrayOfValues(metircData?.tags) && ( +
+ 标签: + + + {metircData?.tags.map((tag) => ( + + {tag} + + ))} + + +
+ )} +
+
    -
  • { - onDimensionRelationBtnClick?.(); - }} - > - + +
  • { + onDimensionRelationBtnClick?.(); + }} + > +
    下钻维度
    - + - 下钻维度配置
    - -
  • + {isArrayOfValues(relationDimensionOptions) && ( +
    + + {relationDimensionOptions.map((item) => ( + + {item.label} + + ))} + +
    + )} + + {/*
  • { onDimensionRelationBtnClick?.(); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricFilter.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricFilter.tsx index 22429fc51..4b29065e8 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricFilter.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricFilter.tsx @@ -33,6 +33,20 @@ const MetricFilter: React.FC = ({ initFilterValues = {}, onFiltersChange }; const filterList = [ + { + title: '展示类型', + key: 'showFilter', + options: [ + { + label: '我创建的', + value: 'onlyShowMe', + }, + { + label: '我收藏的', + value: 'hasCollect', + }, + ], + }, { title: '敏感度', key: 'sensitiveLevel', @@ -89,16 +103,12 @@ const MetricFilter: React.FC = ({ initFilterValues = {}, onFiltersChange - + {/* - - - - - - + */} + {filterList.map((item) => { const { title, key, options } = item; return ( @@ -115,6 +125,11 @@ const MetricFilter: React.FC = ({ initFilterValues = {}, onFiltersChange ); })} + + + + + ); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricStar.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricStar.tsx index 36c241618..36d6eed9a 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricStar.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricStar.tsx @@ -1,5 +1,5 @@ import { Tooltip, message } from 'antd'; -import React, { useState } from 'react'; +import React, { useState, useEffect } from 'react'; import { metricStarState } from '../../service'; import MStar from '@/components/MStar'; @@ -11,6 +11,9 @@ type Props = { const MetricStar: React.FC = ({ metricId, initState = false }) => { const [star, setStar] = useState(initState); + useEffect(() => { + setStar(initState); + }, [initState]); const starStateChange = async (id: number, state: boolean) => { const { code, msg } = await metricStarState({ id, state }); diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricTrendSection.tsx b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricTrendSection.tsx index 63171a6e9..da4be049e 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricTrendSection.tsx +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/components/MetricTrendSection.tsx @@ -1,12 +1,7 @@ import React, { useState, useEffect, useRef } from 'react'; -import { message, Row, Col, Button, Space, Select, Form, Tooltip, Radio } from 'antd'; -import { - queryStruct, - getDrillDownDimension, - getDimensionList, -} from '@/pages/SemanticModel/service'; -import { InfoCircleOutlined, DownloadOutlined, PoweroffOutlined } from '@ant-design/icons'; -import DimensionAndMetricRelationModal from '../../components/DimensionAndMetricRelationModal'; +import { message, Row, Col, Button, Space, Select, Form, Tooltip } from 'antd'; +import { queryStruct } from '@/pages/SemanticModel/service'; +import { DownloadOutlined, PoweroffOutlined, ArrowLeftOutlined } from '@ant-design/icons'; import TrendChart from '@/pages/SemanticModel/Metric/components/MetricTrend'; import MetricTrendDimensionFilterContainer from './MetricTrendDimensionFilterContainer'; import MDatePicker from '@/components/MDatePicker'; @@ -16,6 +11,7 @@ import StandardFormRow from '@/components/StandardFormRow'; import MetricTable from './Table'; import { ColumnConfig } from '../data'; import dayjs from 'dayjs'; +import { history } from 'umi'; import { ISemantic } from '../../data'; import { DateFieldMap } from '@/pages/SemanticModel/constant'; import ProCard from '@ant-design/pro-card'; @@ -25,28 +21,25 @@ import styles from '../style.less'; const FormItem = Form.Item; type Props = { + relationDimensionOptions: { value: string; label: string; modelId: number }[]; + dimensionList: ISemantic.IDimensionItem[]; metircData?: ISemantic.IMetricItem; [key: string]: any; }; -const MetricTrendSection: React.FC = ({ metircData }) => { +const MetricTrendSection: React.FC = ({ + metircData, + relationDimensionOptions, + dimensionList, +}) => { const indicatorFields = useRef<{ name: string; column: string }[]>([]); const [metricTrendData, setMetricTrendData] = useState([]); const [metricTrendLoading, setMetricTrendLoading] = useState(false); const [metricColumnConfig, setMetricColumnConfig] = useState(); - const [metricRelationModalOpenState, setMetricRelationModalOpenState] = useState(false); - const [drillDownDimensions, setDrillDownDimensions] = useState< - ISemantic.IDrillDownDimensionItem[] - >(metircData?.relateDimension?.drillDownDimensions || []); const [authMessage, setAuthMessage] = useState(''); const [downloadLoding, setDownloadLoding] = useState(false); - const [relationDimensionOptions, setRelationDimensionOptions] = useState< - { value: string; label: string; modelId: number }[] - >([]); - const [dimensionList, setDimensionList] = useState([]); const [queryParams, setQueryParams] = useState({}); const [downloadBtnDisabledState, setDownloadBtnDisabledState] = useState(true); - // const [showDimensionOptions, setShowDimensionOptions] = useState([]); const [periodDate, setPeriodDate] = useState<{ startDate: string; endDate: string; @@ -57,7 +50,7 @@ const MetricTrendSection: React.FC = ({ metircData }) => { dateField: DateFieldMap[DateRangeType.DAY], }); const [rowNumber, setRowNumber] = useState(5); - const [chartType, setChartType] = useState<'chart' | 'table'>('chart'); + const [tableColumnConfig, setTableColumnConfig] = useState([]); const [transformState, setTransformState] = useState(false); @@ -138,60 +131,19 @@ const MetricTrendSection: React.FC = ({ metircData }) => { } }; - const queryDimensionList = async (ids: number[]) => { - if (!(Array.isArray(ids) && ids.length > 0)) { - return; - } - const { code, data, msg } = await getDimensionList({ ids }); - if (code === 200 && Array.isArray(data?.list)) { - setDimensionList(data.list); - setRelationDimensionOptions( - data.list.map((item: ISemantic.IMetricItem) => { - return { label: item.name, value: item.bizName, modelId: item.modelId }; - }), - ); - return data.list; - } - message.error(msg); - return []; - }; - - const queryDrillDownDimension = async (metricId: number) => { - const { code, data, msg } = await getDrillDownDimension(metricId); - if (code === 200 && Array.isArray(data)) { - const ids = data.map((item) => item.dimensionId); - queryDimensionList(ids); - return data; - } else { - setDimensionList([]); - setRelationDimensionOptions([]); - } - if (code !== 200) { - message.error(msg); - } - return []; - }; - - const initDimensionData = async (metricItem: ISemantic.IMetricItem) => { - await queryDrillDownDimension(metricItem.id); - }; - useEffect(() => { if (metircData?.id) { getMetricTrendData({ ...queryParams }); - initDimensionData(metircData); - setDrillDownDimensions(metircData?.relateDimension?.drillDownDimensions || []); } }, [metircData, periodDate]); return (
    - +
    { if (value.key) { @@ -269,6 +221,27 @@ const MetricTrendSection: React.FC = ({ metircData }) => { + + {/*
    + +
    */}
    {authMessage &&
    {authMessage}
    }
    @@ -292,7 +265,7 @@ const MetricTrendSection: React.FC = ({ metircData }) => { loading={metricTrendLoading} dateFieldName={periodDate.dateField} groupByDimensionFieldName={groupByDimensionFieldName} - height={400} + height={350} renderType="clear" decimalPlaces={metricColumnConfig?.dataFormat?.decimalPlaces || 2} /> @@ -302,7 +275,7 @@ const MetricTrendSection: React.FC = ({ metircData }) => {
    @@ -345,20 +318,6 @@ const MetricTrendSection: React.FC = ({ metircData }) => {
    - - { - setMetricRelationModalOpenState(false); - }} - onSubmit={(relations) => { - setDrillDownDimensions(relations); - setMetricRelationModalOpenState(false); - initDimensionData(metircData!); - }} - />
    ); }; diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/style.less b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/style.less index 906ac0477..5afd18ee9 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/style.less +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/Metric/style.less @@ -2,6 +2,7 @@ margin: 20px; padding: 20px; border-radius: 10px; + padding-bottom: 5px; background: #fff; } @@ -154,18 +155,27 @@ } } } + .siderContainer { + background-color: rgb(255, 255, 255); + width: 450px; + min-height: 100vh; + margin: 20px 20px 20px 0; + border-radius: 6px; + box-shadow: rgba(0, 0, 0, 0.08) 6px 0px 16px 0px, rgba(0, 0, 0, 0.12) 3px 0px 6px -4px, rgba(0, 0, 0, 0.05) 9px 0px 28px 8px; + } } } .metricTrendSection { .sectionBox { margin: 20px; - padding: 20px; + padding: 10px; box-shadow: #888888 0px 0px 1px, rgba(29, 41, 57, 0.08) 0px 1px 3px; background-color: rgb(255, 255, 255); transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; border-radius: 6px; background-image: none; overflow: hidden; + position: relative; } } @@ -198,10 +208,22 @@ display: block; color: #7b809a; } + .subTitle { + margin: 0px; + font-size: 14px; + line-height: 1.25; + letter-spacing: 0.03333em; + opacity: 1; + text-transform: uppercase; + vertical-align: unset; + text-decoration: none; + color: rgb(123, 128, 154); + font-weight: 700; + } .sectionContainer{ - transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; + // transition: box-shadow 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms; border-radius: 6px; - box-shadow: #888888 0px 0px 1px, rgba(29, 41, 57, 0.08) 0px 1px 3px; + // box-shadow: #888888 0px 0px 1px, rgba(29, 41, 57, 0.08) 0px 1px 3px; background-image: none; margin-top: 20px; overflow: hidden; @@ -231,19 +253,7 @@ font-weight: 600; } } - .subTitle { - margin: 0px; - font-family: Roboto, Helvetica, Arial, sans-serif; - font-size: 14px; - line-height: 1.25; - letter-spacing: 0.03333em; - opacity: 1; - text-transform: uppercase; - vertical-align: unset; - text-decoration: none; - color: rgb(123, 128, 154); - font-weight: 700; - } + .item { display: flex; padding-top: 8px; @@ -284,7 +294,7 @@ .hr { margin: 0px; flex-shrink: 0; - border-width: 0px 0px thin; + // border-width: 0px 0px thin; border-style: solid; border-color: rgb(242, 244, 247); } @@ -329,7 +339,7 @@ } .ctrlItemIcon { flex-shrink: 0; - font-size: 16px; + font-size: 14px; margin-right: 5px; min-width: unset; } diff --git a/webapp/packages/supersonic-fe/src/pages/SemanticModel/data.d.ts b/webapp/packages/supersonic-fe/src/pages/SemanticModel/data.d.ts index 3d2855621..c5f933a60 100644 --- a/webapp/packages/supersonic-fe/src/pages/SemanticModel/data.d.ts +++ b/webapp/packages/supersonic-fe/src/pages/SemanticModel/data.d.ts @@ -200,6 +200,7 @@ export declare namespace ISemantic { modelId: number; hasAdminRes: boolean; type: string; + tags: string[]; typeParams: ITypeParams; fullPath: string; dataFormatType: string; diff --git a/webapp/packages/supersonic-fe/src/utils/utils.ts b/webapp/packages/supersonic-fe/src/utils/utils.ts index 1be12f5d3..2ac4819eb 100644 --- a/webapp/packages/supersonic-fe/src/utils/utils.ts +++ b/webapp/packages/supersonic-fe/src/utils/utils.ts @@ -434,3 +434,10 @@ export function traverseRoutes(routes, env: string, result: any[] = []) { export function isProd() { return process.env.NODE_ENV === 'production'; } + +export function isArrayOfValues(array: any) { + if (array && Array.isArray(array) && array.length > 0) { + return true; + } + return false; +}