import { useState } from "react"; import { useFormContext } from "react-hook-form"; import { createNotification } from "@app/components/notifications"; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, Button, Modal, ModalClose, ModalContent } from "@app/components/v2"; import { ProjectPermissionSub } from "@app/context"; import { useGetProjectTypeFromRoute } from "@app/hooks"; import { ProjectType } from "@app/hooks/api/workspace/types"; import { PROJECT_PERMISSION_OBJECT, RoleTemplate, RoleTemplates, TFormSchema } from "./ProjectRoleModifySection.utils"; type Props = { isOpen: boolean; onOpenChange: (isOpen: boolean) => void; }; type ContentProps = { onClose: () => void; }; const Content = ({ onClose }: ContentProps) => { const rootForm = useFormContext(); const projectType = useGetProjectTypeFromRoute(); const [selectedTemplate, setSelectedTemplate] = useState(); const [conflictingSubjects, setConflictingSubjects] = useState([]); const [showConflictingSubjects, setShowConflictingSubjects] = useState(false); const templates = RoleTemplates[projectType ?? ProjectType.SecretManager]; const onSubmit = (skipConflicting = false) => { if (!selectedTemplate) { createNotification({ type: "error", text: "Please select a template" }); return; } selectedTemplate.permissions.forEach(({ subject, actions }) => { if (skipConflicting && conflictingSubjects.includes(subject)) return; rootForm.setValue( `permissions.${subject}`, // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore-error akhilmhdh: this is because of ts collision with both [Object.fromEntries(actions.map((action) => [action, true]))], { shouldDirty: true, shouldTouch: true, shouldValidate: true } ); }); onClose(); }; const onApply = () => { if (!selectedTemplate) { createNotification({ type: "error", text: "Please select a template" }); return; } const conflictingPolicies: ProjectPermissionSub[] = []; selectedTemplate.permissions.forEach(({ subject }) => { const rootPolicyValue = rootForm.getValues("permissions")?.[subject]; if (rootPolicyValue?.length) { conflictingPolicies.push(subject); } }); if (conflictingPolicies.length) { setConflictingSubjects(conflictingPolicies); setShowConflictingSubjects(true); return; } onSubmit(); }; return ( <>
{conflictingSubjects.map((subject) => (
{PROJECT_PERMISSION_OBJECT[subject].title}
))}
setSelectedTemplate(templates.find((template) => template.id === value)) } collapsible className="w-full border-collapse" > {templates.map(({ name, description, permissions, id }) => (
{name} {description}
Grants the following permissions:
{permissions .map((permission) => ({ ...permission, object: PROJECT_PERMISSION_OBJECT[permission.subject] })) .sort((a, b) => a.object.title.localeCompare(b.object.title)) .map(({ subject, actions, object }) => { return (
{object.title}
    {actions.map((action) => (
  • {object.actions.find((a) => a.value === action)?.label}
  • ))}
); })}
))}
); }; export const PolicyTemplateModal = ({ isOpen, onOpenChange }: Props) => { return ( onOpenChange(false)} /> ); };