From 449ec16675e152a0a4db89c098f12a84e7af2254 Mon Sep 17 00:00:00 2001 From: Brandon Roberts Date: Thu, 29 Feb 2024 15:53:55 -0600 Subject: [PATCH] chore: release 2.4.1 --- CHANGELOG.md | 68 ++- components/Workspaces/InsightUpgradeModal.tsx | 46 +- .../Workspaces/TrackedContributorsTable.tsx | 2 +- .../TrackedRepoWizard/PickReposOrOrgStep.tsx | 4 +- components/Workspaces/TrackedReposTable.tsx | 2 +- components/Workspaces/WorkspaceBanner.tsx | 14 + components/Workspaces/WorkspaceLayout.tsx | 6 +- .../contributor-list-table-row.tsx | 9 +- components/organisms/TopNav/top-nav.tsx | 7 +- components/shared/AppSidebar/AppSidebar.tsx | 6 +- lib/hooks/api/usePullRequestsHistogram.ts | 2 + lib/utils/workspace-utils.test.ts | 26 + lib/utils/workspace-utils.ts | 2 +- middleware.ts | 14 +- next-types.d.ts | 8 +- npm-shrinkwrap.json | 548 +++++------------- pages/404.tsx | 2 +- .../contributor-insights/[listId]/edit.tsx | 287 +++++---- .../[listId]/overview.tsx | 23 +- .../contributor-insights/index.tsx | 5 - .../{repositories.tsx => index.tsx} | 0 .../[insightId]/dashboard.tsx | 32 +- pages/workspaces/[workspaceId]/settings.tsx | 58 +- pages/workspaces/new.tsx | 2 +- vitest.config.ts | 1 + 25 files changed, 523 insertions(+), 651 deletions(-) create mode 100644 components/Workspaces/WorkspaceBanner.tsx create mode 100644 lib/utils/workspace-utils.test.ts rename pages/workspaces/[workspaceId]/{repositories.tsx => index.tsx} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b554106e2..940a34b20f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,71 @@ > All notable changes to this project will be documented in this file +## [2.4.0-beta.55](https://github.com/open-sauced/app/compare/v2.4.0-beta.54...v2.4.0-beta.55) (2024-02-29) + + +### 🐛 Bug Fixes + +* now the workspace creation redirects to the new workspace homepage ([#2830](https://github.com/open-sauced/app/issues/2830)) ([e1bbe84](https://github.com/open-sauced/app/commit/e1bbe849e00d5f4fb87bffbbf022558c1c169566)) +* use pr histogram for contributor pull request activity line chart ([#2831](https://github.com/open-sauced/app/issues/2831)) ([7e93b9d](https://github.com/open-sauced/app/commit/7e93b9dd0b5a4b4b68f47953c7bd3d9d5e19af58)) + +## [2.4.0-beta.54](https://github.com/open-sauced/app/compare/v2.4.0-beta.53...v2.4.0-beta.54) (2024-02-29) + + +### 🐛 Bug Fixes + +* show upgrade banner only when needed ([#2809](https://github.com/open-sauced/app/issues/2809)) ([316ebd2](https://github.com/open-sauced/app/commit/316ebd2cbdefde39939a855d59e7318b5c913d57)) + +## [2.4.0-beta.53](https://github.com/open-sauced/app/compare/v2.4.0-beta.52...v2.4.0-beta.53) (2024-02-29) + + +### 🐛 Bug Fixes + +* now the workspaces homepage is /workspaces/some-workspace-id ([#2821](https://github.com/open-sauced/app/issues/2821)) ([bd5d5c7](https://github.com/open-sauced/app/commit/bd5d5c74a45d44b47f14fd4623f674b80a37b01e)) + +## [2.4.0-beta.52](https://github.com/open-sauced/app/compare/v2.4.0-beta.51...v2.4.0-beta.52) (2024-02-29) + + +### 🐛 Bug Fixes + +* top navigation workspace link works as expected now ([#2804](https://github.com/open-sauced/app/issues/2804)) ([4528b61](https://github.com/open-sauced/app/commit/4528b6172d59d7cd3ef277192d3be5d72500c97b)) + +## [2.4.0-beta.51](https://github.com/open-sauced/app/compare/v2.4.0-beta.50...v2.4.0-beta.51) (2024-02-28) + + +### 🐛 Bug Fixes + +* Rework workspace visibility flow ([#2796](https://github.com/open-sauced/app/issues/2796)) ([856d269](https://github.com/open-sauced/app/commit/856d2692ae8249e8a69d6558548a13da064ac5db)) + +## [2.4.0-beta.50](https://github.com/open-sauced/app/compare/v2.4.0-beta.49...v2.4.0-beta.50) (2024-02-28) + + +### 🐛 Bug Fixes + +* use workspace_id field when redirecting legacy insights and lists ([#2808](https://github.com/open-sauced/app/issues/2808)) ([1fd078d](https://github.com/open-sauced/app/commit/1fd078dc48582583b03bc60b270df381e3d2dd6a)) + +## [2.4.0-beta.49](https://github.com/open-sauced/app/compare/v2.4.0-beta.48...v2.4.0-beta.49) (2024-02-28) + + +### 🐛 Bug Fixes + +* now the complete the onboarding tooltip only appears on screens smaller than 1024px ([#2800](https://github.com/open-sauced/app/issues/2800)) ([86e9d5b](https://github.com/open-sauced/app/commit/86e9d5b24fd7459be85f92b3be0a766dae8817bb)) +* remove duplicate layout on contributor insight edit page ([#2805](https://github.com/open-sauced/app/issues/2805)) ([7e563f9](https://github.com/open-sauced/app/commit/7e563f96fbe097486e76138888e5df8783c1d59c)) + +## [2.4.0-beta.48](https://github.com/open-sauced/app/compare/v2.4.0-beta.47...v2.4.0-beta.48) (2024-02-28) + + +### 🐛 Bug Fixes + +* removed unused feature flags in contributor insights page ([#2798](https://github.com/open-sauced/app/issues/2798)) ([0143738](https://github.com/open-sauced/app/commit/014373873db86b8ea640e85bdb7d57eced336b47)) + +## [2.4.0-beta.47](https://github.com/open-sauced/app/compare/v2.4.0-beta.46...v2.4.0-beta.47) (2024-02-28) + + +### 🐛 Bug Fixes + +* Corrects copy for Github -> GitHub ([#2797](https://github.com/open-sauced/app/issues/2797)) ([9f40019](https://github.com/open-sauced/app/commit/9f4001985bbf2c991099c0c53a83e84dd129be34)) + ## [2.4.0](https://github.com/open-sauced/app/compare/v2.3.1...v2.4.0) (2024-02-27) @@ -235,13 +300,10 @@ ### 🐛 Bug Fixes * now a click outside the tracked repositories modal closes the modal ([#2623](https://github.com/open-sauced/insights/issues/2623)) ([8d9ad05](https://github.com/open-sauced/insights/commit/8d9ad052a2405d94d87399e34b3f1aff414d7945)) -<<<<<<< HEAD -======= * Now you can't type more than 500 characters for a highlight summary ([#2614](https://github.com/open-sauced/insights/issues/2614)) ([ed3d1d9](https://github.com/open-sauced/insights/commit/ed3d1d983023a2d3a9a83a5670239b3fea73be71)) * redirect to `/workspaces/new` if user has no workspaces ([#2607](https://github.com/open-sauced/insights/issues/2607)) ([547fdf5](https://github.com/open-sauced/insights/commit/547fdf5719f0eab14032a6db6accc5fb7c4786e8)) * reduced the height of the chart wrapper that is making the button unclickable ([#2611](https://github.com/open-sauced/insights/issues/2611)) ([7fb4e40](https://github.com/open-sauced/insights/commit/7fb4e4042853c5ad7cb776ef1194a6b06a5acc0f)) * return empty arrays on error when fetching GitHub data ([#2616](https://github.com/open-sauced/insights/issues/2616)) ([5c9ad0b](https://github.com/open-sauced/insights/commit/5c9ad0b12a421e198340d46835aca5fa8dd6fd2f)) ->>>>>>> main ## [2.2.0-beta.6](https://github.com/open-sauced/insights/compare/v2.2.0-beta.5...v2.2.0-beta.6) (2024-02-08) diff --git a/components/Workspaces/InsightUpgradeModal.tsx b/components/Workspaces/InsightUpgradeModal.tsx index e08fee5a30..ba470383da 100644 --- a/components/Workspaces/InsightUpgradeModal.tsx +++ b/components/Workspaces/InsightUpgradeModal.tsx @@ -6,8 +6,8 @@ import Card from "components/atoms/Card/card"; type InsightUpgradeModalProps = { workspaceId: string; - overLimit: number; - variant: "repositories" | "contributors"; + overLimit?: number; + variant: "repositories" | "contributors" | "workspace"; isOpen: boolean; onClose: () => void; }; @@ -26,19 +26,30 @@ export default function InsightUpgradeModal({
- This Insight page is over the free Workspace limit -

- Your Insight page has{" "} - - {overLimit} {variant} - {" "} - but the free Workspace only allows for{" "} - - {variant === "repositories" ? 100 : 10} {variant} - {" "} - tracked. Don't worry, your insights won't be deleted, but if you want to continue using - OpenSauced you should upgrade your Workspace to a PRO Workspace. -

+ + {variant !== "workspace" + ? "This Insight page is over the free Workspace limit" + : "Upgrade to a PRO Workspace"} + + {variant !== "workspace" ? ( +

+ Your Insight page has{" "} + + {overLimit} {variant} + {" "} + but the free Workspace only allows for{" "} + + {variant === "repositories" ? 100 : 10} {variant} + {" "} + tracked. Don't worry, your insights won't be deleted. If you want to continue using + OpenSauced you should upgrade your Workspace to a PRO Account. +

+ ) : ( +

+ Setting your workspace to private is a PRO feature. Upgrade your Workspace and get exclusive access to + your work for you and your team! +

+ )}
@@ -98,7 +109,10 @@ export default function InsightUpgradeModal({
diff --git a/components/Workspaces/TrackedReposTable.tsx b/components/Workspaces/TrackedReposTable.tsx index a654f80bbd..5a5af803ae 100644 --- a/components/Workspaces/TrackedReposTable.tsx +++ b/components/Workspaces/TrackedReposTable.tsx @@ -22,7 +22,7 @@ export const EmptyState = ({ onAddRepos }: { onAddRepos: () => void }) => {
Add repositories to track

- Search and select the repositories you want to track and get insights on your entire Github ecosystem + Search and select the repositories you want to track and get insights on your entire GitHub ecosystem

+ ); +} diff --git a/components/Workspaces/WorkspaceLayout.tsx b/components/Workspaces/WorkspaceLayout.tsx index c735a539fd..574b883022 100644 --- a/components/Workspaces/WorkspaceLayout.tsx +++ b/components/Workspaces/WorkspaceLayout.tsx @@ -10,10 +10,11 @@ import Footer from "components/organisms/Footer/footer"; interface WorkspaceLayoutProps { workspaceId: string; + banner?: React.ReactNode; children: React.ReactNode; } -export const WorkspaceLayout = ({ workspaceId, children }: WorkspaceLayoutProps) => { +export const WorkspaceLayout = ({ workspaceId, banner, children }: WorkspaceLayoutProps) => { const isLargeScreen = useMediaQuery("(min-width: 1024px)"); const [showingSidebar, setShowingSidebar] = useLocalStorage("showingSidebar", isLargeScreen); const hideSidebar = () => setShowingSidebar(false); @@ -60,7 +61,8 @@ export const WorkspaceLayout = ({ workspaceId, children }: WorkspaceLayoutProps) )} -
+
+ {banner}
{children}
diff --git a/components/molecules/ContributorListTableRow/contributor-list-table-row.tsx b/components/molecules/ContributorListTableRow/contributor-list-table-row.tsx index 79ae215464..ad32f25ab0 100644 --- a/components/molecules/ContributorListTableRow/contributor-list-table-row.tsx +++ b/components/molecules/ContributorListTableRow/contributor-list-table-row.tsx @@ -4,7 +4,8 @@ import formatDistanceToNowStrict from "date-fns/formatDistanceToNowStrict"; import { ChevronDownIcon, ChevronUpIcon } from "@heroicons/react/24/solid"; import Sparkline from "components/atoms/Sparkline/sparkline"; -import { getPullRequestsToDays } from "lib/utils/get-prs-to-days"; +import { usePullRequestsHistogram } from "lib/hooks/api/usePullRequestsHistogram"; +import { getPullRequestsHistogramToDays } from "lib/utils/get-prs-to-days"; import { classNames } from "components/organisms/RepositoriesTable/repositories-table"; import useContributorPullRequests from "lib/hooks/api/useContributorPullRequests"; @@ -83,12 +84,14 @@ const ContributorListTableRow = ({ repoIds: [], range, mostRecent: true, + limit: 50, }); + const { data: prData } = usePullRequestsHistogram({ contributor: login, range: Number(range ?? "30"), width: 1 }); const repoList = useRepoList(Array.from(new Set(data.map((prData) => prData.repo_name))).join(",")); const contributorLanguageList = user ? getTopContributorLanguages(user) : []; - const days = getPullRequestsToDays(data, Number(range ?? 30)); - const totalPrs = data.length; + const days = getPullRequestsHistogramToDays(prData, Number(range ?? 30)); + const totalPrs = days.reduce((acc, curr) => acc + curr.y, 0); const last30days = [ { id: `last30-${login}`, diff --git a/components/organisms/TopNav/top-nav.tsx b/components/organisms/TopNav/top-nav.tsx index ae9b55a990..2c832577bc 100644 --- a/components/organisms/TopNav/top-nav.tsx +++ b/components/organisms/TopNav/top-nav.tsx @@ -9,10 +9,13 @@ import useSupabaseAuth from "lib/hooks/useSupabaseAuth"; import { useFetchUser } from "lib/hooks/useFetchUser"; import OnboardingButton from "components/molecules/OnboardingButton/onboarding-button"; import Tooltip from "components/atoms/Tooltip/tooltip"; +import { useMediaQuery } from "lib/hooks/useMediaQuery"; const TopNav = () => { + const isLargeScreen = useMediaQuery("(min-width: 1024px)"); const { user } = useSupabaseAuth(); const { onboarded } = useSession(); + return (
@@ -21,7 +24,7 @@ const TopNav = () => {
diff --git a/pages/workspaces/[workspaceId]/contributor-insights/[listId]/edit.tsx b/pages/workspaces/[workspaceId]/contributor-insights/[listId]/edit.tsx index 6b9752ebb2..5090604471 100644 --- a/pages/workspaces/[workspaceId]/contributor-insights/[listId]/edit.tsx +++ b/pages/workspaces/[workspaceId]/contributor-insights/[listId]/edit.tsx @@ -9,7 +9,6 @@ import { FaUserPlus } from "react-icons/fa6"; import Link from "next/link"; import { MdOutlineArrowBackIos } from "react-icons/md"; import { fetchApiData } from "helpers/fetchApiData"; -import HubContributorsPageLayout from "layouts/hub-contributors"; import Title from "components/atoms/Typography/title"; import Text from "components/atoms/Typography/text"; import ToggleSwitch from "components/atoms/ToggleSwitch/toggle-switch"; @@ -257,156 +256,154 @@ export default function EditListPage({ list, workspaceId, initialContributors }: return ( - -
-
{ - event.preventDefault(); - // FormData was being funky because of the way our ToggleSwitch works - // so went this way instead. - const form = event.target as HTMLFormElement; - const listUpdates = { - name: form["list_name"].value, - is_public: form["is_public"].checked, - contributors: [], - } satisfies UpdateListPayload; - - const { data, error } = await updateList(listUpdates); - - if (!error) { - toast({ description: "List updated successfully!", variant: "success" }); - router.push(`/workspaces/${workspaceId}/contributor-insights/${list.id}/overview`); - } else { - toast({ description: "Error updating list. Please try again", variant: "danger" }); - } - }} - className="flex flex-col gap-8" - > -
-

- - - {" "} - Edit List -

- -
-

- A list is a collection of contributors that you and your team can get insights for. -

- -
- -
-
- - - Make this page publicly visible - -
-
- Make Public - setIsPublic((isPublic: boolean) => !isPublic)} - /> -
-
-
-
-

Add Contributors

- -
-
-
-

Remove Contributors

-
-
+

+ A list is a collection of contributors that you and your team can get insights for. +

+ +
+ +
+
+ + + Make this page publicly visible + +
+
+ Make Public + setIsPublic((isPublic: boolean) => !isPublic)} /> - +
- <> - {isLoading ? ( - - ) : ( - <> - {contributors && contributors.length > 0 ? ( - <> - { - return !removedContributorIds.includes(id); - })} - onRemoveContributor={onRemoveContributor} - /> -
- index + 1)} - pageSize={5} - hasNextPage={meta.hasNextPage} - hasPreviousPage={meta.hasPreviousPage} - totalPage={meta.pageCount} - page={meta.page} - onPageChange={function (page: number): void { - setPage(page); - }} - showTotalPages={false} - /> -
- - ) : ( -

No contributors to remove found.

- )} - - )} -
-
- -
- - Delete List - - Once you delete a list, you're past the point of no return. - - -
+
+

Add Contributors

+
+ +
+

Remove Contributors

+
+ +
+ <> + {isLoading ? ( + + ) : ( + <> + {contributors && contributors.length > 0 ? ( + <> + { + return !removedContributorIds.includes(id); + })} + onRemoveContributor={onRemoveContributor} + /> +
+ index + 1)} + pageSize={5} + hasNextPage={meta.hasNextPage} + hasPreviousPage={meta.hasPreviousPage} + totalPage={meta.pageCount} + page={meta.page} + onPageChange={function (page: number): void { + setPage(page); + }} + showTotalPages={false} + /> +
+ + ) : ( +

No contributors to remove found.

+ )} + + )} +
- - +
+ +
+ + Delete List + + Once you delete a list, you're past the point of no return. + + +
+
+
+ ); } diff --git a/pages/workspaces/[workspaceId]/contributor-insights/[listId]/overview.tsx b/pages/workspaces/[workspaceId]/contributor-insights/[listId]/overview.tsx index 5abe9c5c42..ffd2008c45 100644 --- a/pages/workspaces/[workspaceId]/contributor-insights/[listId]/overview.tsx +++ b/pages/workspaces/[workspaceId]/contributor-insights/[listId]/overview.tsx @@ -15,6 +15,8 @@ import { useContributorsList } from "lib/hooks/api/useContributorList"; import ContributorsList from "components/organisms/ContributorsList/contributors-list"; import { WorkspaceLayout } from "components/Workspaces/WorkspaceLayout"; import { useIsWorkspaceUpgraded } from "lib/hooks/api/useIsWorkspaceUpgraded"; +import useSession from "lib/hooks/useSession"; +import WorkspaceBanner from "components/Workspaces/WorkspaceBanner"; const InsightUpgradeModal = dynamic(() => import("components/Workspaces/InsightUpgradeModal")); @@ -115,21 +117,16 @@ const ListsOverview = ({ const allContributorCommits = allContributorStats?.reduce((acc, curr) => acc + curr.commits, 0) || 0; const prevAllContributorCommits = prevAllContributorStats?.reduce((acc, curr) => acc + curr.commits, 0) || 0; + const { hasReports } = useSession(true); // to check if the user is a PRO account const { data: isWorkspaceUpgraded } = useIsWorkspaceUpgraded({ workspaceId }); - const showNudgeBanner = !isWorkspaceUpgraded && numberOfContributors > 10; + const showBanner = isOwner && !hasReports && !isWorkspaceUpgraded && numberOfContributors > 10; const [isInsightUpgradeModalOpen, setIsInsightUpgradeModalOpen] = useState(false); return ( - - {showNudgeBanner && ( - - )} + setIsInsightUpgradeModalOpen(true) })} + > setIsInsightUpgradeModalOpen(false)} - variant="contributors" + overLimit={numberOfContributors} /> ); diff --git a/pages/workspaces/[workspaceId]/contributor-insights/index.tsx b/pages/workspaces/[workspaceId]/contributor-insights/index.tsx index ce1229bb9a..86a478840f 100644 --- a/pages/workspaces/[workspaceId]/contributor-insights/index.tsx +++ b/pages/workspaces/[workspaceId]/contributor-insights/index.tsx @@ -13,7 +13,6 @@ import ListCard from "components/molecules/ListCard/list-card"; import { useToast } from "lib/hooks/useToast"; import useSupabaseAuth from "lib/hooks/useSupabaseAuth"; -import { getAllFeatureFlags } from "lib/utils/server/feature-flags"; import { WorkspaceLayout } from "components/Workspaces/WorkspaceLayout"; import { fetchApiData } from "helpers/fetchApiData"; import { WORKSPACE_ID_COOKIE_NAME } from "lib/utils/workspace-utils"; @@ -43,13 +42,9 @@ export const getServerSideProps = async (context: GetServerSidePropsContext) => throw new Error(`Error loading workspaces page with ID ${workspaceId}`); } - const userId = Number(session?.user.user_metadata.sub); - const featureFlags = await getAllFeatureFlags(userId); - return { props: { workspace: data, - featureFlags, }, }; }; diff --git a/pages/workspaces/[workspaceId]/repositories.tsx b/pages/workspaces/[workspaceId]/index.tsx similarity index 100% rename from pages/workspaces/[workspaceId]/repositories.tsx rename to pages/workspaces/[workspaceId]/index.tsx diff --git a/pages/workspaces/[workspaceId]/repository-insights/[insightId]/dashboard.tsx b/pages/workspaces/[workspaceId]/repository-insights/[insightId]/dashboard.tsx index 9f8661915e..1ec6a265b6 100644 --- a/pages/workspaces/[workspaceId]/repository-insights/[insightId]/dashboard.tsx +++ b/pages/workspaces/[workspaceId]/repository-insights/[insightId]/dashboard.tsx @@ -1,30 +1,34 @@ -import dynamic from "next/dynamic"; import { useEffect, useState } from "react"; import { GetServerSidePropsContext } from "next"; import { createPagesServerClient } from "@supabase/auth-helpers-nextjs"; +import dynamic from "next/dynamic"; import SEO from "layouts/SEO/SEO"; import fetchSocialCard from "lib/utils/fetch-social-card"; import { WorkspaceLayout } from "components/Workspaces/WorkspaceLayout"; import HubPageLayout from "layouts/hub-page"; import Dashboard from "components/organisms/Dashboard/dashboard"; import { fetchApiData } from "helpers/fetchApiData"; +import useSession from "lib/hooks/useSession"; import { useIsWorkspaceUpgraded } from "lib/hooks/api/useIsWorkspaceUpgraded"; +import WorkspaceBanner from "components/Workspaces/WorkspaceBanner"; const InsightUpgradeModal = dynamic(() => import("components/Workspaces/InsightUpgradeModal")); interface InsightPageProps { insight: DbUserInsight; + isOwner: boolean; ogImage?: string; workspaceId: string; } -const HubPage = ({ insight, ogImage, workspaceId }: InsightPageProps) => { +const HubPage = ({ insight, isOwner, ogImage, workspaceId }: InsightPageProps) => { const repositories = insight.repos.map((repo) => repo.repo_id); const [hydrated, setHydrated] = useState(false); + const { hasReports } = useSession(true); // to check if the user is a PRO account const { data: isWorkspaceUpgraded } = useIsWorkspaceUpgraded({ workspaceId }); - const showNudgeBanner = !isWorkspaceUpgraded && repositories.length > 100; + const showBanner = isOwner && !hasReports && !isWorkspaceUpgraded && repositories.length > 100; const [isInsightUpgradeModalOpen, setIsInsightUpgradeModalOpen] = useState(false); useEffect(() => { @@ -52,25 +56,19 @@ const HubPage = ({ insight, ogImage, workspaceId }: InsightPageProps) => { image={ogImage} twitterCard="summary_large_image" /> - - {showNudgeBanner && ( - - )} + setIsInsightUpgradeModalOpen(true)} /> : null} + > setIsInsightUpgradeModalOpen(false)} - variant="repositories" + overLimit={repositories.length} /> @@ -105,9 +103,13 @@ export const getServerSideProps = async (ctx: GetServerSidePropsContext) => { // Keeping this here so we are sure the page is not private before we fetch the social card. const ogImage = await fetchSocialCard(`insights/${insightId}`); + const insightOwner = insight.members.find((m) => m.access === "admin"); + const isOwner = Number.parseInt(session?.user.user_metadata.provider_id) === insightOwner?.user_id; + return { props: { insight, + isOwner, workspaceId, ogImage, }, diff --git a/pages/workspaces/[workspaceId]/settings.tsx b/pages/workspaces/[workspaceId]/settings.tsx index 80c7226370..a2cb021a20 100644 --- a/pages/workspaces/[workspaceId]/settings.tsx +++ b/pages/workspaces/[workspaceId]/settings.tsx @@ -36,6 +36,7 @@ import { useWorkspaceMembers } from "lib/hooks/api/useWorkspaceMembers"; import ClientOnly from "components/atoms/ClientOnly/client-only"; const DeleteWorkspaceModal = dynamic(() => import("components/Workspaces/DeleteWorkspaceModal"), { ssr: false }); +const InsightUpgradeModal = dynamic(() => import("components/Workspaces/InsightUpgradeModal")); interface WorkspaceSettingsProps { workspace: Workspace; @@ -95,6 +96,7 @@ const WorkspaceSettings = ({ workspace, canDeleteWorkspace }: WorkspaceSettingsP const [isPublic, setIsPublic] = useState(workspace.is_public); const [isWorkspaceVisibilityModalOpen, setIsWorkspaceVisibilityModalOpen] = useState(false); + const [isWorkspaceUpgradeModalOpen, setIsWorkspaceUpgradeModalOpen] = useState(false); const [trackedReposModalOpen, setTrackedReposModalOpen] = useState(false); const { @@ -276,6 +278,33 @@ const WorkspaceSettings = ({ workspace, canDeleteWorkspace }: WorkspaceSettingsP /> +
+

Change Workspace Visibility

+

+ This workspace is set to {isPublic ? "public" : "private"}.{" "} + {!workspace.payee_user_id && ( + + Setting this to private is a paid feature. Upgrade your Workspace to + unlock this feature. + + )} +

+ + +
+ {workspace.payee_user_id ? (
@@ -309,28 +338,6 @@ const WorkspaceSettings = ({ workspace, canDeleteWorkspace }: WorkspaceSettingsP )} -
-

Change Workspace Visibility

-

- This workspace is set to {isPublic ? "public" : "private"}.{" "} - {!workspace.payee_user_id && ( - - Setting this to private is a paid feature. Upgrade your Workspace to - unlock this feature. - - )} -

- - -
- {canDeleteWorkspace && (
@@ -398,6 +405,13 @@ const WorkspaceSettings = ({ workspace, canDeleteWorkspace }: WorkspaceSettingsP }} /> ) : null} + + <InsightUpgradeModal + variant="workspace" + workspaceId={workspace.id} + isOpen={isWorkspaceUpgradeModalOpen} + onClose={() => setIsWorkspaceUpgradeModalOpen(false)} + /> </div> </WorkspaceLayout> ); diff --git a/pages/workspaces/new.tsx b/pages/workspaces/new.tsx index e26e7d1e85..76a8c0b57f 100644 --- a/pages/workspaces/new.tsx +++ b/pages/workspaces/new.tsx @@ -59,7 +59,7 @@ const NewWorkspace = () => { } else { toast({ description: `Workspace created successfully`, variant: "success" }); document.dispatchEvent(new CustomEvent(WORKSPACE_UPDATED_EVENT, { detail: workspace })); - router.push(`/workspaces/${workspace.id}/repositories`); + router.push(`/workspaces/${workspace.id}`); } }; diff --git a/vitest.config.ts b/vitest.config.ts index fef828d4ca..5510bafad8 100644 --- a/vitest.config.ts +++ b/vitest.config.ts @@ -9,6 +9,7 @@ export default defineConfig({ alias: { components: fileURLToPath(new URL("./components", import.meta.url)), lib: fileURLToPath(new URL("./lib", import.meta.url)), + helpers: fileURLToPath(new URL("./helpers", import.meta.url)), img: fileURLToPath(new URL("./img", import.meta.url)), }, },