Skip to content

Commit

Permalink
feat: add collection tag on report page
Browse files Browse the repository at this point in the history
Signed-off-by: laixingyou <[email protected]>
  • Loading branch information
coder-sett committed Sep 14, 2023
1 parent 91efe56 commit 40a808e
Show file tree
Hide file tree
Showing 8 changed files with 90 additions and 184 deletions.
62 changes: 62 additions & 0 deletions apps/web/src/common/components/CollectionTag.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React from 'react';
import { useTranslation } from 'next-i18next';
import { useRouter } from 'next/navigation';
import Tooltip from '@common/components/Tooltip';
import { getSecondIdentName } from '@common/collectionsI18n';
import cls from 'classnames';

const CollectionTag = ({
collections,
className,
}: {
collections: string[];
className: string;
}) => {
const { t, i18n } = useTranslation();
const router = useRouter();
const first = collections?.[0];

let restCollections: string[] = [];
if (collections?.length > 1) {
restCollections = collections?.slice(1).map((item) => {
return getSecondIdentName(item, i18n.language);
});
}

return (
<div
className={cls(
'text-secondary flex cursor-pointer items-center text-xs',
className
)}
>
{first ? (
<>
<div
className="bg-smoke rounded px-2 py-1.5"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
router.push(`/collection/${first}`);
}}
>
{getSecondIdentName(first, i18n.language)}
</div>
{collections?.length > 1 ? (
<Tooltip
title={
<div className="p-2 text-white">
{restCollections?.join(', ')}
</div>
}
>
<div className="ml-1">+{collections.length - 1}</div>
</Tooltip>
) : null}
</>
) : null}
</div>
);
};

export default CollectionTag;
134 changes: 10 additions & 124 deletions apps/web/src/modules/analyze/components/NavBar/LabelItems.tsx
Original file line number Diff line number Diff line change
@@ -1,65 +1,22 @@
import React, { useCallback, useEffect, useState, useRef } from 'react';
import React from 'react';
import { useTranslation } from 'next-i18next';
import useCompareItems from '@modules/analyze/hooks/useCompareItems';
import { getProvider } from '@common/utils';
import ColorSwitcher from '@modules/analyze/components/CompareBar/ColorSwitcher';
import { Level } from '@modules/analyze/constant';
import { useClickAway } from 'react-use';
import { useResizeDetector } from 'react-resize-detector';
import classnames from 'classnames';
import Popper from '@mui/material/Popper';
import ProviderIcon from '../ProviderIcon';
import CollectionTag from '@common/components/CollectionTag';

const LabelItems = () => {
const { t } = useTranslation();
const { compareItems } = useCompareItems();
const [hiddenIndex, setHiddenIndex] = useState(-1);
const [hiddenVisible, setHiddenVisible] = useState(false);
const [anchorEl, setAnchorEl] = React.useState<null | HTMLElement>(null);
const hiddenRef = useRef<HTMLDivElement>(null);
const item = compareItems.length > 0 ? [compareItems[0]] : [];

const computeWidth = () => {
if (ref) {
const parentsWidth = ref.current.offsetWidth;
let childrenWidth = 0;
const index = [...ref.current.children].findIndex((item, index) => {
if (item.id !== 'more') {
childrenWidth += item.offsetWidth;
if (parentsWidth < childrenWidth) {
return index;
}
}
});
setHiddenIndex(index);
}
};
const onResize = useCallback(computeWidth, [hiddenIndex, compareItems]);
useEffect(computeWidth, [compareItems]);
useClickAway(hiddenRef, () => {
setTimeout(() => {
setHiddenVisible(false);
}, 200);
});

const { ref } = useResizeDetector({
handleHeight: false,
refreshMode: 'debounce',
refreshRate: 200,
onResize,
});

const style = {
background: 'linear-gradient(270deg, #FFFFFF 0%, rgba(255,255,255,0) 100%)',
};
return (
<>
<div
className="relative flex h-6 flex-1 items-center overflow-hidden"
ref={ref}
>
{compareItems.map(({ name, label, level }, index) => {
<div className="relative flex h-6 flex-1 items-center overflow-hidden">
{item.map(({ name, label, level, collections }) => {
const host = getProvider(label);

let labelNode = (
<span className={'ml-1 mr-1 font-semibold'}>{name}</span>
);
Expand All @@ -78,92 +35,21 @@ const LabelItems = () => {
}

return (
<div
key={label}
className={classnames('flex items-center', {
invisible: hiddenVisible && index >= hiddenIndex,
})}
>
<div key={label} className={classnames('flex items-center')}>
<ProviderIcon provider={host} />
{labelNode}
{compareItems.length > 1 && <ColorSwitcher label={label} />}
{level === Level.COMMUNITY && (
<div className="ml-2 rounded-[10px] bg-[#FFF9F2] px-2 py-0.5 text-xs text-[#D98523]">
{t('home:community')}
</div>
)}
{index < compareItems.length - 1 ? (
<span className="px-2 text-slate-300">vs</span>
) : null}
<CollectionTag
className={'col-span-2 mx-2'}
collections={collections}
/>
</div>
);
})}
{hiddenIndex !== -1 && (
<div
className="absolute right-0 top-0 h-6 w-24 shrink-0 cursor-pointer"
style={style}
id="more"
>
<div
className="ml-14 h-6 w-8 rounded-[24px] border border-[#EBEFF4] bg-[#f4f4f4] text-center leading-6"
onClick={(event) => {
setAnchorEl(event.currentTarget);
setHiddenVisible(true);
}}
>
+{compareItems.length - hiddenIndex}
</div>
</div>
)}
<Popper
open={hiddenVisible}
anchorEl={anchorEl}
placement={'bottom-end'}
sx={{
zIndex: 9999,
}}
>
<div
ref={hiddenRef}
className="flex flex-col flex-wrap justify-around overflow-hidden rounded bg-white px-2 pt-2 pb-1 drop-shadow-2xl"
>
{compareItems
.filter((item, index) => index >= hiddenIndex)
.map(({ name, label, level }) => {
const host = getProvider(label);

let labelNode = (
<span className={'ml-1 mr-1 font-semibold'}>{name}</span>
);

if (level === Level.REPO) {
labelNode = (
<a
className="ml-1 mr-1 font-semibold hover:underline"
href={label}
target="_blank"
rel={'noreferrer'}
>
{name}
</a>
);
}

return (
<div key={label} className={classnames('flex items-center')}>
<ProviderIcon provider={host} />
{labelNode}
{compareItems.length > 1 && <ColorSwitcher label={label} />}
{level === Level.COMMUNITY && (
<div className="ml-2 rounded-[10px] bg-[#FFF9F2] px-2 py-0.5 text-xs text-[#D98523]">
{t('home:community')}
</div>
)}
</div>
);
})}
</div>
</Popper>
</div>
<div className="hidden md:block">
{/* todo show compare items in mobile */}
Expand Down
4 changes: 2 additions & 2 deletions apps/web/src/modules/analyze/context/ChartsDataProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ const ChartsDataProvider: React.FC<PropsWithChildren> = ({ children }) => {
level,
start: timeStart,
end: timeEnd,
repoType: repoType,
repoType: level === Level.COMMUNITY ? repoType : '',
};
return {
queryKey: useMetricQuery.getKey(variables),
Expand All @@ -80,7 +80,7 @@ const ChartsDataProvider: React.FC<PropsWithChildren> = ({ children }) => {
level,
start: timeStart,
end: timeEnd,
repoType: repoType,
repoType: level === Level.COMMUNITY ? repoType : '',
};
const key = useMetricQuery.getKey(variables);
return {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/src/modules/analyze/context/StatusContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { Level } from '../constant';

type Item = Pick<
StatusVerifyQuery['analysisStatusVerify'],
'label' | 'status' | 'shortCode'
'label' | 'status' | 'shortCode' | 'collections'
>;

export type VerifiedLabelItem = {
Expand Down
10 changes: 6 additions & 4 deletions apps/web/src/modules/analyze/hooks/useCompareItems.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import { Level } from '@modules/analyze/constant';
const useCompareItems = () => {
const { verifiedItems } = useStatusContext();

const items = verifiedItems.map(({ label, level, shortCode }) => {
const name = level === Level.REPO ? getPathname(label) : label;
return { label, level, shortCode, name };
});
const items = verifiedItems.map(
({ label, level, shortCode, collections }) => {
const name = level === Level.REPO ? getPathname(label) : label;
return { label, level, shortCode, name, collections };
}
);

const ids = items.map((i) => i.shortCode);

Expand Down
54 changes: 1 addition & 53 deletions apps/web/src/modules/home/Trending/ListPanel.tsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import React from 'react';
import Link from 'next/link';
import { useRouter } from 'next/navigation';
import cls from 'classnames';
import { useTranslation } from 'next-i18next';
import { BsCodeSquare } from 'react-icons/bs';
import { TrendingQuery } from '@oss-compass/graphql';
import { formatLabel } from '@common/utils/format';
import Tooltip from '@common/components/Tooltip';
import { getShortAnalyzeLink } from '@common/utils/links';
import ProviderIcon from '@common/components/ProviderIcon';
import ImageFallback from '@common/components/ImageFallback';
import transHundredMarkSystem from '@common/transform/transHundredMarkSystem';
import { Level } from '@modules/analyze/constant';
import { getSecondIdentName } from '@common/collectionsI18n';
import CollectionTag from '@common/components/CollectionTag';

const ListPanel = (props: {
loading: boolean;
Expand Down Expand Up @@ -104,55 +101,6 @@ const Avatar = ({ item }: { item: TrendingQuery['trending'][number] }) => {
);
};

const CollectionTag = ({
collections,
className,
}: {
collections: string[];
className: string;
}) => {
const { t, i18n } = useTranslation();
const router = useRouter();
const first = collections?.[0];

let restCollections: string[] = [];
if (collections?.length > 1) {
restCollections = collections?.slice(1).map((item) => {
return getSecondIdentName(item, i18n.language);
});
}

return (
<div className={cls('text-secondary flex items-center text-xs', className)}>
{first ? (
<>
<div
className="bg-smoke rounded px-2 py-1.5"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
router.push(`/collection/${first}`);
}}
>
{getSecondIdentName(first, i18n.language)}
</div>
{collections?.length > 1 ? (
<Tooltip
title={
<div className="p-2 text-white">
{restCollections?.join(', ')}
</div>
}
>
<div className="ml-1">+{collections.length - 1}</div>
</Tooltip>
) : null}
</>
) : null}
</div>
);
};

const Loading = () => (
<div className="rounded border px-6 py-6 shadow">
<div className="flex flex-1 flex-col bg-white">
Expand Down
6 changes: 6 additions & 0 deletions packages/graphql/src/generated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1167,6 +1167,8 @@ export type Permission = {

export type ProjectCompletionRow = {
__typename?: 'ProjectCompletionRow';
/** second collections of this label */
collections?: Maybe<Array<Scalars['String']>>;
/** metric model object identification */
label?: Maybe<Scalars['String']>;
/** metric model object level (project or repo) */
Expand Down Expand Up @@ -3349,6 +3351,7 @@ export type StatusVerifyQuery = {
level?: string | null;
shortCode?: string | null;
status?: string | null;
collections?: Array<string> | null;
};
};

Expand All @@ -3365,6 +3368,7 @@ export type SearchQuery = {
label?: string | null;
status?: string | null;
shortCode?: string | null;
collections?: Array<string> | null;
}>;
};

Expand Down Expand Up @@ -6268,6 +6272,7 @@ export const StatusVerifyDocument = /*#__PURE__*/ `
level
shortCode
status
collections
}
}
`;
Expand Down Expand Up @@ -6311,6 +6316,7 @@ export const SearchDocument = /*#__PURE__*/ `
label
status
shortCode
collections
}
}
`;
Expand Down
Loading

0 comments on commit 40a808e

Please sign in to comment.