feat: battle of ts - unlimited edition

This commit is contained in:
=
2025-10-10 00:09:46 +05:30
parent fd98465dec
commit 44c9575a3d
38 changed files with 492 additions and 498 deletions
@@ -7,6 +7,7 @@ import { createNotification } from "@app/components/notifications";
import { Button, Checkbox, Modal, ModalContent, Tooltip } from "@app/components/v2";
import { useOrgPermission } from "@app/context";
import { useUpgradePrivilegeSystem } from "@app/hooks/api";
import { OrgMembershipRole } from "@app/helpers/roles";
const formSchema = z.object({
isProjectPrivilegesUpdated: z.literal(true),
@@ -21,7 +22,7 @@ type Props = {
};
export const UpgradePrivilegeSystemModal = ({ isOpen, onOpenChange }: Props) => {
const { membership } = useOrgPermission();
const { hasOrgRole } = useOrgPermission();
const [step, setStep] = useState<"info" | "upgrade">("info");
const {
@@ -65,7 +66,7 @@ export const UpgradePrivilegeSystemModal = ({ isOpen, onOpenChange }: Props) =>
setStep("info");
};
const isAdmin = membership?.role === "admin";
const isAdmin = hasOrgRole(OrgMembershipRole.Admin);
return (
<Modal isOpen={isOpen} onOpenChange={handleClose}>
@@ -274,7 +275,7 @@ export const UpgradePrivilegeSystemModal = ({ isOpen, onOpenChange }: Props) =>
<Tooltip
content={
!isAdmin
? `You cannot perform this upgrade because you are not an organization admin. (Your current role: ${membership?.role ?? "Unknown"})`
? `You cannot perform this upgrade because you are not an organization admin.`
: undefined
}
>
@@ -4,12 +4,12 @@ import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { Button } from "@app/components/v2";
import { useOrgPermission } from "@app/context";
import { usePopUp } from "@app/hooks";
import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
import { SelectImportFromPlatformModal } from "./components/SelectImportFromPlatformModal";
import { OrgMembershipRole } from "@app/helpers/roles";
export const ExternalMigrationsTab = () => {
const { membership } = useOrgPermission();
const { hasOrgRole } = useOrgPermission();
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["selectImportPlatform"] as const);
@@ -41,7 +41,7 @@ export const ExternalMigrationsTab = () => {
onClick={() => {
handlePopUpOpen("selectImportPlatform");
}}
isDisabled={membership?.role !== ProjectMembershipRole.Admin}
isDisabled={hasOrgRole(OrgMembershipRole.Admin)}
leftIcon={<FontAwesomeIcon icon={faPlus} />}
>
Import
@@ -6,12 +6,13 @@ import { useOrganization, useOrgPermission } from "@app/context";
import { useDeleteOrgById } from "@app/hooks/api";
import { clearSession } from "@app/hooks/api/users/queries";
import { usePopUp } from "@app/hooks/usePopUp";
import { OrgMembershipRole } from "@app/helpers/roles";
export const OrgDeleteSection = () => {
const navigate = useNavigate();
const { currentOrg } = useOrganization();
const { membership } = useOrgPermission();
const { hasOrgRole } = useOrgPermission();
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["deleteOrg"] as const);
@@ -52,7 +53,7 @@ export const OrgDeleteSection = () => {
variant="outline_bg"
type="submit"
onClick={() => handlePopUpOpen("deleteOrg")}
isDisabled={Boolean(membership && membership.role !== "admin")}
isDisabled={Boolean(!hasOrgRole(OrgMembershipRole.Admin))}
>
{`Delete ${currentOrg?.name}`}
</Button>
@@ -3,14 +3,15 @@ import { useOrgPermission } from "@app/context";
import { OrgDeleteSection } from "../OrgDeleteSection";
import { OrgIncidentContactsSection } from "../OrgIncidentContactsSection";
import { OrgNameChangeSection } from "../OrgNameChangeSection";
import { OrgMembershipRole } from "@app/helpers/roles";
export const OrgGeneralTab = () => {
const { membership } = useOrgPermission();
const { hasOrgRole } = useOrgPermission();
return (
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-6">
<OrgNameChangeSection />
<OrgIncidentContactsSection />
{membership && membership.role === "admin" && <OrgDeleteSection />}
{hasOrgRole(OrgMembershipRole.Admin) && <OrgDeleteSection />}
</div>
);
};
@@ -20,7 +20,7 @@ export const AuditLogsRetentionSection = () => {
const { mutateAsync: updateAuditLogsRetention } = useUpdateWorkspaceAuditLogsRetention();
const { currentProject } = useProject();
const { membership } = useProjectPermission();
const { hasProjectRole } = useProjectPermission();
const { subscription } = useSubscription();
const { popUp, handlePopUpOpen, handlePopUpToggle } = usePopUp(["upgradePlan"] as const);
@@ -82,7 +82,7 @@ export const AuditLogsRetentionSection = () => {
return null;
}
const isAdmin = membership.roles.includes(ProjectMembershipRole.Admin);
const isAdmin = hasProjectRole(ProjectMembershipRole.Admin);
return (
<>
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
@@ -10,7 +10,8 @@ import {
ProjectPermissionSub,
useOrganization,
useProject,
useProjectPermission
useProjectPermission,
useUser
} from "@app/context";
import { useToggle } from "@app/hooks";
import { useDeleteWorkspace, useGetWorkspaceUsers, useLeaveProject } from "@app/hooks/api";
@@ -24,8 +25,9 @@ export const DeleteProjectSection = () => {
"leaveWorkspace"
] as const);
const { user } = useUser();
const { currentOrg } = useOrganization();
const { hasProjectRole, membership } = useProjectPermission();
const { hasProjectRole } = useProjectPermission();
const { currentProject } = useProject();
const [isDeleting, setIsDeleting] = useToggle();
const [isLeaving, setIsLeaving] = useToggle();
@@ -39,14 +41,14 @@ export const DeleteProjectSection = () => {
const isNoAccessMember = hasProjectRole("no-access");
const isOnlyAdminMember = useMemo(() => {
if (!members || !membership || !hasProjectRole("admin")) return false;
if (!members || !hasProjectRole("admin")) return false;
const adminMembers = members.filter(
(member) => member.roles.map((r) => r.role).includes("admin") && member.id !== membership.id // exclude the current user
(member) => member.roles.map((r) => r.role).includes("admin") && member.user.id !== user.id // exclude the current user
);
return !adminMembers.length;
}, [members, membership]);
}, [members, user]);
const handleDeleteWorkspaceSubmit = async () => {
setIsDeleting.on();
@@ -38,7 +38,7 @@ export const SecretV2MigrationSection = () => {
currentProject?.upgradeStatus === ProjectUpgradeStatus.InProgress ? 2000 : false
}
);
const { membership } = useProjectPermission();
const { hasProjectRole } = useProjectPermission();
const migrateProjectToV3 = useMigrateProjectToV3();
const { handleSubmit, control, reset } = useForm({ resolver: zodResolver(formSchema) });
useEffect(() => {
@@ -81,7 +81,7 @@ export const SecretV2MigrationSection = () => {
}
};
const isAdmin = membership?.roles.includes(ProjectMembershipRole.Admin);
const isAdmin = hasProjectRole(ProjectMembershipRole.Admin);
return (
<div className="mt-4 flex max-w-2xl flex-col rounded-lg border border-primary/50 bg-primary/10 px-6 py-5">
{isUpgrading && (
@@ -6,7 +6,7 @@ import { ProjectMembershipRole } from "@app/hooks/api/roles/types";
export const BackfillSecretReferenceSecretion = () => {
const { currentProject } = useProject();
const { membership } = useProjectPermission();
const { hasProjectRole } = useProjectPermission();
const backfillSecretReferences = useBackfillSecretReference();
if (!currentProject) return null;
@@ -21,7 +21,7 @@ export const BackfillSecretReferenceSecretion = () => {
}
};
const isAdmin = membership.roles.includes(ProjectMembershipRole.Admin);
const isAdmin = hasProjectRole(ProjectMembershipRole.Admin);
return (
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<div className="flex w-full items-center justify-between">
@@ -18,7 +18,7 @@ export const PointInTimeVersionLimitSection = () => {
const { mutateAsync: updateProject } = useUpdateProject();
const { currentProject, projectId } = useProject();
const { membership } = useProjectPermission();
const { hasProjectRole } = useProjectPermission();
const {
control,
@@ -52,7 +52,7 @@ export const PointInTimeVersionLimitSection = () => {
}
};
const isAdmin = membership.roles.includes(ProjectMembershipRole.Admin);
const isAdmin = hasProjectRole(ProjectMembershipRole.Admin);
return (
<div className="mb-6 rounded-lg border border-mineshaft-600 bg-mineshaft-900 p-4">
<div className="flex w-full items-center justify-between">
@@ -24,7 +24,7 @@ type TForm = z.infer<typeof formSchema>;
export const SecretDetectionIgnoreValuesSection = () => {
const { currentProject } = useProject();
const { membership } = useProjectPermission();
const { hasProjectRole } = useProjectPermission();
const { mutateAsync: updateProject } = useUpdateProject();
const {
@@ -73,7 +73,7 @@ export const SecretDetectionIgnoreValuesSection = () => {
}
};
const isAdmin = membership.roles.includes(ProjectMembershipRole.Admin);
const isAdmin = hasProjectRole(ProjectMembershipRole.Admin);
if (!currentProject) return null;