From 504d7e2499a6b2a9dd5beaa560dd9ca7aa6af4c8 Mon Sep 17 00:00:00 2001 From: Brandon Roberts Date: Mon, 2 Oct 2023 11:35:36 -0500 Subject: [PATCH 01/45] feat: add form to user settings to apply coupon code (#1771) Co-authored-by: Nick Taylor --- .../UserSettingsPage/coupon-form.tsx | 70 ++++++++++++++++++ .../UserSettingsPage/user-settings-page.tsx | 72 +++++++++++-------- next-types.d.ts | 1 + 3 files changed, 112 insertions(+), 31 deletions(-) create mode 100644 components/organisms/UserSettingsPage/coupon-form.tsx diff --git a/components/organisms/UserSettingsPage/coupon-form.tsx b/components/organisms/UserSettingsPage/coupon-form.tsx new file mode 100644 index 0000000000..8319ebe158 --- /dev/null +++ b/components/organisms/UserSettingsPage/coupon-form.tsx @@ -0,0 +1,70 @@ +import { useState } from "react"; + +import Button from "components/atoms/Button/button"; +import TextInput from "components/atoms/TextInput/text-input"; +import { useToast } from "lib/hooks/useToast"; +import { supabase } from "lib/utils/supabase"; + +interface CouponFormProps { + refreshUser: () => void; +} + +const CouponForm = ({ refreshUser }: CouponFormProps) => { + const [updating, setUpdating] = useState(false); + const [code, setCode] = useState(""); + const { toast } = useToast(); + + const handeApplyCoupon = async () => { + const sessionResponse = await supabase.auth.getSession(); + const sessionToken = sessionResponse?.data.session?.access_token; + setUpdating(true); + + const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/profile/coupon`, { + headers: { + Accept: "application/json", + "Content-Type": "application/json", + Authorization: `Bearer ${sessionToken}`, + }, + method: "PATCH", + body: JSON.stringify({ + couponCode: code, + }), + }); + + if (response.ok) { + toast({ description: "Coupon applied successfully", variant: "success" }); + setCode(""); + refreshUser?.(); + } else { + toast({ description: "Coupon not found!", variant: "danger" }); + } + + setUpdating(false); + }; + + return ( +
+
+ + setCode(e.target.value)} + /> +
+ +
+ ); +}; + +export default CouponForm; diff --git a/components/organisms/UserSettingsPage/user-settings-page.tsx b/components/organisms/UserSettingsPage/user-settings-page.tsx index b570a47572..def6d14328 100644 --- a/components/organisms/UserSettingsPage/user-settings-page.tsx +++ b/components/organisms/UserSettingsPage/user-settings-page.tsx @@ -22,6 +22,7 @@ import { useFetchUser } from "lib/hooks/useFetchUser"; import { getInterestOptions } from "lib/utils/getInterestOptions"; import { useToast } from "lib/hooks/useToast"; import { validateTwitterUsername } from "lib/utils/validate-twitter-username"; +import CouponForm from "./coupon-form"; interface userSettingsPageProps { user: User | null; @@ -59,6 +60,7 @@ const UserSettingsPage = ({ user }: userSettingsPageProps) => { const [selectedInterest, setSelectedInterest] = useState([]); const formRef = useRef(null); const interestArray = getInterestOptions(); + const [coupon, setCoupon] = useState(""); useEffect(() => { const response = session; @@ -68,6 +70,7 @@ const UserSettingsPage = ({ user }: userSettingsPageProps) => { formRef.current!.nameInput.value = response.name; setEmail(response.email); setDisplayLocalTime(response.display_local_time); + setCoupon(response.coupon_code); formRef.current!.bio.value = response.bio; formRef.current!.url.value = response.url; formRef.current!.twitter_username.value = response.twitter_username; @@ -129,7 +132,7 @@ const UserSettingsPage = ({ user }: userSettingsPageProps) => { if (data) { toast({ description: "Updated successfully", variant: "success" }); } else { - toast({ description: "An error occured!", variant: "danger" }); + toast({ description: "An error occurred!", variant: "danger" }); } setUpdating((prev) => ({ ...prev, emailPreferences: false })); @@ -149,7 +152,7 @@ const UserSettingsPage = ({ user }: userSettingsPageProps) => { mutate(); toast({ description: "Updated successfully", variant: "success" }); } else { - toast({ description: "An error occured!", variant: "danger" }); + toast({ description: "An error occurred!", variant: "danger" }); } }; @@ -188,7 +191,7 @@ const UserSettingsPage = ({ user }: userSettingsPageProps) => { mutate(); toast({ description: "Updated successfully", variant: "success" }); } else { - toast({ description: "An error occured!", variant: "danger" }); + toast({ description: "An error occurred!", variant: "danger" }); } }; @@ -373,37 +376,44 @@ const UserSettingsPage = ({ user }: userSettingsPageProps) => { Update Preferences - {!hasReports ? ( -
-
- -
- Upgrade to a subscription to gain access to generate custom reports! -
-
- -
- ) : ( + {userInfo && (
-
-
- -
- - You are currently subscribed to the Pro plan and currently have access to all premium features. - + {!hasReports && !coupon ? ( +
+
+ +
+ Upgrade to a subscription to gain access to generate custom reports! +
+
+ + + {!coupon && } +
+ ) : ( +
+
+
+ +
+ + You are currently subscribed to the Pro plan and currently have access to all premium + features. + +
+
+
- -
+ )}
)}
diff --git a/next-types.d.ts b/next-types.d.ts index db58e48b4a..12686fefc0 100644 --- a/next-types.d.ts +++ b/next-types.d.ts @@ -235,6 +235,7 @@ interface DbUser { readonly following_count: number; readonly highlights_count: number; readonly is_maintainer: boolean; + readonly coupon_code: string; } interface DbHighlight { From f43502655626f6e588caca352e6340a7fcfb2560 Mon Sep 17 00:00:00 2001 From: Brandon Roberts Date: Mon, 2 Oct 2023 16:42:54 +0000 Subject: [PATCH 02/45] chore(minor): release 1.68.0-beta.1 on beta channel [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.68.0-beta.1](https://github.com/open-sauced/insights/compare/v1.67.0...v1.68.0-beta.1) (2023-10-02) ### πŸ• Features * add form to user settings to apply coupon code ([#1771](https://github.com/open-sauced/insights/issues/1771)) ([504d7e2](https://github.com/open-sauced/insights/commit/504d7e2499a6b2a9dd5beaa560dd9ca7aa6af4c8)) --- CHANGELOG.md | 7 +++++++ npm-shrinkwrap.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6de69e7c37..f10f056433 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ > All notable changes to this project will be documented in this file +## [1.68.0-beta.1](https://github.com/open-sauced/insights/compare/v1.67.0...v1.68.0-beta.1) (2023-10-02) + + +### πŸ• Features + +* add form to user settings to apply coupon code ([#1771](https://github.com/open-sauced/insights/issues/1771)) ([504d7e2](https://github.com/open-sauced/insights/commit/504d7e2499a6b2a9dd5beaa560dd9ca7aa6af4c8)) + ## [1.67.0](https://github.com/open-sauced/insights/compare/v1.66.0...v1.67.0) (2023-10-02) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 8905c03774..bf39cf977f 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "@open-sauced/insights", - "version": "1.67.0", + "version": "1.68.0-beta.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@open-sauced/insights", - "version": "1.67.0", + "version": "1.68.0-beta.1", "hasInstallScript": true, "license": "Apache 2.0", "dependencies": { diff --git a/package.json b/package.json index a7ebad974b..3c2f656701 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@open-sauced/insights", "description": "πŸ•The dashboard for open source discovery.", "keywords": [], - "version": "1.67.0", + "version": "1.68.0-beta.1", "author": "Brian Douglas ", "private": true, "license": "Apache 2.0", From 9b81371bde8ce5a9838dec6d19a007aa964b072b Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Mon, 2 Oct 2023 15:31:42 -0400 Subject: [PATCH 03/45] fix: removed GitHub avatar when loading user profile avatars --- .../CollaborationCard/collaboration-card.tsx | 7 +++---- lib/utils/github.ts | 6 ++---- stories/molecules/collaboration-card.stories.tsx | 5 ++++- .../molecules/collaboration-summary-card.stories.tsx | 11 ++++++++--- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/components/molecules/CollaborationCard/collaboration-card.tsx b/components/molecules/CollaborationCard/collaboration-card.tsx index 66beafff8c..5ffc35593c 100644 --- a/components/molecules/CollaborationCard/collaboration-card.tsx +++ b/components/molecules/CollaborationCard/collaboration-card.tsx @@ -5,7 +5,7 @@ import { getAvatarByUsername } from "lib/utils/github"; import Button from "components/atoms/Button/button"; export interface CollaborationRequestObject extends React.ComponentProps<"div"> { - requestor: DbUser | undefined; + requestor: DbUser; outreachMessage: string; requestId: string; onAccept: (id: string) => void; @@ -24,9 +24,8 @@ const CollaborationCard = ({
- - -
{requestor?.name}
+ +
{requestor.name}
+ + + {Object.entries(dateFilters).map(([key, value]) => ( + setCurrentDateFilter(key as keyof typeof dateFilters)} + > + {value} + + ))} + + + + + + + + {Object.entries(peopleFilters).map(([key, value]) => ( + setCurrentPeopleFilter(key as keyof typeof peopleFilters)} + > + {value} + + ))} + + +
+ {/* chart */} +
+
+ colors[d.id as keyof typeof colors]} + tooltipLabel={(d) => labels[d.id as keyof typeof labels]} + /> +
+
+ {/* key */} +
+ {dataTypes.map((type) => ( +
+
+
{type}
+
+ ))} +
+
+ +
+ ); +} diff --git a/components/molecules/ContributionsEvolutionByTypeCard/contributions-evolution-by-type-card.tsx b/components/molecules/ContributionsEvolutionByTypeCard/contributions-evolution-by-type-card.tsx new file mode 100644 index 0000000000..53910785c1 --- /dev/null +++ b/components/molecules/ContributionsEvolutionByTypeCard/contributions-evolution-by-type-card.tsx @@ -0,0 +1,200 @@ +import { useState } from "react"; +import { ResponsiveLine } from "@nivo/line"; +import { format } from "date-fns"; +import Button from "components/atoms/Button/button"; +import Card from "components/atoms/Card/card"; +import Icon from "components/atoms/Icon/icon"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "components/atoms/Dropdown/dropdown"; +import PeopleIcon from "img/icons/people.svg"; +import CalendarIcon from "img/calendar.svg"; +import ChevronDownIcon from "img/chevron-down.svg"; +import SVGIcon from "components/atoms/SVGIcon/svg-icon"; + +const dataTypes = ["active", "new", "churned"] as const; +type Stat = (typeof dataTypes)[number]; + +const dataLabels = { + active: "Active", + new: "New", + churned: "Churned", +} as const satisfies Record; + +const colors = { + active: "#46a758", // green + new: "#0ea5e9", // blue + churned: "#f59e0b", // orange +} as const satisfies Record; + +interface ContributionEvolutionByTypeDatum { + startTime: string; + active: number; + new: number; + churned: number; +} + +interface Props { + data: ContributionEvolutionByTypeDatum[]; +} + +const dateFilters = { + last7days: "Last 7 days", + last30days: "Last 30 days", + last3months: "Last 3 months", +}; + +const peopleFilters = { + all: "All Contributors", + active: "Active Contributors", + new: "New Contributors", + churned: "Churned Contributors", +}; + +export default function ContributionsEvolutionByType(props: Props) { + const [currentDateFilter, setCurrentDateFilter] = useState("last7days"); // TODO: make this a prop + const [currentPeopleFilter, setCurrentPeopleFilter] = useState("all"); // TODO: make this a prop + + /* + Group the data by kind of contributor 'active', 'new', 'churned' + format it like so: + + [ + { + id: 'active', + color: colors['active'], + data: [ + { + x: '01/01', + y: 10 + }, + { + x: '01/02', + y: 20 + }, + ... + ], + }, + ] + */ + + const groupedData = dataTypes.map((type) => ({ + id: dataLabels[type], + color: colors[type], + data: props.data.map((datum) => ({ + x: new Date(datum.startTime), + y: datum[type], + })), + })); + console.log(groupedData); + + return ( +
+ +
+
Contributions Evolution
+
This is going to be an auto-generated insight.
+ {/* buttons */} +
+ + + + + + {Object.entries(dateFilters).map(([key, value]) => ( + setCurrentDateFilter(key as keyof typeof dateFilters)} + > + {value} + + ))} + + + + + + + + {Object.entries(peopleFilters).map(([key, value]) => ( + setCurrentPeopleFilter(key as keyof typeof peopleFilters)} + > + {value} + + ))} + + +
+ {/* chart */} +
+
+ format(value, "MM/dd"), + tickSize: 0, + }} + margin={{ top: 20, right: 40, bottom: 30, left: 40 }} + motionConfig="stiff" + curve="monotoneX" + colors={(d) => d.color} + /> +
+
+ {/* key */} +
+ {dataTypes.map((type) => ( +
+
+
{type}
+
+ ))} +
+
+
+
+ ); +} diff --git a/components/molecules/MostActiveContributorsCard/most-active-contributors-card.tsx b/components/molecules/MostActiveContributorsCard/most-active-contributors-card.tsx new file mode 100644 index 0000000000..7d8f904db8 --- /dev/null +++ b/components/molecules/MostActiveContributorsCard/most-active-contributors-card.tsx @@ -0,0 +1,261 @@ +import { useSprings, animated } from "@react-spring/web"; +import { useGesture } from "@use-gesture/react"; +import Image from "next/image"; +import { useState } from "react"; +import * as Tooltip from "@radix-ui/react-tooltip"; +import clsx from "clsx"; +import Button from "components/atoms/Button/button"; +import Card from "components/atoms/Card/card"; +import Icon from "components/atoms/Icon/icon"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "components/atoms/Dropdown/dropdown"; +import { getAvatarByUsername } from "lib/utils/github"; +import PeopleIcon from "img/icons/people.svg"; +import CalendarIcon from "img/calendar.svg"; +import ChevronDownIcon from "img/chevron-down.svg"; +import SortArrowsIcon from "img/icons/sort-arrows.svg"; +import SVGIcon from "components/atoms/SVGIcon/svg-icon"; + +const dataTypes = ["commits", "prsCreated", "prsReviewed", "issuesCreated", "comments"] as const; +type Stat = (typeof dataTypes)[number]; + +const dataLabels = { + commits: "Commits", + prsCreated: "Created PR", + prsReviewed: "Reviewed PR", + issuesCreated: "Created Issues", + comments: "Commented", +} as const satisfies Record; + +const colors = { + commits: "hsla(217, 91%, 60%, 1)", + prsCreated: "hsla(173, 80%, 40%, 1)", + prsReviewed: "hsla(198, 93%, 60%, 1)", + issuesCreated: "hsla(258, 90%, 66%, 1)", + comments: "hsla(245, 58%, 51%, 1)", +} as const satisfies Record; + +interface ContributorStat { + login: string; + totalContributions: number; + contributions: Record; +} + +interface Props { + data: ContributorStat[]; +} + +const dateFilters = { + last7days: "Last 7 days", + last30days: "Last 30 days", + last3months: "Last 3 months", +}; + +const peopleFilters = { + all: "All Contributors", + active: "Active Contributors", + new: "New Contributors", + churned: "Churned Contributors", +}; + +export default function MostActiveContributorsCard(props: Props) { + const [currentDateFilter, setCurrentDateFilter] = useState("last7days"); // TODO: make this a prop + const [currentPeopleFilter, setCurrentPeopleFilter] = useState("all"); // TODO: make this a prop + const sortedData = props.data.sort((a, b) => b.totalContributions - a.totalContributions); + + const topContributor = sortedData[0]; + const allContributions = sortedData.reduce((acc, curr) => acc + curr.totalContributions, 0); + const maxContributions = topContributor.totalContributions; + const topContributorPercent = ((maxContributions / allContributions) * 100).toFixed(2) + "%"; + + return ( +
+ +
+
Most active contributors
+
+ {topContributor.login} made {topContributorPercent} of all code contributions +
+ {/* buttons */} +
+ + + + + + {Object.entries(dateFilters).map(([key, value]) => ( + setCurrentDateFilter(key as keyof typeof dateFilters)} + > + {value} + + ))} + + + + + + + + {Object.entries(peopleFilters).map(([key, value]) => ( + setCurrentPeopleFilter(key as keyof typeof peopleFilters)} + > + {value} + + ))} + + + + + + + + One + Two + Three + + +
+ {/* chart */} +
+ {/* inset shadow */} +
+
+ {sortedData.map((user) => ( + + ))} +
+
+ {/* key */} +
+ {dataTypes.map((type) => ( +
+
+
{dataLabels[type]}
+
+ ))} +
+
+
+
+ ); +} + +function RowTooltip({ + contributor, + highlightedStat, + children, +}: { + contributor: ContributorStat; + highlightedStat: keyof ContributorStat["contributions"]; + children: React.ReactNode; +}) { + return ( + + {children} + + +
+
{contributor.login}
+ {Object.keys(contributor.contributions).map((key) => ( +
+
+
+ {contributor.contributions[key as keyof typeof contributor.contributions]} {dataLabels[key as Stat]} +
+
+ ))} +
+
+
+
+ ); +} + +function GraphRow({ user, maxContributions }: { user: ContributorStat; maxContributions: number }) { + const [isHovered, setIsHovered] = useState(false); + const [springs] = useSprings( + dataTypes.length, + (index: number) => ({ + from: { + width: "0%", + }, + to: { + width: `${(user.contributions[dataTypes[index]] / user.totalContributions) * 100}%`, + }, + }), + [user.contributions, user.totalContributions, maxContributions] + ); + + // When hovered the tooltip should show for the the GraphRow + const hoverGesture = useGesture({ + onHover: (state) => { + setIsHovered(Boolean(state.hovering)); + }, + }); + + return ( + <> + {user.login} +
{user.login}
+
+
+ {springs.map((spring, index) => ( + + + {" "} + + + ))} +
+
+ + ); +} diff --git a/img/calendar.svg b/img/calendar.svg new file mode 100644 index 0000000000..20247c94c6 --- /dev/null +++ b/img/calendar.svg @@ -0,0 +1,3 @@ + + + diff --git a/img/icons/people.svg b/img/icons/people.svg new file mode 100644 index 0000000000..6d942ddfee --- /dev/null +++ b/img/icons/people.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/img/icons/sort-arrows.svg b/img/icons/sort-arrows.svg new file mode 100644 index 0000000000..325f851476 --- /dev/null +++ b/img/icons/sort-arrows.svg @@ -0,0 +1,4 @@ + + + + diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 9d2b21369f..ee1c0494d0 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -12,6 +12,7 @@ "dependencies": { "@headlessui/react": "^1.7.8", "@heroicons/react": "^2.0.14", + "@nivo/bar": "^0.83.0", "@nivo/core": "^0.80.0", "@nivo/line": "^0.80.0", "@nivo/pie": "^0.80.0", @@ -5009,6 +5010,187 @@ "react-dom": "^16.8.0 || >=17.0.0 || >=18.0.0" } }, + "node_modules/@nivo/bar": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/bar/-/bar-0.83.0.tgz", + "integrity": "sha512-QXN6BcT1PiT/YViyoDU4G5mytbOUP1jYbuQmJhDDxKPMLNcZ/pHfThedRGVfDoD1poHBRJtV6mbgeCpAVmlTtw==", + "dependencies": { + "@nivo/annotations": "0.83.0", + "@nivo/axes": "0.83.0", + "@nivo/colors": "0.83.0", + "@nivo/core": "0.83.0", + "@nivo/legends": "0.83.0", + "@nivo/scales": "0.83.0", + "@nivo/tooltip": "0.83.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-scale": "^3.2.3", + "@types/d3-shape": "^2.0.0", + "d3-scale": "^3.2.3", + "d3-shape": "^1.3.5", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/bar/node_modules/@nivo/annotations": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/annotations/-/annotations-0.83.0.tgz", + "integrity": "sha512-FkfCprk1a3WCCNcQOfI2+Ww7vqTP/nJjQDVhFYf1YAaEGwXi4+OO4uJAtKtNcGE5cJWdOp+f0Gt4aNPGx7RtEw==", + "dependencies": { + "@nivo/colors": "0.83.0", + "@nivo/core": "0.83.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/prop-types": "^15.7.2", + "lodash": "^4.17.21", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/bar/node_modules/@nivo/axes": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/axes/-/axes-0.83.0.tgz", + "integrity": "sha512-rHMl+DdXQlY2wl7VCSQNcJi4QNISUWOkcWzJeJeVaYR73Z13SVGgiC7kW0czJuogDTSnDAJ/EcFCGmyGVuznGQ==", + "dependencies": { + "@nivo/core": "0.83.0", + "@nivo/scales": "0.83.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-format": "^1.4.1", + "@types/d3-time-format": "^2.3.1", + "@types/prop-types": "^15.7.2", + "d3-format": "^1.4.4", + "d3-time-format": "^3.0.0", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/bar/node_modules/@nivo/colors": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/colors/-/colors-0.83.0.tgz", + "integrity": "sha512-n34LWYtE2hbd1fdCDP7TCHNZdbiO1PwcvXLo0VsKK5lNPY/FA5SXA7Z9Ubl/ChSwBwbzAsaAhjTy8KzKzSjDcA==", + "dependencies": { + "@nivo/core": "0.83.0", + "@types/d3-color": "^2.0.0", + "@types/d3-scale": "^3.2.3", + "@types/d3-scale-chromatic": "^2.0.0", + "@types/prop-types": "^15.7.2", + "d3-color": "^3.1.0", + "d3-scale": "^3.2.3", + "d3-scale-chromatic": "^2.0.0", + "lodash": "^4.17.21", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/bar/node_modules/@nivo/core": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/core/-/core-0.83.0.tgz", + "integrity": "sha512-I9fjZAbIPz41JA2WP8Avsud/xk0iiM1nWUzcvZBDebBGFDB5Y1lrldUt9l5kvOeMth3Qj/1lVFTiJxQuojxH4Q==", + "dependencies": { + "@nivo/recompose": "0.83.0", + "@nivo/tooltip": "0.83.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-shape": "^2.0.0", + "d3-color": "^3.1.0", + "d3-format": "^1.4.4", + "d3-interpolate": "^2.0.1", + "d3-scale": "^3.2.3", + "d3-scale-chromatic": "^2.0.0", + "d3-shape": "^1.3.5", + "d3-time-format": "^3.0.0", + "lodash": "^4.17.21" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nivo/donate" + }, + "peerDependencies": { + "prop-types": ">= 15.5.10 < 16.0.0", + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/bar/node_modules/@nivo/legends": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/legends/-/legends-0.83.0.tgz", + "integrity": "sha512-WWl3/hTpFJ7/2L0RG53Gbr9KQk+ZjD71a/RIPMJ5ArEvAvKKfWuWQCtEm3FpqAazX8eYMnsQ3Pi17c8ohEIXRg==", + "dependencies": { + "@nivo/colors": "0.83.0", + "@nivo/core": "0.83.0", + "@types/d3-scale": "^3.2.3", + "@types/prop-types": "^15.7.2", + "d3-scale": "^3.2.3", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/bar/node_modules/@nivo/recompose": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/recompose/-/recompose-0.83.0.tgz", + "integrity": "sha512-3cLEoi9ZoE4LTn6B98oUVd0MRAy5bWK7W3yb0u4EkjLoXXCRvUAI08Wr2AAagOzVOg5PmvghIDgvkz1tlFZTGQ==", + "dependencies": { + "@types/prop-types": "^15.7.2", + "@types/react-lifecycles-compat": "^3.0.1", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/bar/node_modules/@nivo/scales": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/scales/-/scales-0.83.0.tgz", + "integrity": "sha512-DZn5IcMJErCURDuQPmYltu6GTPphTDVLMvbeN/Id/VSVbD1uYKvdXPKUNOe/N2IvnE8wjjCPv88DLcRhw6VTVg==", + "dependencies": { + "@types/d3-scale": "^3.2.3", + "@types/d3-time": "^1.1.1", + "@types/d3-time-format": "^3.0.0", + "d3-scale": "^3.2.3", + "d3-time": "^1.0.11", + "d3-time-format": "^3.0.0", + "lodash": "^4.17.21" + } + }, + "node_modules/@nivo/bar/node_modules/@nivo/scales/node_modules/@types/d3-time-format": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-3.0.1.tgz", + "integrity": "sha512-5GIimz5IqaRsdnxs4YlyTZPwAMfALu/wA4jqSiuqgdbCxUZ2WjrnwANqOtoBJQgeaUTdYNfALJO0Yb0YrDqduA==" + }, + "node_modules/@nivo/bar/node_modules/@nivo/tooltip": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/tooltip/-/tooltip-0.83.0.tgz", + "integrity": "sha512-HewujRqZNmcVnAv/LPLVyYwViad+rYTsFMdzLRzuTPq2hju1R+cfxokTomunG8e1SDtUPtULEVXtPg2ATIzNYg==", + "dependencies": { + "@nivo/core": "0.83.0", + "@react-spring/web": "9.4.5 || ^9.7.2" + } + }, + "node_modules/@nivo/bar/node_modules/@types/d3-time": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-1.1.1.tgz", + "integrity": "sha512-ULX7LoqXTCYtM+tLYOaeAJK7IwCT+4Gxlm2MaH0ErKLi07R5lh8NHCAyWcDkCCmx1AfRcBEV6H9QE9R25uP7jw==" + }, + "node_modules/@nivo/bar/node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, + "node_modules/@nivo/bar/node_modules/d3-time": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz", + "integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA==" + }, "node_modules/@nivo/colors": { "version": "0.80.0", "resolved": "https://registry.npmjs.org/@nivo/colors/-/colors-0.80.0.tgz", @@ -13882,6 +14064,52 @@ "@types/node": "*" } }, + "node_modules/@types/d3-color": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/d3-color/-/d3-color-2.0.3.tgz", + "integrity": "sha512-+0EtEjBfKEDtH9Rk3u3kLOUXM5F+iZK+WvASPb0MhIZl8J8NUvGeZRwKCXl+P3HkYx5TdU4YtcibpqHkSR9n7w==" + }, + "node_modules/@types/d3-format": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-1.4.2.tgz", + "integrity": "sha512-WeGCHAs7PHdZYq6lwl/+jsl+Nfc1J2W1kNcMeIMYzQsT6mtBDBgtJ/rcdjZ0k0rVIvqEZqhhuD5TK/v3P2gFHQ==" + }, + "node_modules/@types/d3-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@types/d3-path/-/d3-path-2.0.2.tgz", + "integrity": "sha512-3YHpvDw9LzONaJzejXLOwZ3LqwwkoXb9LI2YN7Hbd6pkGo5nIlJ09ul4bQhBN4hQZJKmUpX8HkVqbzgUKY48cg==" + }, + "node_modules/@types/d3-scale": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/@types/d3-scale/-/d3-scale-3.3.2.tgz", + "integrity": "sha512-gGqr7x1ost9px3FvIfUMi5XA/F/yAf4UkUDtdQhpH92XCT0Oa7zkkRzY61gPVJq+DxpHn/btouw5ohWkbBsCzQ==", + "dependencies": { + "@types/d3-time": "^2" + } + }, + "node_modules/@types/d3-scale-chromatic": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/d3-scale-chromatic/-/d3-scale-chromatic-2.0.1.tgz", + "integrity": "sha512-3EuZlbPu+pvclZcb1DhlymTWT2W+lYsRKBjvkH2ojDbCWDYavifqu1vYX9WGzlPgCgcS4Alhk1+zapXbGEGylQ==" + }, + "node_modules/@types/d3-shape": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@types/d3-shape/-/d3-shape-2.1.3.tgz", + "integrity": "sha512-HAhCel3wP93kh4/rq+7atLdybcESZ5bRHDEZUojClyZWsRuEMo3A52NGYJSh48SxfxEU6RZIVbZL2YFZ2OAlzQ==", + "dependencies": { + "@types/d3-path": "^2" + } + }, + "node_modules/@types/d3-time": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/@types/d3-time/-/d3-time-2.1.1.tgz", + "integrity": "sha512-9MVYlmIgmRR31C5b4FVSWtuMmBHh2mOWQYfl7XAYOa8dsnb7iEmUmRSWSFgXFtkjxO65d7hTUHQC+RhR/9IWFg==" + }, + "node_modules/@types/d3-time-format": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@types/d3-time-format/-/d3-time-format-2.3.1.tgz", + "integrity": "sha512-fck0Z9RGfIQn3GJIEKVrp15h9m6Vlg0d5XXeiE/6+CQiBmMDZxfR21XtjEPuDeg7gC3bBM0SdieA5XF3GW1wKA==" + }, "node_modules/@types/detect-port": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/@types/detect-port/-/detect-port-1.3.3.tgz", @@ -14168,8 +14396,7 @@ "node_modules/@types/prop-types": { "version": "15.7.5", "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.5.tgz", - "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==", - "dev": true + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" }, "node_modules/@types/qs": { "version": "6.9.7", @@ -14187,7 +14414,6 @@ "version": "18.0.27", "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.27.tgz", "integrity": "sha512-3vtRKHgVxu3Jp9t718R9BuzoD4NcQ8YJ5XRzsSKxNDiDonD2MXIT1TmSkenxuCycZJoQT5d2vE8LwWJxBC1gmA==", - "dev": true, "dependencies": { "@types/prop-types": "*", "@types/scheduler": "*", @@ -14212,11 +14438,18 @@ "@types/react": "*" } }, + "node_modules/@types/react-lifecycles-compat": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@types/react-lifecycles-compat/-/react-lifecycles-compat-3.0.1.tgz", + "integrity": "sha512-4KiU5s1Go4xRbf7t6VxUUpBeN5PGjpjpBv9VvET4uiPHC500VNYBclU13f8ehHkHoZL39b2cfwHu6RzbV3b44A==", + "dependencies": { + "@types/react": "*" + } + }, "node_modules/@types/scheduler": { "version": "0.16.2", "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "dev": true + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, "node_modules/@types/semver": { "version": "7.5.0", diff --git a/package.json b/package.json index e0be5c153f..91f21fc866 100644 --- a/package.json +++ b/package.json @@ -48,6 +48,7 @@ "dependencies": { "@headlessui/react": "^1.7.8", "@heroicons/react": "^2.0.14", + "@nivo/bar": "^0.83.0", "@nivo/core": "^0.80.0", "@nivo/line": "^0.80.0", "@nivo/pie": "^0.80.0", diff --git a/stories/molecules/contributions-evolution-by-type.stories.tsx b/stories/molecules/contributions-evolution-by-type.stories.tsx new file mode 100644 index 0000000000..ad2db06567 --- /dev/null +++ b/stories/molecules/contributions-evolution-by-type.stories.tsx @@ -0,0 +1,78 @@ +import { Meta } from "@storybook/react"; +import { useState } from "react"; +import eachDayOfInterval from "date-fns/eachDayOfInterval"; +import { subDays } from "date-fns"; +import Button from "components/atoms/Button/button"; +import ContributionsEvolutionByType from "components/molecules/ContributionsEvolutionByTypeCard/contributions-evolution-by-type-card"; + +const meta = { + title: "Design System/Molecules/Contributions Evolution By Type Card", + parameters: { + layout: "fullscreen", + }, + component: ContributionsEvolutionByType, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} satisfies Meta; + +export default meta; + +export const Default = () => { + const [data, setData] = useState(generateData()); + + return ( +
+ + +
+ ); +}; + +function generateData() { + // Use date-fns to get an array of the last 6 weeks + const today = new Date(); + const sixWeeksAgo = subDays(today, 7 * 6); + const result = eachDayOfInterval({ + start: sixWeeksAgo, + end: today, + }); + + // return result.map((date) => ({ + // startTime: date.toString(), + // active: Math.floor(Math.random() * 500), + // new: Math.floor(Math.random() * 500), + // churned: Math.floor(Math.random() * 500), + // })); + + // generate data for each day but make it so that the next value is a random value that is close to the previous value + let previousActive = Math.floor(Math.random() * 500); + let previousNew = Math.floor(Math.random() * 500); + let previousChurned = Math.floor(Math.random() * 500); + return result.map((date) => { + const newActive = randomValueCloseToValue(previousActive); + const newNew = randomValueCloseToValue(previousNew); + const newChurned = randomValueCloseToValue(previousChurned); + + previousActive = newActive; + previousNew = newNew; + previousChurned = newChurned; + + return { + startTime: date.toString(), + active: newActive, + new: newNew, + churned: newChurned, + }; + }); +} + +function randomValueCloseToValue(value: number) { + return Math.max(value + Math.floor(Math.random() * 100 - 50), 0); +} diff --git a/stories/molecules/contributions-evolution.stories.tsx b/stories/molecules/contributions-evolution.stories.tsx new file mode 100644 index 0000000000..29d524f98b --- /dev/null +++ b/stories/molecules/contributions-evolution.stories.tsx @@ -0,0 +1,55 @@ +import { Meta } from "@storybook/react"; +import { useState } from "react"; +import eachDayOfInterval from "date-fns/eachDayOfInterval"; +import { subDays } from "date-fns"; +import Button from "components/atoms/Button/button"; +import ContributionsEvolutionCard from "components/molecules/ContributionsEvolution/contributions-evolution-card"; + +const meta = { + title: "Design System/Molecules/Contributions Evolution Card", + parameters: { + layout: "fullscreen", + }, + component: ContributionsEvolutionCard, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} satisfies Meta; + +export default meta; + +export const Default = () => { + const [data, setData] = useState(generateData()); + + return ( +
+ + +
+ ); +}; + +function generateData() { + // Use date-fns to get an array of the last 7 days + const today = new Date(); + const weekAgo = subDays(today, 6); + const result = eachDayOfInterval({ + start: weekAgo, + end: today, + }); + + return result.map((date) => ({ + startTime: date.toString(), + commits: Math.floor(Math.random() * 500), + prsCreated: Math.floor(Math.random() * 500), + prsReviewed: Math.floor(Math.random() * 500), + issuesCreated: Math.floor(Math.random() * 500), + comments: Math.floor(Math.random() * 500), + })); +} diff --git a/stories/molecules/most-active-contributors-card.stories.tsx b/stories/molecules/most-active-contributors-card.stories.tsx new file mode 100644 index 0000000000..49e60e10dc --- /dev/null +++ b/stories/molecules/most-active-contributors-card.stories.tsx @@ -0,0 +1,106 @@ +import { Meta, StoryObj } from "@storybook/react"; +import { useState } from "react"; +import Button from "components/atoms/Button/button"; +import MostActiveContributorsCard from "components/molecules/MostActiveContributorsCard/most-active-contributors-card"; + +const meta = { + title: "Design System/Molecules/Most Active Contributors Card", + parameters: { + layout: "fullscreen", + }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +export const Default = () => { + const [data, setData] = useState(generateData()); + + return ( +
+ + +
+ ); +}; + +function generateData() { + return [ + "CBID2", + "OgDev-01", + "brandonroberts", + "deepakrudrapaul", + "bdougie", + "diivi", + "babblebey", + "BekahHW", + "dominicduffin1", + "adiati98", + "Anush008", + "a0m0rajab", + "NsdHSO", + "RitaDee", + "doaortu", + "danielglejzner", + "jpmcb", + "goetzrobin", + "nickytonline", + "hankadev", + "k1nho", + "KashishLakhara04", + "fmerian", + "davidgetahead", + "MartiinWalsh", + "Muyixone", + "zillBoy", + "Edlavio", + "kelvinyelyen", + "JacobMGEvans", + "0-vortex", + "takanome-dev", + "kevinctofel", + "Brian-Pob", + "jmslynn", + "Satyxm", + "sudojunior", + "ozgursar", + "droffilc1", + "UlisesGascon", + "MohitBansal321", + "shelleymcq", + "WebDevCode", + "bpirrocco", + "Ntshangase", + "mihrab34", + "code-briomar", + "Deadreyo", + "MaurerKrisztian", + "stephengade", + ].map((login) => { + const user = { + login, + contributions: { + commits: Math.floor(Math.random() * 500), + prsCreated: Math.floor(Math.random() * 500), + prsReviewed: Math.floor(Math.random() * 500), + issuesCreated: Math.floor(Math.random() * 500), + comments: Math.floor(Math.random() * 500), + }, + }; + + return { + ...user, + totalContributions: Object.values(user.contributions).reduce((acc, curr) => acc + curr, 0), + }; + }); +} diff --git a/tailwind.config.js b/tailwind.config.js index cd1bb34580..0801f0d8e0 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,6 +1,11 @@ const plugin = require("tailwindcss/plugin"); module.exports = { - content: ["./pages/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}", "./layouts/**/*.{js,ts,jsx,tsx}"], + content: [ + "./pages/**/*.{js,ts,jsx,tsx}", + "./components/**/*.{js,ts,jsx,tsx}", + "./layouts/**/*.{js,ts,jsx,tsx}", + "./stories/**/*.{js,ts,jsx,tsx}", + ], theme: { extend: { gridTemplateColumns: { From 2c3db8d5fe9a9ccd9041d3daed5e72758e49e1ae Mon Sep 17 00:00:00 2001 From: Chris Schlensker Date: Tue, 3 Oct 2023 15:44:53 +0000 Subject: [PATCH 09/45] chore(minor): release 1.68.0-beta.3 on beta channel [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.68.0-beta.3](https://github.com/open-sauced/insights/compare/v1.68.0-beta.2...v1.68.0-beta.3) (2023-10-03) ### πŸ• Features * add prototype contributor activity charts ([#1594](https://github.com/open-sauced/insights/issues/1594)) ([379db6d](https://github.com/open-sauced/insights/commit/379db6dbe6d852da52ef333c7fc313817647f477)) --- CHANGELOG.md | 7 +++++++ npm-shrinkwrap.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3e9c574210..40c0fbe310 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ > All notable changes to this project will be documented in this file +## [1.68.0-beta.3](https://github.com/open-sauced/insights/compare/v1.68.0-beta.2...v1.68.0-beta.3) (2023-10-03) + + +### πŸ• Features + +* add prototype contributor activity charts ([#1594](https://github.com/open-sauced/insights/issues/1594)) ([379db6d](https://github.com/open-sauced/insights/commit/379db6dbe6d852da52ef333c7fc313817647f477)) + ## [1.68.0-beta.2](https://github.com/open-sauced/insights/compare/v1.68.0-beta.1...v1.68.0-beta.2) (2023-10-03) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index ee1c0494d0..877d40401c 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "@open-sauced/insights", - "version": "1.68.0-beta.2", + "version": "1.68.0-beta.3", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@open-sauced/insights", - "version": "1.68.0-beta.2", + "version": "1.68.0-beta.3", "hasInstallScript": true, "license": "Apache 2.0", "dependencies": { diff --git a/package.json b/package.json index 91f21fc866..ef464106da 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@open-sauced/insights", "description": "πŸ•The dashboard for open source discovery.", "keywords": [], - "version": "1.68.0-beta.2", + "version": "1.68.0-beta.3", "author": "Brian Douglas ", "private": true, "license": "Apache 2.0", From f057de8b59bbdcf7c6a8cecab859cdcd6ba1d121 Mon Sep 17 00:00:00 2001 From: Chris Schlensker Date: Tue, 3 Oct 2023 09:49:43 -0700 Subject: [PATCH 10/45] feat: add Treemap chart prototype (#1569) Co-authored-by: Brandon Roberts --- npm-shrinkwrap.json | 112 ++++- package.json | 1 + .../treemap-prototype/contributor-node.tsx | 87 ++++ stories/molecules/treemap-prototype/data.ts | 421 ++++++++++++++++++ .../treemap-prototype/special-node.tsx | 72 +++ .../treemap-prototype.stories.tsx | 217 +++++++++ 6 files changed, 907 insertions(+), 3 deletions(-) create mode 100644 stories/molecules/treemap-prototype/contributor-node.tsx create mode 100644 stories/molecules/treemap-prototype/data.ts create mode 100644 stories/molecules/treemap-prototype/special-node.tsx create mode 100644 stories/molecules/treemap-prototype/treemap-prototype.stories.tsx diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 877d40401c..1b4f89317d 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -17,6 +17,7 @@ "@nivo/line": "^0.80.0", "@nivo/pie": "^0.80.0", "@nivo/scatterplot": "^0.80.0", + "@nivo/treemap": "^0.83.0", "@primer/octicons-react": "^17.11.1", "@radix-ui/react-alert-dialog": "^1.0.2", "@radix-ui/react-aspect-ratio": "^1.0.3", @@ -5604,6 +5605,101 @@ "react-dom": "^16.8.0 || >=17.0.0 || >=18.0.0" } }, + "node_modules/@nivo/treemap": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/treemap/-/treemap-0.83.0.tgz", + "integrity": "sha512-Fs3Dahm66yoI//Dzzpn5Lg9vtFQdWYPiaZGX5xpEeTg87SofvB/W35iaMtxACyZc1j+6WOE2EMxQp6QC2Rkqew==", + "dependencies": { + "@nivo/colors": "0.83.0", + "@nivo/core": "0.83.0", + "@nivo/tooltip": "0.83.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-hierarchy": "^1.1.8", + "d3-hierarchy": "^1.1.8", + "lodash": "^4.17.21" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/treemap/node_modules/@nivo/colors": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/colors/-/colors-0.83.0.tgz", + "integrity": "sha512-n34LWYtE2hbd1fdCDP7TCHNZdbiO1PwcvXLo0VsKK5lNPY/FA5SXA7Z9Ubl/ChSwBwbzAsaAhjTy8KzKzSjDcA==", + "dependencies": { + "@nivo/core": "0.83.0", + "@types/d3-color": "^2.0.0", + "@types/d3-scale": "^3.2.3", + "@types/d3-scale-chromatic": "^2.0.0", + "@types/prop-types": "^15.7.2", + "d3-color": "^3.1.0", + "d3-scale": "^3.2.3", + "d3-scale-chromatic": "^2.0.0", + "lodash": "^4.17.21", + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/treemap/node_modules/@nivo/core": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/core/-/core-0.83.0.tgz", + "integrity": "sha512-I9fjZAbIPz41JA2WP8Avsud/xk0iiM1nWUzcvZBDebBGFDB5Y1lrldUt9l5kvOeMth3Qj/1lVFTiJxQuojxH4Q==", + "dependencies": { + "@nivo/recompose": "0.83.0", + "@nivo/tooltip": "0.83.0", + "@react-spring/web": "9.4.5 || ^9.7.2", + "@types/d3-shape": "^2.0.0", + "d3-color": "^3.1.0", + "d3-format": "^1.4.4", + "d3-interpolate": "^2.0.1", + "d3-scale": "^3.2.3", + "d3-scale-chromatic": "^2.0.0", + "d3-shape": "^1.3.5", + "d3-time-format": "^3.0.0", + "lodash": "^4.17.21" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/nivo/donate" + }, + "peerDependencies": { + "prop-types": ">= 15.5.10 < 16.0.0", + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/treemap/node_modules/@nivo/recompose": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/recompose/-/recompose-0.83.0.tgz", + "integrity": "sha512-3cLEoi9ZoE4LTn6B98oUVd0MRAy5bWK7W3yb0u4EkjLoXXCRvUAI08Wr2AAagOzVOg5PmvghIDgvkz1tlFZTGQ==", + "dependencies": { + "@types/prop-types": "^15.7.2", + "@types/react-lifecycles-compat": "^3.0.1", + "prop-types": "^15.7.2", + "react-lifecycles-compat": "^3.0.4" + }, + "peerDependencies": { + "react": ">= 16.14.0 < 19.0.0" + } + }, + "node_modules/@nivo/treemap/node_modules/@nivo/tooltip": { + "version": "0.83.0", + "resolved": "https://registry.npmjs.org/@nivo/tooltip/-/tooltip-0.83.0.tgz", + "integrity": "sha512-HewujRqZNmcVnAv/LPLVyYwViad+rYTsFMdzLRzuTPq2hju1R+cfxokTomunG8e1SDtUPtULEVXtPg2ATIzNYg==", + "dependencies": { + "@nivo/core": "0.83.0", + "@react-spring/web": "9.4.5 || ^9.7.2" + } + }, + "node_modules/@nivo/treemap/node_modules/d3-color": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz", + "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==", + "engines": { + "node": ">=12" + } + }, "node_modules/@nivo/voronoi": { "version": "0.80.0", "resolved": "https://registry.npmjs.org/@nivo/voronoi/-/voronoi-0.80.0.tgz", @@ -14070,9 +14166,14 @@ "integrity": "sha512-+0EtEjBfKEDtH9Rk3u3kLOUXM5F+iZK+WvASPb0MhIZl8J8NUvGeZRwKCXl+P3HkYx5TdU4YtcibpqHkSR9n7w==" }, "node_modules/@types/d3-format": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-1.4.2.tgz", - "integrity": "sha512-WeGCHAs7PHdZYq6lwl/+jsl+Nfc1J2W1kNcMeIMYzQsT6mtBDBgtJ/rcdjZ0k0rVIvqEZqhhuD5TK/v3P2gFHQ==" + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@types/d3-format/-/d3-format-1.4.3.tgz", + "integrity": "sha512-Rp3dUYGqPSn4RY+GDW1GfY++JoFvnXU2E+5pU0/4iYLVgdwt029lRlAsAeHk9lJvq3UXl10l09Cmmj2G1wnNlA==" + }, + "node_modules/@types/d3-hierarchy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/@types/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz", + "integrity": "sha512-AbStKxNyWiMDQPGDguG2Kuhlq1Sv539pZSxYbx4UZeYkutpPwXCcgyiRrlV4YH64nIOsKx7XVnOMy9O7rJsXkg==" }, "node_modules/@types/d3-path": { "version": "2.0.2", @@ -17668,6 +17769,11 @@ "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==" }, + "node_modules/d3-hierarchy": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.9.tgz", + "integrity": "sha512-j8tPxlqh1srJHAtxfvOUwKNYJkQuBFdM1+JAUfq6xqH5eAqf93L7oG1NVqDa4CpFZNvnNKtCYEUC8KY9yEn9lQ==" + }, "node_modules/d3-interpolate": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-2.0.1.tgz", diff --git a/package.json b/package.json index ef464106da..0eb4a74d94 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "@nivo/line": "^0.80.0", "@nivo/pie": "^0.80.0", "@nivo/scatterplot": "^0.80.0", + "@nivo/treemap": "^0.83.0", "@primer/octicons-react": "^17.11.1", "@radix-ui/react-alert-dialog": "^1.0.2", "@radix-ui/react-aspect-ratio": "^1.0.3", diff --git a/stories/molecules/treemap-prototype/contributor-node.tsx b/stories/molecules/treemap-prototype/contributor-node.tsx new file mode 100644 index 0000000000..ca5ffc1098 --- /dev/null +++ b/stories/molecules/treemap-prototype/contributor-node.tsx @@ -0,0 +1,87 @@ +import { memo } from "react"; +import { animated } from "@react-spring/web"; +import { NodeProps, htmlNodeTransform } from "@nivo/treemap"; +import { getAvatarByUsername } from "lib/utils/github"; + +const NonMemoizedContributorNode = ({ + node, + animatedProps, + borderWidth, + enableLabel, + labelSkipSize, +}: NodeProps) => { + const showLabel = + enableLabel && node.isLeaf && (labelSkipSize === 0 || Math.min(node.width, node.height) > labelSkipSize); + + const avatarURL = getAvatarByUsername(node.id); + + return ( + + + {showLabel && ( + +
+ +
+ {node.id} +
+
+ {node.formattedValue} Contributions +
+
+
+ )} +
+ ); +}; + +export const ContributorNode = memo(NonMemoizedContributorNode) as typeof NonMemoizedContributorNode; diff --git a/stories/molecules/treemap-prototype/data.ts b/stories/molecules/treemap-prototype/data.ts new file mode 100644 index 0000000000..c443aa2a3a --- /dev/null +++ b/stories/molecules/treemap-prototype/data.ts @@ -0,0 +1,421 @@ +export const data = { + name: "nivo", + color: "hsl(189, 70%, 50%)", + children: [ + { + name: "viz", + color: "hsl(261, 70%, 50%)", + children: [ + { + name: "stack", + color: "hsl(5, 70%, 50%)", + children: [ + { + name: "cchart", + color: "hsl(138, 70%, 50%)", + loc: 112734, + }, + { + name: "xAxis", + color: "hsl(239, 70%, 50%)", + loc: 71469, + }, + { + name: "yAxis", + color: "hsl(286, 70%, 50%)", + loc: 47029, + }, + { + name: "layers", + color: "hsl(345, 70%, 50%)", + loc: 154411, + }, + ], + }, + { + name: "ppie", + color: "hsl(72, 70%, 50%)", + children: [ + { + name: "chart", + color: "hsl(337, 70%, 50%)", + children: [ + { + name: "pie", + color: "hsl(228, 70%, 50%)", + children: [ + { + name: "outline", + color: "hsl(195, 70%, 50%)", + loc: 93291, + }, + { + name: "slices", + color: "hsl(1, 70%, 50%)", + loc: 74503, + }, + { + name: "bbox", + color: "hsl(344, 70%, 50%)", + loc: 93284, + }, + ], + }, + { + name: "donut", + color: "hsl(51, 70%, 50%)", + loc: 148773, + }, + { + name: "gauge", + color: "hsl(24, 70%, 50%)", + loc: 172515, + }, + ], + }, + { + name: "legends", + color: "hsl(236, 70%, 50%)", + loc: 181781, + }, + ], + }, + ], + }, + { + name: "colors", + color: "hsl(326, 70%, 50%)", + children: [ + { + name: "rgb", + color: "hsl(11, 70%, 50%)", + loc: 199524, + }, + { + name: "hsl", + color: "hsl(152, 70%, 50%)", + loc: 46649, + }, + ], + }, + { + name: "utils", + color: "hsl(205, 70%, 50%)", + children: [ + { + name: "randomize", + color: "hsl(247, 70%, 50%)", + loc: 166728, + }, + { + name: "resetClock", + color: "hsl(121, 70%, 50%)", + loc: 117624, + }, + { + name: "noop", + color: "hsl(293, 70%, 50%)", + loc: 50104, + }, + { + name: "tick", + color: "hsl(136, 70%, 50%)", + loc: 35188, + }, + { + name: "forceGC", + color: "hsl(259, 70%, 50%)", + loc: 19014, + }, + { + name: "stackTrace", + color: "hsl(296, 70%, 50%)", + loc: 152117, + }, + { + name: "dbg", + color: "hsl(272, 70%, 50%)", + loc: 187021, + }, + ], + }, + { + name: "generators", + color: "hsl(105, 70%, 50%)", + children: [ + { + name: "address", + color: "hsl(212, 70%, 50%)", + loc: 106084, + }, + { + name: "city", + color: "hsl(86, 70%, 50%)", + loc: 97735, + }, + { + name: "animal", + color: "hsl(228, 70%, 50%)", + loc: 129734, + }, + { + name: "movie", + color: "hsl(128, 70%, 50%)", + loc: 115500, + }, + { + name: "user", + color: "hsl(130, 70%, 50%)", + loc: 96608, + }, + ], + }, + { + name: "set", + color: "hsl(250, 70%, 50%)", + children: [ + { + name: "clone", + color: "hsl(144, 70%, 50%)", + loc: 56957, + }, + { + name: "intersect", + color: "hsl(119, 70%, 50%)", + loc: 116255, + }, + { + name: "merge", + color: "hsl(329, 70%, 50%)", + loc: 132810, + }, + { + name: "reverse", + color: "hsl(146, 70%, 50%)", + loc: 179227, + }, + { + name: "toArray", + color: "hsl(153, 70%, 50%)", + loc: 82125, + }, + { + name: "toObject", + color: "hsl(281, 70%, 50%)", + loc: 84641, + }, + { + name: "fromCSV", + color: "hsl(198, 70%, 50%)", + loc: 137308, + }, + { + name: "slice", + color: "hsl(255, 70%, 50%)", + loc: 148517, + }, + { + name: "append", + color: "hsl(81, 70%, 50%)", + loc: 151057, + }, + { + name: "prepend", + color: "hsl(298, 70%, 50%)", + loc: 33588, + }, + { + name: "shuffle", + color: "hsl(69, 70%, 50%)", + loc: 113555, + }, + { + name: "pick", + color: "hsl(19, 70%, 50%)", + loc: 125108, + }, + { + name: "plouc", + color: "hsl(148, 70%, 50%)", + loc: 177573, + }, + ], + }, + { + name: "text", + color: "hsl(237, 70%, 50%)", + children: [ + { + name: "trim", + color: "hsl(92, 70%, 50%)", + loc: 192414, + }, + { + name: "slugify", + color: "hsl(313, 70%, 50%)", + loc: 98323, + }, + { + name: "snakeCase", + color: "hsl(311, 70%, 50%)", + loc: 140702, + }, + { + name: "camelCase", + color: "hsl(31, 70%, 50%)", + loc: 189412, + }, + { + name: "repeat", + color: "hsl(42, 70%, 50%)", + loc: 177940, + }, + { + name: "padLeft", + color: "hsl(70, 70%, 50%)", + loc: 94736, + }, + { + name: "padRight", + color: "hsl(251, 70%, 50%)", + loc: 161758, + }, + { + name: "sanitize", + color: "hsl(7, 70%, 50%)", + loc: 68324, + }, + { + name: "ploucify", + color: "hsl(41, 70%, 50%)", + loc: 131979, + }, + ], + }, + { + name: "misc", + color: "hsl(40, 70%, 50%)", + children: [ + { + name: "greetings", + color: "hsl(271, 70%, 50%)", + children: [ + { + name: "hey", + color: "hsl(351, 70%, 50%)", + loc: 82305, + }, + { + name: "HOWDY", + color: "hsl(43, 70%, 50%)", + loc: 157783, + }, + { + name: "aloha", + color: "hsl(33, 70%, 50%)", + loc: 179847, + }, + { + name: "AHOY", + color: "hsl(146, 70%, 50%)", + loc: 198481, + }, + ], + }, + { + name: "other", + color: "hsl(79, 70%, 50%)", + loc: 117383, + }, + { + name: "path", + color: "hsl(137, 70%, 50%)", + children: [ + { + name: "pathA", + color: "hsl(320, 70%, 50%)", + loc: 63674, + }, + { + name: "pathB", + color: "hsl(37, 70%, 50%)", + children: [ + { + name: "pathB1", + color: "hsl(89, 70%, 50%)", + loc: 182356, + }, + { + name: "pathB2", + color: "hsl(93, 70%, 50%)", + loc: 97722, + }, + { + name: "pathB3", + color: "hsl(73, 70%, 50%)", + loc: 58316, + }, + { + name: "pathB4", + color: "hsl(314, 70%, 50%)", + loc: 182338, + }, + ], + }, + { + name: "pathC", + color: "hsl(302, 70%, 50%)", + children: [ + { + name: "pathC1", + color: "hsl(146, 70%, 50%)", + loc: 39231, + }, + { + name: "pathC2", + color: "hsl(270, 70%, 50%)", + loc: 192574, + }, + { + name: "pathC3", + color: "hsl(312, 70%, 50%)", + loc: 63845, + }, + { + name: "pathC4", + color: "hsl(304, 70%, 50%)", + loc: 61593, + }, + { + name: "pathC5", + color: "hsl(146, 70%, 50%)", + loc: 138936, + }, + { + name: "pathC6", + color: "hsl(279, 70%, 50%)", + loc: 93730, + }, + { + name: "pathC7", + color: "hsl(302, 70%, 50%)", + loc: 10242, + }, + { + name: "pathC8", + color: "hsl(25, 70%, 50%)", + loc: 79281, + }, + { + name: "pathC9", + color: "hsl(135, 70%, 50%)", + loc: 198445, + }, + ], + }, + ], + }, + ], + }, + ], +}; diff --git a/stories/molecules/treemap-prototype/special-node.tsx b/stories/molecules/treemap-prototype/special-node.tsx new file mode 100644 index 0000000000..67f33275f8 --- /dev/null +++ b/stories/molecules/treemap-prototype/special-node.tsx @@ -0,0 +1,72 @@ +import { memo } from "react"; +import { animated } from "@react-spring/web"; +import { NodeProps, htmlNodeTransform } from "@nivo/treemap"; + +const NonMemoizedSpecialNode = ({ + node, + animatedProps, + borderWidth, + enableLabel, + labelSkipSize, +}: NodeProps) => { + const showLabel = + enableLabel && node.isLeaf && (labelSkipSize === 0 || Math.min(node.width, node.height) > labelSkipSize); + + return ( + + + {showLabel && ( + +
+
{node.id}
+
+ {node.label} +
+
+
+ )} +
+ ); +}; + +export const SpecialNode = memo(NonMemoizedSpecialNode) as typeof NonMemoizedSpecialNode; diff --git a/stories/molecules/treemap-prototype/treemap-prototype.stories.tsx b/stories/molecules/treemap-prototype/treemap-prototype.stories.tsx new file mode 100644 index 0000000000..076f9ceedb --- /dev/null +++ b/stories/molecules/treemap-prototype/treemap-prototype.stories.tsx @@ -0,0 +1,217 @@ +import { ResponsiveTreeMapHtml, NodeMouseEventHandler } from "@nivo/treemap"; +import { useState } from "react"; +import { animated, useSpring } from "@react-spring/web"; +import { ContributorNode } from "stories/molecules/treemap-prototype/contributor-node"; +import Card from "components/atoms/Card/card"; +import { SpecialNode } from "stories/molecules/treemap-prototype/special-node"; +import type { Meta, StoryObj } from "@storybook/react"; + +const meta = { + title: "Design System/Prototypes/Treemap", + parameters: { + layout: "fullscreen", + }, + decorators: [ + (Story) => ( +
+ +
+ ), + ], +} satisfies Meta; + +export default meta; + +type Story = StoryObj; + +const color = "hsla(21, 90%, 48%, 1)"; +const repos = [ + { + id: "/insights", + value: 340, + }, + { + id: "/hot", + value: 120, + }, + { + id: "/ai", + value: 120, + }, + { + id: "/pizza-cli", + value: 100, + }, + { + id: "/super-secret-special-sauce", + value: 84, + }, +]; +const contributors = [ + { + id: "foxyblocks", + value: 68, + color: color, + }, + { + id: "codebytere", + value: 166, + color: color, + }, + { + id: "miniak", + value: 163, + color: color, + }, + { + id: "ckerr", + value: 115, + color: color, + }, + { + id: "JeanMeche", + value: 84, + color: color, + }, + { + id: "annacmc", + value: 90, + color: color, + }, +]; + +export const Repos: Story = { + render: () => { + const data = { + id: "root", + color: color, + children: repos, + }; + return ( + +
+ {/* Label: Text */} +
Organizations / Repos
+
+ `${node.formattedValue} Contributors`} + /> +
+
+
+ ); + }, +}; +export const Contributors: Story = { + render: () => { + const color = "hsla(21, 90%, 48%, 1)"; + const data = { + id: "root", + color: color, + children: contributors, + }; + return ( + +
+ {/* Label: Text */} +
Organizations / Repos / Contributors
+
+ +
+
+
+ ); + }, +}; + +function BreadCrumb({ isActive, ...rest }: any) { + const separatorStyle = useSpring(isActive ? { opacity: 1 } : { opacity: 0 }); + const textStyle = useSpring(isActive ? { opacity: 1, translateX: 0 } : { opacity: 0, translateX: 100 }); + return ( + <> + + {"/"} + + + + ); +} + +function TreeTransitionExample() { + const [currentLevel, setCurrentLevel] = useState(0); + + const data = { + id: "root", + color: color, + children: repos, + }; + const data2 = { + id: "root", + color: color, + children: contributors, + }; + + const handleClick: NodeMouseEventHandler = (node, event) => { + setCurrentLevel((prev) => prev + 1); + }; + + return ( + +
+ {/* Label: Text */} +
+
setCurrentLevel(0)}> + Repos +
+
+ 0}>Contributors +
+
+
+ +
+
+
+
+ ); +} + +export const TransitionBetweenLevels: Story = { + render: () => { + return ; + }, +}; From 1dacf4d63d31c12a5c1d7fbf6238951426e969c7 Mon Sep 17 00:00:00 2001 From: Chris Schlensker Date: Tue, 3 Oct 2023 16:57:01 +0000 Subject: [PATCH 11/45] chore(minor): release 1.68.0-beta.4 on beta channel [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.68.0-beta.4](https://github.com/open-sauced/insights/compare/v1.68.0-beta.3...v1.68.0-beta.4) (2023-10-03) ### πŸ• Features * add Treemap chart prototype ([#1569](https://github.com/open-sauced/insights/issues/1569)) ([f057de8](https://github.com/open-sauced/insights/commit/f057de8b59bbdcf7c6a8cecab859cdcd6ba1d121)) --- CHANGELOG.md | 7 +++++++ npm-shrinkwrap.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40c0fbe310..1afbb387f0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ > All notable changes to this project will be documented in this file +## [1.68.0-beta.4](https://github.com/open-sauced/insights/compare/v1.68.0-beta.3...v1.68.0-beta.4) (2023-10-03) + + +### πŸ• Features + +* add Treemap chart prototype ([#1569](https://github.com/open-sauced/insights/issues/1569)) ([f057de8](https://github.com/open-sauced/insights/commit/f057de8b59bbdcf7c6a8cecab859cdcd6ba1d121)) + ## [1.68.0-beta.3](https://github.com/open-sauced/insights/compare/v1.68.0-beta.2...v1.68.0-beta.3) (2023-10-03) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 1b4f89317d..5f097ae08b 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "@open-sauced/insights", - "version": "1.68.0-beta.3", + "version": "1.68.0-beta.4", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@open-sauced/insights", - "version": "1.68.0-beta.3", + "version": "1.68.0-beta.4", "hasInstallScript": true, "license": "Apache 2.0", "dependencies": { diff --git a/package.json b/package.json index 0eb4a74d94..4c5f0cc597 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@open-sauced/insights", "description": "πŸ•The dashboard for open source discovery.", "keywords": [], - "version": "1.68.0-beta.3", + "version": "1.68.0-beta.4", "author": "Brian Douglas ", "private": true, "license": "Apache 2.0", From 9b156d1c7e974924e8689be6dc2b8dd600443b64 Mon Sep 17 00:00:00 2001 From: Rita Nkem Daniel Date: Tue, 3 Oct 2023 21:38:03 +0100 Subject: [PATCH 12/45] style: add w-full --- components/atoms/Search/search.tsx | 2 +- components/organisms/InsightPage/InsightPage.tsx | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/components/atoms/Search/search.tsx b/components/atoms/Search/search.tsx index 142b954c7d..3d95ed2bbe 100644 --- a/components/atoms/Search/search.tsx +++ b/components/atoms/Search/search.tsx @@ -71,7 +71,7 @@ const Search = ({ > { isLoading={createLoading} placeholder="Repository URL or Full Name (ex: open-sauced/open-sauced)" className="!w-full text-md text-gra" - style={{ width: "100%" }} name={"query"} suggestions={suggestions} onChange={(value) => setRepoSearchTerm(value)} From 1fe65c039ba6cf4f23bbb225ed257b77d0a03d1d Mon Sep 17 00:00:00 2001 From: Rita Nkem Daniel Date: Tue, 3 Oct 2023 21:45:57 +0100 Subject: [PATCH 13/45] style: remove unused style prop --- components/atoms/Search/search.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/components/atoms/Search/search.tsx b/components/atoms/Search/search.tsx index 3d95ed2bbe..10f0a21287 100644 --- a/components/atoms/Search/search.tsx +++ b/components/atoms/Search/search.tsx @@ -14,7 +14,6 @@ interface SearchProps { suggestions?: string[]; onChange?: (value: string) => void; isLoading?: boolean; - style?: React.CSSProperties; } const suggestionsStyle = { From 674a58815886a836567bc6c3999ea9d0764e9a44 Mon Sep 17 00:00:00 2001 From: OGBONNA SUNDAY <62995161+OgDev-01@users.noreply.github.com> Date: Tue, 3 Oct 2023 22:11:43 +0100 Subject: [PATCH 14/45] feat: add timezone filters for list contributors (#1747) --- components/atoms/Select/multi-select.tsx | 50 +++++-------------- components/atoms/Select/single-select.tsx | 41 +++++++++++++++ .../component-date-filter.tsx | 2 +- .../hub-contributors-header.tsx | 36 +++++++++---- .../ContributorsTable/contributors-table.tsx | 12 +++-- lib/hooks/useFetchAllContributors.ts | 32 +++++++----- pages/hub/lists/new.tsx | 15 ++++-- stories/atoms/multi-select.stories.tsx | 7 +-- 8 files changed, 122 insertions(+), 73 deletions(-) create mode 100644 components/atoms/Select/single-select.tsx diff --git a/components/atoms/Select/multi-select.tsx b/components/atoms/Select/multi-select.tsx index a351c198c0..d05fa938b7 100644 --- a/components/atoms/Select/multi-select.tsx +++ b/components/atoms/Select/multi-select.tsx @@ -13,8 +13,7 @@ export type OptionKeys = Record<"value" | "label", string>; interface MultiSelectProps { options: OptionKeys[]; selected: OptionKeys[]; - handleSelect: (value: OptionKeys["value"]) => void; - handleUnSelect: (option: OptionKeys["value"]) => void; + handleSelect: (value: OptionKeys) => void; placeholder?: string; inputPlaceholder?: string; className?: string; @@ -27,7 +26,6 @@ const MultiSelect = ({ handleSelect, className, placeholder, - handleUnSelect, handleKeyDown, inputPlaceholder, }: MultiSelectProps) => { @@ -37,28 +35,6 @@ const MultiSelect = ({ const [dummySelected, setDummySelected] = useState([]); // For testing purposes, this component is meant to be stateless. - const dummyOptions = [ - { value: "1", label: "Option 1" }, - { value: "2", label: "Option 2" }, - { value: "3", label: "Option 3" }, - { value: "4", label: "Option 4" }, - { value: "5", label: "Option 5" }, - { value: "6", label: "Option 6" }, - { value: "7", label: "Option 7" }, - { value: "8", label: "Option 8" }, - { value: "9", label: "Option 9" }, - { value: "10", label: "Option 10" }, - { value: "11", label: "Option 11" }, - { value: "12", label: "Option 12" }, - { value: "13", label: "Option 13" }, - { value: "14", label: "Option 14" }, - { value: "15", label: "Option 15" }, - { value: "16", label: "Option 16" }, - { value: "17", label: "Option 17" }, - { value: "18", label: "Option 18" }, - { value: "19", label: "Option 19" }, - { value: "20", label: "Option 20" }, - ]; const toggleFramework = (option: OptionKeys) => { const isOptionSelected = dummySelected.some((s) => s.value === option.value); @@ -72,10 +48,10 @@ const MultiSelect = ({ return ( setOpen(value)}> -
+
- + - {open && dummyOptions.length > 0 - ? dummyOptions.map((option) => ( + {open && options.length > 0 + ? options.map((option) => ( { @@ -130,12 +106,12 @@ const MultiSelect = ({ }} onClick={() => toggleFramework(option)} className={clsx( - "!cursor-pointer flex justify-between items-center !px-1 rounded-md", - dummySelected.some((s) => s.value === option.value) && "bg-gray-100" + "!cursor-pointer flex justify-between items-center !px-1 rounded-md truncate break-words w-full", + selected.some((s) => s.value === option.value) && "bg-gray-100" )} > {option.label} - {dummySelected.some((s) => s.value === option.value) && ( + {selected.some((s) => s.value === option.value) && ( )} diff --git a/components/atoms/Select/single-select.tsx b/components/atoms/Select/single-select.tsx new file mode 100644 index 0000000000..ff904b7cf2 --- /dev/null +++ b/components/atoms/Select/single-select.tsx @@ -0,0 +1,41 @@ +import React from "react"; +import { RiArrowDownSLine } from "react-icons/ri"; + +import { truncateString } from "lib/utils/truncate-string"; + +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./select"; + +interface SingleSelectProps { + value?: string; + onValueChange: (value: string) => void; + placeholder?: string; + options: { label: string; value: string }[]; + position?: "popper" | "item-aligned"; +} + +const SingleSelect = ({ placeholder, value, onValueChange, options, position }: SingleSelectProps) => { + return ( + + ); +}; + +export default SingleSelect; diff --git a/components/molecules/ComponentDateFilter/component-date-filter.tsx b/components/molecules/ComponentDateFilter/component-date-filter.tsx index 14de0f7eb5..ff1fdcde2f 100644 --- a/components/molecules/ComponentDateFilter/component-date-filter.tsx +++ b/components/molecules/ComponentDateFilter/component-date-filter.tsx @@ -20,7 +20,7 @@ const ComponentDateFilter = ({ setRangeFilter, defaultRange }: ComponentDateFilt }; return ( -
+
{dates.map((range, index) => (
handleFilterClick(range)} diff --git a/components/molecules/HubContributorsHeader/hub-contributors-header.tsx b/components/molecules/HubContributorsHeader/hub-contributors-header.tsx index f53d68bb1e..e6bf350680 100644 --- a/components/molecules/HubContributorsHeader/hub-contributors-header.tsx +++ b/components/molecules/HubContributorsHeader/hub-contributors-header.tsx @@ -2,19 +2,24 @@ import { FaPlus } from "react-icons/fa"; import clsx from "clsx"; import { FiGlobe } from "react-icons/fi"; -import Button from "components/atoms/Button/button"; -import Text from "components/atoms/Typography/text"; +import { timezones } from "lib/utils/timezones"; import { useToast } from "lib/hooks/useToast"; + import ListNameHeader from "components/atoms/ListNameHeader/list-name-header"; import LimitSelect from "components/atoms/Select/limit-select"; -// import Search from "components/atoms/Search/search"; +import SingleSelect from "components/atoms/Select/single-select"; import ToggleSwitch from "components/atoms/ToggleSwitch/toggle-switch"; +import Button from "components/atoms/Button/button"; +import Text from "components/atoms/Typography/text"; import ComponentDateFilter from "../ComponentDateFilter/component-date-filter"; +// import Search from "components/atoms/Search/search"; interface ListHeaderProps { setLimit?: (limit: number) => void; setRangeFilter?: (range: number) => void; + timezone?: string; + setTimezoneFilter: (timezone: string) => void; isPublic: boolean; handleToggleIsPublic: () => void; range?: number; @@ -36,8 +41,14 @@ const HubContributorsHeader = ({ loading, isPublic, handleToggleIsPublic, + timezone, + setTimezoneFilter, }: ListHeaderProps): JSX.Element => { const { toast } = useToast(); + const timezoneOptions = timezones.map((timezone) => ({ + label: timezone.text, + value: timezone.value, + })); return (
@@ -54,7 +65,7 @@ const HubContributorsHeader = ({
- + Make Public @@ -83,12 +94,17 @@ const HubContributorsHeader = ({
-
-
-
- {/*
- -
*/} +
+
+ setTimezoneFilter(value)} + /> +
+
setRangeFilter?.(range)} defaultRange={range} /> {loading && } - {contributors && - contributors.length > 0 && - contributors.map((contributor) => ( + {contributors && contributors.length > 0 ? ( + contributors.map((contributor, i) => ( selected.user_id === contributor.user_id)} handleOnSelectContributor={handleSelectContributors} /> - ))} + )) + ) : ( +
+ No contributors found for the selected filters +
+ )}
); }; diff --git a/lib/hooks/useFetchAllContributors.ts b/lib/hooks/useFetchAllContributors.ts index b88396d07e..95bf0cd4ba 100644 --- a/lib/hooks/useFetchAllContributors.ts +++ b/lib/hooks/useFetchAllContributors.ts @@ -10,33 +10,39 @@ interface PaginatedResponse { readonly meta: Meta; } -const useFetchAllContributors = (initialLimit = 10) => { +type queryObj = { + location?: string; + pr_velocity?: string; + timezone?: string; + initialLimit?: number; +}; + +const useFetchAllContributors = (query: queryObj) => { const { toast } = useToast(); const router = useRouter(); const [page, setPage] = useState(1); - const [limit, setLimit] = useState(initialLimit); - const { location, pr_velocity, timezone } = router.query; + const [limit, setLimit] = useState(query.initialLimit ?? 10); - const query = new URLSearchParams(); + const urlQuery = new URLSearchParams(); if (page) { - query.set("page", `${page}`); + urlQuery.set("page", `${page}`); } - if (location) { - query.set("location", `${location}`); + if (query.location) { + urlQuery.set("location", `${query.location}`); } - if (pr_velocity) { - query.set("pr_velocity", `${pr_velocity}`); + if (query.pr_velocity) { + urlQuery.set("pr_velocity", `${query.pr_velocity}`); } - if (timezone) { - query.set("timezone", `${timezone}`); + if (query.timezone) { + urlQuery.set("timezone", `${query.timezone}`); } if (limit) { - query.set("limit", `${limit}`); + urlQuery.set("limit", `${limit}`); } const baseEndpoint = "lists/contributors"; - const endpointString = `${baseEndpoint}?${query}`; + const endpointString = `${baseEndpoint}?${urlQuery}`; const { data, error, mutate } = useSWR( endpointString, diff --git a/pages/hub/lists/new.tsx b/pages/hub/lists/new.tsx index 2c5d0def53..f7e1ae4e86 100644 --- a/pages/hub/lists/new.tsx +++ b/pages/hub/lists/new.tsx @@ -36,8 +36,11 @@ const NewListCreationPage: WithPageLayout = () => { const [title, setTitle] = useState(""); const [selectedContributors, setSelectedContributors] = useState([]); const [range, setRange] = useState(30); + const [timezone, setTimezone] = useState(undefined); const [isPublic, setIsPublic] = useState(false); - const { data, meta, isLoading, setLimit, setPage } = useFetchAllContributors(); + const { data, meta, isLoading, setLimit, setPage } = useFetchAllContributors({ + timezone: timezone, + }); const contributors = data ? data.length > 0 && @@ -129,11 +132,16 @@ const NewListCreationPage: WithPageLayout = () => { } }; + const handleSelectTimezone = (selected: string) => { + setTimezone(selected); + }; + return (
setIsPublic(!isPublic)} loading={createLoading} @@ -142,15 +150,16 @@ const NewListCreationPage: WithPageLayout = () => { setRangeFilter={(range) => { setRange(range); }} + timezone={timezone} title={title} onAddToList={handleOnListCreate} onTitleChange={(title) => setTitle(title)} />
-
+
0 && selectedContributors.length === meta.limit} handleOnSelectAllContributor={handleOnSelectAllChecked} /> { - const exists = selectedOptions.find((option) => option.value === value); + handleSelect: (selectedValue) => { + const exists = selectedOptions.find((option) => option.value === selectedValue.value); if (exists) { selectedOptions = selectedOptions.filter((option) => option.value !== exists.value); } }, - handleUnSelect: (value) => { - selectedOptions = selectedOptions.filter((option) => option.value !== value); - }, }, }; From 20113d49cb05af22682573e8474e606a06def08d Mon Sep 17 00:00:00 2001 From: OGBONNA SUNDAY <62995161+OgDev-01@users.noreply.github.com> Date: Tue, 3 Oct 2023 21:18:30 +0000 Subject: [PATCH 15/45] chore(minor): release 1.68.0-beta.5 on beta channel [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.68.0-beta.5](https://github.com/open-sauced/insights/compare/v1.68.0-beta.4...v1.68.0-beta.5) (2023-10-03) ### πŸ• Features * add timezone filters for list contributors ([#1747](https://github.com/open-sauced/insights/issues/1747)) ([674a588](https://github.com/open-sauced/insights/commit/674a58815886a836567bc6c3999ea9d0764e9a44)) --- CHANGELOG.md | 7 +++++++ npm-shrinkwrap.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1afbb387f0..3f017201f3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ > All notable changes to this project will be documented in this file +## [1.68.0-beta.5](https://github.com/open-sauced/insights/compare/v1.68.0-beta.4...v1.68.0-beta.5) (2023-10-03) + + +### πŸ• Features + +* add timezone filters for list contributors ([#1747](https://github.com/open-sauced/insights/issues/1747)) ([674a588](https://github.com/open-sauced/insights/commit/674a58815886a836567bc6c3999ea9d0764e9a44)) + ## [1.68.0-beta.4](https://github.com/open-sauced/insights/compare/v1.68.0-beta.3...v1.68.0-beta.4) (2023-10-03) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 5f097ae08b..3ed660aa74 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "@open-sauced/insights", - "version": "1.68.0-beta.4", + "version": "1.68.0-beta.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@open-sauced/insights", - "version": "1.68.0-beta.4", + "version": "1.68.0-beta.5", "hasInstallScript": true, "license": "Apache 2.0", "dependencies": { diff --git a/package.json b/package.json index 4c5f0cc597..ec53dd6870 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@open-sauced/insights", "description": "πŸ•The dashboard for open source discovery.", "keywords": [], - "version": "1.68.0-beta.4", + "version": "1.68.0-beta.5", "author": "Brian Douglas ", "private": true, "license": "Apache 2.0", From 783b1c9d957f4998f7bbb73fb7548bcd57118eee Mon Sep 17 00:00:00 2001 From: Rita Nkem Daniel Date: Wed, 4 Oct 2023 10:25:17 +0100 Subject: [PATCH 16/45] refactor: remove unused props in Search component --- components/atoms/Search/search.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/components/atoms/Search/search.tsx b/components/atoms/Search/search.tsx index 10f0a21287..cacb734bce 100644 --- a/components/atoms/Search/search.tsx +++ b/components/atoms/Search/search.tsx @@ -32,7 +32,6 @@ const Search = ({ suggestions, onChange, isLoading, - ...props }: SearchProps): JSX.Element => { const [search, setSearch] = useState(value); const [showSuggestions, setShowSuggestions] = useState(false); @@ -78,7 +77,6 @@ const Search = ({ type="search" id={name} onChange={handleChange} - {...props} onKeyUp={(e) => { if (e.code === "Enter") { handleOnSearch(); From fceae35fb17a027636966e5f52587155a70d9d8c Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Wed, 4 Oct 2023 19:06:33 +0000 Subject: [PATCH 17/45] chore(patch): release 1.68.0-beta.6 on beta channel [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.68.0-beta.6](https://github.com/open-sauced/insights/compare/v1.68.0-beta.5...v1.68.0-beta.6) (2023-10-04) ### 🎨 Styles * add w-full ([9b156d1](https://github.com/open-sauced/insights/commit/9b156d1c7e974924e8689be6dc2b8dd600443b64)) * remove unused style prop ([1fe65c0](https://github.com/open-sauced/insights/commit/1fe65c039ba6cf4f23bbb225ed257b77d0a03d1d)) ### πŸ§‘β€πŸ’» Code Refactoring * remove unused props in Search component ([783b1c9](https://github.com/open-sauced/insights/commit/783b1c9d957f4998f7bbb73fb7548bcd57118eee)) ### πŸ› Bug Fixes * add style prop to SearchProps ([16fbc82](https://github.com/open-sauced/insights/commit/16fbc82f3c72dde7d54359c61cf15e3c9563ff96)) * adjust style to fit urls ([55a6bbc](https://github.com/open-sauced/insights/commit/55a6bbcf799856477b80c0286507c0475867f4b3)) * Improve the input's width to accommodate full URL ([#1789](https://github.com/open-sauced/insights/issues/1789)) ([e37df4f](https://github.com/open-sauced/insights/commit/e37df4f8c5b52246d7c48f7e7c2c94bf22c227e5)) --- CHANGELOG.md | 20 ++++++++++++++++++++ npm-shrinkwrap.json | 4 ++-- package.json | 2 +- 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f017201f3..24fe5c1bd6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,26 @@ > All notable changes to this project will be documented in this file +## [1.68.0-beta.6](https://github.com/open-sauced/insights/compare/v1.68.0-beta.5...v1.68.0-beta.6) (2023-10-04) + + +### 🎨 Styles + +* add w-full ([9b156d1](https://github.com/open-sauced/insights/commit/9b156d1c7e974924e8689be6dc2b8dd600443b64)) +* remove unused style prop ([1fe65c0](https://github.com/open-sauced/insights/commit/1fe65c039ba6cf4f23bbb225ed257b77d0a03d1d)) + + +### πŸ§‘β€πŸ’» Code Refactoring + +* remove unused props in Search component ([783b1c9](https://github.com/open-sauced/insights/commit/783b1c9d957f4998f7bbb73fb7548bcd57118eee)) + + +### πŸ› Bug Fixes + +* add style prop to SearchProps ([16fbc82](https://github.com/open-sauced/insights/commit/16fbc82f3c72dde7d54359c61cf15e3c9563ff96)) +* adjust style to fit urls ([55a6bbc](https://github.com/open-sauced/insights/commit/55a6bbcf799856477b80c0286507c0475867f4b3)) +* Improve the input's width to accommodate full URL ([#1789](https://github.com/open-sauced/insights/issues/1789)) ([e37df4f](https://github.com/open-sauced/insights/commit/e37df4f8c5b52246d7c48f7e7c2c94bf22c227e5)) + ## [1.68.0-beta.5](https://github.com/open-sauced/insights/compare/v1.68.0-beta.4...v1.68.0-beta.5) (2023-10-03) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 3ed660aa74..45a7fceb71 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "@open-sauced/insights", - "version": "1.68.0-beta.5", + "version": "1.68.0-beta.6", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@open-sauced/insights", - "version": "1.68.0-beta.5", + "version": "1.68.0-beta.6", "hasInstallScript": true, "license": "Apache 2.0", "dependencies": { diff --git a/package.json b/package.json index ec53dd6870..68c95cd031 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@open-sauced/insights", "description": "πŸ•The dashboard for open source discovery.", "keywords": [], - "version": "1.68.0-beta.5", + "version": "1.68.0-beta.6", "author": "Brian Douglas ", "private": true, "license": "Apache 2.0", From f3da2a1512e36900d1c9edceb490d893323b1f49 Mon Sep 17 00:00:00 2001 From: OGBONNA SUNDAY <62995161+OgDev-01@users.noreply.github.com> Date: Fri, 6 Oct 2023 10:32:31 +0100 Subject: [PATCH 18/45] fix: hide weird top nav for edit insight page (#1809) --- layouts/hub.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/layouts/hub.tsx b/layouts/hub.tsx index 53afde2ae2..fbfd6765bf 100644 --- a/layouts/hub.tsx +++ b/layouts/hub.tsx @@ -23,6 +23,12 @@ const HubLayout = ({ children }: { children: React.ReactNode }) => { ]; const router = useRouter(); + const validatePath = (path: string) => { + const PATHREGEX = /^\/hub\/(insights|lists)(\/(new|[\d]+\/edit))?$/; + + return PATHREGEX.test(path); + }; + useEffect(() => { async function getUser() { try { @@ -53,7 +59,7 @@ const HubLayout = ({ children }: { children: React.ReactNode }) => { {user ? ( <>
- {router.pathname.split("/")[3] !== "new" ? ( + {validatePath(router.pathname) ? (
Your pages From 3f5a01333b68ded67eb4ebac84cfc491f6dc4109 Mon Sep 17 00:00:00 2001 From: OGBONNA SUNDAY <62995161+OgDev-01@users.noreply.github.com> Date: Fri, 6 Oct 2023 09:42:34 +0000 Subject: [PATCH 19/45] chore(patch): release 1.68.0-beta.7 on beta channel [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.68.0-beta.7](https://github.com/open-sauced/insights/compare/v1.68.0-beta.6...v1.68.0-beta.7) (2023-10-06) ### πŸ› Bug Fixes * hide weird top nav for edit insight page ([#1809](https://github.com/open-sauced/insights/issues/1809)) ([f3da2a1](https://github.com/open-sauced/insights/commit/f3da2a1512e36900d1c9edceb490d893323b1f49)) --- CHANGELOG.md | 7 +++++++ npm-shrinkwrap.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 24fe5c1bd6..6a50b3fd7c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ > All notable changes to this project will be documented in this file +## [1.68.0-beta.7](https://github.com/open-sauced/insights/compare/v1.68.0-beta.6...v1.68.0-beta.7) (2023-10-06) + + +### πŸ› Bug Fixes + +* hide weird top nav for edit insight page ([#1809](https://github.com/open-sauced/insights/issues/1809)) ([f3da2a1](https://github.com/open-sauced/insights/commit/f3da2a1512e36900d1c9edceb490d893323b1f49)) + ## [1.68.0-beta.6](https://github.com/open-sauced/insights/compare/v1.68.0-beta.5...v1.68.0-beta.6) (2023-10-04) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 45a7fceb71..f6ca52d33b 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "@open-sauced/insights", - "version": "1.68.0-beta.6", + "version": "1.68.0-beta.7", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@open-sauced/insights", - "version": "1.68.0-beta.6", + "version": "1.68.0-beta.7", "hasInstallScript": true, "license": "Apache 2.0", "dependencies": { diff --git a/package.json b/package.json index 68c95cd031..cc23821e0d 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@open-sauced/insights", "description": "πŸ•The dashboard for open source discovery.", "keywords": [], - "version": "1.68.0-beta.6", + "version": "1.68.0-beta.7", "author": "Brian Douglas ", "private": true, "license": "Apache 2.0", From f6b71df7e0d25b7c2513f1b20115a832383983fc Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Thu, 5 Oct 2023 22:45:38 -0400 Subject: [PATCH 20/45] chore: reworked lists layout to receive a setRange prop to display range picker --- .../molecules/TableHeader/table-header.tsx | 7 +------ .../ContributorsList/contributors-list.tsx | 6 ++---- layouts/lists.tsx | 17 ++++++++++------- lib/hooks/api/useContributorList.ts | 12 +++++++++++- pages/lists/[listId]/contributors.tsx | 5 ++++- 5 files changed, 28 insertions(+), 19 deletions(-) diff --git a/components/molecules/TableHeader/table-header.tsx b/components/molecules/TableHeader/table-header.tsx index 17bda21521..f905914b66 100644 --- a/components/molecules/TableHeader/table-header.tsx +++ b/components/molecules/TableHeader/table-header.tsx @@ -95,12 +95,7 @@ const TableHeader = ({ />
- {range ? ( - setRangeFilter?.(range)} defaultRange={range} /> - ) : ( - "" - )} - + {setRangeFilter && range ? : null} {layout ? (
diff --git a/components/organisms/ContributorsList/contributors-list.tsx b/components/organisms/ContributorsList/contributors-list.tsx index 3fc8cade66..52f4b5aa3f 100644 --- a/components/organisms/ContributorsList/contributors-list.tsx +++ b/components/organisms/ContributorsList/contributors-list.tsx @@ -16,6 +16,7 @@ interface ContributorsListProps { meta: Meta; setPage: (page: number) => void; setLimit: (limit: number) => void; + range: number; } interface ContributorCardListProps { @@ -48,8 +49,7 @@ const ContributorCardList = ({ contributors = [], topic, range }: ContributorCar ); }; -const ContributorsList = ({ contributors, isLoading, meta, setPage, setLimit }: ContributorsListProps) => { - const [range, setRange] = useState(30); +const ContributorsList = ({ contributors, isLoading, meta, setPage, setLimit, range }: ContributorsListProps) => { const [layout, setLayout] = useState("grid"); return ( @@ -59,8 +59,6 @@ const ContributorsList = ({ contributors, isLoading, meta, setPage, setLimit }: metaInfo={meta} entity="contributors" updateLimit={setLimit} - range={range} - setRangeFilter={setRange} layout={layout} onLayoutToggle={setLayout} /> diff --git a/layouts/lists.tsx b/layouts/lists.tsx index 9116fc0452..37d1970657 100644 --- a/layouts/lists.tsx +++ b/layouts/lists.tsx @@ -6,28 +6,26 @@ import Header from "components/organisms/Header/header"; import TopNav from "components/organisms/TopNav/top-nav"; import ListHeader from "components/ListHeader/list-header"; import TabsList from "components/TabList/tab-list"; +import ComponentDateFilter from "components/molecules/ComponentDateFilter/component-date-filter"; const ListPageLayout = ({ children, list, numberOfContributors, isOwner = false, + setRange, }: { children: React.ReactNode; list?: DBList; numberOfContributors: number; isOwner: boolean; + setRange?: (range: number) => void; }) => { const router = useRouter(); const paths = router.asPath.split("/"); const selectedTab = paths[3] ?? "overview"; - const tabList = [ - { name: "Overview" }, - // Uncomment once the activity page has been implemented - // { name: "Activity" }, - { name: "Contributors" }, - ]; + const tabList = [{ name: "Overview" }, { name: "Activity" }, { name: "Contributors" }]; return (
@@ -47,7 +45,12 @@ const ListPageLayout = ({ )} - {list && } +
+ {list && } +
+
{setRange && }
+
+
diff --git a/lib/hooks/api/useContributorList.ts b/lib/hooks/api/useContributorList.ts index aff5e6c3f4..911d3129a0 100644 --- a/lib/hooks/api/useContributorList.ts +++ b/lib/hooks/api/useContributorList.ts @@ -21,6 +21,7 @@ export const useContributorsList = ({ initialData, initialPage = 1, defaultLimit = 10, + defaultRange = 30, }: { listId: string | undefined; initialData?: { @@ -29,11 +30,18 @@ export const useContributorsList = ({ }; initialPage?: number; defaultLimit?: number; + defaultRange?: number; }) => { + const [range, setRange] = useState(defaultRange); // [start, end const [page, setPage] = useState(initialPage); const [limit, setLimit] = useState(defaultLimit); + const query = new URLSearchParams(); + query.append("page", page.toString()); + query.append("limit", limit.toString()); + query.append("range", range.toString()); + const { data, error, mutate } = useSWR( - `lists/${listId}/contributors?page=${page}&limit=${limit}`, + `lists/${listId}/contributors?${query}`, publicApiFetcher as Fetcher, Error>, { fallbackData: initialData, @@ -44,6 +52,8 @@ export const useContributorsList = ({ return { setPage, setLimit, + setRange, + range, data: data ? { data: contributors, meta: data.meta } : { data: [], meta: {} }, isLoading: !error && !data, isError: !!error, diff --git a/pages/lists/[listId]/contributors.tsx b/pages/lists/[listId]/contributors.tsx index 467e105f80..ebe820abda 100644 --- a/pages/lists/[listId]/contributors.tsx +++ b/pages/lists/[listId]/contributors.tsx @@ -58,11 +58,13 @@ const ContributorsListPage = ({ list, initialData, isError }: ContributorListPag isLoading, setPage, setLimit, + setRange, + range, data: { data: contributors, meta }, } = useContributorsList({ listId: list?.id, initialData }); return ( - + {isError ? ( ) : ( @@ -72,6 +74,7 @@ const ContributorsListPage = ({ list, initialData, isError }: ContributorListPag isLoading={isLoading} setPage={setPage} setLimit={setLimit} + range={range} /> )} From e29e96bb85bb0498ba5da7d548870bd40d03bd46 Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Thu, 5 Oct 2023 23:09:12 -0400 Subject: [PATCH 21/45] chore: fixed range filtering for contributors list --- .../contributor-list-table-header.tsx | 9 +++++++-- .../contributor-list-table-row.tsx | 6 ++++-- .../organisms/ContributorsList/contributors-list.tsx | 4 ++-- .../organisms/ContributorsTable/contributors-table.tsx | 3 +++ 4 files changed, 16 insertions(+), 6 deletions(-) diff --git a/components/molecules/ContributorListTableHeader/contributor-list-table-header.tsx b/components/molecules/ContributorListTableHeader/contributor-list-table-header.tsx index 194d8f3ccc..3e6222be2f 100644 --- a/components/molecules/ContributorListTableHeader/contributor-list-table-header.tsx +++ b/components/molecules/ContributorListTableHeader/contributor-list-table-header.tsx @@ -7,9 +7,14 @@ import Checkbox from "components/atoms/Checkbox/checkbox"; interface ContributorListTableHeadersProps { selected?: boolean; handleOnSelectAllContributor?: (contributor: any) => void; + range: number; } -const ContributorListTableHeaders = ({ selected, handleOnSelectAllContributor }: ContributorListTableHeadersProps) => { +const ContributorListTableHeaders = ({ + selected, + handleOnSelectAllContributor, + range, +}: ContributorListTableHeadersProps) => { return (
{/* Mobile */} @@ -60,7 +65,7 @@ const ContributorListTableHeaders = ({ selected, handleOnSelectAllContributor }: Contributions
- Last 30 Days + {`Last ${range} Days`}
diff --git a/components/molecules/ContributorListTableRow/contributor-list-table-row.tsx b/components/molecules/ContributorListTableRow/contributor-list-table-row.tsx index 80bd259b0a..245862aad1 100644 --- a/components/molecules/ContributorListTableRow/contributor-list-table-row.tsx +++ b/components/molecules/ContributorListTableRow/contributor-list-table-row.tsx @@ -19,6 +19,7 @@ interface ContributorListTableRow { topic: string; selected?: boolean; handleOnSelectContributor?: (state: boolean, contributor: DbPRContributor) => void; + range: number; } function getLastContributionDate(contributions: DbRepoPR[]) { @@ -47,14 +48,15 @@ const ContributorListTableRow = ({ topic, selected, handleOnSelectContributor, + range, }: ContributorListTableRow) => { const [tableOpen, setTableOpen] = useState(false); const { data: user } = useFetchUser(contributor.author_login); - const { data } = useContributorPullRequests(contributor.author_login, topic, [], 30); + const { data } = useContributorPullRequests(contributor.author_login, topic, [], range); const repoList = useRepoList(Array.from(new Set(data.map((prData) => prData.full_name))).join(",")); const contributorLanguageList = user ? Object.keys(user.languages).map((language) => language) : []; - const days = getPullRequestsToDays(data); + const days = getPullRequestsToDays(data, range); const totalPrs = data.length; const last30days = [ { diff --git a/components/organisms/ContributorsList/contributors-list.tsx b/components/organisms/ContributorsList/contributors-list.tsx index 52f4b5aa3f..185d10cb2c 100644 --- a/components/organisms/ContributorsList/contributors-list.tsx +++ b/components/organisms/ContributorsList/contributors-list.tsx @@ -65,8 +65,8 @@ const ContributorsList = ({ contributors, isLoading, meta, setPage, setLimit, ra {layout === "grid" ? ( <> - - + + ) : ( diff --git a/components/organisms/ContributorsTable/contributors-table.tsx b/components/organisms/ContributorsTable/contributors-table.tsx index 8baf97d077..0cb8033f63 100644 --- a/components/organisms/ContributorsTable/contributors-table.tsx +++ b/components/organisms/ContributorsTable/contributors-table.tsx @@ -8,6 +8,7 @@ export interface ContributorTableProps { loading?: boolean; selectedContributors?: DbPRContributor[]; handleSelectContributors?: (state: boolean, contributor: DbPRContributor) => void; + range: number; } const ContributorTable = ({ @@ -16,6 +17,7 @@ const ContributorTable = ({ loading, selectedContributors, handleSelectContributors, + range, }: ContributorTableProps) => { return (
@@ -29,6 +31,7 @@ const ContributorTable = ({ key={contributor.user_id} selected={!!selectedContributors?.find((selected) => selected.user_id === contributor.user_id)} handleOnSelectContributor={handleSelectContributors} + range={range} /> )) ) : ( From 50cd0da11b641e13881a424ad9fd0d7179db6140 Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Fri, 6 Oct 2023 06:23:49 -0400 Subject: [PATCH 22/45] chore: fixed a couple spots I missed passing in the range --- .../contributor-list-table-header.tsx | 4 ++-- components/organisms/Contributors/contributors.tsx | 2 +- components/organisms/ContributorsTable/contributors-table.tsx | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/components/molecules/ContributorListTableHeader/contributor-list-table-header.tsx b/components/molecules/ContributorListTableHeader/contributor-list-table-header.tsx index 3e6222be2f..d276c179c6 100644 --- a/components/molecules/ContributorListTableHeader/contributor-list-table-header.tsx +++ b/components/molecules/ContributorListTableHeader/contributor-list-table-header.tsx @@ -7,13 +7,13 @@ import Checkbox from "components/atoms/Checkbox/checkbox"; interface ContributorListTableHeadersProps { selected?: boolean; handleOnSelectAllContributor?: (contributor: any) => void; - range: number; + range?: number; } const ContributorListTableHeaders = ({ selected, handleOnSelectAllContributor, - range, + range = 30, }: ContributorListTableHeadersProps) => { return (
diff --git a/components/organisms/Contributors/contributors.tsx b/components/organisms/Contributors/contributors.tsx index 38138decbd..9bfac2a0bf 100644 --- a/components/organisms/Contributors/contributors.tsx +++ b/components/organisms/Contributors/contributors.tsx @@ -83,7 +83,7 @@ const Contributors = ({ repositories }: ContributorProps): JSX.Element => {
) : (
- +
)} diff --git a/components/organisms/ContributorsTable/contributors-table.tsx b/components/organisms/ContributorsTable/contributors-table.tsx index 0cb8033f63..dfa5a6df30 100644 --- a/components/organisms/ContributorsTable/contributors-table.tsx +++ b/components/organisms/ContributorsTable/contributors-table.tsx @@ -8,7 +8,7 @@ export interface ContributorTableProps { loading?: boolean; selectedContributors?: DbPRContributor[]; handleSelectContributors?: (state: boolean, contributor: DbPRContributor) => void; - range: number; + range?: number; } const ContributorTable = ({ @@ -17,7 +17,7 @@ const ContributorTable = ({ loading, selectedContributors, handleSelectContributors, - range, + range = 30, }: ContributorTableProps) => { return (
From 3934d1390611420a5a18c9eb22fcc2e5b03d9d30 Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Fri, 6 Oct 2023 06:34:08 -0400 Subject: [PATCH 23/45] chore: remove Activity from list tabs --- layouts/lists.tsx | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/layouts/lists.tsx b/layouts/lists.tsx index 37d1970657..c67f0955fc 100644 --- a/layouts/lists.tsx +++ b/layouts/lists.tsx @@ -25,7 +25,12 @@ const ListPageLayout = ({ const paths = router.asPath.split("/"); const selectedTab = paths[3] ?? "overview"; - const tabList = [{ name: "Overview" }, { name: "Activity" }, { name: "Contributors" }]; + const tabList = [ + { name: "Overview" }, + // Uncomment once the activity page has been implemented + // { name: "Activity" }, + { name: "Contributors" }, + ]; return (
From d7112074ec7996d86258c3d7b7814cf7fcc3b16a Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Fri, 6 Oct 2023 08:37:06 -0400 Subject: [PATCH 24/45] fix: now range filter works on list contributors page --- .../contributor-list-table-header.tsx | 9 +++++-- .../contributor-list-table-row.tsx | 6 +++-- .../molecules/TableHeader/table-header.tsx | 7 +---- .../organisms/Contributors/contributors.tsx | 2 +- .../ContributorsList/contributors-list.tsx | 27 ++++++++++++++----- .../ContributorsTable/contributors-table.tsx | 5 ++++ lib/hooks/api/useContributorList.ts | 12 ++++++++- pages/lists/[listId]/contributors.tsx | 4 +++ 8 files changed, 54 insertions(+), 18 deletions(-) diff --git a/components/molecules/ContributorListTableHeader/contributor-list-table-header.tsx b/components/molecules/ContributorListTableHeader/contributor-list-table-header.tsx index 194d8f3ccc..d276c179c6 100644 --- a/components/molecules/ContributorListTableHeader/contributor-list-table-header.tsx +++ b/components/molecules/ContributorListTableHeader/contributor-list-table-header.tsx @@ -7,9 +7,14 @@ import Checkbox from "components/atoms/Checkbox/checkbox"; interface ContributorListTableHeadersProps { selected?: boolean; handleOnSelectAllContributor?: (contributor: any) => void; + range?: number; } -const ContributorListTableHeaders = ({ selected, handleOnSelectAllContributor }: ContributorListTableHeadersProps) => { +const ContributorListTableHeaders = ({ + selected, + handleOnSelectAllContributor, + range = 30, +}: ContributorListTableHeadersProps) => { return (
{/* Mobile */} @@ -60,7 +65,7 @@ const ContributorListTableHeaders = ({ selected, handleOnSelectAllContributor }: Contributions
- Last 30 Days + {`Last ${range} Days`}
diff --git a/components/molecules/ContributorListTableRow/contributor-list-table-row.tsx b/components/molecules/ContributorListTableRow/contributor-list-table-row.tsx index 80bd259b0a..245862aad1 100644 --- a/components/molecules/ContributorListTableRow/contributor-list-table-row.tsx +++ b/components/molecules/ContributorListTableRow/contributor-list-table-row.tsx @@ -19,6 +19,7 @@ interface ContributorListTableRow { topic: string; selected?: boolean; handleOnSelectContributor?: (state: boolean, contributor: DbPRContributor) => void; + range: number; } function getLastContributionDate(contributions: DbRepoPR[]) { @@ -47,14 +48,15 @@ const ContributorListTableRow = ({ topic, selected, handleOnSelectContributor, + range, }: ContributorListTableRow) => { const [tableOpen, setTableOpen] = useState(false); const { data: user } = useFetchUser(contributor.author_login); - const { data } = useContributorPullRequests(contributor.author_login, topic, [], 30); + const { data } = useContributorPullRequests(contributor.author_login, topic, [], range); const repoList = useRepoList(Array.from(new Set(data.map((prData) => prData.full_name))).join(",")); const contributorLanguageList = user ? Object.keys(user.languages).map((language) => language) : []; - const days = getPullRequestsToDays(data); + const days = getPullRequestsToDays(data, range); const totalPrs = data.length; const last30days = [ { diff --git a/components/molecules/TableHeader/table-header.tsx b/components/molecules/TableHeader/table-header.tsx index 17bda21521..f905914b66 100644 --- a/components/molecules/TableHeader/table-header.tsx +++ b/components/molecules/TableHeader/table-header.tsx @@ -95,12 +95,7 @@ const TableHeader = ({ />
- {range ? ( - setRangeFilter?.(range)} defaultRange={range} /> - ) : ( - "" - )} - + {setRangeFilter && range ? : null} {layout ? (
diff --git a/components/organisms/Contributors/contributors.tsx b/components/organisms/Contributors/contributors.tsx index 38138decbd..9bfac2a0bf 100644 --- a/components/organisms/Contributors/contributors.tsx +++ b/components/organisms/Contributors/contributors.tsx @@ -83,7 +83,7 @@ const Contributors = ({ repositories }: ContributorProps): JSX.Element => {
) : (
- +
)} diff --git a/components/organisms/ContributorsList/contributors-list.tsx b/components/organisms/ContributorsList/contributors-list.tsx index 3fc8cade66..30bbd4cfb8 100644 --- a/components/organisms/ContributorsList/contributors-list.tsx +++ b/components/organisms/ContributorsList/contributors-list.tsx @@ -16,6 +16,8 @@ interface ContributorsListProps { meta: Meta; setPage: (page: number) => void; setLimit: (limit: number) => void; + range: number; + setRange: (range: number) => void; } interface ContributorCardListProps { @@ -48,8 +50,15 @@ const ContributorCardList = ({ contributors = [], topic, range }: ContributorCar ); }; -const ContributorsList = ({ contributors, isLoading, meta, setPage, setLimit }: ContributorsListProps) => { - const [range, setRange] = useState(30); +const ContributorsList = ({ + contributors, + isLoading, + meta, + setPage, + setLimit, + range, + setRange, +}: ContributorsListProps) => { const [layout, setLayout] = useState("grid"); return ( @@ -59,16 +68,22 @@ const ContributorsList = ({ contributors, isLoading, meta, setPage, setLimit }: metaInfo={meta} entity="contributors" updateLimit={setLimit} - range={range} - setRangeFilter={setRange} layout={layout} onLayoutToggle={setLayout} + range={range} + setRangeFilter={setRange} /> {layout === "grid" ? ( <> - - + + ) : ( diff --git a/components/organisms/ContributorsTable/contributors-table.tsx b/components/organisms/ContributorsTable/contributors-table.tsx index 8baf97d077..790f49dc78 100644 --- a/components/organisms/ContributorsTable/contributors-table.tsx +++ b/components/organisms/ContributorsTable/contributors-table.tsx @@ -8,6 +8,8 @@ export interface ContributorTableProps { loading?: boolean; selectedContributors?: DbPRContributor[]; handleSelectContributors?: (state: boolean, contributor: DbPRContributor) => void; + range?: number; + setRange?: (range: number) => void; } const ContributorTable = ({ @@ -16,6 +18,8 @@ const ContributorTable = ({ loading, selectedContributors, handleSelectContributors, + range = 30, + setRange, }: ContributorTableProps) => { return (
@@ -29,6 +33,7 @@ const ContributorTable = ({ key={contributor.user_id} selected={!!selectedContributors?.find((selected) => selected.user_id === contributor.user_id)} handleOnSelectContributor={handleSelectContributors} + range={range} /> )) ) : ( diff --git a/lib/hooks/api/useContributorList.ts b/lib/hooks/api/useContributorList.ts index aff5e6c3f4..911d3129a0 100644 --- a/lib/hooks/api/useContributorList.ts +++ b/lib/hooks/api/useContributorList.ts @@ -21,6 +21,7 @@ export const useContributorsList = ({ initialData, initialPage = 1, defaultLimit = 10, + defaultRange = 30, }: { listId: string | undefined; initialData?: { @@ -29,11 +30,18 @@ export const useContributorsList = ({ }; initialPage?: number; defaultLimit?: number; + defaultRange?: number; }) => { + const [range, setRange] = useState(defaultRange); // [start, end const [page, setPage] = useState(initialPage); const [limit, setLimit] = useState(defaultLimit); + const query = new URLSearchParams(); + query.append("page", page.toString()); + query.append("limit", limit.toString()); + query.append("range", range.toString()); + const { data, error, mutate } = useSWR( - `lists/${listId}/contributors?page=${page}&limit=${limit}`, + `lists/${listId}/contributors?${query}`, publicApiFetcher as Fetcher, Error>, { fallbackData: initialData, @@ -44,6 +52,8 @@ export const useContributorsList = ({ return { setPage, setLimit, + setRange, + range, data: data ? { data: contributors, meta: data.meta } : { data: [], meta: {} }, isLoading: !error && !data, isError: !!error, diff --git a/pages/lists/[listId]/contributors.tsx b/pages/lists/[listId]/contributors.tsx index 467e105f80..164361298a 100644 --- a/pages/lists/[listId]/contributors.tsx +++ b/pages/lists/[listId]/contributors.tsx @@ -58,6 +58,8 @@ const ContributorsListPage = ({ list, initialData, isError }: ContributorListPag isLoading, setPage, setLimit, + setRange, + range, data: { data: contributors, meta }, } = useContributorsList({ listId: list?.id, initialData }); @@ -72,6 +74,8 @@ const ContributorsListPage = ({ list, initialData, isError }: ContributorListPag isLoading={isLoading} setPage={setPage} setLimit={setLimit} + range={range} + setRange={setRange} /> )} From cf1245625c0611a57ba6f0997ccb4ddb02a79ad0 Mon Sep 17 00:00:00 2001 From: OGBONNA SUNDAY <62995161+OgDev-01@users.noreply.github.com> Date: Fri, 6 Oct 2023 14:49:19 +0100 Subject: [PATCH 25/45] refactor: redirect user to newly created insight page after creation (#1808) --- components/atoms/Button/button.tsx | 2 +- .../organisms/InsightPage/InsightPage.tsx | 20 +++++++++++++------ 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/components/atoms/Button/button.tsx b/components/atoms/Button/button.tsx index 51ec41355b..2cb886f248 100644 --- a/components/atoms/Button/button.tsx +++ b/components/atoms/Button/button.tsx @@ -58,7 +58,7 @@ const Button = React.forwardRef( fill="currentColor" > - {showLoadingText && Loading...} + {showLoadingText && Loading...}
) : ( children diff --git a/components/organisms/InsightPage/InsightPage.tsx b/components/organisms/InsightPage/InsightPage.tsx index 37d53ef158..3e22496001 100644 --- a/components/organisms/InsightPage/InsightPage.tsx +++ b/components/organisms/InsightPage/InsightPage.tsx @@ -1,5 +1,6 @@ import { useEffect, useState } from "react"; import { useRouter } from "next/router"; +import dynamic from "next/dynamic"; import { UserGroupIcon } from "@heroicons/react/24/outline"; import { useDebounce } from "rooks"; @@ -19,12 +20,15 @@ import useStore from "lib/store"; import Error from "components/atoms/Error/Error"; import Search from "components/atoms/Search/search"; import { useToast } from "lib/hooks/useToast"; -import TeamMembersConfig, { TeamMemberData } from "components/molecules/TeamMembersConfig/team-members-config"; +import { TeamMemberData } from "components/molecules/TeamMembersConfig/team-members-config"; import useInsightMembers from "lib/hooks/useInsightMembers"; import { useFetchInsightRecommendedRepositories } from "lib/hooks/useFetchOrgRecommendations"; import { RepoCardProfileProps } from "components/molecules/RepoCardProfile/repo-card-profile"; import SuggestedRepositoriesList from "../SuggestedRepoList/suggested-repo-list"; -import DeleteInsightPageModal from "./DeleteInsightPageModal"; + +// lazy import DeleteInsightPageModal and TeamMembersConfig component to optimize bundle size they don't load on initial render +const DeleteInsightPageModal = dynamic(() => import("./DeleteInsightPageModal")); +const TeamMembersConfig = dynamic(() => import("components/molecules/TeamMembersConfig/team-members-config")); enum RepoLookupError { Initial = 0, @@ -63,7 +67,7 @@ const staticSuggestedRepos: RepoCardProfileProps[] = [ ]; const InsightPage = ({ edit, insight, pageRepos }: InsightPageProps) => { - const { sessionToken, providerToken } = useSupabaseAuth(); + const { sessionToken, providerToken, user } = useSupabaseAuth(); const { toast } = useToast(); const router = useRouter(); const pageHref = router.asPath; @@ -188,6 +192,11 @@ const InsightPage = ({ edit, insight, pageRepos }: InsightPageProps) => { const handleCreateInsightPage = async () => { setSubmitted(true); setCreateLoading(true); + + if (!sessionToken || !user) { + toast({ description: "You must be logged in to create a page", variant: "danger" }); + return; + } const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/user/insights`, { method: "POST", headers: { @@ -202,10 +211,9 @@ const InsightPage = ({ edit, insight, pageRepos }: InsightPageProps) => { }); setCreateLoading(false); if (response.ok) { + const { id } = await response.json(); toast({ description: "Page created successfully", variant: "success" }); - setTimeout(() => { - router.push("/hub/insights"); - }, 1000); + router.push(`/pages/${user.user_metadata.user_name}/${id}/dashboard`); } setSubmitted(false); From 9a7424a9fa34f0ebca94baafc7ace8cb113d49e3 Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Fri, 6 Oct 2023 14:09:53 +0000 Subject: [PATCH 26/45] chore(patch): release 1.68.0-beta.8 on beta channel [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.68.0-beta.8](https://github.com/open-sauced/insights/compare/v1.68.0-beta.7...v1.68.0-beta.8) (2023-10-06) ### πŸ§‘β€πŸ’» Code Refactoring * redirect user to newly created insight page after creation ([#1808](https://github.com/open-sauced/insights/issues/1808)) ([cf12456](https://github.com/open-sauced/insights/commit/cf1245625c0611a57ba6f0997ccb4ddb02a79ad0)) ### πŸ› Bug Fixes * now range filter works on list contributors page ([d711207](https://github.com/open-sauced/insights/commit/d7112074ec7996d86258c3d7b7814cf7fcc3b16a)) * now range filter works on list contributors page grid view ([#1819](https://github.com/open-sauced/insights/issues/1819)) ([989ebba](https://github.com/open-sauced/insights/commit/989ebbaa97b7c8fa1498d329bd27c2c1e95df3b2)) --- CHANGELOG.md | 13 +++++++++++++ npm-shrinkwrap.json | 4 ++-- package.json | 2 +- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6a50b3fd7c..7ffb0e948b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,19 @@ > All notable changes to this project will be documented in this file +## [1.68.0-beta.8](https://github.com/open-sauced/insights/compare/v1.68.0-beta.7...v1.68.0-beta.8) (2023-10-06) + + +### πŸ§‘β€πŸ’» Code Refactoring + +* redirect user to newly created insight page after creation ([#1808](https://github.com/open-sauced/insights/issues/1808)) ([cf12456](https://github.com/open-sauced/insights/commit/cf1245625c0611a57ba6f0997ccb4ddb02a79ad0)) + + +### πŸ› Bug Fixes + +* now range filter works on list contributors page ([d711207](https://github.com/open-sauced/insights/commit/d7112074ec7996d86258c3d7b7814cf7fcc3b16a)) +* now range filter works on list contributors page grid view ([#1819](https://github.com/open-sauced/insights/issues/1819)) ([989ebba](https://github.com/open-sauced/insights/commit/989ebbaa97b7c8fa1498d329bd27c2c1e95df3b2)) + ## [1.68.0-beta.7](https://github.com/open-sauced/insights/compare/v1.68.0-beta.6...v1.68.0-beta.7) (2023-10-06) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index f6ca52d33b..321155fa6a 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "@open-sauced/insights", - "version": "1.68.0-beta.7", + "version": "1.68.0-beta.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@open-sauced/insights", - "version": "1.68.0-beta.7", + "version": "1.68.0-beta.8", "hasInstallScript": true, "license": "Apache 2.0", "dependencies": { diff --git a/package.json b/package.json index cc23821e0d..69b69d950c 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@open-sauced/insights", "description": "πŸ•The dashboard for open source discovery.", "keywords": [], - "version": "1.68.0-beta.7", + "version": "1.68.0-beta.8", "author": "Brian Douglas ", "private": true, "license": "Apache 2.0", From 5c6eee61716926baf6493e4432911648baa942ed Mon Sep 17 00:00:00 2001 From: Nick Taylor Date: Fri, 6 Oct 2023 11:23:22 -0400 Subject: [PATCH 27/45] chore: fixed alignement of table header filters --- components/molecules/TableHeader/table-header.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/molecules/TableHeader/table-header.tsx b/components/molecules/TableHeader/table-header.tsx index f905914b66..f4444736d9 100644 --- a/components/molecules/TableHeader/table-header.tsx +++ b/components/molecules/TableHeader/table-header.tsx @@ -75,7 +75,7 @@ const TableHeader = ({ }, [searchTerm]); return ( -
+
{title} From 1753ce9a9134815dc99c1d192dafb78239390a57 Mon Sep 17 00:00:00 2001 From: Nick Taylor <nick@nickyt.co> Date: Fri, 6 Oct 2023 18:05:51 +0000 Subject: [PATCH 28/45] chore(minor): release 1.68.0-beta.9 on beta channel [skip ci] MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [1.68.0-beta.9](https://github.com/open-sauced/insights/compare/v1.68.0-beta.8...v1.68.0-beta.9) (2023-10-06) ### πŸ• Features * move range filter to list pages header ([#1817](https://github.com/open-sauced/insights/issues/1817)) ([0b82760](https://github.com/open-sauced/insights/commit/0b82760dfd20b14230f8f0b4496b75c3086db139)) --- CHANGELOG.md | 7 +++++++ npm-shrinkwrap.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7ffb0e948b..bec79cf36d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,13 @@ > All notable changes to this project will be documented in this file +## [1.68.0-beta.9](https://github.com/open-sauced/insights/compare/v1.68.0-beta.8...v1.68.0-beta.9) (2023-10-06) + + +### πŸ• Features + +* move range filter to list pages header ([#1817](https://github.com/open-sauced/insights/issues/1817)) ([0b82760](https://github.com/open-sauced/insights/commit/0b82760dfd20b14230f8f0b4496b75c3086db139)) + ## [1.68.0-beta.8](https://github.com/open-sauced/insights/compare/v1.68.0-beta.7...v1.68.0-beta.8) (2023-10-06) diff --git a/npm-shrinkwrap.json b/npm-shrinkwrap.json index 321155fa6a..5ec670602d 100644 --- a/npm-shrinkwrap.json +++ b/npm-shrinkwrap.json @@ -1,12 +1,12 @@ { "name": "@open-sauced/insights", - "version": "1.68.0-beta.8", + "version": "1.68.0-beta.9", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@open-sauced/insights", - "version": "1.68.0-beta.8", + "version": "1.68.0-beta.9", "hasInstallScript": true, "license": "Apache 2.0", "dependencies": { diff --git a/package.json b/package.json index 69b69d950c..21f7b264aa 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "@open-sauced/insights", "description": "πŸ•The dashboard for open source discovery.", "keywords": [], - "version": "1.68.0-beta.8", + "version": "1.68.0-beta.9", "author": "Brian Douglas <brian@opensauced.pizza>", "private": true, "license": "Apache 2.0", From f7276e97c54f71ece8b5b60e6c76fa11ad1f96b3 Mon Sep 17 00:00:00 2001 From: OGBONNA SUNDAY <62995161+OgDev-01@users.noreply.github.com> Date: Mon, 9 Oct 2023 14:09:42 +0100 Subject: [PATCH 29/45] refactor: use api timezone options for contributors filter (#1827) --- .../hub-contributors-header.tsx | 13 +- helpers/fetchApiData.ts | 9 +- lib/hooks/useFetchAllContributors.ts | 7 +- pages/hub/lists/new.tsx | 319 +++++++++++------- pages/lists/[listId]/contributors.tsx | 6 +- pages/lists/[listId]/overview.tsx | 6 +- 6 files changed, 205 insertions(+), 155 deletions(-) diff --git a/components/molecules/HubContributorsHeader/hub-contributors-header.tsx b/components/molecules/HubContributorsHeader/hub-contributors-header.tsx index e6bf350680..5e94ff3d3a 100644 --- a/components/molecules/HubContributorsHeader/hub-contributors-header.tsx +++ b/components/molecules/HubContributorsHeader/hub-contributors-header.tsx @@ -3,7 +3,6 @@ import { FaPlus } from "react-icons/fa"; import clsx from "clsx"; import { FiGlobe } from "react-icons/fi"; -import { timezones } from "lib/utils/timezones"; import { useToast } from "lib/hooks/useToast"; import ListNameHeader from "components/atoms/ListNameHeader/list-name-header"; @@ -12,17 +11,15 @@ import SingleSelect from "components/atoms/Select/single-select"; import ToggleSwitch from "components/atoms/ToggleSwitch/toggle-switch"; import Button from "components/atoms/Button/button"; import Text from "components/atoms/Typography/text"; -import ComponentDateFilter from "../ComponentDateFilter/component-date-filter"; // import Search from "components/atoms/Search/search"; interface ListHeaderProps { setLimit?: (limit: number) => void; - setRangeFilter?: (range: number) => void; + timezoneOptions: { label: string; value: string }[]; timezone?: string; setTimezoneFilter: (timezone: string) => void; isPublic: boolean; handleToggleIsPublic: () => void; - range?: number; selectedContributorsIds: number[]; title?: string; onAddToList?: () => void; @@ -32,23 +29,18 @@ interface ListHeaderProps { const HubContributorsHeader = ({ setLimit, - setRangeFilter, selectedContributorsIds, title, onAddToList, onTitleChange, - range, loading, isPublic, handleToggleIsPublic, timezone, setTimezoneFilter, + timezoneOptions, }: ListHeaderProps): JSX.Element => { const { toast } = useToast(); - const timezoneOptions = timezones.map((timezone) => ({ - label: timezone.text, - value: timezone.value, - })); return ( <div className="relative flex flex-col justify-between w-full gap-6 py-2"> @@ -105,7 +97,6 @@ const HubContributorsHeader = ({ /> </div> <div className="flex flex-col gap-2 md:items-center md:gap-4 md:flex-row"> - <ComponentDateFilter setRangeFilter={(range: number) => setRangeFilter?.(range)} defaultRange={range} /> <LimitSelect placeholder="10 per page" options={[ diff --git a/helpers/fetchApiData.ts b/helpers/fetchApiData.ts index 14dd787e02..2d82934e7f 100644 --- a/helpers/fetchApiData.ts +++ b/helpers/fetchApiData.ts @@ -10,17 +10,16 @@ export async function fetchApiData<T>({ method = "GET", headers, bearerToken, - pathValidator, }: { path: string; method?: "GET" | "POST" | "PUT" | "DELETE" | "PATCH"; headers?: HeadersInit; bearerToken: string; - pathValidator(path: string): boolean; + // pathValidator(path: string): boolean; }) { - if (!pathValidator(path)) { - return { data: null, error: { status: 400, statusText: "bad request" } }; - } + // if (!pathValidator(path)) { + // return { data: null, error: { status: 400, statusText: "bad request" } }; + // } const apiUrl = `${process.env.NEXT_PUBLIC_API_URL}/${path}`; const response = await fetch(apiUrl, { diff --git a/lib/hooks/useFetchAllContributors.ts b/lib/hooks/useFetchAllContributors.ts index 95bf0cd4ba..19b6ab0938 100644 --- a/lib/hooks/useFetchAllContributors.ts +++ b/lib/hooks/useFetchAllContributors.ts @@ -1,5 +1,5 @@ import { useState } from "react"; -import useSWR, { Fetcher } from "swr"; +import useSWR, { Fetcher, SWRConfiguration } from "swr"; import { useRouter } from "next/router"; import publicApiFetcher from "lib/utils/public-api-fetcher"; @@ -17,7 +17,7 @@ type queryObj = { initialLimit?: number; }; -const useFetchAllContributors = (query: queryObj) => { +const useFetchAllContributors = (query: queryObj, config?: SWRConfiguration) => { const { toast } = useToast(); const router = useRouter(); const [page, setPage] = useState(1); @@ -46,7 +46,8 @@ const useFetchAllContributors = (query: queryObj) => { const { data, error, mutate } = useSWR<PaginatedResponse, Error>( endpointString, - publicApiFetcher as Fetcher<PaginatedResponse, Error> + publicApiFetcher as Fetcher<PaginatedResponse, Error>, + config ); return { diff --git a/pages/hub/lists/new.tsx b/pages/hub/lists/new.tsx index f7e1ae4e86..3c9d119da2 100644 --- a/pages/hub/lists/new.tsx +++ b/pages/hub/lists/new.tsx @@ -2,17 +2,22 @@ import React, { useEffect, useState } from "react"; import { FiCheckCircle, FiCopy } from "react-icons/fi"; import { AiOutlineWarning } from "react-icons/ai"; import { usePostHog } from "posthog-js/react"; +import { GetServerSidePropsContext } from "next"; +import { createPagesServerClient } from "@supabase/auth-helpers-nextjs"; + +import useFetchAllContributors from "lib/hooks/useFetchAllContributors"; +import { fetchApiData } from "helpers/fetchApiData"; +import { timezones } from "lib/utils/timezones"; +import { useToast } from "lib/hooks/useToast"; +import useSupabaseAuth from "lib/hooks/useSupabaseAuth"; + import ContributorListTableHeaders from "components/molecules/ContributorListTableHeader/contributor-list-table-header"; -import { WithPageLayout } from "interfaces/with-page-layout"; import HubContributorsPageLayout from "layouts/hub-contributors"; -import useFetchAllContributors from "lib/hooks/useFetchAllContributors"; import ContributorTable from "components/organisms/ContributorsTable/contributors-table"; import Header from "components/organisms/Header/header"; import HubContributorsHeader from "components/molecules/HubContributorsHeader/hub-contributors-header"; import Pagination from "components/molecules/Pagination/pagination"; import PaginationResults from "components/molecules/PaginationResults/pagination-result"; -import { useToast } from "lib/hooks/useToast"; -import useSupabaseAuth from "lib/hooks/useSupabaseAuth"; import { Dialog, DialogContent } from "components/molecules/Dialog/dialog"; import Title from "components/atoms/Typography/title"; import Text from "components/atoms/Typography/text"; @@ -24,7 +29,46 @@ interface CreateListPayload { is_public: boolean; contributors: number[]; } -const NewListCreationPage: WithPageLayout = () => { + +interface NewListCreationPageProps { + initialData: { + meta: Meta; + data: DbPRContributor[]; + }; + timezoneOption: { timezone: string }[]; +} + +export const getServerSideProps = async (ctx: GetServerSidePropsContext) => { + const supabase = createPagesServerClient(ctx); + + const { + data: { session }, + } = await supabase.auth.getSession(); + const bearerToken = session ? session.access_token : ""; + + const fetchTimezone = fetchApiData<{ timezone: string }[]>({ path: `lists/timezones`, bearerToken }); + const fetchContributors = fetchApiData<PagedData<DbPRContributor>>({ + path: `lists/contributors`, + bearerToken, + }); + + const [{ data: timezoneOptions }, { data, error }] = await Promise.all([fetchTimezone, fetchContributors]); + + if (error?.status === 404) { + return { + notFound: true, + }; + } + + return { + props: { + initialData: data ? { data: data.data, meta: data.meta } : { data: [], meta: {} }, + timezoneOption: timezoneOptions ? timezoneOptions : timezones, + }, + }; +}; + +const NewListCreationPage = ({ initialData, timezoneOption }: NewListCreationPageProps) => { const { toast } = useToast(); const posthog = usePostHog(); const { sessionToken } = useSupabaseAuth(); @@ -35,13 +79,30 @@ const NewListCreationPage: WithPageLayout = () => { const [isSuccess, setIsSuccess] = useState(false); const [title, setTitle] = useState(""); const [selectedContributors, setSelectedContributors] = useState<DbPRContributor[]>([]); - const [range, setRange] = useState<number>(30); - const [timezone, setTimezone] = useState<string | undefined>(undefined); + const [selectedTimezone, setSelectedTimezone] = useState<string | undefined>(undefined); const [isPublic, setIsPublic] = useState<boolean>(false); - const { data, meta, isLoading, setLimit, setPage } = useFetchAllContributors({ - timezone: timezone, - }); + const { data, meta, isLoading, setLimit, setPage } = useFetchAllContributors( + { + timezone: selectedTimezone, + }, + { + fallbackData: initialData, + revalidateOnFocus: false, + } + ); + + // get all timezones from the api that exists in the dummy timezone list + const timezoneList = timezones + .filter((timezone) => { + return timezoneOption.some((timezoneOption) => timezoneOption.timezone === timezone.value); + }) + .map((timezone) => { + return { + label: timezone.text, + value: timezone.value, + }; + }); const contributors = data ? data.length > 0 && data.map((contributor) => { @@ -133,141 +194,139 @@ const NewListCreationPage: WithPageLayout = () => { }; const handleSelectTimezone = (selected: string) => { - setTimezone(selected); + setSelectedTimezone(selected); }; return ( - <Dialog open={isOpen}> - <div className="info-container container w-full min-h-[6.25rem]"> - <Header> - <HubContributorsHeader - setTimezoneFilter={handleSelectTimezone} - isPublic={isPublic} - handleToggleIsPublic={() => setIsPublic(!isPublic)} - loading={createLoading} - selectedContributorsIds={selectedContributors.map((contributor) => contributor.user_id)} - setLimit={setLimit} - setRangeFilter={(range) => { - setRange(range); - }} - timezone={timezone} - title={title} - onAddToList={handleOnListCreate} - onTitleChange={(title) => setTitle(title)} + <HubContributorsPageLayout> + <Dialog open={isOpen}> + <div className="info-container container w-full min-h-[6.25rem]"> + <Header> + <HubContributorsHeader + setTimezoneFilter={handleSelectTimezone} + isPublic={isPublic} + handleToggleIsPublic={() => setIsPublic(!isPublic)} + loading={createLoading} + selectedContributorsIds={selectedContributors.map((contributor) => contributor.user_id)} + setLimit={setLimit} + timezoneOptions={timezoneList} + timezone={selectedTimezone} + title={title} + onAddToList={handleOnListCreate} + onTitleChange={(title) => setTitle(title)} + /> + </Header> + </div> + <div className="lg:min-w-[1150px] px-4 md:px-16 py-8"> + <ContributorListTableHeaders + selected={selectedContributors.length > 0 && selectedContributors.length === meta.limit} + handleOnSelectAllContributor={handleOnSelectAllChecked} /> - </Header> - </div> - <div className="lg:min-w-[1150px] px-4 md:px-16 py-8"> - <ContributorListTableHeaders - selected={selectedContributors.length > 0 && selectedContributors.length === meta.limit} - handleOnSelectAllContributor={handleOnSelectAllChecked} - /> - <ContributorTable - loading={isLoading} - selectedContributors={selectedContributors} - topic={"*"} - handleSelectContributors={handleOnSelectChecked} - contributors={contributors as DbPRContributor[]} - ></ContributorTable> - <div className="flex items-center justify-between w-full py-1 md:py-4 md:mt-5"> - <div> - <div className=""> - <PaginationResults metaInfo={meta} total={meta.itemCount} entity={"contributors"} /> + <ContributorTable + loading={isLoading} + selectedContributors={selectedContributors} + topic={"*"} + handleSelectContributors={handleOnSelectChecked} + contributors={contributors as DbPRContributor[]} + ></ContributorTable> + <div className="flex items-center justify-between w-full py-1 md:py-4 md:mt-5"> + <div> + <div className=""> + <PaginationResults metaInfo={meta} total={meta.itemCount} entity={"contributors"} /> + </div> </div> - </div> - <div> - <div className="flex flex-col gap-4"> - <Pagination - pages={[]} - hasNextPage={meta.hasNextPage} - hasPreviousPage={meta.hasPreviousPage} - totalPage={meta.pageCount} - page={meta.page} - onPageChange={function (page: number): void { - setPage(page); - }} - divisor={true} - goToPage - /> + <div> + <div className="flex flex-col gap-4"> + <Pagination + pages={[]} + hasNextPage={meta.hasNextPage} + hasPreviousPage={meta.hasPreviousPage} + totalPage={meta.pageCount} + page={meta.page} + onPageChange={function (page: number): void { + setPage(page); + }} + divisor={true} + goToPage + /> + </div> </div> </div> </div> - </div> - {/* Success and error state dialog section */} - <DialogContent> - {isSuccess ? ( - <div className="flex flex-col max-w-xs gap-6 w-max"> - <div className="flex flex-col items-center gap-2"> - <span className="flex items-center justify-center p-3 bg-green-100 rounded-full w-max"> - <span className="flex items-center justify-center w-10 h-10 bg-green-300 rounded-full"> - <FiCheckCircle className="text-green-800" size={24} /> + {/* Success and error state dialog section */} + <DialogContent> + {isSuccess ? ( + <div className="flex flex-col max-w-xs gap-6 w-max"> + <div className="flex flex-col items-center gap-2"> + <span className="flex items-center justify-center p-3 bg-green-100 rounded-full w-max"> + <span className="flex items-center justify-center w-10 h-10 bg-green-300 rounded-full"> + <FiCheckCircle className="text-green-800" size={24} /> + </span> </span> - </span> - <Title level={3} className="text-lg"> - Your list has been created - - - You can now edit and track your new list in the pages tab, and get useful insights. - -
-
- -
-
- - + + Your list has been created + + + You can now edit and track your new list in the pages tab, and get useful insights. + +
+
+ +
+
+ + +
-
- ) : ( -
-
- - - + ) : ( +
+
+ + + + - - - Something went wrong - - - We couldn’t create your list. Please, try again in a few minutes. - -
+ + Something went wrong + + + We couldn’t create your list. Please, try again in a few minutes. + +
-
- - +
+ + +
-
- )} - -
+ )} + + + ); }; -NewListCreationPage.PageLayout = HubContributorsPageLayout; - export default NewListCreationPage; diff --git a/pages/lists/[listId]/contributors.tsx b/pages/lists/[listId]/contributors.tsx index ebe820abda..3247421633 100644 --- a/pages/lists/[listId]/contributors.tsx +++ b/pages/lists/[listId]/contributors.tsx @@ -1,7 +1,7 @@ import { GetServerSidePropsContext } from "next"; import { createPagesServerClient } from "@supabase/auth-helpers-nextjs"; import ListPageLayout from "layouts/lists"; -import { fetchApiData, validateListPath } from "helpers/fetchApiData"; +import { fetchApiData } from "helpers/fetchApiData"; import Error from "components/atoms/Error/Error"; import { convertToContributors, useContributorsList } from "lib/hooks/api/useContributorList"; import ContributorsList from "components/organisms/ContributorsList/contributors-list"; @@ -20,9 +20,9 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => { fetchApiData>({ path: `lists/${listId}/contributors?limit=${limit}`, bearerToken, - pathValidator: validateListPath, + // pathValidator: validateListPath, }), - fetchApiData({ path: `lists/${listId}`, bearerToken, pathValidator: validateListPath }), + fetchApiData({ path: `lists/${listId}`, bearerToken }), ]); if (error?.status === 404) { diff --git a/pages/lists/[listId]/overview.tsx b/pages/lists/[listId]/overview.tsx index c2c6154a40..a753ac6ee3 100644 --- a/pages/lists/[listId]/overview.tsx +++ b/pages/lists/[listId]/overview.tsx @@ -14,7 +14,7 @@ import { getAvatarByUsername } from "lib/utils/github"; import useListContributions from "lib/hooks/useListContributions"; import useListStats from "lib/hooks/useListStats"; import HighlightCard from "components/molecules/HighlightCard/highlight-card"; -import { fetchApiData, validateListPath } from "helpers/fetchApiData"; +import { fetchApiData } from "helpers/fetchApiData"; import ClientOnly from "components/atoms/ClientOnly/client-only"; type ContributorPrMap = { [contributor: string]: DbRepoPR }; @@ -38,9 +38,9 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => { fetchApiData>({ path: `lists/${listId}/contributors?limit=${limit}`, bearerToken, - pathValidator: validateListPath, + // pathValidator: validateListPath, }), - fetchApiData({ path: `lists/${listId}`, bearerToken, pathValidator: validateListPath }), + fetchApiData({ path: `lists/${listId}`, bearerToken }), ]); if (error?.status === 404) { From 566b0d1f8946b3d19ed6a8ea38251891e435610d Mon Sep 17 00:00:00 2001 From: OGBONNA SUNDAY <62995161+OgDev-01@users.noreply.github.com> Date: Mon, 9 Oct 2023 14:14:11 +0100 Subject: [PATCH 30/45] fix: show insight link for not onboarded users (#1830) --- components/organisms/TopNav/top-nav.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/organisms/TopNav/top-nav.tsx b/components/organisms/TopNav/top-nav.tsx index 68659c70c7..d8dfe30618 100644 --- a/components/organisms/TopNav/top-nav.tsx +++ b/components/organisms/TopNav/top-nav.tsx @@ -35,7 +35,7 @@ const Nav = ({ className, name = "Main" }: { className?: string; name?: string } return (