diff --git a/apps/web/i18n b/apps/web/i18n index ec6f692e..0b43e53d 160000 --- a/apps/web/i18n +++ b/apps/web/i18n @@ -1 +1 @@ -Subproject commit ec6f692eb0e40fff1d28cda19f946a234c95dff8 +Subproject commit 0b43e53dd2735a9c58d1ef8f211618eef992c952 diff --git a/apps/web/src/common/components/OrgEdit/ManageOrgEdit.tsx b/apps/web/src/common/components/OrgEdit/ManageOrgEdit.tsx index 0c8d253a..136fa962 100644 --- a/apps/web/src/common/components/OrgEdit/ManageOrgEdit.tsx +++ b/apps/web/src/common/components/OrgEdit/ManageOrgEdit.tsx @@ -96,7 +96,7 @@ const ManageOrgEdit = ({ { setOrgName(e); diff --git a/apps/web/src/common/components/OrgEdit/OrgInput.tsx b/apps/web/src/common/components/OrgEdit/OrgInput.tsx index 9b650eb6..b19edff1 100644 --- a/apps/web/src/common/components/OrgEdit/OrgInput.tsx +++ b/apps/web/src/common/components/OrgEdit/OrgInput.tsx @@ -83,7 +83,8 @@ const Select: React.FC< )}
{showLoading ? ( diff --git a/apps/web/src/common/components/OrgEdit/index.tsx b/apps/web/src/common/components/OrgEdit/index.tsx index fa5dc0d1..ef13af73 100644 --- a/apps/web/src/common/components/OrgEdit/index.tsx +++ b/apps/web/src/common/components/OrgEdit/index.tsx @@ -116,7 +116,7 @@ const OrgEdit = ({ onChange={(e) => { setOrgName(e); }} - placeholder={''} + placeholder={t('common:org_name')} /> { + return getMaxDomain(tableData); + }, [tableData]); const { isLoading, isFetching } = useContributorsDetailListQuery( client, query, @@ -112,9 +115,11 @@ const MetricTable: React.FC<{ let value = hasTypeFilter.values; items.map((item) => { let list = item.contributionTypeList; - item.contributionTypeList = list.filter((i) => - value.includes(i.contributionType) - ); + item.contributionTypeList = list.filter((i) => { + if (value.includes(i.contributionType)) { + return true; + } + }); }); } setTableParams({ @@ -217,27 +222,14 @@ const MetricTable: React.FC<{ { title: t('analyze:metric_detail:domain_persona'), dataIndex: 'contributionTypeList', - render: (list) => { - let arr = list.map( - (item) => contributionTypeMap[item.contributionType] + render: (dataList, col) => { + return ( + ); - let sortObj = arr.reduce((result, item) => { - (result[item.color] = result[item.color] || []).push(item); - return result; - }, {}); - let newArr = Object.keys(sortObj).sort(); - const str = newArr.map((item) => { - return ( -
- {sortObj[item]?.map((obj, index) => ( - - {obj.text} - - ))} -
- ); - }); - return str; }, filters: useContributionTypeLsit(), defaultFilteredValue: @@ -246,7 +238,7 @@ const MetricTable: React.FC<{ filterMode: 'tree', // ellipsis: { showTitle: true }, align: 'left', - width: '590px', + width: '300px', }, { title: t('analyze:metric_detail:organization'), diff --git a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/DomainPersona/index.tsx b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/DomainPersona/index.tsx new file mode 100644 index 00000000..782aa3c1 --- /dev/null +++ b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/DomainPersona/index.tsx @@ -0,0 +1,148 @@ +import React, { useState, useMemo } from 'react'; +import { useTranslation } from 'next-i18next'; +import { useGetContributionTypeI18n } from '../contribution'; +import { getDomainData } from '../utils'; +import { toFixed } from '@common/utils'; +import classnames from 'classnames'; +import Popper from '@mui/material/Popper'; +import { ClickAwayListener } from '@mui/base/ClickAwayListener'; + +const PopperContent = ({ dataList, name, active, setActive }) => { + const activeItem = dataList + .find((item) => item.type === active) + ?.childern.sort((a, b) => b.contribution - a.contribution); + + // const allType = ['Code', 'Code Admin', 'Issue', 'Issue Admin', 'Observe']; + return ( +
+
+ {name} +
+
+
+ {dataList.map(({ type, color, contribution }) => { + return ( +
{ + setActive(type); + }} + className={classnames( + 'flex h-9 w-full cursor-pointer items-center justify-between border-b border-r bg-[#F6F6F6] last:border-b-0', + { '!border-r-0 !bg-[#FFFFFF]': active === type } + )} + > +
+
{type}
+
+ {contribution} +
+
+ ); + })} +
+
+
+ {activeItem.map(({ text, contribution }) => { + return ( +
+
{text}
+
{contribution}
+
+ ); + })} +
+
+
+ ); +}; + +const DomainPersona = ({ maxDomain, dataList, name }) => { + const { t } = useTranslation(); + const contributionTypeMap = useGetContributionTypeI18n(); + const domainData = useMemo(() => { + return getDomainData(dataList, contributionTypeMap); + }, [dataList]); + const [active, setActive] = useState(''); + const [popperOpen, togglePopperOpen] = React.useState(false); + const [anchorEl, setAnchorEl] = React.useState(null); + const handleClick = (event: React.MouseEvent, type) => { + setActive(type); + setAnchorEl(event.currentTarget); + togglePopperOpen(() => true); + }; + + return ( + { + setActive(''); + popperOpen && togglePopperOpen(() => false); + }} + > +
+
+ {domainData.map(({ type, color, contribution }) => { + const width = toFixed((contribution / maxDomain) * 100, 2); + const bg = { + backgroundColor: color, + width: `${width}%`, + }; + return active === type ? ( +
+
+
+ ) : ( +
{ + handleClick(e, type); + }} + key={type} + style={{ backgroundColor: color, width: `${width}%` }} + className="h-2 cursor-pointer" + >
+ ); + })} +
+ + + +
+
+ ); +}; + +export default DomainPersona; diff --git a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/contribution.ts b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/contribution.ts index 679a6c61..7a7df510 100644 --- a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/contribution.ts +++ b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/contribution.ts @@ -4,9 +4,51 @@ import { useTranslation } from 'next-i18next'; const useContributionTypeMap = () => { const { t } = useTranslation(); return { - Observe: { - fork: t('analyze:metric_detail:observe:fork'), - star: t('analyze:metric_detail:observe:star'), + Code: { + pr_creation: t('analyze:metric_detail:code:pr_creation'), + pr_comments: t('analyze:metric_detail:code:pr_comments'), + code_commit: t('analyze:metric_detail:code:code_commit'), + }, + 'Code Admin': { + pr_labeled: t('analyze:metric_detail:code_admin:pr_labeled'), + pr_unlabeled: t('analyze:metric_detail:code_admin:pr_unlabeled'), + pr_closed: t('analyze:metric_detail:code_admin:pr_closed'), + pr_assigned: t('analyze:metric_detail:code_admin:pr_assigned'), + pr_unassigned: t('analyze:metric_detail:code_admin:pr_unassigned'), + pr_reopened: t('analyze:metric_detail:code_admin:pr_reopened'), + pr_milestoned: t('analyze:metric_detail:code_admin:pr_milestoned'), + pr_demilestoned: t('analyze:metric_detail:code_admin:pr_demilestoned'), + pr_marked_as_duplicate: t( + 'analyze:metric_detail:code_admin:pr_marked_as_duplicate' + ), + pr_transferred: t('analyze:metric_detail:code_admin:pr_transferred'), + pr_renamed_title: t('analyze:metric_detail:code_admin:pr_renamed_title'), + pr_change_description: t( + 'analyze:metric_detail:code_admin:pr_change_description' + ), + pr_setting_priority: t( + 'analyze:metric_detail:code_admin:pr_setting_priority' + ), + pr_change_priority: t( + 'analyze:metric_detail:code_admin:pr_change_priority' + ), + pr_merged: t('analyze:metric_detail:code_admin:pr_merged'), + pr_review: t('analyze:metric_detail:code_admin:pr_review'), + pr_set_tester: t('analyze:metric_detail:code_admin:pr_set_tester'), + pr_unset_tester: t('analyze:metric_detail:code_admin:pr_unset_tester'), + pr_check_pass: t('analyze:metric_detail:code_admin:pr_check_pass'), + pr_test_pass: t('analyze:metric_detail:code_admin:pr_test_pass'), + pr_reset_assign_result: t( + 'analyze:metric_detail:code_admin:pr_reset_assign_result' + ), + pr_reset_test_result: t( + 'analyze:metric_detail:code_admin:pr_reset_test_result' + ), + pr_link_issue: t('analyze:metric_detail:code_admin:pr_link_issue'), + pr_unlink_issue: t('analyze:metric_detail:code_admin:pr_unlink_issue'), + code_direct_commit: t( + 'analyze:metric_detail:code_admin:code_direct_commit' + ), }, Issue: { issue_creation: t('analyze:metric_detail:issue:issue_creation'), @@ -66,51 +108,9 @@ const useContributionTypeMap = () => { 'analyze:metric_detail:issue_admin:issue_change_branch' ), }, - Code: { - pr_creation: t('analyze:metric_detail:code:pr_creation'), - pr_comments: t('analyze:metric_detail:code:pr_comments'), - code_commit: t('analyze:metric_detail:code:code_commit'), - }, - 'Code Admin': { - pr_labeled: t('analyze:metric_detail:code_admin:pr_labeled'), - pr_unlabeled: t('analyze:metric_detail:code_admin:pr_unlabeled'), - pr_closed: t('analyze:metric_detail:code_admin:pr_closed'), - pr_assigned: t('analyze:metric_detail:code_admin:pr_assigned'), - pr_unassigned: t('analyze:metric_detail:code_admin:pr_unassigned'), - pr_reopened: t('analyze:metric_detail:code_admin:pr_reopened'), - pr_milestoned: t('analyze:metric_detail:code_admin:pr_milestoned'), - pr_demilestoned: t('analyze:metric_detail:code_admin:pr_demilestoned'), - pr_marked_as_duplicate: t( - 'analyze:metric_detail:code_admin:pr_marked_as_duplicate' - ), - pr_transferred: t('analyze:metric_detail:code_admin:pr_transferred'), - pr_renamed_title: t('analyze:metric_detail:code_admin:pr_renamed_title'), - pr_change_description: t( - 'analyze:metric_detail:code_admin:pr_change_description' - ), - pr_setting_priority: t( - 'analyze:metric_detail:code_admin:pr_setting_priority' - ), - pr_change_priority: t( - 'analyze:metric_detail:code_admin:pr_change_priority' - ), - pr_merged: t('analyze:metric_detail:code_admin:pr_merged'), - pr_review: t('analyze:metric_detail:code_admin:pr_review'), - pr_set_tester: t('analyze:metric_detail:code_admin:pr_set_tester'), - pr_unset_tester: t('analyze:metric_detail:code_admin:pr_unset_tester'), - pr_check_pass: t('analyze:metric_detail:code_admin:pr_check_pass'), - pr_test_pass: t('analyze:metric_detail:code_admin:pr_test_pass'), - pr_reset_assign_result: t( - 'analyze:metric_detail:code_admin:pr_reset_assign_result' - ), - pr_reset_test_result: t( - 'analyze:metric_detail:code_admin:pr_reset_test_result' - ), - pr_link_issue: t('analyze:metric_detail:code_admin:pr_link_issue'), - pr_unlink_issue: t('analyze:metric_detail:code_admin:pr_unlink_issue'), - code_direct_commit: t( - 'analyze:metric_detail:code_admin:code_direct_commit' - ), + Observe: { + fork: t('analyze:metric_detail:observe:fork'), + star: t('analyze:metric_detail:observe:star'), }, }; }; @@ -139,19 +139,19 @@ export const useContributionTypeLsit = () => { export const useGetContributionTypeI18n = () => { const obj = useContributionTypeMap(); const result = {}; - const colors = ['cyan', 'green', 'geekblue', 'purple', 'orange']; - const defaultColors = 'volcano'; - function traverseObject(obj, color) { + const colors = ['#4A90E2', '#9ECDF2', '#EAB308', '#FDE047', '#D1D5DB']; + const defaultColors = '#D1D5DB'; + function traverseObject(obj, color, type) { for (const key in obj) { if (typeof obj[key] === 'object') { const c = colors.shift() || defaultColors; - traverseObject(obj[key], c); + traverseObject(obj[key], c, key); } else { - result[key] = { text: obj[key], color }; + result[key] = { text: obj[key], color, type }; } } } - traverseObject(obj, defaultColors); + traverseObject(obj, defaultColors, null); return result; }; diff --git a/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/utils.ts b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/utils.ts new file mode 100644 index 00000000..a8c14230 --- /dev/null +++ b/apps/web/src/modules/analyze/DataView/MetricDetail/MetricContributor/utils.ts @@ -0,0 +1,46 @@ +export const getMaxDomain = (tableData) => { + if (tableData?.length > 0) { + const filterData = tableData?.map((item) => { + let filterCount = item?.contributionTypeList?.reduce( + (acc, current) => acc + current.contribution, + 0 + ); + return { ...item, filterCount }; + }); + let maxCountElement = filterData?.reduce((prev, current) => + prev?.filterCount > current.filterCount ? prev : current + ); + return maxCountElement.filterCount; + } else { + return 0; + } +}; +export const getDomainData = (data, contributionTypeMap) => { + let arr = data.map((item) => { + return { ...item, ...contributionTypeMap[item.contributionType] }; + }); + const result = []; + arr.forEach(({ color, contribution, text, type }) => { + const domainType = result.find((z) => z.type === type); + if (domainType) { + domainType.contribution += contribution; + domainType.childern.push({ text, contribution }); + } else { + result.push({ + type, + color, + contribution, + childern: [{ text, contribution }], + }); + } + }); + return result.sort((a, b) => { + if (a.type < b.type) { + return -1; + } + if (a.type > b.type) { + return 1; + } + return 0; + }); +};