feat: completed all layout changes needed for frontend

This commit is contained in:
=
2025-07-20 14:50:03 +05:30
parent cc9f4fb5b3
commit ec8ea76e2c
79 changed files with 1098 additions and 697 deletions

View File

@@ -4,6 +4,7 @@ import { faInfoCircle } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { zodResolver } from "@hookform/resolvers/zod";
import { useNavigate } from "@tanstack/react-router";
import { twMerge } from "tailwind-merge";
import z from "zod";
import { createNotification } from "@app/components/notifications";
@@ -16,6 +17,7 @@ import {
Button,
FormControl,
Input,
Lottie,
Modal,
ModalClose,
ModalContent,
@@ -35,6 +37,7 @@ import { getProjectHomePage } from "@app/helpers/project";
import { useCreateWorkspace, useGetExternalKmsList, useGetUserWorkspaces } from "@app/hooks/api";
import { INTERNAL_KMS_KEY_ID } from "@app/hooks/api/kms/types";
import { InfisicalProjectTemplate, useListProjectTemplates } from "@app/hooks/api/projectTemplates";
import { ProjectType } from "@app/hooks/api/workspace/types";
const formSchema = z.object({
name: z.string().trim().min(1, "Required").max(64, "Too long, maximum length is 64 characters"),
@@ -43,6 +46,7 @@ const formSchema = z.object({
.trim()
.max(256, "Description too long, max length is 256 characters")
.optional(),
type: z.nativeEnum(ProjectType),
kmsKeyId: z.string(),
template: z.string()
});
@@ -56,6 +60,34 @@ interface NewProjectModalProps {
type NewProjectFormProps = Pick<NewProjectModalProps, "onOpenChange">;
const PROJECT_TYPE_MENU_ITEMS = [
{
label: "Secret Manager",
value: ProjectType.SecretManager,
icon: "vault"
},
{
label: "Certificate Manager",
value: ProjectType.CertificateManager,
icon: "note"
},
{
label: "KMS",
value: ProjectType.KMS,
icon: "unlock"
},
{
label: "SSH",
value: ProjectType.SSH,
icon: "terminal"
},
{
label: "Secret Scanning",
value: ProjectType.SecretScanning,
icon: "secret-scan"
}
];
const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => {
const navigate = useNavigate();
const { currentOrg } = useOrganization();
@@ -101,7 +133,8 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => {
name,
description,
kmsKeyId,
template
template,
type
}: TAddProjectFormData) => {
// type check
if (!currentOrg) return;
@@ -113,7 +146,8 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => {
projectName: name,
projectDescription: description,
kmsKeyId: kmsKeyId !== INTERNAL_KMS_KEY_ID ? kmsKeyId : undefined,
template
template,
type
});
await refetchWorkspaces();
@@ -150,6 +184,42 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => {
</FormControl>
)}
/>
<Controller
control={control}
name="type"
defaultValue={ProjectType.SecretManager}
render={({ field, fieldState: { error } }) => (
<FormControl
label="Project Type"
isError={Boolean(error)}
errorText={error?.message}
className="flex-1"
>
<div className="mt-2 grid grid-cols-5 gap-4">
{PROJECT_TYPE_MENU_ITEMS.map((el) => (
<div
key={el.value}
className={twMerge(
"flex cursor-pointer flex-col items-center gap-2 rounded border border-mineshaft-600 p-4 opacity-75 transition-all hover:border-primary-400 hover:bg-mineshaft-600",
field.value === el.value && "border-primary-400 bg-mineshaft-600 opacity-100"
)}
onClick={() => field.onChange(el.value)}
role="button"
tabIndex={0}
onKeyDown={(e) => {
if (e.key === "Enter") {
field.onChange(el.value);
}
}}
>
<Lottie icon={el.icon} className="h-8 w-8" />
<div className="text-center text-xs">{el.label}</div>
</div>
))}
</div>
</FormControl>
)}
/>
<Controller
control={control}
name="description"
@@ -171,6 +241,7 @@ const NewProjectForm = ({ onOpenChange }: NewProjectFormProps) => {
</FormControl>
)}
/>
<Controller
control={control}
name="template"

View File

@@ -94,3 +94,14 @@ export const getProjectTitle = (type: ProjectType) => {
};
return titleConvert[type];
};
export const getProjectLottieIcon = (type: ProjectType) => {
const titleConvert = {
[ProjectType.SecretManager]: "vault",
[ProjectType.KMS]: "unlock",
[ProjectType.CertificateManager]: "note",
[ProjectType.SSH]: "terminal",
[ProjectType.SecretScanning]: "secret-scan"
};
return titleConvert[type];
};

View File

@@ -51,7 +51,7 @@ export type IdentityMembershipOrg = {
export type IdentityMembership = {
id: string;
identity: Identity;
project: Pick<Workspace, "id" | "name">;
project: Pick<Workspace, "id" | "name" | "type">;
roles: Array<
{
id: string;

View File

@@ -184,6 +184,7 @@ export type TSearchProjectsDTO = {
name?: string;
limit?: number;
offset?: number;
type?: ProjectType;
options?: { enabled?: boolean };
orderBy?: ProjectIdentityOrderBy;
orderDirection?: OrderByDirection;

View File

@@ -1,10 +1,10 @@
import { faCog, faCube, faHome, faLock, faUsers } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Link, Outlet } from "@tanstack/react-router";
import { motion } from "framer-motion";
import { Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2";
import { useWorkspace } from "@app/context";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCog, faUsers } from "@fortawesome/free-solid-svg-icons";
export const KmsLayout = () => {
const { currentWorkspace } = useWorkspace();
@@ -34,7 +34,16 @@ export const KmsLayout = () => {
projectId: currentWorkspace.id
}}
>
{({ isActive }) => <MenuItem isSelected={isActive}>Overview</MenuItem>}
{({ isActive }) => (
<MenuItem isSelected={isActive}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={faCube} />
</div>
Overview
</div>
</MenuItem>
)}
</Link>
<Link
to="/projects/kms/$projectId/kmip"
@@ -42,7 +51,16 @@ export const KmsLayout = () => {
projectId: currentWorkspace.id
}}
>
{({ isActive }) => <MenuItem isSelected={isActive}>KMIP</MenuItem>}
{({ isActive }) => (
<MenuItem isSelected={isActive}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={faLock} />
</div>
KMIP
</div>
</MenuItem>
)}
</Link>
</MenuGroup>
<MenuGroup title="Others">
@@ -83,6 +101,22 @@ export const KmsLayout = () => {
</MenuGroup>
</Menu>
</div>
<div>
<Menu>
<Link to="/organization/projects">
<MenuItem
className="relative flex items-center gap-2 overflow-hidden text-sm text-mineshaft-400 hover:text-mineshaft-300"
leftIcon={
<div className="w-6">
<FontAwesomeIcon className="mx-1 inline-block shrink-0" icon={faHome} />
</div>
}
>
Organization Home
</MenuItem>
</Link>
</Menu>
</div>
</nav>
</motion.div>
<div className="flex-1 overflow-y-auto overflow-x-hidden bg-bunker-800 p-4 pt-8">

View File

@@ -1,5 +1,15 @@
import { useTranslation } from "react-i18next";
import { faCog, faMobile, faUsers } from "@fortawesome/free-solid-svg-icons";
import {
faBell,
faCertificate,
faCog,
faFileLines,
faHome,
faMobile,
faSitemap,
faStamp,
faUsers
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Link, Outlet } from "@tanstack/react-router";
import { motion } from "framer-motion";
@@ -37,7 +47,16 @@ export const PkiManagerLayout = () => {
projectId: currentWorkspace.id
}}
>
{({ isActive }) => <MenuItem isSelected={isActive}>Subscribers</MenuItem>}
{({ isActive }) => (
<MenuItem isSelected={isActive}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={faSitemap} />
</div>
Subscribers
</div>
</MenuItem>
)}
</Link>
<Link
to="/projects/cert-management/$projectId/certificate-templates"
@@ -46,7 +65,14 @@ export const PkiManagerLayout = () => {
}}
>
{({ isActive }) => (
<MenuItem isSelected={isActive}> Certificate Templates</MenuItem>
<MenuItem isSelected={isActive}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={faFileLines} />
</div>
Certificate Templates
</div>
</MenuItem>
)}
</Link>
<Link
@@ -55,7 +81,16 @@ export const PkiManagerLayout = () => {
projectId: currentWorkspace.id
}}
>
{({ isActive }) => <MenuItem isSelected={isActive}> Certificates</MenuItem>}
{({ isActive }) => (
<MenuItem isSelected={isActive}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={faCertificate} />
</div>
Certificates
</div>
</MenuItem>
)}
</Link>
<Link
to="/projects/cert-management/$projectId/certificate-authorities"
@@ -64,7 +99,14 @@ export const PkiManagerLayout = () => {
}}
>
{({ isActive }) => (
<MenuItem isSelected={isActive}> Certificates Authorities</MenuItem>
<MenuItem isSelected={isActive}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={faStamp} />
</div>
Certificates Authority
</div>
</MenuItem>
)}
</Link>
<Link
@@ -73,7 +115,16 @@ export const PkiManagerLayout = () => {
projectId: currentWorkspace.id
}}
>
{({ isActive }) => <MenuItem isSelected={isActive}>Alerting</MenuItem>}
{({ isActive }) => (
<MenuItem isSelected={isActive}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={faBell} />
</div>
Alerting
</div>
</MenuItem>
)}
</Link>
</MenuGroup>
<MenuGroup title="Others">
@@ -114,6 +165,22 @@ export const PkiManagerLayout = () => {
</MenuGroup>
</Menu>
</div>
<div>
<Menu>
<Link to="/organization/projects">
<MenuItem
className="relative flex items-center gap-2 overflow-hidden text-sm text-mineshaft-400 hover:text-mineshaft-300"
leftIcon={
<div className="w-6">
<FontAwesomeIcon className="mx-1 inline-block shrink-0" icon={faHome} />
</div>
}
>
Organization Home
</MenuItem>
</Link>
</Menu>
</div>
</nav>
</motion.div>
<div className="flex-1 overflow-y-auto overflow-x-hidden bg-bunker-800 p-4 pt-8">

View File

@@ -3,6 +3,7 @@ import {
faArrowsSpin,
faCheckToSlot,
faCog,
faHome,
faMobile,
faPuzzlePiece,
faUsers,
@@ -182,6 +183,22 @@ export const SecretManagerLayout = () => {
</MenuGroup>
</Menu>
</div>
<div>
<Menu>
<Link to="/organization/projects">
<MenuItem
className="relative flex items-center gap-2 overflow-hidden text-sm text-mineshaft-400 hover:text-mineshaft-300"
leftIcon={
<div className="w-6">
<FontAwesomeIcon className="mx-1 inline-block shrink-0" icon={faHome} />
</div>
}
>
Organization Home
</MenuItem>
</Link>
</Menu>
</div>
</nav>
</motion.div>
<div className="flex-1 overflow-y-auto overflow-x-hidden bg-bunker-800 p-4 pt-8">

View File

@@ -1,9 +1,15 @@
import { faCog, faUsers } from "@fortawesome/free-solid-svg-icons";
import {
faCog,
faDatabase,
faHome,
faMagnifyingGlass,
faUsers
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Link, Outlet } from "@tanstack/react-router";
import { motion } from "framer-motion";
import { Menu, MenuGroup, MenuItem } from "@app/components/v2";
import { Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2";
import { useWorkspace } from "@app/context";
export const SecretScanningLayout = () => {
@@ -21,7 +27,8 @@ export const SecretScanningLayout = () => {
className="dark w-full border-r border-mineshaft-600 bg-gradient-to-tr from-mineshaft-700 via-mineshaft-800 to-mineshaft-900 md:w-60"
>
<nav className="items-between flex h-full flex-col overflow-y-auto dark:[color-scheme:dark]">
<div className="border-b border-mineshaft-600 px-4 py-3.5 text-lg text-white">
<div className="flex items-center gap-3 border-b border-mineshaft-600 px-4 py-3.5 text-lg text-white">
<Lottie className="inline-block h-5 w-5 shrink-0" icon="secret-scan" />
Secret Scanning
</div>
<div className="flex-1">
@@ -33,7 +40,16 @@ export const SecretScanningLayout = () => {
projectId: currentWorkspace.id
}}
>
{({ isActive }) => <MenuItem isSelected={isActive}> Data Sources</MenuItem>}
{({ isActive }) => (
<MenuItem isSelected={isActive}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={faDatabase} />
</div>
Data Sources
</div>
</MenuItem>
)}
</Link>
<Link
to="/projects/secret-scanning/$projectId/findings"
@@ -41,7 +57,16 @@ export const SecretScanningLayout = () => {
projectId: currentWorkspace.id
}}
>
{({ isActive }) => <MenuItem isSelected={isActive}>Findings</MenuItem>}
{({ isActive }) => (
<MenuItem isSelected={isActive}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={faMagnifyingGlass} />
</div>
Findings
</div>
</MenuItem>
)}
</Link>
</MenuGroup>
<MenuGroup title="Others">
@@ -82,6 +107,22 @@ export const SecretScanningLayout = () => {
</MenuGroup>
</Menu>
</div>
<div>
<Menu>
<Link to="/organization/projects">
<MenuItem
className="relative flex items-center gap-2 overflow-hidden text-sm text-mineshaft-400 hover:text-mineshaft-300"
leftIcon={
<div className="w-6">
<FontAwesomeIcon className="mx-1 inline-block shrink-0" icon={faHome} />
</div>
}
>
Organization Home
</MenuItem>
</Link>
</Menu>
</div>
</nav>
</motion.div>
<div className="flex-1 overflow-y-auto overflow-x-hidden bg-bunker-800 p-4 pt-8">

View File

@@ -1,11 +1,11 @@
import { faCog, faHome, faServer, faStamp, faUsers } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Link, Outlet } from "@tanstack/react-router";
import { motion } from "framer-motion";
import { ProjectPermissionCan } from "@app/components/permissions";
import { Menu, MenuGroup, MenuItem } from "@app/components/v2";
import { Lottie, Menu, MenuGroup, MenuItem } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faCog, faUsers } from "@fortawesome/free-solid-svg-icons";
export const SshLayout = () => {
const { currentWorkspace } = useWorkspace();
@@ -22,7 +22,10 @@ export const SshLayout = () => {
className="dark w-full border-r border-mineshaft-600 bg-gradient-to-tr from-mineshaft-700 via-mineshaft-800 to-mineshaft-900 md:w-60"
>
<nav className="items-between flex h-full flex-col overflow-y-auto dark:[color-scheme:dark]">
<div className="border-b border-mineshaft-600 px-4 py-3.5 text-lg text-white">SSH</div>
<div className="flex items-center gap-3 border-b border-mineshaft-600 px-4 py-3.5 text-lg text-white">
<Lottie className="inline-block h-5 w-5 shrink-0" icon="terminal" />
SSH
</div>
<div className="flex-1">
<Menu>
<MenuGroup title="Resources">
@@ -32,7 +35,16 @@ export const SshLayout = () => {
projectId: currentWorkspace.id
}}
>
{({ isActive }) => <MenuItem isSelected={isActive}>Hosts</MenuItem>}
{({ isActive }) => (
<MenuItem isSelected={isActive}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={faServer} />
</div>
Hosts
</div>
</MenuItem>
)}
</Link>
<ProjectPermissionCan
I={ProjectPermissionActions.Read}
@@ -47,7 +59,14 @@ export const SshLayout = () => {
}}
>
{({ isActive }) => (
<MenuItem isSelected={isActive}>Certificate Authorities</MenuItem>
<MenuItem isSelected={isActive}>
<div className="mx-1 flex gap-2">
<div className="w-6">
<FontAwesomeIcon icon={faStamp} />
</div>
Certificates Authority
</div>
</MenuItem>
)}
</Link>
)
@@ -93,6 +112,22 @@ export const SshLayout = () => {
</MenuGroup>
</Menu>
</div>
<div>
<Menu>
<Link to="/organization/projects">
<MenuItem
className="relative flex items-center gap-2 overflow-hidden text-sm text-mineshaft-400 hover:text-mineshaft-300"
leftIcon={
<div className="w-6">
<FontAwesomeIcon className="mx-1 inline-block shrink-0" icon={faHome} />
</div>
}
>
Organization Home
</MenuItem>
</Link>
</Menu>
</div>
</nav>
</motion.div>
<div className="flex-1 overflow-y-auto overflow-x-hidden bg-bunker-800 p-4 pt-8">

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { CertificateAuthoritiesPage } from './CertificateAuthoritiesPage'
import { CertificateAuthoritiesPage } from "./CertificateAuthoritiesPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities',
"/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-authorities"
)({
component: CertificateAuthoritiesPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Certificate Authorities',
},
],
}
},
})
label: "Certificate Authorities"
}
]
};
}
});

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { CertificatesPage } from './CertificatesPage'
import { CertificatesPage } from "./CertificatesPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificates',
"/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificates"
)({
component: CertificatesPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Certificates',
},
],
}
},
})
label: "Certificates"
}
]
};
}
});

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { PkiSubscribersPage } from './PkiSubscribersPage'
import { PkiSubscribersPage } from "./PkiSubscribersPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/',
"/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/subscribers/"
)({
component: PkiSubscribersPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Subscribers',
},
],
}
},
})
label: "Subscribers"
}
]
};
}
});

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { PkiTemplateListPage } from './PkiTemplateListPage'
import { PkiTemplateListPage } from "./PkiTemplateListPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/',
"/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/certificate-templates/"
)({
component: PkiTemplateListPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Certificate Templates',
},
],
}
},
})
label: "Certificate Templates"
}
]
};
}
});

View File

@@ -2,12 +2,13 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab";
const tabs = [
{
name: "General",
key: "tab-project-general",
Component: () => <div className="text-white">Coming soon</div>
Component: ProjectGeneralTab
}
];

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { SettingsPage } from './SettingsPage'
import { SettingsPage } from "./SettingsPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/settings',
"/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/settings"
)({
component: SettingsPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Settings',
},
],
}
},
})
label: "Settings"
}
]
};
}
});

View File

@@ -1,10 +1,10 @@
import { createFileRoute } from "@tanstack/react-router";
import { PkiManagerLayout } from "@app/layouts/PkiManagerLayout";
import { workspaceKeys } from "@app/hooks/api";
import { fetchWorkspaceById } from "@app/hooks/api/workspace/queries";
import { fetchUserProjectPermissions, roleQueryKeys } from "@app/hooks/api/roles/queries";
import { BreadcrumbTypes } from "@app/components/v2";
import { workspaceKeys } from "@app/hooks/api";
import { fetchUserProjectPermissions, roleQueryKeys } from "@app/hooks/api/roles/queries";
import { fetchWorkspaceById } from "@app/hooks/api/workspace/queries";
import { PkiManagerLayout } from "@app/layouts/PkiManagerLayout";
import { ProjectSelect } from "@app/layouts/ProjectLayout/components/ProjectSelect";
export const Route = createFileRoute(

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { KmipPage } from './KmipPage'
import { KmipPage } from "./KmipPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/kmip',
"/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/kmip"
)({
component: KmipPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'KMIP',
},
],
}
},
})
label: "KMIP"
}
]
};
}
});

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { OverviewPage } from './OverviewPage'
import { OverviewPage } from "./OverviewPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/overview',
"/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/overview"
)({
component: OverviewPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Overview',
},
],
}
},
})
label: "Overview"
}
]
};
}
});

View File

@@ -2,12 +2,13 @@ import { Helmet } from "react-helmet";
import { useTranslation } from "react-i18next";
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab";
const tabs = [
{
name: "General",
key: "tab-project-general",
Component: () => <div className="text-white">Coming soon...</div>
Component: ProjectGeneralTab
}
];

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { SettingsPage } from './SettingsPage'
import { SettingsPage } from "./SettingsPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/settings',
"/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/settings"
)({
component: SettingsPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Settings',
},
],
}
},
})
label: "Settings"
}
]
};
}
});

View File

@@ -6,7 +6,6 @@ import { format } from "date-fns";
import { createNotification } from "@app/components/notifications";
import { IconButton, Td, Tooltip, Tr } from "@app/components/v2";
import { useWorkspace } from "@app/context";
import { getProjectBaseURL } from "@app/helpers/project";
import { formatProjectRoleName } from "@app/helpers/roles";
import { useGetUserWorkspaces } from "@app/hooks/api";
@@ -34,7 +33,6 @@ export const IdentityProjectRow = ({
}: Props) => {
const { data: workspaces } = useGetUserWorkspaces();
const navigate = useNavigate();
const { currentWorkspace } = useWorkspace();
const isAccessible = useMemo(() => {
const workspaceIds = new Map();
@@ -53,7 +51,7 @@ export const IdentityProjectRow = ({
onClick={() => {
if (isAccessible) {
navigate({
to: `${getProjectBaseURL(currentWorkspace.type)}/access-management` as const,
to: `${getProjectBaseURL(project.type)}/access-management` as const,
params: {
projectId: project.id
},

View File

@@ -4,6 +4,7 @@ import {
faArrowDownAZ,
faBorderAll,
faCheck,
faCheckCircle,
faFolderOpen,
faList,
faMagnifyingGlass,
@@ -17,6 +18,11 @@ import { createNotification } from "@app/components/notifications";
import { OrgPermissionCan } from "@app/components/permissions";
import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuTrigger,
FormControl,
IconButton,
Input,
@@ -27,7 +33,7 @@ import {
Tooltip
} from "@app/components/v2";
import { OrgPermissionActions, OrgPermissionSubjects } from "@app/context";
import { getProjectHomePage } from "@app/helpers/project";
import { getProjectHomePage, getProjectTitle } from "@app/helpers/project";
import {
getUserTablePreference,
PreferenceKey,
@@ -35,7 +41,7 @@ import {
} from "@app/helpers/userTablePreferences";
import { useDebounce, usePagination, usePopUp, useResetPageHelper } from "@app/hooks";
import { useRequestProjectAccess, useSearchProjects } from "@app/hooks/api";
import { Workspace } from "@app/hooks/api/workspace/types";
import { ProjectType, Workspace } from "@app/hooks/api/workspace/types";
type Props = {
onAddNewProject: () => void;
@@ -98,6 +104,7 @@ export const AllProjectView = ({
const navigate = useNavigate();
const [searchFilter, setSearchFilter] = useState("");
const [debouncedSearch] = useDebounce(searchFilter);
const [projectTypeFilter, setProjectTypeFilter] = useState<ProjectType>();
const {
setPage,
perPage,
@@ -124,7 +131,8 @@ export const AllProjectView = ({
limit,
offset,
name: debouncedSearch || undefined,
orderDirection
orderDirection,
type: projectTypeFilter
});
useResetPageHelper({
@@ -134,6 +142,9 @@ export const AllProjectView = ({
});
const requestedWorkspaceDetails = (popUp.requestAccessConfirmation.data || {}) as Workspace;
const handleToggleFilterByProjectType = (el: ProjectType) =>
setProjectTypeFilter((state) => (state === el ? undefined : el));
return (
<div>
<div className="flex w-full flex-row">
@@ -160,6 +171,49 @@ export const AllProjectView = ({
</IconButton>
</Tooltip>
</div>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<div
className={twMerge(
"ml-2 flex rounded-md border border-mineshaft-600 bg-mineshaft-800 p-1",
projectTypeFilter && "border-primary-400 text-primary-400"
)}
>
<Tooltip content="Choose visible project type" className="mb-2">
<IconButton
ariaLabel="project-types"
className={twMerge(
"min-w-[2.4rem] border-none hover:bg-mineshaft-600",
projectTypeFilter && "text-primary-400"
)}
variant="plain"
size="xs"
colorSchema="secondary"
>
<FontAwesomeIcon icon={faList} />
</IconButton>
</Tooltip>
</div>
</DropdownMenuTrigger>
<DropdownMenuContent className="thin-scrollbar overflow-y-auto" align="end">
<DropdownMenuLabel>Filter By Project Type</DropdownMenuLabel>
{Object.values(ProjectType).map((el) => (
<DropdownMenuItem
key={`filter-item-${el}`}
onClick={(e) => {
e.preventDefault();
handleToggleFilterByProjectType(el);
}}
icon={projectTypeFilter === el && <FontAwesomeIcon icon={faCheckCircle} />}
iconPos="right"
>
<div className="flex items-center gap-2">
<span>{getProjectTitle(el)}</span>
</div>
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
<div className="ml-2 flex rounded-md border border-mineshaft-600 bg-mineshaft-800 p-1">
<Tooltip content="Disabled across All Project view.">
<IconButton
@@ -270,7 +324,8 @@ export const AllProjectView = ({
</div>
</div>
<div className="mt-1 max-w-lg overflow-hidden text-ellipsis whitespace-nowrap text-xs text-mineshaft-300">
{workspace.description}
{getProjectTitle(workspace.type)}{" "}
{workspace.description ? `- ${workspace.description}` : ""}
</div>
</div>
</div>

View File

@@ -2,9 +2,9 @@ import { ReactNode, useMemo, useState } from "react";
import { faFolderOpen, faStar } from "@fortawesome/free-regular-svg-icons";
import {
faArrowDownAZ,
faArrowRight,
faArrowUpZA,
faBorderAll,
faCheckCircle,
faList,
faMagnifyingGlass,
faPlus,
@@ -13,12 +13,26 @@ import {
} from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { useNavigate } from "@tanstack/react-router";
import { twMerge } from "tailwind-merge";
import { createNotification } from "@app/components/notifications";
import { OrgPermissionCan } from "@app/components/permissions";
import { Button, IconButton, Input, Pagination, Skeleton, Tooltip } from "@app/components/v2";
import {
Button,
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuTrigger,
IconButton,
Input,
Lottie,
Pagination,
Skeleton,
Tooltip
} from "@app/components/v2";
import { OrgPermissionActions, OrgPermissionSubjects, useOrganization } from "@app/context";
import { getProjectHomePage } from "@app/helpers/project";
import { getProjectHomePage, getProjectLottieIcon, getProjectTitle } from "@app/helpers/project";
import {
getUserTablePreference,
PreferenceKey,
@@ -29,7 +43,7 @@ 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 { Workspace } from "@app/hooks/api/workspace/types";
import { ProjectType, Workspace } from "@app/hooks/api/workspace/types";
type Props = {
onAddNewProject: () => void;
@@ -53,6 +67,9 @@ export const MyProjectView = ({
}: Props) => {
const navigate = useNavigate();
const { currentOrg } = useOrganization();
const [projectTypeFilter, setProjectTypeFilter] = useState<Partial<Record<ProjectType, boolean>>>(
{}
);
const { data: workspaces = [], isPending: isWorkspaceLoading } = useGetUserWorkspaces();
const {
@@ -67,6 +84,7 @@ export const MyProjectView = ({
} = usePagination(ProjectOrderBy.Name, {
initPerPage: getUserTablePreference("myProjectsTable", PreferenceKey.PerPage, 24)
});
const isTableFilteredByType = Boolean(Object.values(projectTypeFilter).some((el) => el));
const handlePerPageChange = (newPerPage: number) => {
setPerPage(newPerPage);
@@ -88,13 +106,18 @@ export const MyProjectView = ({
const filteredWorkspaces = useMemo(
() =>
workspaces
.filter((ws) => ws?.name?.toLowerCase().includes(searchFilter.toLowerCase()))
.filter((ws) => {
if (isTableFilteredByType && !projectTypeFilter?.[ws.type]) {
return false;
}
return ws?.name?.toLowerCase().includes(searchFilter.toLowerCase());
})
.sort((a, b) =>
orderDirection === OrderByDirection.ASC
? a.name.toLowerCase().localeCompare(b.name.toLowerCase())
: b.name.toLowerCase().localeCompare(a.name.toLowerCase())
),
[searchFilter, orderDirection, workspaces]
[searchFilter, orderDirection, workspaces, projectTypeFilter]
);
useResetPageHelper({
@@ -117,6 +140,15 @@ export const MyProjectView = ({
};
}, [filteredWorkspaces, projectFavorites, offset, limit, page]);
const handleToggleFilterByProjectType = (type: ProjectType) => {
setProjectTypeFilter((state) => {
return {
...(state || {}),
[type]: !state?.[type]
};
});
};
const addProjectToFavorites = async (projectId: string) => {
try {
if (currentOrg?.id) {
@@ -160,53 +192,46 @@ export const MyProjectView = ({
});
}}
key={workspace.id}
className="flex h-40 min-w-72 cursor-pointer flex-col rounded-md border border-mineshaft-600 bg-mineshaft-800 p-4"
className="relative flex h-36 min-w-72 cursor-pointer flex-col rounded-md border border-mineshaft-500 bg-mineshaft-800 p-4 transition-all hover:border-mineshaft-400"
>
<div className="flex flex-row justify-between">
<div className="mt-0 truncate text-lg text-mineshaft-100">{workspace.name}</div>
{isFavorite ? (
<FontAwesomeIcon
icon={faSolidStar}
className="text-sm text-yellow-600 hover:text-mineshaft-400"
onClick={(e) => {
e.stopPropagation();
removeProjectFromFavorites(workspace.id);
}}
/>
) : (
<FontAwesomeIcon
icon={faStar}
className="text-sm text-mineshaft-400 hover:text-mineshaft-300"
onClick={(e) => {
e.stopPropagation();
addProjectToFavorites(workspace.id);
}}
/>
)}
</div>
<div
className="mb-2.5 mt-1 grow text-sm text-mineshaft-300"
style={{
overflow: "hidden",
display: "-webkit-box",
WebkitBoxOrient: "vertical",
WebkitLineClamp: 2
}}
>
{workspace.description}
</div>
<div className="flex w-full flex-row items-end justify-between place-self-end">
<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{" "}
<FontAwesomeIcon
icon={faArrowRight}
className="pl-1.5 pr-0.5 duration-200 hover:pl-2 hover:pr-0"
/>
<div className="flex items-center gap-4">
<div className="h-12 w-12 rounded bg-mineshaft-600 p-2">
<Lottie icon={getProjectLottieIcon(workspace.type)} className="h-full w-full" />
</div>
<div className="flex-1">
<div className="flex">
<div className="flex-1 truncate text-lg font-semibold text-mineshaft-100">
{workspace.name}
</div>
<div className="">
{isFavorite ? (
<FontAwesomeIcon
icon={faSolidStar}
className="text-sm text-yellow-600 hover:text-mineshaft-400"
onClick={(e) => {
e.stopPropagation();
removeProjectFromFavorites(workspace.id);
}}
/>
) : (
<FontAwesomeIcon
icon={faStar}
className="text-sm text-mineshaft-400 hover:text-mineshaft-300"
onClick={(e) => {
e.stopPropagation();
addProjectToFavorites(workspace.id);
}}
/>
)}
</div>
</div>
</button>
<div className="truncate text-sm text-mineshaft-300">
{getProjectTitle(workspace.type)}
</div>
</div>
</div>
<div className="mt-4 text-sm text-mineshaft-400">
{workspace.description || "No description"}
</div>
</div>
);
@@ -222,12 +247,16 @@ export const MyProjectView = ({
});
}}
key={workspace.id}
className={`group grid h-14 min-w-72 cursor-pointer grid-cols-6 border-l border-r border-t border-mineshaft-600 bg-mineshaft-800 px-6 hover:bg-mineshaft-700 ${
className={`group grid h-16 min-w-72 cursor-pointer grid-cols-6 border-l border-r border-t border-mineshaft-600 bg-mineshaft-800 px-6 hover:bg-mineshaft-700 ${
index === 0 && "rounded-t-md"
}`}
>
<div className="flex items-center sm:col-span-3 lg:col-span-4">
<div className="flex flex-col justify-center sm:col-span-3 lg:col-span-4">
<div className="truncate text-sm text-mineshaft-100">{workspace.name}</div>
<div className="mt-1 text-xs text-mineshaft-300">
{getProjectTitle(workspace.type)}{" "}
{workspace.description ? `- ${workspace.description}` : ""}
</div>
</div>
<div className="flex items-center justify-end sm:col-span-3 lg:col-span-2">
{isFavorite ? (
@@ -258,7 +287,7 @@ export const MyProjectView = ({
switch (projectsViewMode) {
case ProjectsViewMode.GRID:
projectsComponents = (
<div className="mt-4 grid w-full grid-cols-1 gap-4 lg:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-4">
<div className="mt-4 grid w-full grid-cols-1 gap-4 lg:grid-cols-2 xl:grid-cols-3">
{isProjectViewLoading &&
Array.apply(0, Array(3)).map((_x, i) => (
<div
@@ -351,6 +380,49 @@ export const MyProjectView = ({
</IconButton>
</Tooltip>
</div>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<div
className={twMerge(
"ml-2 flex rounded-md border border-mineshaft-600 bg-mineshaft-800 p-1",
isTableFilteredByType && "border-primary-400 text-primary-400"
)}
>
<Tooltip content="Choose visible project type" className="mb-2">
<IconButton
ariaLabel="project-types"
className={twMerge(
"min-w-[2.4rem] border-none hover:bg-mineshaft-600",
isTableFilteredByType && "text-primary-400"
)}
variant="plain"
size="xs"
colorSchema="secondary"
>
<FontAwesomeIcon icon={faList} />
</IconButton>
</Tooltip>
</div>
</DropdownMenuTrigger>
<DropdownMenuContent className="thin-scrollbar overflow-y-auto" align="end">
<DropdownMenuLabel>Filter By Project Type</DropdownMenuLabel>
{Object.values(ProjectType).map((el) => (
<DropdownMenuItem
key={`filter-item-${el}`}
onClick={(e) => {
e.preventDefault();
handleToggleFilterByProjectType(el);
}}
icon={projectTypeFilter?.[el] && <FontAwesomeIcon icon={faCheckCircle} />}
iconPos="right"
>
<div className="flex items-center gap-2">
<span>{getProjectTitle(el)}</span>
</div>
</DropdownMenuItem>
))}
</DropdownMenuContent>
</DropdownMenu>
<div className="ml-2 flex rounded-md border border-mineshaft-600 bg-mineshaft-800 p-1">
<IconButton
variant="outline_bg"

View File

@@ -5,13 +5,12 @@ import { useNavigate } from "@tanstack/react-router";
import { createNotification } from "@app/components/notifications";
import { IconButton, Td, Tooltip, Tr } from "@app/components/v2";
import { getProjectBaseURL } from "@app/helpers/project";
import { formatProjectRoleName } from "@app/helpers/roles";
import { useGetUserWorkspaces } from "@app/hooks/api";
import { TWorkspaceUser } from "@app/hooks/api/types";
import { UsePopUpState } from "@app/hooks/usePopUp";
import { OrgAccessControlTabSections } from "@app/types/org";
import { getProjectBaseURL } from "@app/helpers/project";
import { useWorkspace } from "@app/context";
type Props = {
membership: TWorkspaceUser;
@@ -27,7 +26,6 @@ export const UserProjectRow = ({
}: Props) => {
const { data: workspaces = [] } = useGetUserWorkspaces();
const navigate = useNavigate();
const { currentWorkspace } = useWorkspace();
const isAccessible = useMemo(() => {
const workspaceIds = new Map();
@@ -46,7 +44,7 @@ export const UserProjectRow = ({
onClick={() => {
if (isAccessible) {
navigate({
to: `${getProjectBaseURL(currentWorkspace.type)}/access-management` as const,
to: `${getProjectBaseURL(project.type)}/access-management` as const,
params: {
projectId: project.id
},

View File

@@ -33,6 +33,7 @@ import {
Tr
} from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { getProjectBaseURL } from "@app/helpers/project";
import {
getUserTablePreference,
PreferenceKey,
@@ -44,7 +45,6 @@ import { OrderByDirection } from "@app/hooks/api/generic/types";
import { UsePopUpState } from "@app/hooks/usePopUp";
import { GroupRoles } from "./GroupRoles";
import { getProjectBaseURL } from "@app/helpers/project";
type Props = {
handlePopUpOpen: (

View File

@@ -46,6 +46,7 @@ import {
Tr
} from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { getProjectBaseURL } from "@app/helpers/project";
import { formatProjectRoleName } from "@app/helpers/roles";
import {
getUserTablePreference,
@@ -60,7 +61,6 @@ import { ProjectIdentityOrderBy } from "@app/hooks/api/workspace/types";
import { usePopUp } from "@app/hooks/usePopUp";
import { IdentityModal } from "./components/IdentityModal";
import { getProjectBaseURL } from "@app/helpers/project";
const MAX_ROLES_TO_BE_SHOWN_IN_TABLE = 2;

View File

@@ -2,10 +2,10 @@ import { Link } from "@tanstack/react-router";
import { Alert, AlertDescription } from "@app/components/v2";
import { useWorkspace } from "@app/context";
import { getProjectBaseURL } from "@app/helpers/project";
import { TWorkspaceUser } from "@app/hooks/api/types";
import { MemberRbacSection } from "./MemberRbacSection";
import { getProjectBaseURL } from "@app/helpers/project";
type Props = {
projectMember: TWorkspaceUser;

View File

@@ -50,6 +50,7 @@ import {
useUser,
useWorkspace
} from "@app/context";
import { getProjectBaseURL } from "@app/helpers/project";
import { formatProjectRoleName } from "@app/helpers/roles";
import {
getUserTablePreference,
@@ -60,7 +61,6 @@ import { usePagination, useResetPageHelper } from "@app/hooks";
import { useGetProjectRoles, useGetWorkspaceUsers } from "@app/hooks/api";
import { OrderByDirection } from "@app/hooks/api/generic/types";
import { UsePopUpState } from "@app/hooks/usePopUp";
import { getProjectBaseURL } from "@app/helpers/project";
const MAX_ROLES_TO_BE_SHOWN_IN_TABLE = 2;

View File

@@ -40,6 +40,7 @@ import {
Tr
} from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { getProjectBaseURL } from "@app/helpers/project";
import { isCustomProjectRole } from "@app/helpers/roles";
import {
getUserTablePreference,
@@ -52,7 +53,6 @@ import { OrderByDirection } from "@app/hooks/api/generic/types";
import { ProjectMembershipRole, TProjectRole } from "@app/hooks/api/roles/types";
import { DuplicateProjectRoleModal } from "@app/pages/project/RoleDetailsBySlugPage/components/DuplicateProjectRoleModal";
import { RoleModal } from "@app/pages/project/RoleDetailsBySlugPage/components/RoleModal";
import { getProjectBaseURL } from "@app/helpers/project";
enum RolesOrderBy {
Name = "name",

View File

@@ -1,34 +1,32 @@
import { createFileRoute, stripSearchParams } from '@tanstack/react-router'
import { zodValidator } from '@tanstack/zod-adapter'
import { z } from 'zod'
import { createFileRoute, stripSearchParams } from "@tanstack/react-router";
import { zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { AccessControlPage } from './AccessControlPage'
import { AccessControlPage } from "./AccessControlPage";
const AccessControlPageQuerySchema = z.object({
selectedTab: z
.nativeEnum(ProjectAccessControlTabs)
.catch(ProjectAccessControlTabs.Member),
requesterEmail: z.string().catch(''),
})
selectedTab: z.nativeEnum(ProjectAccessControlTabs).catch(ProjectAccessControlTabs.Member),
requesterEmail: z.string().catch("")
});
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/access-management',
"/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/access-management"
)({
component: AccessControlPage,
validateSearch: zodValidator(AccessControlPageQuerySchema),
search: {
middlewares: [stripSearchParams({ requesterEmail: '' })],
middlewares: [stripSearchParams({ requesterEmail: "" })]
},
beforeLoad: ({ context }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
},
],
}
},
})
label: "Access Control"
}
]
};
}
});

View File

@@ -1,34 +1,32 @@
import { createFileRoute, stripSearchParams } from '@tanstack/react-router'
import { zodValidator } from '@tanstack/zod-adapter'
import { z } from 'zod'
import { createFileRoute, stripSearchParams } from "@tanstack/react-router";
import { zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { AccessControlPage } from './AccessControlPage'
import { AccessControlPage } from "./AccessControlPage";
const AccessControlPageQuerySchema = z.object({
selectedTab: z
.nativeEnum(ProjectAccessControlTabs)
.catch(ProjectAccessControlTabs.Member),
requesterEmail: z.string().catch(''),
})
selectedTab: z.nativeEnum(ProjectAccessControlTabs).catch(ProjectAccessControlTabs.Member),
requesterEmail: z.string().catch("")
});
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/access-management',
"/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/access-management"
)({
component: AccessControlPage,
validateSearch: zodValidator(AccessControlPageQuerySchema),
search: {
middlewares: [stripSearchParams({ requesterEmail: '' })],
middlewares: [stripSearchParams({ requesterEmail: "" })]
},
beforeLoad: ({ context }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
},
],
}
},
})
label: "Access Control"
}
]
};
}
});

View File

@@ -1,34 +1,32 @@
import { createFileRoute, stripSearchParams } from '@tanstack/react-router'
import { zodValidator } from '@tanstack/zod-adapter'
import { z } from 'zod'
import { createFileRoute, stripSearchParams } from "@tanstack/react-router";
import { zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { AccessControlPage } from './AccessControlPage'
import { AccessControlPage } from "./AccessControlPage";
const AccessControlPageQuerySchema = z.object({
selectedTab: z
.nativeEnum(ProjectAccessControlTabs)
.catch(ProjectAccessControlTabs.Member),
requesterEmail: z.string().catch(''),
})
selectedTab: z.nativeEnum(ProjectAccessControlTabs).catch(ProjectAccessControlTabs.Member),
requesterEmail: z.string().catch("")
});
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/access-management',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/access-management"
)({
component: AccessControlPage,
validateSearch: zodValidator(AccessControlPageQuerySchema),
search: {
middlewares: [stripSearchParams({ requesterEmail: '' })],
middlewares: [stripSearchParams({ requesterEmail: "" })]
},
beforeLoad: ({ context }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
},
],
}
},
})
label: "Access Control"
}
]
};
}
});

View File

@@ -1,34 +1,32 @@
import { createFileRoute, stripSearchParams } from '@tanstack/react-router'
import { zodValidator } from '@tanstack/zod-adapter'
import { z } from 'zod'
import { createFileRoute, stripSearchParams } from "@tanstack/react-router";
import { zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { AccessControlPage } from './AccessControlPage'
import { AccessControlPage } from "./AccessControlPage";
const AccessControlPageQuerySchema = z.object({
selectedTab: z
.nativeEnum(ProjectAccessControlTabs)
.catch(ProjectAccessControlTabs.Member),
requesterEmail: z.string().catch(''),
})
selectedTab: z.nativeEnum(ProjectAccessControlTabs).catch(ProjectAccessControlTabs.Member),
requesterEmail: z.string().catch("")
});
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/access-management"
)({
component: AccessControlPage,
validateSearch: zodValidator(AccessControlPageQuerySchema),
search: {
middlewares: [stripSearchParams({ requesterEmail: '' })],
middlewares: [stripSearchParams({ requesterEmail: "" })]
},
beforeLoad: ({ context }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
},
],
}
},
})
label: "Access Control"
}
]
};
}
});

View File

@@ -1,34 +1,32 @@
import { createFileRoute, stripSearchParams } from '@tanstack/react-router'
import { zodValidator } from '@tanstack/zod-adapter'
import { z } from 'zod'
import { createFileRoute, stripSearchParams } from "@tanstack/react-router";
import { zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { AccessControlPage } from './AccessControlPage'
import { AccessControlPage } from "./AccessControlPage";
const AccessControlPageQuerySchema = z.object({
selectedTab: z
.nativeEnum(ProjectAccessControlTabs)
.catch(ProjectAccessControlTabs.Member),
requesterEmail: z.string().catch(''),
})
selectedTab: z.nativeEnum(ProjectAccessControlTabs).catch(ProjectAccessControlTabs.Member),
requesterEmail: z.string().catch("")
});
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/access-management',
"/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/access-management"
)({
component: AccessControlPage,
validateSearch: zodValidator(AccessControlPageQuerySchema),
search: {
middlewares: [stripSearchParams({ requesterEmail: '' })],
middlewares: [stripSearchParams({ requesterEmail: "" })]
},
beforeLoad: ({ context }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
},
],
}
},
})
label: "Access Control"
}
]
};
}
});

View File

@@ -15,11 +15,11 @@ import {
} from "@app/components/v2";
import { CopyButton } from "@app/components/v2/CopyButton";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { getProjectBaseURL } from "@app/helpers/project";
import { usePopUp } from "@app/hooks";
import { useDeleteGroupFromWorkspace } from "@app/hooks/api";
import { TGroupMembership } from "@app/hooks/api/groups/types";
import { GroupRoles } from "@app/pages/project/AccessControlPage/components/GroupsTab/components/GroupsSection/GroupRoles";
import { getProjectBaseURL } from "@app/helpers/project";
type Props = {
groupMembership: TGroupMembership;

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { GroupDetailsByIDPage } from './GroupDetailsByIDPage'
import { GroupDetailsByIDPage } from "./GroupDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId',
"/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/groups/$groupId"
)({
component: GroupDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Groups,
},
}),
selectedTab: ProjectAccessControlTabs.Groups
}
})
},
{
label: 'Group',
},
],
}
},
})
label: "Group"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { GroupDetailsByIDPage } from './GroupDetailsByIDPage'
import { GroupDetailsByIDPage } from "./GroupDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/groups/$groupId',
"/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/groups/$groupId"
)({
component: GroupDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Groups,
},
}),
selectedTab: ProjectAccessControlTabs.Groups
}
})
},
{
label: 'Group',
},
],
}
},
})
label: "Group"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { GroupDetailsByIDPage } from './GroupDetailsByIDPage'
import { GroupDetailsByIDPage } from "./GroupDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/groups/$groupId"
)({
component: GroupDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Groups,
},
}),
selectedTab: ProjectAccessControlTabs.Groups
}
})
},
{
label: 'Group',
},
],
}
},
})
label: "Group"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { GroupDetailsByIDPage } from './GroupDetailsByIDPage'
import { GroupDetailsByIDPage } from "./GroupDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/groups/$groupId"
)({
component: GroupDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Groups,
},
}),
selectedTab: ProjectAccessControlTabs.Groups
}
})
},
{
label: 'Group',
},
],
}
},
})
label: "Group"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { GroupDetailsByIDPage } from './GroupDetailsByIDPage'
import { GroupDetailsByIDPage } from "./GroupDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/groups/$groupId',
"/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/groups/$groupId"
)({
component: GroupDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Groups,
},
}),
selectedTab: ProjectAccessControlTabs.Groups
}
})
},
{
label: 'Group',
},
],
}
},
})
label: "Group"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { IdentityDetailsByIDPage } from './IdentityDetailsByIDPage'
import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId',
"/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/identities/$identityId"
)({
component: IdentityDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Identities,
},
}),
selectedTab: ProjectAccessControlTabs.Identities
}
})
},
{
label: 'Machine Identity',
},
],
}
},
})
label: "Machine Identity"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { IdentityDetailsByIDPage } from './IdentityDetailsByIDPage'
import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/identities/$identityId',
"/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/identities/$identityId"
)({
component: IdentityDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Identities,
},
}),
selectedTab: ProjectAccessControlTabs.Identities
}
})
},
{
label: 'Machine Identity',
},
],
}
},
})
label: "Machine Identity"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { IdentityDetailsByIDPage } from './IdentityDetailsByIDPage'
import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/identities/$identityId"
)({
component: IdentityDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Identities,
},
}),
selectedTab: ProjectAccessControlTabs.Identities
}
})
},
{
label: 'Machine Identity',
},
],
}
},
})
label: "Machine Identity"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { IdentityDetailsByIDPage } from './IdentityDetailsByIDPage'
import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/identities/$identityId"
)({
component: IdentityDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Identities,
},
}),
selectedTab: ProjectAccessControlTabs.Identities
}
})
},
{
label: 'Machine Identity',
},
],
}
},
})
label: "Machine Identity"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { IdentityDetailsByIDPage } from './IdentityDetailsByIDPage'
import { IdentityDetailsByIDPage } from "./IdentityDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/identities/$identityId',
"/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/identities/$identityId"
)({
component: IdentityDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Identities,
},
}),
selectedTab: ProjectAccessControlTabs.Identities
}
})
},
{
label: 'Machine Identity',
},
],
}
},
})
label: "Machine Identity"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { MemberDetailsByIDPage } from './MemberDetailsByIDPage'
import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId',
"/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/members/$membershipId"
)({
component: MemberDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Member,
},
}),
selectedTab: ProjectAccessControlTabs.Member
}
})
},
{
label: 'User',
},
],
}
},
})
label: "User"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { MemberDetailsByIDPage } from './MemberDetailsByIDPage'
import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/members/$membershipId',
"/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/members/$membershipId"
)({
component: MemberDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Member,
},
}),
selectedTab: ProjectAccessControlTabs.Member
}
})
},
{
label: 'User',
},
],
}
},
})
label: "User"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { MemberDetailsByIDPage } from './MemberDetailsByIDPage'
import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/members/$membershipId"
)({
component: MemberDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Member,
},
}),
selectedTab: ProjectAccessControlTabs.Member
}
})
},
{
label: 'User',
},
],
}
},
})
label: "User"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { MemberDetailsByIDPage } from './MemberDetailsByIDPage'
import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/members/$membershipId"
)({
component: MemberDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Member,
},
}),
selectedTab: ProjectAccessControlTabs.Member
}
})
},
{
label: 'User',
},
],
}
},
})
label: "User"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { MemberDetailsByIDPage } from './MemberDetailsByIDPage'
import { MemberDetailsByIDPage } from "./MemberDetailsByIDPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/members/$membershipId',
"/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/members/$membershipId"
)({
component: MemberDetailsByIDPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Member,
},
}),
selectedTab: ProjectAccessControlTabs.Member
}
})
},
{
label: 'User',
},
],
}
},
})
label: "User"
}
]
};
}
});

View File

@@ -17,6 +17,7 @@ import {
PageHeader
} from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { getProjectBaseURL } from "@app/helpers/project";
import { useDeleteProjectRole, useGetProjectRoleBySlug } from "@app/hooks/api";
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
import { usePopUp } from "@app/hooks/usePopUp";
@@ -25,7 +26,6 @@ import { RolePermissionsSection } from "@app/pages/project/RoleDetailsBySlugPage
import { ProjectAccessControlTabs } from "@app/types/project";
import { RoleModal } from "./components/RoleModal";
import { getProjectBaseURL } from "@app/helpers/project";
const Page = () => {
const navigate = useNavigate();

View File

@@ -7,10 +7,10 @@ import { createNotification } from "@app/components/notifications";
import { Button, FormControl, Input, Modal, ModalContent, Spinner } from "@app/components/v2";
import { ProjectPermissionSub, useWorkspace } from "@app/context";
import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionContext/types";
import { getProjectBaseURL } from "@app/helpers/project";
import { useCreateProjectRole, useGetProjectRoleBySlug } from "@app/hooks/api";
import { TProjectRole } from "@app/hooks/api/roles/types";
import { slugSchema } from "@app/lib/schemas";
import { getProjectBaseURL } from "@app/helpers/project";
type Props = {
isOpen: boolean;

View File

@@ -7,6 +7,7 @@ import { z } from "zod";
import { createNotification } from "@app/components/notifications";
import { Button, FormControl, Input, Modal, ModalContent } from "@app/components/v2";
import { useWorkspace } from "@app/context";
import { getProjectBaseURL } from "@app/helpers/project";
import {
useCreateProjectRole,
useGetProjectRoleBySlug,
@@ -14,7 +15,6 @@ import {
} from "@app/hooks/api";
import { UsePopUpState } from "@app/hooks/usePopUp";
import { slugSchema } from "@app/lib/schemas";
import { getProjectBaseURL } from "@app/helpers/project";
const schema = z
.object({

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { RoleDetailsBySlugPage } from './RoleDetailsBySlugPage'
import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug',
"/_authenticate/_inject-org-details/_org-layout/projects/cert-management/$projectId/_cert-manager-layout/roles/$roleSlug"
)({
component: RoleDetailsBySlugPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Roles,
},
}),
selectedTab: ProjectAccessControlTabs.Roles
}
})
},
{
label: 'Roles',
},
],
}
},
})
label: "Roles"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { RoleDetailsBySlugPage } from './RoleDetailsBySlugPage'
import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/roles/$roleSlug',
"/_authenticate/_inject-org-details/_org-layout/projects/kms/$projectId/_kms-layout/roles/$roleSlug"
)({
component: RoleDetailsBySlugPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Roles,
},
}),
selectedTab: ProjectAccessControlTabs.Roles
}
})
},
{
label: 'Roles',
},
],
}
},
})
label: "Roles"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { RoleDetailsBySlugPage } from './RoleDetailsBySlugPage'
import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/roles/$roleSlug"
)({
component: RoleDetailsBySlugPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Roles,
},
}),
selectedTab: ProjectAccessControlTabs.Roles
}
})
},
{
label: 'Roles',
},
],
}
},
})
label: "Roles"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { RoleDetailsBySlugPage } from './RoleDetailsBySlugPage'
import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/roles/$roleSlug"
)({
component: RoleDetailsBySlugPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Roles,
},
}),
selectedTab: ProjectAccessControlTabs.Roles
}
})
},
{
label: 'Roles',
},
],
}
},
})
label: "Roles"
}
]
};
}
});

View File

@@ -1,11 +1,11 @@
import { createFileRoute, linkOptions } from '@tanstack/react-router'
import { createFileRoute, linkOptions } from "@tanstack/react-router";
import { ProjectAccessControlTabs } from '@app/types/project'
import { ProjectAccessControlTabs } from "@app/types/project";
import { RoleDetailsBySlugPage } from './RoleDetailsBySlugPage'
import { RoleDetailsBySlugPage } from "./RoleDetailsBySlugPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug',
"/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/roles/$roleSlug"
)({
component: RoleDetailsBySlugPage,
beforeLoad: ({ context, params }) => {
@@ -13,21 +13,21 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Access Control',
label: "Access Control",
link: linkOptions({
to: '/projects/$projectId/access-management',
to: "/projects/$projectId/access-management",
params: {
projectId: params.projectId,
projectId: params.projectId
},
search: {
selectedTab: ProjectAccessControlTabs.Roles,
},
}),
selectedTab: ProjectAccessControlTabs.Roles
}
})
},
{
label: 'Roles',
},
],
}
},
})
label: "Roles"
}
]
};
}
});

View File

@@ -16,4 +16,4 @@ export const Route = createFileRoute(
]
};
}
});
});

View File

@@ -16,4 +16,4 @@ export const Route = createFileRoute(
]
};
}
});
});

View File

@@ -16,4 +16,4 @@ export const Route = createFileRoute(
]
};
}
});
});

View File

@@ -16,4 +16,4 @@ export const Route = createFileRoute(
]
};
}
});
});

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { SettingsPage } from './SettingsPage'
import { SettingsPage } from "./SettingsPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/_project-layout/projects/ssh/$projectId/_ssh-layout/settings',
"/_authenticate/_inject-org-details/_org-layout/_project-layout/projects/ssh/$projectId/_ssh-layout/settings"
)({
component: SettingsPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Settings',
},
],
}
},
})
label: "Settings"
}
]
};
}
});

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { IPAllowListPage } from './IPAllowlistPage'
import { IPAllowListPage } from "./IPAllowlistPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/allowlist',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/allowlist"
)({
component: () => IPAllowListPage,
})
component: () => IPAllowListPage
});

View File

@@ -1,15 +1,15 @@
import { createFileRoute } from '@tanstack/react-router'
import { zodValidator } from '@tanstack/zod-adapter'
import { z } from 'zod'
import { createFileRoute } from "@tanstack/react-router";
import { zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
import { SecretApprovalsPage } from './SecretApprovalsPage'
import { SecretApprovalsPage } from "./SecretApprovalsPage";
const SecretApprovalPageQueryParams = z.object({
requestId: z.string().catch(''),
})
requestId: z.string().catch("")
});
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/approval',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/approval"
)({
component: SecretApprovalsPage,
validateSearch: zodValidator(SecretApprovalPageQueryParams),
@@ -18,9 +18,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Approvals',
},
],
}
},
})
label: "Approvals"
}
]
};
}
});

View File

@@ -52,6 +52,7 @@ import {
useWorkspace
} from "@app/context";
import { ProjectPermissionSecretActions } from "@app/context/ProjectPermissionContext/types";
import { getProjectBaseURL } from "@app/helpers/project";
import { usePopUp, useToggle } from "@app/hooks";
import { useGetSecretVersion } from "@app/hooks/api";
import { ActorType } from "@app/hooks/api/auditLogs/enums";
@@ -64,7 +65,6 @@ import { camelCaseToSpaces } from "@app/lib/fn/string";
import { CreateReminderForm } from "./CreateReminderForm";
import { HIDDEN_SECRET_VALUE } from "./SecretItem";
import { formSchema, SecretActionType, TFormSchema } from "./SecretListView.utils";
import { getProjectBaseURL } from "@app/helpers/project";
type Props = {
isOpen?: boolean;

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { SecretRotationPage } from './SecretRotationPage'
import { SecretRotationPage } from "./SecretRotationPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/secret-rotation"
)({
component: SecretRotationPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Secret Rotation',
},
],
}
},
})
label: "Secret Rotation"
}
]
};
}
});

View File

@@ -4,9 +4,10 @@ import { useTranslation } from "react-i18next";
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { useWorkspace } from "@app/context";
import { ProjectVersion } from "@app/hooks/api/workspace/types";
import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab";
import { EncryptionTab } from "./components/EncryptionTab";
import { ProjectGeneralTab } from "./components/ProjectGeneralTab";
import { SecretSettingsTab } from "./components/ProjectGeneralTab";
import { WebhooksTab } from "./components/WebhooksTab";
import { WorkflowIntegrationTab } from "./components/WorkflowIntegrationSection";
@@ -15,6 +16,7 @@ export const SettingsPage = () => {
const { currentWorkspace } = useWorkspace();
const tabs = [
{ name: "General", key: "tab-project-general", Component: ProjectGeneralTab },
{ name: "Secrets Settings", key: "tab-secret-general", Component: SecretSettingsTab },
{
name: "Encryption",
key: "tab-project-encryption",

View File

@@ -6,7 +6,7 @@ import { SecretSharingSection } from "../SecretSharingSection";
import { SecretSnapshotsLegacySection } from "../SecretSnapshotsLegacySection";
import { SecretTagsSection } from "../SecretTagsSection";
export const ProjectGeneralTab = () => {
export const SecretSettingsTab = () => {
return (
<div>
<EnvironmentSection />

View File

@@ -1 +1 @@
export { ProjectGeneralTab } from "./ProjectGeneralTab";
export { SecretSettingsTab } from "./ProjectGeneralTab";

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { SettingsPage } from './SettingsPage'
import { SettingsPage } from "./SettingsPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/settings',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-management/$projectId/_secret-manager-layout/settings"
)({
component: SettingsPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Settings',
},
],
}
},
})
label: "Settings"
}
]
};
}
});

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { SecretScanningDataSourcesPage } from './SecretScanningDataSourcesPage'
import { SecretScanningDataSourcesPage } from "./SecretScanningDataSourcesPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/data-sources/"
)({
component: SecretScanningDataSourcesPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Data Sources',
},
],
}
},
})
label: "Data Sources"
}
]
};
}
});

View File

@@ -1,32 +1,29 @@
import { createFileRoute } from '@tanstack/react-router'
import { zodValidator } from '@tanstack/zod-adapter'
import { z } from 'zod'
import { createFileRoute } from "@tanstack/react-router";
import { zodValidator } from "@tanstack/zod-adapter";
import { z } from "zod";
import { SecretScanningFindingStatus } from '@app/hooks/api/secretScanningV2'
import { SecretScanningFindingStatus } from "@app/hooks/api/secretScanningV2";
import { SecretScanningFindingsPage } from './SecretScanningFindingsPage'
import { SecretScanningFindingsPage } from "./SecretScanningFindingsPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/findings',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/findings"
)({
validateSearch: zodValidator(
z.object({
search: z.string().optional(),
status: z
.nativeEnum(SecretScanningFindingStatus)
.optional()
.catch(undefined),
}),
status: z.nativeEnum(SecretScanningFindingStatus).optional().catch(undefined)
})
),
beforeLoad: ({ context }) => {
return {
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Findings',
},
],
}
label: "Findings"
}
]
};
},
component: SecretScanningFindingsPage,
})
component: SecretScanningFindingsPage
});

View File

@@ -10,6 +10,7 @@ import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectPermissionSub, useSubscription } from "@app/context";
import { ProjectPermissionSecretScanningConfigActions } from "@app/context/ProjectPermissionContext/types";
import { usePopUp } from "@app/hooks";
import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab";
import { ProjectScanningConfigTab } from "./components/ProjectScanningConfigTab";
@@ -62,8 +63,12 @@ export const SettingsPage = () => {
<Tabs defaultValue="tab-project-general">
<TabList>
<Tab value="tab-project-general">General</Tab>
<Tab value="tab-project-secret-scanning">Scanning Settings</Tab>
</TabList>
<TabPanel value="tab-project-general">
<ProjectGeneralTab />
</TabPanel>
<TabPanel value="tab-project-secret-scanning">
<ProjectPermissionCan
I={ProjectPermissionSecretScanningConfigActions.Read}
a={ProjectPermissionSub.SecretScanningConfigs}

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { SettingsPage } from './SettingsPage'
import { SettingsPage } from "./SettingsPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/settings',
"/_authenticate/_inject-org-details/_org-layout/projects/secret-scanning/$projectId/_secret-scanning-layout/settings"
)({
component: SettingsPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Settings',
},
],
}
},
})
label: "Settings"
}
]
};
}
});

View File

@@ -4,6 +4,7 @@ import { useTranslation } from "react-i18next";
import { ProjectPermissionCan } from "@app/components/permissions";
import { PageHeader, Tab, TabList, TabPanel, Tabs } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub } from "@app/context";
import { ProjectGeneralTab } from "@app/pages/project/SettingsPage/components/ProjectGeneralTab";
import { ProjectSshTab } from "./components/ProjectSshTab";
@@ -20,8 +21,12 @@ export const SettingsPage = () => {
<Tabs defaultValue="tab-project-general">
<TabList>
<Tab value="tab-project-general">General</Tab>
<Tab value="tab-ssh-settings">SSH Settings</Tab>
</TabList>
<TabPanel value="tab-project-general">
<ProjectGeneralTab />
</TabPanel>
<TabPanel value="tab-ssh-settings">
<ProjectPermissionCan
I={ProjectPermissionActions.Edit}
a={ProjectPermissionSub.Project}

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { SettingsPage } from './SettingsPage'
import { SettingsPage } from "./SettingsPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/settings',
"/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/settings"
)({
component: SettingsPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Settings',
},
],
}
},
})
label: "Settings"
}
]
};
}
});

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { SshCertsPage } from './SshCertsPage'
import { SshCertsPage } from "./SshCertsPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/certificates',
"/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/certificates"
)({
component: SshCertsPage,
})
component: SshCertsPage
});

View File

@@ -1,9 +1,9 @@
import { createFileRoute } from '@tanstack/react-router'
import { createFileRoute } from "@tanstack/react-router";
import { SshHostsPage } from './SshHostsPage'
import { SshHostsPage } from "./SshHostsPage";
export const Route = createFileRoute(
'/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/overview',
"/_authenticate/_inject-org-details/_org-layout/projects/ssh/$projectId/_ssh-layout/overview"
)({
component: SshHostsPage,
beforeLoad: ({ context }) => {
@@ -11,9 +11,9 @@ export const Route = createFileRoute(
breadcrumbs: [
...context.breadcrumbs,
{
label: 'Hosts',
},
],
}
},
})
label: "Hosts"
}
]
};
}
});