diff --git a/frontend/src/components/signup/TeamInviteStep.tsx b/frontend/src/components/signup/TeamInviteStep.tsx index 60276d217..63588ca5c 100644 --- a/frontend/src/components/signup/TeamInviteStep.tsx +++ b/frontend/src/components/signup/TeamInviteStep.tsx @@ -4,6 +4,7 @@ import { useRouter } from "next/router"; import { useAddUsersToOrg } from "@app/hooks/api"; import { useFetchServerStatus } from "@app/hooks/api/serverDetails"; +import { ProjectType } from "@app/hooks/api/workspace/types"; import { usePopUp } from "@app/hooks/usePopUp"; import { Button, EmailServiceSetupModal } from "../v2"; @@ -22,7 +23,7 @@ export default function TeamInviteStep(): JSX.Element { // Redirect user to the getting started page const redirectToHome = async () => { - router.push(`/org/${localStorage.getItem("orgData.id")}/overview`); + router.push(`/org/${localStorage.getItem("orgData.id")}/${ProjectType.SecretManager}/overview`); }; const inviteUsers = async ({ emails: inviteEmails }: { emails: string }) => { diff --git a/frontend/src/components/v2/projects/NewProjectModal.tsx b/frontend/src/components/v2/projects/NewProjectModal.tsx index a081ef4f0..839153ea2 100644 --- a/frontend/src/components/v2/projects/NewProjectModal.tsx +++ b/frontend/src/components/v2/projects/NewProjectModal.tsx @@ -32,6 +32,7 @@ import { useSubscription, useUser } from "@app/context"; +import { getWorkspaceHomePage } from "@app/helpers/workspace"; import { fetchOrgUsers, useAddUserToWsNonE2EE, @@ -120,7 +121,7 @@ const NewProjectForm = ({ onOpenChange, projectType }: NewProjectFormProps) => { try { const { data: { - project: { id: newProjectId } + project } } = await createWs.mutateAsync({ projectName: name, @@ -129,6 +130,7 @@ const NewProjectForm = ({ onOpenChange, projectType }: NewProjectFormProps) => { template, type: projectType }); + const { id: newProjectId } = project if (addMembers) { const orgUsers = await fetchOrgUsers(currentOrg.id); @@ -148,7 +150,7 @@ const NewProjectForm = ({ onOpenChange, projectType }: NewProjectFormProps) => { createNotification({ text: "Project created", type: "success" }); reset(); onOpenChange(false); - router.push(`/${projectType}/${newProjectId}/${projectType}/overview`); + router.push(getWorkspaceHomePage(project)); } catch (err) { console.error(err); createNotification({ text: "Failed to create project", type: "error" }); diff --git a/frontend/src/layouts/AppLayout/AppLayout.tsx b/frontend/src/layouts/AppLayout/AppLayout.tsx index 0cbe2362d..07a40156a 100644 --- a/frontend/src/layouts/AppLayout/AppLayout.tsx +++ b/frontend/src/layouts/AppLayout/AppLayout.tsx @@ -41,6 +41,7 @@ import { usePopUp, useToggle } from "@app/hooks"; import { useGetOrgTrialUrl, useLogoutUser, useSelectOrganization } from "@app/hooks/api"; import { MfaMethod } from "@app/hooks/api/auth/types"; import { AuthMethod } from "@app/hooks/api/users/types"; +import { ProjectType } from "@app/hooks/api/workspace/types"; import { InsecureConnectionBanner } from "@app/layouts/AppLayout/components/InsecureConnectionBanner"; import { ProjectSelect } from "@app/layouts/AppLayout/components/ProjectSelect"; import { navigateUserToOrg } from "@app/views/Login/Login.utils"; @@ -340,30 +341,40 @@ export const AppLayout = ({ children }: LayoutProps) => { {router.pathname.startsWith("/org") && ( - + Secret Manager - + Cert Manager - + Cmek diff --git a/frontend/src/layouts/AppLayout/ErrorBoundary.tsx b/frontend/src/layouts/AppLayout/ErrorBoundary.tsx index 55acf3433..982dce8d2 100644 --- a/frontend/src/layouts/AppLayout/ErrorBoundary.tsx +++ b/frontend/src/layouts/AppLayout/ErrorBoundary.tsx @@ -5,6 +5,7 @@ import { faBugs, faHome } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { Button } from "@app/components/v2"; +import { ProjectType } from "@app/hooks/api/workspace/types"; interface ErrorBoundaryProps { children: ReactNode; @@ -62,7 +63,7 @@ const ErrorPage = ({ error }: { error: Error | null }) => { size="xs" onClick={() => // we need to go to /org/${orgId}/overview, but we need to do a full page reload to ensure that the error the user is facing is properly reset. - window.location.assign(`/org/${orgId}/overview`) + window.location.assign(`/org/${orgId}/${ProjectType.SecretManager}/overview`) } > diff --git a/frontend/src/pages/org/[id]/secret-manager/overview.tsx b/frontend/src/pages/org/[id]/secret-manager/overview.tsx index 0e5c2cec8..56eefa1e1 100644 --- a/frontend/src/pages/org/[id]/secret-manager/overview.tsx +++ b/frontend/src/pages/org/[id]/secret-manager/overview.tsx @@ -1,39 +1,27 @@ // REFACTOR(akhilmhdh): This file needs to be split into multiple components too complex -import { ReactNode, useEffect, useMemo, useState } from "react"; +import { ReactNode, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; import Head from "next/head"; import Link from "next/link"; import { useRouter } from "next/router"; -import { IconProp } from "@fortawesome/fontawesome-svg-core"; -import { faSlack } from "@fortawesome/free-brands-svg-icons"; import { faFolderOpen, faStar } from "@fortawesome/free-regular-svg-icons"; import { faArrowDownAZ, faArrowRight, - faArrowUpRightFromSquare, faArrowUpZA, faBorderAll, - faCheck, - faCheckCircle, - faClipboard, faExclamationCircle, - faHandPeace, faList, faMagnifyingGlass, - faNetworkWired, - faPlug, faPlus, faSearch, - faStar as faSolidStar, - faUserPlus + faStar as faSolidStar } from "@fortawesome/free-solid-svg-icons"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; -import * as Tabs from "@radix-ui/react-tabs"; import { createNotification } from "@app/components/notifications"; import { OrgPermissionCan } from "@app/components/permissions"; -import onboardingCheck from "@app/components/utilities/checks/OnboardingCheck"; import { Button, IconButton, @@ -48,12 +36,11 @@ import { OrgPermissionActions, OrgPermissionSubjects, useOrganization, - useSubscription, - useUser + useSubscription } from "@app/context"; import { getWorkspaceHomePage } from "@app/helpers/workspace"; import { usePagination, useResetPageHelper } from "@app/hooks"; -import { useGetUserWorkspaces, useRegisterUserAction } from "@app/hooks/api"; +import { useGetUserWorkspaces } from "@app/hooks/api"; import { OrderByDirection } from "@app/hooks/api/generic/types"; // import { fetchUserWsKey } from "@app/hooks/api/keys/queries"; import { useFetchServerStatus } from "@app/hooks/api/serverDetails"; @@ -63,32 +50,6 @@ import { useGetUserProjectFavorites } from "@app/hooks/api/users/queries"; import { ProjectType } from "@app/hooks/api/workspace/types"; import { usePopUp } from "@app/hooks/usePopUp"; -const features = [ - { - id: 0, - name: "Kubernetes Operator", - link: "https://infisical.com/docs/documentation/getting-started/kubernetes", - description: - "Pull secrets into your Kubernetes containers and automatically redeploy upon secret changes." - }, - { - id: 1, - name: "Infisical Agent", - link: "https://infisical.com/docs/infisical-agent/overview", - description: "Inject secrets into your apps without modifying any application logic." - } -]; - -type ItemProps = { - text: string; - subText: string; - complete: boolean; - icon: IconProp; - time: string; - userAction?: string; - link?: string; -}; - enum ProjectsViewMode { GRID = "grid", LIST = "list" @@ -98,373 +59,6 @@ enum ProjectOrderBy { Name = "name" } -function copyToClipboard(id: string, setState: (value: boolean) => void) { - // Get the text field - const copyText = document.getElementById(id) as HTMLInputElement; - - // Select the text field - copyText.select(); - copyText.setSelectionRange(0, 99999); // For mobile devices - - // Copy the text inside the text field - navigator.clipboard.writeText(copyText.value); - - setState(true); - setTimeout(() => setState(false), 2000); - // Alert the copied text - // alert("Copied the text: " + copyText.value); -} - -const CodeItem = ({ - isCopied, - setIsCopied, - textExplanation, - code, - id -}: { - isCopied: boolean; - setIsCopied: (value: boolean) => void; - textExplanation: string; - code: string; - id: string; -}) => { - return ( - <> -

{textExplanation}

-
- - -
- - ); -}; - -const TabsObject = () => { - const [downloadCodeCopied, setDownloadCodeCopied] = useState(false); - const [downloadCode2Copied, setDownloadCode2Copied] = useState(false); - const [loginCodeCopied, setLoginCodeCopied] = useState(false); - const [initCodeCopied, setInitCodeCopied] = useState(false); - const [runCodeCopied, setRunCodeCopied] = useState(false); - - return ( - - - - MacOS - - - Windows - - {/* - Arch Linux - */} -
- Other Platforms - - - - - - - -

- You can find example of start commands for different frameworks{" "} - - here - - .{" "} -

-
- - -
- - -
- - - -

- You can find example of start commands for different frameworks{" "} - - here - - .{" "} -

-
- - ); -}; - -const LearningItem = ({ - text, - subText, - complete, - icon, - time, - userAction, - link -}: ItemProps): JSX.Element => { - const registerUserAction = useRegisterUserAction(); - if (link) { - return ( - -
-
null} - role="button" - tabIndex={0} - onClick={async () => { - if (userAction && userAction !== "first_time_secrets_pushed") { - await registerUserAction.mutateAsync(userAction); - } - }} - className={`group relative flex h-[5.5rem] w-full items-center justify-between overflow-hidden rounded-md border ${ - complete - ? "cursor-default border-mineshaft-900 bg-gradient-to-r from-[#0e1f01] to-mineshaft-700" - : "cursor-pointer border-mineshaft-600 bg-mineshaft-800 shadow-xl hover:bg-mineshaft-700" - } text-mineshaft-100 duration-200`} - > -
- - {complete && ( -
- -
- )} -
-
{text}
-
{subText}
-
-
-
- {complete ? "Complete!" : `About ${time}`} -
- {/* {complete &&
} */} -
-
-
- ); - } - return ( -
null} - role="button" - tabIndex={0} - onClick={async () => { - if (userAction) { - await registerUserAction.mutateAsync(userAction); - } - }} - className="relative my-1.5 flex h-[5.5rem] w-full cursor-pointer items-center justify-between overflow-hidden rounded-md border border-dashed border-bunker-400 bg-bunker-700 py-2 pl-2 pr-6 shadow-xl duration-200 hover:bg-bunker-500" - > -
- - {complete && ( -
- -
- )} -
-
{text}
-
{subText}
-
-
-
- {complete ? "Complete!" : `About ${time}`} -
- {complete &&
} -
- ); -}; - -const LearningItemSquare = ({ - text, - subText, - complete, - icon, - time, - userAction, - link -}: ItemProps): JSX.Element => { - const registerUserAction = useRegisterUserAction(); - return ( - -
-
null} - role="button" - tabIndex={0} - onClick={async () => { - if (userAction && userAction !== "first_time_secrets_pushed") { - await registerUserAction.mutateAsync(userAction); - } - }} - className={`group relative flex w-full items-center justify-between overflow-hidden rounded-md border ${ - complete - ? "cursor-default border-mineshaft-900 bg-gradient-to-r from-[#0e1f01] to-mineshaft-700" - : "cursor-pointer border-mineshaft-600 bg-mineshaft-800 shadow-xl hover:bg-mineshaft-700" - } text-mineshaft-100 duration-200`} - > -
-
- - {complete && ( -
- -
- )} -
- {complete ? "Complete!" : `About ${time}`} -
-
-
-
{text}
-
{subText}
-
-
-
-
-
- ); -}; - const formatTitle = (type: ProjectType) => { if (type === ProjectType.SecretManager) return "Secret Managers"; if (type === ProjectType.CertificateManager) return "Cert Managers"; @@ -483,7 +77,6 @@ export const ProductOverview = ({ type }: Props) => { const { data: workspaces, isLoading: isWorkspaceLoading } = useGetUserWorkspaces({ type }); const { currentOrg } = useOrganization(); - const routerOrgId = String(router.query.id); const orgWorkspaces = workspaces || []; const { data: projectFavorites, isLoading: isProjectFavoritesLoading } = useGetUserProjectFavorites(currentOrg?.id!); @@ -496,12 +89,7 @@ export const ProductOverview = ({ type }: Props) => { "upgradePlan" ] as const); - const [hasUserClickedSlack, setHasUserClickedSlack] = useState(false); - const [hasUserClickedIntro, setHasUserClickedIntro] = useState(false); - const [hasUserPushedSecrets, setHasUserPushedSecrets] = useState(false); - const [usersInOrg, setUsersInOrg] = useState(false); const [searchFilter, setSearchFilter] = useState(""); - const { user } = useUser(); const { data: serverDetails } = useFetchServerStatus(); const [projectsViewMode, setProjectsViewMode] = useState( (localStorage.getItem("projectsViewMode") as ProjectsViewMode) || ProjectsViewMode.GRID @@ -513,16 +101,6 @@ export const ProductOverview = ({ type }: Props) => { ? subscription.workspacesUsed < subscription.workspaceLimit : true; - useEffect(() => { - onboardingCheck({ - orgId: routerOrgId, - setHasUserClickedIntro, - setHasUserClickedSlack, - setHasUserPushedSecrets, - setUsersInOrg - }); - }, []); - const isWorkspaceEmpty = !isProjectViewLoading && orgWorkspaces?.length === 0; const { @@ -917,127 +495,6 @@ export const ProductOverview = ({ type }: Props) => {
)}
-
-

Explore Infisical

-
- {features.map((feature) => ( -
-
{feature.name}
-
- {feature.description} -
-
-

- Setup time: 20 min -

- - Learn more{" "} - - -
-
- ))} -
-
- {!(new Date().getTime() - new Date(user?.createdAt).getTime() < 30 * 24 * 60 * 60 * 1000) && ( -
-

Onboarding Guide

-
- - {orgWorkspaces.length !== 0 && ( - <> - - - - )} -
- -
-
- {orgWorkspaces.length !== 0 && ( -
-
-
- - {false && ( -
- -
- )} -
-
Inject secrets locally
-
- Replace .env files with a more secure and efficient alternative. -
-
-
-
- About 2 min -
-
- - {false &&
} -
- )} - {orgWorkspaces.length !== 0 && ( - - )} -
- )} handlePopUpToggle("addNewWs", isOpen)} diff --git a/frontend/src/views/Login/Login.utils.tsx b/frontend/src/views/Login/Login.utils.tsx index 71089532a..dc714e4b0 100644 --- a/frontend/src/views/Login/Login.utils.tsx +++ b/frontend/src/views/Login/Login.utils.tsx @@ -13,7 +13,7 @@ export const navigateUserToOrg = async (router: NextRouter, organizationId?: str if (organizationId) { localStorage.setItem("orgData.id", organizationId); - router.push(`/org/${organizationId}/overview`); + router.push(`/org/${organizationId}/${ProjectType.SecretManager}/overview`); return; }