mirror of
https://github.com/awatertrevi/infisical.git
synced 2026-09-22 13:39:35 +00:00
feat: completed all layout changes needed for frontend
This commit is contained in:
@@ -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"
|
||||
|
||||
@@ -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];
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -184,6 +184,7 @@ export type TSearchProjectsDTO = {
|
||||
name?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
type?: ProjectType;
|
||||
options?: { enabled?: boolean };
|
||||
orderBy?: ProjectIdentityOrderBy;
|
||||
orderDirection?: OrderByDirection;
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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
|
||||
},
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
},
|
||||
|
||||
@@ -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: (
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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({
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -16,4 +16,4 @@ export const Route = createFileRoute(
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,4 +16,4 @@ export const Route = createFileRoute(
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,4 +16,4 @@ export const Route = createFileRoute(
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -16,4 +16,4 @@ export const Route = createFileRoute(
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 />
|
||||
|
||||
@@ -1 +1 @@
|
||||
export { ProjectGeneralTab } from "./ProjectGeneralTab";
|
||||
export { SecretSettingsTab } from "./ProjectGeneralTab";
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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
|
||||
});
|
||||
|
||||
@@ -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"
|
||||
}
|
||||
]
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user