Skip to content

Commit

Permalink
Merge pull request #1115 from open-sauced/beta
Browse files Browse the repository at this point in the history
v1.43.0-beta.5 -> production
  • Loading branch information
brandonroberts committed Apr 20, 2023
2 parents 2f40987 + c27df89 commit dcd36b0
Show file tree
Hide file tree
Showing 38 changed files with 649 additions and 278 deletions.
40 changes: 40 additions & 0 deletions CHANGELOG.md
Expand Up @@ -5,6 +5,46 @@

> All notable changes to this project will be documented in this file
## [1.43.0-beta.5](https://github.com/open-sauced/insights/compare/v1.43.0-beta.4...v1.43.0-beta.5) (2023-04-20)


### 馃悰 Bug Fixes

* only redirect on contributor profile if login is defined ([#1114](https://github.com/open-sauced/insights/issues/1114)) ([483f38c](https://github.com/open-sauced/insights/commit/483f38c54c6c707873b9e63c78b751bc5a994494))

## [1.43.0-beta.4](https://github.com/open-sauced/insights/compare/v1.43.0-beta.3...v1.43.0-beta.4) (2023-04-20)


### 馃崟 Features

* connect contributors page to API ([#1113](https://github.com/open-sauced/insights/issues/1113)) ([e51c51e](https://github.com/open-sauced/insights/commit/e51c51e4b4f6bc21fa171495578993325c3427ba))

## [1.43.0-beta.3](https://github.com/open-sauced/insights/compare/v1.43.0-beta.2...v1.43.0-beta.3) (2023-04-20)


### 馃悰 Bug Fixes

* adds spacing to contributor highlights container ([#1089](https://github.com/open-sauced/insights/issues/1089)) ([83d89bd](https://github.com/open-sauced/insights/commit/83d89bd95212fd6e739343c3b9774217b5433cab)), closes [#1057](https://github.com/open-sauced/insights/issues/1057)


### 馃崟 Features

* connect contributor page and graphs to the API ([#1072](https://github.com/open-sauced/insights/issues/1072)) ([#1112](https://github.com/open-sauced/insights/issues/1112)) ([4fc471c](https://github.com/open-sauced/insights/commit/4fc471c3223a6cff4bf8cc3c1a4c8a074a56d576))

## [1.43.0-beta.2](https://github.com/open-sauced/insights/compare/v1.43.0-beta.1...v1.43.0-beta.2) (2023-04-18)


### 馃崟 Features

* implement insights team feature ([#1080](https://github.com/open-sauced/insights/issues/1080)) ([5186a60](https://github.com/open-sauced/insights/commit/5186a6089c7dd5f306b7854f5a7706015e33e0f0))

## [1.43.0-beta.1](https://github.com/open-sauced/insights/compare/v1.42.0...v1.43.0-beta.1) (2023-04-18)


### 馃崟 Features

* add page to accept insight member invitation ([#1102](https://github.com/open-sauced/insights/issues/1102)) ([ffe35e2](https://github.com/open-sauced/insights/commit/ffe35e210e6d4115480a0c44478998c73fade875))

## [1.42.0](https://github.com/open-sauced/insights/compare/v1.41.1...v1.42.0) (2023-04-18)


Expand Down
6 changes: 5 additions & 1 deletion components/atoms/Search/search.tsx
@@ -1,4 +1,4 @@
import React, { useState } from "react";
import React, { useEffect, useState } from "react";
import { GrClose } from "react-icons/gr";
import { FaSearch } from "react-icons/fa";
import { Spinner } from "../SpinLoader/spin-loader";
Expand Down Expand Up @@ -44,6 +44,10 @@ const Search = ({
onChange?.("");
};

useEffect(() => {
setSearch(value);
}, [value]);

const handleOnSelect = (suggestion: string) => {
setSearch(suggestion);
onSearch?.(suggestion);
Expand Down
61 changes: 27 additions & 34 deletions components/atoms/Selector/selector.tsx
Expand Up @@ -2,46 +2,39 @@ import Radio from "components/atoms/Radio/radio";
import RadioCheck from "../RadioCheck/radio-check";

interface SelectorProps {
filterOptions: string[];
filterOptions: { name: string; value: string }[];
handleFilterClick: (filter: string) => void;
selected?: string;
variation?: "circle" | "check"
variation?: "circle" | "check";
}

const Selector = ({
filterOptions,
handleFilterClick,
selected,
variation = "circle"
}: SelectorProps) => {
const Selector = ({ filterOptions, handleFilterClick, selected, variation = "circle" }: SelectorProps) => {
return (
<div className="mt-2 absolute transform md:translate-x-0 space-y-1 mt-1 shadow-superlative z-10 w-72 bg-white rounded-lg px-1.5 py-2">
<div className="mt-2 absolute transform md:translate-x-0 space-y-1 shadow-superlative z-10 w-72 bg-white rounded-lg px-1.5 py-2">
{filterOptions.length > 0 &&
filterOptions.map((option, index) => {
return (
variation === "circle" ? (
<Radio
key={index}
onClick={() => {
handleFilterClick(option);
}}
className="!w-full"
checked={selected === option ? true : false}
>
{option}
</Radio>
) : (
<RadioCheck
key={index}
onClick={() => {
handleFilterClick(option);
}}
className="!w-full"
checked={selected === option ? true : false}
>
{option}
</RadioCheck>
)
filterOptions.map(({ name, value }, index) => {
return variation === "circle" ? (
<Radio
key={index}
onClick={() => {
handleFilterClick(value);
}}
className="!w-full"
checked={selected === value ? true : false}
>
{name}
</Radio>
) : (
<RadioCheck
key={index}
onClick={() => {
handleFilterClick(value);
}}
className="!w-full"
checked={selected === value ? true : false}
>
{name}
</RadioCheck>
);
})}
</div>
Expand Down
Expand Up @@ -29,13 +29,15 @@ const CardHorizontalBarChart = ({ languageList, withDescription }: CardHorizonta
// used this state to calculate thte percentage of each language
const [percentage, setPercentage] = useState<any>(0);

const [descriptText, setDescriptText] = useState(sortedLangArray[0].languageName);
const [descriptText, setDescriptText] = useState(sortedLangArray[0]?.languageName || "javascript");

const handleChangeDescriptText = (descriptText: string) => {
setDescriptText(descriptText);
};

useEffect(() => {
if (sortedLangArray.length === 0) return;

const totalSumOfFirstFivePercentage = sortedLangArray
.slice(0, 4)
.map((lang) => lang.percentageUsed)
Expand Down
46 changes: 27 additions & 19 deletions components/molecules/FilterCardSelect/filter-card-select.tsx
Expand Up @@ -8,10 +8,10 @@ import repoIcon from "../../../img/icons/repo.svg";
import Selector from "../../atoms/Selector/selector";

interface FilterCardSelectProps {
selected: string;
icon?: "topic" | "repo" | "org" | "contributor";
options: string[];
handleFilterClick: (filter: string) => void;
selected: string;
icon?: "topic" | "repo" | "org" | "contributor";
options: string[];
handleFilterClick: (filter: string) => void;
}

const icons = {
Expand All @@ -33,8 +33,12 @@ const icons = {
}
};

const FilterCardSelect: React.FC<FilterCardSelectProps> = ({ selected: filterName, icon = "topic", options, handleFilterClick }) => {

const FilterCardSelect: React.FC<FilterCardSelectProps> = ({
selected: filterName,
icon = "topic",
options,
handleFilterClick
}) => {
const ref = useRef<HTMLDivElement>(null);
const [isOpen, setIsOpen] = useState(false);
const toggleFilter = () => {
Expand Down Expand Up @@ -62,22 +66,26 @@ const FilterCardSelect: React.FC<FilterCardSelectProps> = ({ selected: filterNam
<div
onClick={toggleFilter}
ref={ref}
className={"inline-block py-1 border border-slate-300 outline-none hover:bg-slate-50 focus:ring-2 bg-slate-100 focus:ring-slate-300 rounded-lg cursor-pointer"}>
className={
"inline-block py-1 border border-slate-300 outline-none hover:bg-slate-50 focus:ring-2 bg-slate-100 focus:ring-slate-300 rounded-lg cursor-pointer"
}
>
<button className="flex items-center gap-1 mx-2">
<Image
width={14} height={14}
alt={icon === "topic" ? icons.topic.alt : icon === "org" ? icons.org.alt : icon === "contributor" ? icons.contributor.alt : icon === "repo" ? icons.repo.alt : "Icon"}
src={icon === "topic" ? icons.topic.src : icon === "org" ? icons.org.src : icon === "contributor" ? icons.contributor.src : icon === "repo" ? icons.repo.src : icons.topic.src} />
<Text className="!text-sm font-semibold tracking-tight !text-slate-900">
{filterName}
</Text>
width={14}
height={14}
alt={icons[icon] ? icons[icon].alt : "Icons"}
src={icons[icon] ? icons[icon].src : icons.topic.src}
/>
<Text className="!text-sm font-semibold tracking-tight !text-slate-900">{filterName}</Text>
</button>
{ isOpen && <Selector
filterOptions={options}
handleFilterClick={handleFilterClick}
selected={filterName}
/>
}
{isOpen && (
<Selector
filterOptions={options.map((option) => ({ name: option, value: option }))}
handleFilterClick={handleFilterClick}
selected={filterName}
/>
)}
</div>
</>
);
Expand Down
5 changes: 3 additions & 2 deletions components/molecules/PullRequestTable/pull-request-table.tsx
Expand Up @@ -19,10 +19,11 @@ interface CardTableProps {
repositories?: number[];
limit?: number;
isHoverCard?: boolean;
range?: number;
}

const PullRequestTable = ({ contributor, topic, repositories, limit, isHoverCard }: CardTableProps): JSX.Element => {
const { data, isLoading } = useContributorPullRequests(contributor, topic, repositories, limit);
const PullRequestTable = ({ contributor, topic, repositories, limit, isHoverCard, range }: CardTableProps): JSX.Element => {
const { data, isLoading } = useContributorPullRequests(contributor, topic, repositories, limit, range);

return data.length > 0 ? (
<>
Expand Down
4 changes: 3 additions & 1 deletion components/molecules/RepoRow/repo-row.tsx
Expand Up @@ -24,6 +24,7 @@ import { getAvatarByUsername } from "lib/utils/github";
import useRepositoryPullRequests from "lib/hooks/api/useRepositoryPullRequests";
import getPullRequestsToDays from "lib/utils/get-prs-to-days";
import getPullRequestsContributors from "lib/utils/get-pr-contributors";
import useStore from "lib/store";

interface RepoProps {
repo: RepositoriesRows;
Expand Down Expand Up @@ -92,7 +93,8 @@ const RepoRow = ({ repo, topic, userPage, selected, handleOnSelectRepo }: RepoPr
const ownerAvatar = getAvatarByUsername(fullName.split("/")[0]);

const { user } = useSupabaseAuth();
const { data: repositoryPullRequests } = useRepositoryPullRequests(repo.full_name, 100);
const range = useStore((state) => state.range);
const { data: repositoryPullRequests } = useRepositoryPullRequests(repo.full_name, 100, range);
const totalPrs = getTotalPrs(openPrsCount, mergedPrsCount, closedPrsCount, draftPrsCount);
const prsMergedPercentage = getPercent(totalPrs, mergedPrsCount || 0);
const spamPrsPercentage = getPrsSpam(totalPrs, spamPrsCount || 0);
Expand Down
63 changes: 48 additions & 15 deletions components/molecules/TeamMemberRow/team-member-row.tsx
Expand Up @@ -3,43 +3,76 @@ import { AiOutlineCaretDown } from "react-icons/ai";
import pendingImg from "img/icons/fallback-image-disabled-square.svg";
import { useState } from "react";
import Selector from "components/atoms/Selector/selector";
import { TeamMemberData } from "../TeamMembersConfig/team-members-config";
import { MemberAccess, TeamMemberData } from "../TeamMembersConfig/team-members-config";

interface TeamMemberRowProps extends TeamMemberData {
className?: string;
onDelete: (memberId: string) => void;
onUpdate: (memberId: string, access: MemberAccess) => Promise<any> | undefined;
}

const mapRoleToText: Record<TeamMemberRowProps["role"], string> = {
const mapRoleToText: Record<TeamMemberRowProps["access"], string> = {
owner: "Owner",
admin: "Admin",
editor: "can edit",
viewer: "can view",
edit: "can edit",
view: "can view",
pending: "Pending"
};

const TeamMemberRow = ({ className, name, avatarUrl, role }: TeamMemberRowProps) => {

const TeamMemberRow = ({ className, name, avatarUrl, access, email, onDelete, onUpdate, id }: TeamMemberRowProps) => {
const [isMenuOpen, setIsMenuOpen] = useState(false);

const pending = role == "pending";
const pending = access == "pending";
const isOwner = access == "owner";

const handleRoleChange = (role: string) => {};
const handleRoleChange = async (role: string) => {
setIsMenuOpen(false);
if (role === "remove") {
onDelete(id);
} else {
onUpdate(id, role as MemberAccess);
}
};

return(
return (
<div className={`flex justify-between items-center ${className && className} ${pending && "text-light-slate-10"}`}>
<div className="flex items-center">
<div className="flex items-center gap-3">
<Avatar size={40} isCircle avatarURL={pending ? pendingImg : avatarUrl} />
<p className="ml-3">{name}</p>
<p>{name || email}</p>
</div>
<div>
<div className="flex items-center gap-3">
{mapRoleToText[role]} {!pending && <AiOutlineCaretDown onClick={() => {setIsMenuOpen(!isMenuOpen);}} />}
{mapRoleToText[access]}
{!pending && (
<>
{isOwner ? (
<AiOutlineCaretDown />
) : (
<AiOutlineCaretDown
className="cursor-pointer"
onClick={() => {
setIsMenuOpen(!isMenuOpen);
}}
/>
)}
</>
)}
</div>
{ !pending && isMenuOpen && (
<Selector filterOptions={["Admin", "can edit", "can view"]} selected={mapRoleToText[role]} variation="check" handleFilterClick={handleRoleChange} />
{!pending && isMenuOpen && (
<Selector
filterOptions={[
{ name: "Admin", value: "admin" },
{ name: "can edit", value: "edit" },
{ name: "can view", value: "view" },
{ name: "remove", value: "remove" }
]}
selected={access}
variation="check"
handleFilterClick={handleRoleChange}
/>
)}
</div>
</div>
);

};
export default TeamMemberRow;

0 comments on commit dcd36b0

Please sign in to comment.