Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: domain persona optimize #306

Merged
merged 1 commit into from
Jan 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/web/i18n
2 changes: 1 addition & 1 deletion apps/web/src/common/components/OrgEdit/ManageOrgEdit.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const ManageOrgEdit = ({
<OrgInput
className="h-full w-full"
inputClass="daisy-input-bordered daisy-input h-12 w-full flex-1 border-2 px-4 text-base outline-none border-black"
dropClass="top-[50px] border-2"
dropClass="top-[50px] border-2"
value={orgName}
onChange={(e) => {
setOrgName(e);
Expand Down
3 changes: 2 additions & 1 deletion apps/web/src/common/components/OrgEdit/OrgInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ const Select: React.FC<
)}
<div
className={classnames(
'absolute top-1.5 right-2 cursor-pointer text-[#CCCCCC]'
'absolute top-1.5 right-2 cursor-pointer text-[#CCCCCC]',
inputClass ? 'top-5' : ''
)}
>
{showLoading ? (
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/common/components/OrgEdit/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ const OrgEdit = ({
onChange={(e) => {
setOrgName(e);
}}
placeholder={''}
placeholder={t('common:org_name')}
/>
</Form.Item>
<Form.Item
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ import MyTable from '@common/components/Table';
import classnames from 'classnames';
import {
useContributionTypeLsit,
useGetContributionTypeI18n,
useEcologicalType,
useMileageOptions,
} from './contribution';
import { Tag } from 'antd';
import { getMaxDomain } from './utils';
import DomainPersona from './DomainPersona';
import type { ColumnsType, TablePaginationConfig } from 'antd/es/table';
import type { FilterValue, SorterResult } from 'antd/es/table/interface';
import { useTranslation } from 'next-i18next';
Expand Down Expand Up @@ -54,7 +54,6 @@ const MetricTable: React.FC<{
ecologicalType: 'ecological_type',
contributionTypeList: 'contribution_type',
};
const contributionTypeMap = useGetContributionTypeI18n();
const router = useRouter();
const { handleQueryParams } = useHandleQueryParams();

Expand Down Expand Up @@ -99,6 +98,10 @@ const MetricTable: React.FC<{
beginDate,
endDate,
};

const maxDomain = useMemo(() => {
return getMaxDomain(tableData);
}, [tableData]);
const { isLoading, isFetching } = useContributorsDetailListQuery(
client,
query,
Expand All @@ -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({
Expand Down Expand Up @@ -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 (
<DomainPersona
maxDomain={maxDomain}
dataList={dataList}
name={col.contributor}
/>
);
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 (
<div key={item} className="line-clamp-1 my-1">
{sortObj[item]?.map((obj, index) => (
<Tag key={index} color={obj.color}>
{obj.text}
</Tag>
))}
</div>
);
});
return str;
},
filters: useContributionTypeLsit(),
defaultFilteredValue:
Expand All @@ -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'),
Expand Down
Original file line number Diff line number Diff line change
@@ -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 (
<div className="right-0 rounded bg-[#fcfcfc] text-xs drop-shadow-md">
<div className="flex h-10 items-center pl-3 text-sm font-semibold">
{name}
</div>
<div className="flex h-[300px]">
<div className="flex h-full w-40 flex-shrink-0 flex-col border-t">
{dataList.map(({ type, color, contribution }) => {
return (
<div
key={type}
onClick={() => {
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 }
)}
>
<div
style={{ backgroundColor: color }}
className="ml-3 h-2 w-2"
></div>
<div className="ml-2 text-xs font-bold">{type}</div>
<div className="ml-auto mr-3 text-[#868690]">
{contribution}
</div>
</div>
);
})}
<div className="flex-1 border-r bg-[#F6F6F6]"></div>
</div>
<div className="h-full w-[216px] flex-shrink-0 overflow-auto border-t px-4 py-2 text-xs">
{activeItem.map(({ text, contribution }) => {
return (
<div
key={text}
className="flex h-7 w-full items-center justify-between"
>
<div className="text-[#2C3542]">{text}</div>
<div className="text-[#868690]">{contribution}</div>
</div>
);
})}
</div>
</div>
</div>
);
};

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 | HTMLElement>(null);
const handleClick = (event: React.MouseEvent<HTMLElement>, type) => {
setActive(type);
setAnchorEl(event.currentTarget);
togglePopperOpen(() => true);
};

return (
<ClickAwayListener
onClickAway={() => {
setActive('');
popperOpen && togglePopperOpen(() => false);
}}
>
<div>
<div className="flex items-center">
{domainData.map(({ type, color, contribution }) => {
const width = toFixed((contribution / maxDomain) * 100, 2);
const bg = {
backgroundColor: color,
width: `${width}%`,
};
return active === type ? (
<div
key={type}
className="cursor-pointer border"
style={{
width: `${width}%`,
borderColor: color,
padding: '1px',
}}
>
<div className="h-2" style={{ backgroundColor: color }}></div>
</div>
) : (
<div
onClick={(e) => {
handleClick(e, type);
}}
key={type}
style={{ backgroundColor: color, width: `${width}%` }}
className="h-2 cursor-pointer"
></div>
);
})}
</div>
<Popper
open={popperOpen}
style={{
zIndex: 1000,
}}
placement={'bottom'}
anchorEl={anchorEl}
modifiers={[
{
name: 'offset',
options: {
offset: [0, 5],
},
},
]}
>
<PopperContent
dataList={domainData}
name={name}
active={active}
setActive={setActive}
/>
</Popper>
</div>
</ClickAwayListener>
);
};

export default DomainPersona;
Loading
Loading