feat: re-arranged org project pages

This commit is contained in:
=
2025-07-02 01:16:47 +05:30
parent 0d97fc27c7
commit b8f7ffbf53
45 changed files with 128 additions and 556 deletions
@@ -5,6 +5,7 @@ import { OrgPermissionCan } from "@app/components/permissions";
import { OrgPermissionBillingActions, OrgPermissionSubjects } from "@app/context";
import { BillingTabGroup } from "./components";
import { PageHeader } from "@app/components/v2";
export const BillingPage = () => {
const { t } = useTranslation();
@@ -18,10 +19,11 @@ export const BillingPage = () => {
</Helmet>
<div className="flex h-full w-full justify-center bg-bunker-800 text-white">
<div className="w-full max-w-7xl px-6">
<div className="my-6">
<p className="text-3xl font-semibold text-gray-200">{t("billing.title")}</p>
<div />
</div>
<PageHeader
title={t("billing.title")}
description="View your billing plan, next billing cycle."
/>
<OrgPermissionCan
passThrough={false}
I={OrgPermissionBillingActions.Read}
@@ -5,5 +5,14 @@ import { BillingPage } from "./BillingPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/_org-layout/organization/billing"
)({
component: BillingPage
component: BillingPage,
beforeLoad: () => {
return {
breadcrumbs: [
{
label: "Billing"
}
]
};
}
});
@@ -1,7 +0,0 @@
import { ProjectType } from "@app/hooks/api/workspace/types";
import { ProductOverviewPage } from "../SecretManagerOverviewPage/SecretManagerOverviewPage";
export const CertManagerOverviewPage = () => (
<ProductOverviewPage type={ProjectType.CertificateManager} />
);
@@ -1,17 +0,0 @@
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { CertManagerOverviewPage } from "./CertManagerOverviewPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/_org-layout/organization/cert-manager/overview"
)({
component: CertManagerOverviewPage,
context: () => ({
breadcrumbs: [
{
label: "Cert Management",
link: linkOptions({ to: "/organization/cert-manager/overview" })
}
]
})
});
@@ -44,7 +44,7 @@ type Props = {
const Content = ({ identityId, handlePopUpToggle }: Omit<Props, "popUp">) => {
const { currentOrg } = useOrganization();
const { data: workspaces = [] } = useGetUserWorkspaces({ type: "all" });
const { data: workspaces = [] } = useGetUserWorkspaces();
const { mutateAsync: addIdentityToWorkspace } = useAddIdentityToWorkspace();
const {
@@ -1,5 +0,0 @@
import { ProjectType } from "@app/hooks/api/workspace/types";
import { ProductOverviewPage } from "../SecretManagerOverviewPage/SecretManagerOverviewPage";
export const KmsOverviewPage = () => <ProductOverviewPage type={ProjectType.KMS} />;
@@ -1,17 +0,0 @@
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { KmsOverviewPage } from "./KmsOverviewPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/_org-layout/organization/kms/overview"
)({
component: KmsOverviewPage,
context: () => ({
breadcrumbs: [
{
label: "KMS",
link: linkOptions({ to: "/organization/kms/overview" })
}
]
})
});
@@ -10,31 +10,25 @@ import { NewProjectModal } from "@app/components/projects";
import { PageHeader } from "@app/components/v2";
import { useSubscription } from "@app/context";
import { useFetchServerStatus } from "@app/hooks/api/serverDetails";
import { ProjectType } from "@app/hooks/api/workspace/types";
import { usePopUp } from "@app/hooks/usePopUp";
import { AllProjectView } from "./components/AllProjectView";
import { MyProjectView } from "./components/MyProjectView";
import { ProjectListToggle, ProjectListView } from "./components/ProjectListToggle";
const formatDescription = (type: ProjectType) => {
if (type === ProjectType.SecretManager)
return "Securely store, manage, and rotate various application secrets, such as database credentials, API keys, etc.";
if (type === ProjectType.CertificateManager)
return "Manage your PKI infrastructure and issue digital certificates for services, applications, and devices.";
if (type === ProjectType.KMS)
return "Centralize the management of keys for cryptographic operations, such as encryption and decryption.";
if (type === ProjectType.SecretScanning)
return "Connect and monitor data sources to prevent secret leaks.";
return "Infisical SSH lets you issue SSH credentials to users for short-lived, secure SSH access to infrastructure.";
};
// const formatDescription = (type: ProjectType) => {
// if (type === ProjectType.SecretManager)
// return "Securely store, manage, and rotate various application secrets, such as database credentials, API keys, etc.";
// if (type === ProjectType.CertificateManager)
// return "Manage your PKI infrastructure and issue digital certificates for services, applications, and devices.";
// if (type === ProjectType.KMS)
// return "Centralize the management of keys for cryptographic operations, such as encryption and decryption.";
// if (type === ProjectType.SecretScanning)
// return "Connect and monitor data sources to prevent secret leaks.";
// return "Infisical SSH lets you issue SSH credentials to users for short-lived, secure SSH access to infrastructure.";
// };
type Props = {
type: ProjectType;
};
// #TODO: Update all the workspaceIds
export const ProductOverviewPage = ({ type }: Props) => {
export const ProjectsPage = () => {
const { t } = useTranslation();
const [projectListView, setProjectListView] = useState(ProjectListView.MyProjects);
@@ -87,19 +81,17 @@ export const ProductOverviewPage = ({ type }: Props) => {
<ProjectListToggle value={projectListView} onChange={setProjectListView} />
</div>
}
description={formatDescription(type)}
description="Your team's complete security toolkit - organized and ready when you need them."
/>
</div>
{projectListView === ProjectListView.MyProjects ? (
<MyProjectView
type={type}
onAddNewProject={() => handlePopUpOpen("addNewWs")}
onUpgradePlan={() => handlePopUpOpen("upgradePlan")}
isAddingProjectsAllowed={isAddingProjectsAllowed}
/>
) : (
<AllProjectView
type={type}
onAddNewProject={() => handlePopUpOpen("addNewWs")}
onUpgradePlan={() => handlePopUpOpen("upgradePlan")}
isAddingProjectsAllowed={isAddingProjectsAllowed}
@@ -108,7 +100,6 @@ export const ProductOverviewPage = ({ type }: Props) => {
<NewProjectModal
isOpen={popUp.addNewWs.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("addNewWs", isOpen)}
projectType={type}
/>
<UpgradePlanModal
isOpen={popUp.upgradePlan.isOpen}
@@ -118,7 +109,3 @@ export const ProductOverviewPage = ({ type }: Props) => {
</div>
);
};
export const SecretManagerOverviewPage = () => (
<ProductOverviewPage type={ProjectType.SecretManager} />
);
@@ -35,10 +35,9 @@ import {
} from "@app/helpers/userTablePreferences";
import { useDebounce, usePagination, usePopUp, useResetPageHelper } from "@app/hooks";
import { useRequestProjectAccess, useSearchProjects } from "@app/hooks/api";
import { ProjectType, Workspace } from "@app/hooks/api/workspace/types";
import { Workspace } from "@app/hooks/api/workspace/types";
type Props = {
type: ProjectType;
onAddNewProject: () => void;
onUpgradePlan: () => void;
isAddingProjectsAllowed: boolean;
@@ -92,7 +91,6 @@ const RequestAccessModal = ({ projectId, onPopUpToggle }: RequestAccessModalProp
};
export const AllProjectView = ({
type,
onAddNewProject,
onUpgradePlan,
isAddingProjectsAllowed
@@ -125,7 +123,6 @@ export const AllProjectView = ({
const { data: searchedProjects, isPending: isProjectLoading } = useSearchProjects({
limit,
offset,
type,
name: debouncedSearch || undefined,
orderDirection
});
@@ -29,10 +29,9 @@ import { useGetUserWorkspaces } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types";
import { useUpdateUserProjectFavorites } from "@app/hooks/api/users/mutation";
import { useGetUserProjectFavorites } from "@app/hooks/api/users/queries";
import { ProjectType, Workspace } from "@app/hooks/api/workspace/types";
import { Workspace } from "@app/hooks/api/workspace/types";
type Props = {
type: ProjectType;
onAddNewProject: () => void;
onUpgradePlan: () => void;
isAddingProjectsAllowed: boolean;
@@ -48,7 +47,6 @@ enum ProjectsViewMode {
}
export const MyProjectView = ({
type,
onAddNewProject,
onUpgradePlan,
isAddingProjectsAllowed
@@ -56,9 +54,7 @@ export const MyProjectView = ({
const navigate = useNavigate();
const { currentOrg } = useOrganization();
const { data: workspaces = [], isPending: isWorkspaceLoading } = useGetUserWorkspaces({
type
});
const { data: workspaces = [], isPending: isWorkspaceLoading } = useGetUserWorkspaces();
const {
setPage,
perPage,
@@ -202,11 +198,6 @@ export const MyProjectView = ({
</div>
<div className="flex w-full flex-row items-end justify-between place-self-end">
{type === ProjectType.SecretManager && (
<div className="mt-0 text-xs text-mineshaft-400">
{workspace.environments?.length || 0} environments
</div>
)}
<button type="button">
<div className="group ml-auto w-max cursor-pointer rounded-full border border-mineshaft-600 bg-mineshaft-900 px-4 py-2 text-sm text-mineshaft-300 transition-all hover:border-primary-500/80 hover:bg-primary-800/20 hover:text-mineshaft-200">
Explore{" "}
@@ -239,11 +230,6 @@ export const MyProjectView = ({
<div className="truncate text-sm text-mineshaft-100">{workspace.name}</div>
</div>
<div className="flex items-center justify-end sm:col-span-3 lg:col-span-2">
{type === ProjectType.SecretManager && (
<div className="text-center text-sm text-mineshaft-300">
{workspace.environments?.length || 0} environments
</div>
)}
{isFavorite ? (
<FontAwesomeIcon
icon={faSolidStar}
@@ -0,0 +1,16 @@
import { createFileRoute } from "@tanstack/react-router";
import { ProjectsPage } from "./ProjectsPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/_org-layout/organization/projects"
)({
component: ProjectsPage,
context: () => ({
breadcrumbs: [
{
label: "Projects"
}
]
})
});
@@ -1,16 +0,0 @@
import { createFileRoute } from "@tanstack/react-router";
import { SecretManagerOverviewPage } from "./SecretManagerOverviewPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/_org-layout/organization/secret-manager/overview"
)({
component: SecretManagerOverviewPage,
context: () => ({
breadcrumbs: [
{
label: "Secret Management"
}
]
})
});
@@ -1,7 +0,0 @@
import { ProjectType } from "@app/hooks/api/workspace/types";
import { ProductOverviewPage } from "../SecretManagerOverviewPage/SecretManagerOverviewPage";
export const SecretScanningOverviewPage = () => (
<ProductOverviewPage type={ProjectType.SecretScanning} />
);
@@ -1,17 +0,0 @@
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { SecretScanningOverviewPage } from "./SecretScanningOverviewPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/_org-layout/organization/secret-scanning/overview"
)({
component: SecretScanningOverviewPage,
context: () => ({
breadcrumbs: [
{
label: "Secret Scanning",
link: linkOptions({ to: "/organization/secret-scanning/overview" })
}
]
})
});
@@ -1,5 +0,0 @@
import { ProjectType } from "@app/hooks/api/workspace/types";
import { ProductOverviewPage } from "../SecretManagerOverviewPage/SecretManagerOverviewPage";
export const SshOverviewPage = () => <ProductOverviewPage type={ProjectType.SSH} />;
@@ -1,17 +0,0 @@
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { SshOverviewPage } from "./SshOverviewPage";
export const Route = createFileRoute(
"/_authenticate/_inject-org-details/_org-layout/organization/ssh/overview"
)({
component: SshOverviewPage,
context: () => ({
breadcrumbs: [
{
label: "SSH",
link: linkOptions({ to: "/organization/ssh/overview" })
}
]
})
});