From 2b4a750685c2f53de4942cacca91d4aeaf1e8ce8 Mon Sep 17 00:00:00 2001 From: laixingyou Date: Wed, 8 May 2024 11:29:08 +0800 Subject: [PATCH 1/6] Feat: add bot filter Signed-off-by: laixingyou --- .../src/common/components/Table/Download.tsx | 12 +- .../ContributorContribution.tsx | 24 ++-- .../ContributorOrganizations.tsx | 6 +- .../index.tsx} | 8 +- .../ContributorTable/index.tsx | 16 +-- .../MetricContributor/Contributors.tsx | 6 +- .../MetricDetail/MetricContributor/index.tsx | 122 ++++++++++-------- .../MetricDetail/MetricIssue/IssueTable.tsx | 2 +- .../MetricDetail/MetricIssue/index.tsx | 19 ++- .../MetricDetail/MetricPr/PrTable.tsx | 2 +- .../DataView/MetricDetail/MetricPr/index.tsx | 18 ++- .../MetricDetail/DetailHeaderFilter.tsx | 54 ++++++++ apps/web/src/styles/antd.scss | 11 +- 13 files changed, 192 insertions(+), 108 deletions(-) rename apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/{ => ContributionCount}/ContributorContribution.tsx (95%) rename apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/{ => ContributionCount}/ContributorOrganizations.tsx (96%) rename apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/{ContributionCount.tsx => ContributionCount/index.tsx} (78%) create mode 100644 apps/web/src/modules/analyze/components/MetricDetail/DetailHeaderFilter.tsx diff --git a/apps/web/src/common/components/Table/Download.tsx b/apps/web/src/common/components/Table/Download.tsx index f8b9e4d7..aa9db11b 100644 --- a/apps/web/src/common/components/Table/Download.tsx +++ b/apps/web/src/common/components/Table/Download.tsx @@ -7,6 +7,7 @@ import { apiDownloadFiles, Status, } from '@modules/analyze/DataView/MetricDetail/tableDownload'; +import { useTranslation } from 'react-i18next'; // 对象驼峰转下划线 const objectHumpToLine = (obj) => { @@ -27,6 +28,7 @@ const Download = ({ query: any; fileName: string; }) => { + const { t } = useTranslation(); const newQuery = objectHumpToLine(query); newQuery['sort_opts'] && (newQuery['sort_opts'] = [newQuery['sort_opts']]); @@ -66,9 +68,12 @@ const Download = ({ }; return ( <> -
+
{loadingDownLoad ? ( - + <> + + {t('analyze:metric_detail.download_data')} + ) : (
- + + {t('analyze:metric_detail.download_data')}
)} diff --git a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributorContribution.tsx b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributionCount/ContributorContribution.tsx similarity index 95% rename from apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributorContribution.tsx rename to apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributionCount/ContributorContribution.tsx index 74a9c16e..c570cc59 100644 --- a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributorContribution.tsx +++ b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributionCount/ContributorContribution.tsx @@ -6,9 +6,9 @@ import { import client from '@common/gqlClient'; import { useTranslation } from 'next-i18next'; import MetricChart from '@modules/analyze/DataView/MetricDetail/MetricChart'; -import { useGetEcologicalText } from './contribution'; +import { useGetEcologicalText } from '../contribution'; import { gradientRamp } from '@common/options'; -import PieDropDownMenu from '../PieDropDownMenu'; +import PieDropDownMenu from '../../PieDropDownMenu'; import type { EChartsOption } from 'echarts'; const ContributorContribution: React.FC<{ @@ -16,8 +16,8 @@ const ContributorContribution: React.FC<{ level: string; beginDate: Date; endDate: Date; - mileage: string[]; -}> = ({ label, level, beginDate, endDate, mileage }) => { + commonFilterOpts: any[]; +}> = ({ label, level, beginDate, endDate, commonFilterOpts }) => { const [orgModel, setOrgModel] = useState(true); const [onlyIdentity, setOnlyIdentity] = useState(false); const [onlyOrg, setOnlyOrg] = useState(false); @@ -59,7 +59,7 @@ const ContributorContribution: React.FC<{ level={level} beginDate={beginDate} endDate={endDate} - mileage={mileage} + commonFilterOpts={commonFilterOpts} /> ) : ( { @@ -301,8 +301,8 @@ const OrgContributorContribution: React.FC<{ level: string; beginDate: Date; endDate: Date; - mileage: string[]; -}> = ({ label, level, beginDate, endDate, mileage }) => { + commonFilterOpts: any[]; +}> = ({ label, level, beginDate, endDate, commonFilterOpts }) => { const { t } = useTranslation(); const chartRef = useRef(null); const { data, isLoading } = useOrgContributionDistributionQuery(client, { @@ -310,7 +310,7 @@ const OrgContributorContribution: React.FC<{ level: level, beginDate: beginDate, endDate: endDate, - filterOpts: [{ type: 'mileage_type', values: mileage }], + filterOpts: commonFilterOpts, }); const getEcologicalText = useGetEcologicalText(); const getSeries = useMemo(() => { diff --git a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributorOrganizations.tsx b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributionCount/ContributorOrganizations.tsx similarity index 96% rename from apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributorOrganizations.tsx rename to apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributionCount/ContributorOrganizations.tsx index 25bd0634..74fe031c 100644 --- a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributorOrganizations.tsx +++ b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributionCount/ContributorOrganizations.tsx @@ -11,8 +11,8 @@ const ContributorContribution: React.FC<{ level: string; beginDate: Date; endDate: Date; - mileage: string[]; -}> = ({ label, level, beginDate, endDate, mileage }) => { + commonFilterOpts: any[]; +}> = ({ label, level, beginDate, endDate, commonFilterOpts }) => { const { t } = useTranslation(); const chartRef = useRef(null); const { data, isLoading } = useOrgContributorsOverviewQuery(client, { @@ -20,7 +20,7 @@ const ContributorContribution: React.FC<{ level: level, beginDate: beginDate, endDate: endDate, - filterOpts: [{ type: 'mileage_type', values: mileage }], + filterOpts: commonFilterOpts, }); const getSeries = useMemo(() => { const legend = []; diff --git a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributionCount.tsx b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributionCount/index.tsx similarity index 78% rename from apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributionCount.tsx rename to apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributionCount/index.tsx index d110a11f..8368b97b 100644 --- a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributionCount.tsx +++ b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributionCount/index.tsx @@ -7,8 +7,8 @@ const ContributionCount: React.FC<{ level: string; beginDate: Date; endDate: Date; - mileage: string[]; -}> = ({ label, level, beginDate, endDate, mileage }) => { + commonFilterOpts: any[]; +}> = ({ label, level, beginDate, endDate, commonFilterOpts }) => { return (
); diff --git a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributorTable/index.tsx b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributorTable/index.tsx index be31845d..ebaffc77 100644 --- a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributorTable/index.tsx +++ b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/ContributorTable/index.tsx @@ -49,8 +49,8 @@ const MetricTable: React.FC<{ level: string; beginDate: Date; endDate: Date; - mileage: string[]; -}> = ({ label, level, beginDate, endDate, mileage }) => { + commonFilterOpts: any[]; +}> = ({ label, level, beginDate, endDate, commonFilterOpts }) => { const { t } = useTranslation(); const [openConfirm, setOpenConfirm] = useState(false); const [currentName, setCurrentName] = useState(''); @@ -68,14 +68,6 @@ const MetricTable: React.FC<{ const router = useRouter(); const { handleQueryParams } = useHandleQueryParams(); - const mileageFilter = useMemo(() => { - if (mileage.length > 0) { - return { type: 'mileage_type', values: mileage }; - } else { - return null; - } - }, [mileage]); - const queryFilterOpts = router.query?.filterOpts as string; const defaultFilterOpts = queryFilterOpts ? JSON.parse(queryFilterOpts) : []; const defaultSortOpts = router.query?.sortOpts @@ -101,7 +93,7 @@ const MetricTable: React.FC<{ const query = { page: tableParams.pagination.current, per: tableParams.pagination.pageSize, - filterOpts: [...filterOpts, mileageFilter], + filterOpts: [...filterOpts, ...commonFilterOpts], sortOpts: tableParams.sortOpts, label, level, @@ -330,7 +322,7 @@ const MetricTable: React.FC<{ ]; return ( <> -
+
= ({ label, level, beginDate, endDate, mileage }) => { + commonFilterOpts: any[]; +}> = ({ label, level, beginDate, endDate, commonFilterOpts }) => { const { t } = useTranslation(); const getEcologicalText = useGetEcologicalText(); const chartRef = useRef(null); @@ -137,7 +137,7 @@ const ContributorContributors: React.FC<{ level: level, beginDate: beginDate, endDate: endDate, - filterOpts: [{ type: 'mileage_type', values: mileage }], + filterOpts: commonFilterOpts, }); const getSeries = useMemo(() => { diff --git a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/index.tsx b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/index.tsx index 958a5388..2d33a641 100644 --- a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/index.tsx +++ b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/index.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { useState, useMemo } from 'react'; import Tabs from '@mui/material/Tabs'; import Tab from '@mui/material/Tab'; import useVerifyDateRange from '../useVerifyDateRange'; @@ -11,9 +11,9 @@ import ContributorContributors from './Contributors'; import { AiOutlineQuestionCircle } from 'react-icons/ai'; import Tooltip from '@common/components/Tooltip'; import useLabelStatus from '@modules/analyze/hooks/useLabelStatus'; -import BaseCard from '@common/components/BaseCard'; import { useRouter } from 'next/router'; import { useHandleQueryParams } from '@modules/analyze/hooks/useHandleQueryParams'; +import DetailHeaderFilter from '@modules/analyze/components/MetricDetail/DetailHeaderFilter'; const MetricContributor = () => { const { t } = useTranslation(); @@ -30,10 +30,21 @@ const MetricContributor = () => { ? JSON.parse(queryMileage) : ['core', 'regular']; const [mileage, setMileage] = useState(defaultMileage); - const onChange = (checkedValues: string[]) => { + const [isBot, setIsBot] = useState(true); + const onMileageChange = (checkedValues: string[]) => { setMileage(checkedValues); handleQueryParams({ mileage: JSON.stringify(checkedValues) }); }; + const commonFilterOpts = useMemo(() => { + let opts = []; + if (mileage.length > 0) { + opts.push({ type: 'mileage_type', values: mileage }); + } + if (!isBot) { + opts.push({ type: 'is_bot', values: [String(isBot)] }); + } + return opts; + }, [mileage, isBot]); let source; switch (tab) { case '1': { @@ -43,7 +54,7 @@ const MetricContributor = () => { level={level} beginDate={timeStart} endDate={timeEnd} - mileage={mileage} + commonFilterOpts={commonFilterOpts} /> ); break; @@ -55,7 +66,7 @@ const MetricContributor = () => { level={level} beginDate={timeStart} endDate={timeEnd} - mileage={mileage} + commonFilterOpts={commonFilterOpts} /> ); break; @@ -67,7 +78,7 @@ const MetricContributor = () => { level={level} beginDate={timeStart} endDate={timeEnd} - mileage={mileage} + commonFilterOpts={commonFilterOpts} /> ); break; @@ -79,58 +90,24 @@ const MetricContributor = () => { level={level} beginDate={timeStart} endDate={timeEnd} - mileage={mileage} + commonFilterOpts={commonFilterOpts} /> ); break; } } return ( - -
-
- { - setTab(v); - handleQueryParams({ card: v }); - }} - aria-label="Tabs where selection follows focus" - selectionFollowsFocus - > - - - - -
- -
+
+ setIsBot(v)} + /> +
{t('analyze:metric_detail:milestone_persona_filter')} {
+
+
+
+ { + setTab(v); + handleQueryParams({ card: v }); + }} + aria-label="Tabs where selection follows focus" + selectionFollowsFocus + > + + + + +
{source}
- +
); }; diff --git a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricIssue/IssueTable.tsx b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricIssue/IssueTable.tsx index d3b9b699..0f97426a 100644 --- a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricIssue/IssueTable.tsx +++ b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricIssue/IssueTable.tsx @@ -187,7 +187,7 @@ const MetricTable: React.FC<{ ]; return ( <> -
+
{ const router = useRouter(); @@ -19,7 +19,12 @@ const MetricIssue = () => { const { label, level } = verifiedItems[0]; const { t } = useTranslation(); const queryCard = router.query?.card as string; + const [isBot, setIsBot] = useState(true); const [tab, setTab] = useState(queryCard || '1'); + const commonFilterOpts = useMemo(() => { + let opts = []; + return opts; + }, [isBot]); let source; switch (tab) { case '1': { @@ -68,11 +73,11 @@ const MetricIssue = () => { } } return ( - + {
{source}
-
+
); }; diff --git a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricPr/PrTable.tsx b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricPr/PrTable.tsx index 824b437d..9bac7089 100644 --- a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricPr/PrTable.tsx +++ b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricPr/PrTable.tsx @@ -194,7 +194,7 @@ const MetricTable: React.FC<{ ]; return ( <> -
+
{ const { t } = useTranslation(); @@ -20,6 +20,10 @@ const MetricPr = () => { const queryCard = router.query?.card as string; const [tab, setTab] = useState(queryCard || '1'); const { timeStart, timeEnd } = useVerifyDateRange(); + const commonFilterOpts = useMemo(() => { + let opts = []; + return opts; + }, []); let source; switch (tab) { case '1': { @@ -68,11 +72,11 @@ const MetricPr = () => { } } return ( - + { />
{source}
-
+
); }; diff --git a/apps/web/src/modules/analyze/components/MetricDetail/DetailHeaderFilter.tsx b/apps/web/src/modules/analyze/components/MetricDetail/DetailHeaderFilter.tsx new file mode 100644 index 00000000..db88a2a1 --- /dev/null +++ b/apps/web/src/modules/analyze/components/MetricDetail/DetailHeaderFilter.tsx @@ -0,0 +1,54 @@ +import React, { useState } from 'react'; +import { Select } from 'antd'; +import { useTranslation } from 'next-i18next'; + +const DetailHeaderFilter: React.FC<{ + type: string; + isBot?: boolean; + onBotChange?: (v) => void; +}> = ({ type, isBot, onBotChange }) => { + const { t } = useTranslation(); + + const isBotOptions = [ + { + label: t('analyze:metric_detail:include_robot'), + value: true, + }, + { + label: t('analyze:metric_detail:exclude_robot'), + value: false, + }, + ]; + if (type == 'issue') { + return ( + <> +
+ {t('analyze:metric_detail:issues')} +
+ + ); + } else if (type == 'pr') { + return ( + <> +
+ {t('analyze:metric_detail:pull_requests')} +
+ + ); + } + return ( + <> + + selectState ? ( + {t('analyze:metric_detail:all_repos')} + ) : ( + '+' + value.length + // label).join(', ')}> + // Hover Me + // + ) + } + options={options} + onChange={(newValue) => { + setValue(newValue); + if (newValue.length === options.length) { + setSelectState(true); + onRepoChange([]); + } else { + setSelectState(false); + onRepoChange(newValue); + } + }} + style={{ width: 130 }} + // allowClear + dropdownRender={(menu) => ( +
+ {menu} + +
+ { + if (e.target.checked === true) { + setSelectState(true); //选中时 给 checked 改变状态 + // 当选的时候 把所有列表值赋值给 functionIds + setValue(options.map((item) => item.value)); + } else { + setSelectState(false); + setValue([]); + } + onRepoChange([]); + }} + > + {t('analyze:metric_detail:select_all')} + +
+
+ )} + /> + ); +}; + +export default CommunityFilter; diff --git a/apps/web/src/modules/analyze/components/MetricDetail/DetailHeaderFilter.tsx b/apps/web/src/modules/analyze/components/MetricDetail/DetailHeaderFilter.tsx index db88a2a1..26034095 100644 --- a/apps/web/src/modules/analyze/components/MetricDetail/DetailHeaderFilter.tsx +++ b/apps/web/src/modules/analyze/components/MetricDetail/DetailHeaderFilter.tsx @@ -1,12 +1,16 @@ import React, { useState } from 'react'; import { Select } from 'antd'; import { useTranslation } from 'next-i18next'; +import CommunityFilter from './CommunityFilter'; const DetailHeaderFilter: React.FC<{ type: string; + level: string; + label: string; isBot?: boolean; onBotChange?: (v) => void; -}> = ({ type, isBot, onBotChange }) => { + onRepoChange?: (v) => void; +}> = ({ type, label, isBot, onBotChange, onRepoChange }) => { const { t } = useTranslation(); const isBotOptions = [ @@ -37,9 +41,10 @@ const DetailHeaderFilter: React.FC<{ ); } return ( - <> +
+ onRepoChange(v)} /> { + onBotChange(v); + // handleQueryParams({ tab: v }); + }} + value={isBot} + options={isBotOptions} + /> + )} +
+ ); } - return ( -
- onRepoChange(v)} /> - selectState ? ( {t('analyze:metric_detail:all_repos')} @@ -60,7 +60,7 @@ const CommunityFilter = ({ label, onRepoChange }) => { onRepoChange(newValue); } }} - style={{ width: 130 }} + style={{ width: 200 }} // allowClear dropdownRender={(menu) => (
diff --git a/apps/web/src/modules/analyze/components/MetricDetail/DetailHeaderFilter.tsx b/apps/web/src/modules/analyze/components/MetricDetail/DetailHeaderFilter.tsx index 2f38f4ff..dd51e7d8 100644 --- a/apps/web/src/modules/analyze/components/MetricDetail/DetailHeaderFilter.tsx +++ b/apps/web/src/modules/analyze/components/MetricDetail/DetailHeaderFilter.tsx @@ -26,7 +26,7 @@ const DetailHeaderFilter: React.FC<{ if (type == 'issue') { return ( <> - {level === 'community' ? ( + {level === 'community1' ? ( onRepoChange(v)} @@ -41,7 +41,7 @@ const DetailHeaderFilter: React.FC<{ } else if (type == 'pr') { return ( <> - {level === 'community' ? ( + {level === 'community1' ? ( onRepoChange(v)} @@ -57,10 +57,21 @@ const DetailHeaderFilter: React.FC<{ return (
{level === 'community' ? ( - onRepoChange(v)} - /> + <> + onRepoChange(v)} + /> +