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: create mobile version of repo table #409

Merged
merged 20 commits into from
Sep 23, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
55514d9
feat: made provisions for mobile vertion of repositorytable
OgDev-01 Sep 21, 2022
7e2d834
refactor: removed unused var
OgDev-01 Sep 21, 2022
d47ac3b
fix: fix eslint errors
OgDev-01 Sep 21, 2022
2cc5634
refactor: created a repo-row-mobile component
OgDev-01 Sep 21, 2022
b7595e0
chore: add onClick to toggle between tableOpen state
OgDev-01 Sep 21, 2022
9b6f22b
Merge branch 'beta' of https://github.com/open-sauced/insights into m…
OgDev-01 Sep 22, 2022
c6c9a03
style: adjust vertical alignments of churn arrow and churn
OgDev-01 Sep 22, 2022
0d72441
style: update pill text alignments
OgDev-01 Sep 22, 2022
ed17d86
chore: add support for mobile screens
OgDev-01 Sep 22, 2022
8655459
chore: added useMediaQuery for mobile responsiveness
OgDev-01 Sep 22, 2022
401569a
feat: split repo row component in to two
OgDev-01 Sep 22, 2022
067c8a3
feat: completing mobile responsiveness for repo row
OgDev-01 Sep 22, 2022
6bb3625
refactor: refactored repository table
OgDev-01 Sep 22, 2022
b6eca18
Merge branch 'beta' into mobile-repositories-tobile
OgDev-01 Sep 22, 2022
d9deb67
Merge branch 'beta' of https://github.com/open-sauced/insights into m…
OgDev-01 Sep 23, 2022
2089d7e
chore: add clsx package for classname concatination
OgDev-01 Sep 23, 2022
e8cc33d
refactor: removed all traces of useMediaQuery and used css for respon…
OgDev-01 Sep 23, 2022
50c5421
refactor: removed unused vars
OgDev-01 Sep 23, 2022
fea34f7
style: adjust css for arrow icon
OgDev-01 Sep 23, 2022
9c3795d
refactor: add min-width to each cols to avoid layout breaks
OgDev-01 Sep 23, 2022
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 components/atoms/Pill/pill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const Pill: React.FC<PillProps> = ({ className, text, color = "slate", size = "b
className={`
${color === "green" ? "bg-light-grass-4 " : color === "yellow" ? "bg-amber-200 " : color === "red" ? "bg-light-red-4 " : "bg-light-slate-4 "}
${size === "small" ? "py-1 px-1.5 gap-1 " : "py-1.5 px-2 gap-1 "}
inline-flex rounded-full`}>
inline-flex items-center rounded-full`}>
{icon}

<div
Expand Down
5 changes: 3 additions & 2 deletions components/molecules/Pagination/pagination.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { useMediaQuery } from "lib/hooks/useMediaQuery";
import humanizeNumber from "lib/utils/humanizeNumber";
import React, { useState } from "react";
import { RiArrowLeftSLine } from "react-icons/ri";
Expand Down Expand Up @@ -42,7 +43,7 @@ const Pagination = ({
<div className=" w-max flex gap-x-4 items-center ">
<div className="flex items-center gap-x-4">
<button className="text-light-slate-9 disabled:text-light-slate-7" disabled={!hasPreviousPage ? true : false} onClick={() => handlePrev()}>
<RiArrowLeftSLine onClick={() => handlePrev()} className="text-lg " />
<RiArrowLeftSLine onClick={() => handlePrev()} className="text-2xl md:text-lg" />
</button>
{pages.map((page, index) => {
return (
Expand All @@ -63,7 +64,7 @@ const Pagination = ({
})}

<button className="text-light-slate-9 disabled:text-light-slate-7" disabled={!hasNextPage ? true : false} onClick={() => handleNext()}>
<RiArrowRightSLine className="text-lg" />
<RiArrowRightSLine className="text-2xl md:text-lg" />
</button>
</div>
<div
Expand Down
4 changes: 3 additions & 1 deletion components/molecules/PaginationResults/pagination-result.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@ interface PaginationResultsProps {
entity: string; // The entity name
}
const PaginationResults = ({ from, to, entity, total }: PaginationResultsProps): JSX.Element => {


return (
<div className="flex items-center gap-x-1 font-medium text-sm text-light-slate-9 tracking-tight">
<span>Showing</span> <span className="text-light-slate-12">{from} -</span>
<span className="hidden md:block">Showing</span> <span className="text-light-slate-12">{from} -</span>
<span className="text-light-slate-12">{to}</span> of {total > 999 ? humanizeNumber(total, null) : total}
<span>{entity}</span>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,9 @@ const PullRequestOverview: React.FC<PullRequestOverviewProps> = ({ className, op
{/* Churn Number compared with previous date (default: last 30 days vs. previous 30 days range) */}
<div className={`
${churnDirection === "up" ? "text-light-grass-10" : "text-light-red-10"}
font-medium text-base tracking-tight`}>
{churnDirection === "up" ? <ArrowUpIcon size={14} /> : <ArrowDownIcon size={14} />}{activePrPercentage || 0}%
font-medium flex items-center gap-x-1 text-base tracking-tight`}>
{churnDirection === "up" ? <ArrowUpIcon size={14} /> : <ArrowDownIcon size={14} />}{churn || 0}%

</div>
</div>

Expand Down
211 changes: 157 additions & 54 deletions components/molecules/RepoRow/repo-row.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import { ArrowTrendingDownIcon, ArrowTrendingUpIcon, MinusSmallIcon } from "@heroicons/react/24/solid";
import StackedAvatar from "components/molecules/StackedAvatar/stacked-avatar";
import { ArrowTrendingDownIcon, ArrowTrendingUpIcon, ChevronDownIcon, ChevronUpIcon, MinusSmallIcon } from "@heroicons/react/24/solid";
import { RepositoriesRows } from "components/organisms/RepositoriesTable/repositories-table";

import {classNames} from "components/organisms/RepositoriesTable/repositories-table";
import TableRepositoryName from "../TableRepositoryName/table-repository-name";
import Pill from "components/atoms/Pill/pill";
import PullRequestOverview from "../PullRequestOverview/pull-request-overview";

import Sparkline from "components/atoms/Sparkline/sparkline";

import { useContributionsList } from "lib/hooks/useContributionsList";
import { useRepositoryCommits } from "lib/hooks/useRepositoryCommits";
import differenceInDays from "date-fns/differenceInDays";

interface RepoRowProps {
import TableRepositoryName from "../TableRepositoryName/table-repository-name";
import Sparkline from "components/atoms/Sparkline/sparkline";
import PullRequestOverview from "../PullRequestOverview/pull-request-overview";
import StackedAvatar from "../StackedAvatar/stacked-avatar";
import { useState } from "react";
import { classNames } from "components/organisms/RepositoriesTable/repositories-table";
import clsx from "clsx";
interface RepoProps {
repo: RepositoriesRows;
}

Expand Down Expand Up @@ -94,13 +92,27 @@ const getPrsSpam = (total: number, spam: number): number => {
return result;
};

const RepoRow = ({repo}:RepoRowProps): JSX.Element => {
const { name, owner: handle, owner_avatar: ownerAvatar, openPrsCount, closedPrsCount, draftPrsCount, mergedPrsCount, spamPrsCount, churn, churnTotalCount, churnDirection, prVelocityCount, prActiveCount } = repo;

const RepoRow = ({repo}:RepoProps): JSX.Element => {
const { name,
owner: handle,
owner_avatar: ownerAvatar,
openPrsCount,
closedPrsCount,
draftPrsCount,
mergedPrsCount,
spamPrsCount,
churn,
churnTotalCount,
churnDirection,
prVelocityCount } = repo;

const { data: contributorData, meta: contributorMeta } = useContributionsList(repo.id, "", "updated_at");
const { data: commitsData, meta: commitMeta, isLoading: commitLoading } = useRepositoryCommits(repo.id);
const totalPrs = getTotalPrs(openPrsCount, mergedPrsCount, closedPrsCount, draftPrsCount);
const prsMergedPercentage = getPrsMerged(totalPrs, mergedPrsCount || 0);
const spamPrsPercentage = getPrsSpam(totalPrs, spamPrsCount || 0);


const days = getCommitsLast30Days(commitsData);
const last30days = [
Expand All @@ -111,56 +123,147 @@ const RepoRow = ({repo}:RepoRowProps): JSX.Element => {
}
];

return (<div className={`${classNames.row}`}>

{/* Column: Repository Name */}
<div className={classNames.cols.repository}>
<TableRepositoryName avatarURL={ownerAvatar} name={name} handle={handle}></TableRepositoryName>
</div>

{/* Column: Activity */}
<div className={classNames.cols.activity}>
{ getActivity(commitMeta.itemCount, commitLoading) }
const [tableOpen, setTableOpen] = useState<boolean>(false);
return (<>
<div key={`${ownerAvatar}/${name}`} className="odd:bg-white md:hidden px-5 overflow-hidden py-2 even:bg-light-slate-2">
{/* Row: Repository Name and Pr overview */}
<div className="flex items-center gap-x-3">
<div className="w-[55%]">
<TableRepositoryName avatarURL={ownerAvatar} name={name} handle={handle} />
</div>
<div className="w-[45%]">
<PullRequestOverview
open={openPrsCount}
merged={mergedPrsCount}
closed={closedPrsCount}
draft={draftPrsCount}
churn={churnTotalCount}
churnDirection={`${churnDirection}`}
/>
</div>
<div className="">
<div
onClick={() => setTableOpen(!tableOpen)}
className="border rounded-md p-1 w-6 h-6 items-center justify-between"
>

{tableOpen ? <ChevronUpIcon className="" /> : <ChevronDownIcon />}
</div>
</div>
</div>

<div className={`${!tableOpen && "max-h-0"} font-medium text-light-slate-11 text-sm transition`}>
{/* Column: Last 30 Days */}
<div className="py-3">{last30days && <Sparkline data={last30days} width="100%" height={54} />}</div>
{/* Row: Activity */}
<div className="flex items-center py-3 border-b justify-between">
<div>Activity</div>
{getActivity(commitMeta.itemCount, commitLoading)}
</div>

{/* Row: Pr velocity */}
<div className="flex items-center py-3 border-b justify-between">
<div>Pr Velocity</div>
<div className="flex text-base gap-x-3">
<div>
{prVelocityCount ?? 0} PR{prVelocityCount === 1 ? "" : "s"}
</div>
<Pill text={`${prsMergedPercentage}%`} size="small" color="green" />
</div>
</div>

{/* Row: SPAM */}
<div className="flex items-center py-3 border-b justify-between">
<div>Spam</div>
<div className="flex text-base gap-x-3">
{spamPrsCount && spamPrsCount > 0 ? (
<>
<div>
{spamPrsCount || 0} PR{spamPrsCount === 1 ? "" : "s"}
</div>
<Pill
text={`${spamPrsPercentage || 0}%`}
size="small"
color={spamPrsPercentage > 10 ? "red" : "yellow"}
/>
</>
) : (
"-"
)}
</div>
</div>

{/* Row: Contributors */}

<div className="flex items-center py-3 justify-between">
<div>Contributors</div>
<div className="flex text-base items-center">
{contributorMeta.itemCount! > 0 ? <StackedAvatar contributors={contributorData} /> : "-"}

{contributorMeta.itemCount! >= 5 ? <div>&nbsp;{`+${contributorMeta.itemCount - 5}`}</div> : ""}
</div>
</div>

<div onClick={() => setTableOpen(!tableOpen)} className="text-center border rounded-lg py-1 mt-3">
Hide details
</div>
</div>
</div>

{/* Column: PR Overview */}
<div className={classNames.cols.prOverview}>
<PullRequestOverview open={openPrsCount} merged={mergedPrsCount} closed={closedPrsCount} draft={draftPrsCount} churn={churnTotalCount} churnDirection={`${churnDirection}`} prActiveCount={prActiveCount}></PullRequestOverview>
</div>

{/* Column: PR Velocity */}
<div className={`${classNames.cols.prVelocity}`}>
<div>{ prVelocityCount ?? 0 } PR{ prVelocityCount === 1 ? "" : "s" }</div>
<Pill text={`${prsMergedPercentage}%`} size="small" color="green" />
</div>

{/* Column: SPAM */}
<div className={`${classNames.cols.spam}`}>
{
spamPrsCount && spamPrsCount > 0 ?
<div className={`${classNames.row} `}>
{/* Column: Repository Name */}
<div className={classNames.cols.repository}>
<TableRepositoryName avatarURL={ownerAvatar} name={name} handle={handle}></TableRepositoryName>
</div>

{/* Column: Activity */}
<div className={classNames.cols.activity}>{getActivity(commitMeta.itemCount, commitLoading)}</div>

{/* Column: PR Overview */}
<div className={classNames.cols.prOverview}>
<PullRequestOverview
open={openPrsCount}
merged={mergedPrsCount}
closed={closedPrsCount}
draft={draftPrsCount}
churn={churnTotalCount}
churnDirection={`${churnDirection}`}
></PullRequestOverview>
</div>

{/* Column: PR Velocity */}
<div className={`${classNames.cols.prVelocity}`}>
<div>
{prVelocityCount ?? 0} PR{prVelocityCount === 1 ? "" : "s"}
</div>
<Pill text={`${prsMergedPercentage}%`} size="small" color="green" />
</div>

{/* Column: SPAM */}
<div className={`${classNames.cols.spam}`}>
{spamPrsCount && spamPrsCount > 0 ? (
<>
<div>{spamPrsCount || 0} PR{ spamPrsCount === 1 ? "" : "s" }</div>
<div>
{spamPrsCount || 0} PR{spamPrsCount === 1 ? "" : "s"}
</div>
<Pill text={`${spamPrsPercentage || 0}%`} size="small" color={spamPrsPercentage > 10 ? "red" : "yellow"} />
</>
:
) : (
"-"
}
</div>
)}
</div>

{/* Column: Contributors */}
<div className={`flex ${classNames.cols.contributors}`}>
{ contributorMeta.itemCount! > 0 ? <StackedAvatar contributors={contributorData}/> : "-" }
{/* Column: Contributors */}
<div className={clsx(classNames.cols.contributors, "hidden lg:flex")}>
{contributorMeta.itemCount! > 0 ? <StackedAvatar contributors={contributorData} /> : "-"}

{ contributorMeta.itemCount! >= 5 ? <div>&nbsp;{`+${contributorMeta.itemCount - 5}`}</div>: "" }
</div>
{contributorMeta.itemCount! >= 5 ? <div>&nbsp;{`+${contributorMeta.itemCount - 5}`}</div> : ""}
</div>

{/* Column: Last 30 Days */}
<div className={classNames.cols.last30days}>
{ last30days &&
<Sparkline data={last30days} />
}
{/* Column: Last 30 Days */}
<div className={clsx(classNames.cols.last30days,"hidden lg:flex" )}>{last30days && <Sparkline data={last30days} />}</div>
</div>
</div>)
</>)

;
};
export default RepoRow;
Loading