Rename group fns and add upgrade plan modal to project level groups tab

This commit is contained in:
Tuan Dang
2024-03-28 20:54:25 -07:00
parent f2e5f1bb10
commit 38adc83f2b
11 changed files with 55 additions and 48 deletions
+6 -12
View File
@@ -18,11 +18,11 @@ import { OrgPermissionActions, OrgPermissionSubjects } from "../permission/org-p
import { TPermissionServiceFactory } from "../permission/permission-service"; import { TPermissionServiceFactory } from "../permission/permission-service";
import { TGroupDALFactory } from "./group-dal"; import { TGroupDALFactory } from "./group-dal";
import { import {
TAddUserToGroupDTO,
TCreateGroupDTO, TCreateGroupDTO,
TCreateGroupUserMembershipDTO,
TDeleteGroupDTO, TDeleteGroupDTO,
TDeleteGroupUserMembershipDTO, TListGroupUsersDTO,
TGetGroupUserMembershipsDTO, TRemoveUserFromGroupDTO,
TUpdateGroupDTO TUpdateGroupDTO
} from "./group-types"; } from "./group-types";
import { TUserGroupMembershipDALFactory } from "./user-group-membership-dal"; import { TUserGroupMembershipDALFactory } from "./user-group-membership-dal";
@@ -185,13 +185,7 @@ export const groupServiceFactory = ({
return group; return group;
}; };
const listGroupUsers = async ({ const listGroupUsers = async ({ groupSlug, actor, actorId, actorAuthMethod, actorOrgId }: TListGroupUsersDTO) => {
groupSlug,
actor,
actorId,
actorAuthMethod,
actorOrgId
}: TGetGroupUserMembershipsDTO) => {
if (!actorOrgId) throw new BadRequestError({ message: "Failed to create group without organization" }); if (!actorOrgId) throw new BadRequestError({ message: "Failed to create group without organization" });
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
@@ -224,7 +218,7 @@ export const groupServiceFactory = ({
actorId, actorId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TCreateGroupUserMembershipDTO) => { }: TAddUserToGroupDTO) => {
if (!actorOrgId) throw new BadRequestError({ message: "Failed to create group without organization" }); if (!actorOrgId) throw new BadRequestError({ message: "Failed to create group without organization" });
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
@@ -368,7 +362,7 @@ export const groupServiceFactory = ({
actorId, actorId,
actorAuthMethod, actorAuthMethod,
actorOrgId actorOrgId
}: TDeleteGroupUserMembershipDTO) => { }: TRemoveUserFromGroupDTO) => {
if (!actorOrgId) throw new BadRequestError({ message: "Failed to create group without organization" }); if (!actorOrgId) throw new BadRequestError({ message: "Failed to create group without organization" });
const { permission } = await permissionService.getOrgPermission( const { permission } = await permissionService.getOrgPermission(
+3 -3
View File
@@ -19,16 +19,16 @@ export type TDeleteGroupDTO = {
groupSlug: string; groupSlug: string;
} & TGenericPermission; } & TGenericPermission;
export type TGetGroupUserMembershipsDTO = { export type TListGroupUsersDTO = {
groupSlug: string; groupSlug: string;
} & TGenericPermission; } & TGenericPermission;
export type TCreateGroupUserMembershipDTO = { export type TAddUserToGroupDTO = {
groupSlug: string; groupSlug: string;
username: string; username: string;
} & TGenericPermission; } & TGenericPermission;
export type TDeleteGroupUserMembershipDTO = { export type TRemoveUserFromGroupDTO = {
groupSlug: string; groupSlug: string;
username: string; username: string;
} & TGenericPermission; } & TGenericPermission;
+3 -3
View File
@@ -1,9 +1,9 @@
export { export {
useAddUserToGroup,
useCreateGroup, useCreateGroup,
useCreateGroupUserMembership,
useDeleteGroup, useDeleteGroup,
useDeleteGroupUserMembership, useRemoveUserFromGroup,
useUpdateGroup} from "./mutations"; useUpdateGroup} from "./mutations";
export { export {
useGetGroupUserMemberships useListGroupUsers
} from "./queries"; } from "./queries";
+2 -2
View File
@@ -85,7 +85,7 @@ export const useDeleteGroup = () => {
}); });
}; };
export const useCreateGroupUserMembership = () => { export const useAddUserToGroup = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn: async ({ mutationFn: async ({
@@ -107,7 +107,7 @@ export const useCreateGroupUserMembership = () => {
}); });
}; };
export const useDeleteGroupUserMembership = () => { export const useRemoveUserFromGroup = () => {
const queryClient = useQueryClient(); const queryClient = useQueryClient();
return useMutation({ return useMutation({
mutationFn: async ({ mutationFn: async ({
+1 -1
View File
@@ -15,7 +15,7 @@ type TUser = {
isPartOfGroup: boolean; isPartOfGroup: boolean;
} }
export const useGetGroupUserMemberships = (groupSlug: string) => { export const useListGroupUsers = (groupSlug: string) => {
return useQuery({ return useQuery({
queryKey: groupKeys.getGroupUserMembership(groupSlug), queryKey: groupKeys.getGroupUserMembership(groupSlug),
queryFn: async () => { queryFn: async () => {
+1 -1
View File
@@ -13,12 +13,12 @@ export {
useGetUserWorkspaces, useGetUserWorkspaces,
useGetWorkspaceAuthorizations, useGetWorkspaceAuthorizations,
useGetWorkspaceById, useGetWorkspaceById,
useGetWorkspaceGroupMemberships,
useGetWorkspaceIdentityMemberships, useGetWorkspaceIdentityMemberships,
useGetWorkspaceIndexStatus, useGetWorkspaceIndexStatus,
useGetWorkspaceIntegrations, useGetWorkspaceIntegrations,
useGetWorkspaceSecrets, useGetWorkspaceSecrets,
useGetWorkspaceUsers, useGetWorkspaceUsers,
useListWorkspaceGroups,
useNameWorkspaceSecrets, useNameWorkspaceSecrets,
useRenameWorkspace, useRenameWorkspace,
useToggleAutoCapitalization, useToggleAutoCapitalization,
+1 -1
View File
@@ -526,7 +526,7 @@ export const useDeleteGroupFromWorkspace = () => {
}); });
}; };
export const useGetWorkspaceGroupMemberships = (projectSlug: string) => { export const useListWorkspaceGroups = (projectSlug: string) => {
return useQuery({ return useQuery({
queryKey: workspaceKeys.getWorkspaceGroupMemberships(projectSlug), queryKey: workspaceKeys.getWorkspaceGroupMemberships(projectSlug),
queryFn: async () => { queryFn: async () => {
@@ -24,9 +24,9 @@ import {
OrgPermissionSubjects OrgPermissionSubjects
} from "@app/context"; } from "@app/context";
import { import {
useCreateGroupUserMembership, useAddUserToGroup,
useDeleteGroupUserMembership, useListGroupUsers,
useGetGroupUserMemberships} from "@app/hooks/api"; useRemoveUserFromGroup} from "@app/hooks/api";
import { UsePopUpState } from "@app/hooks/usePopUp"; import { UsePopUpState } from "@app/hooks/usePopUp";
type Props = { type Props = {
@@ -44,9 +44,9 @@ export const OrgGroupMembersModal = ({
slug: string; slug: string;
}; };
const { data: users, isLoading } = useGetGroupUserMemberships(popUpData?.slug ?? ""); const { data: users, isLoading } = useListGroupUsers(popUpData?.slug ?? "");
const { mutateAsync: assignMutateAsync } = useCreateGroupUserMembership(); const { mutateAsync: assignMutateAsync } = useAddUserToGroup();
const { mutateAsync: unassignMutateAsync } = useDeleteGroupUserMembership(); const { mutateAsync: unassignMutateAsync } = useRemoveUserFromGroup();
const handleAssignment = async (username: string, assign: boolean) => { const handleAssignment = async (username: string, assign: boolean) => {
try { try {
@@ -1,8 +1,8 @@
import { useMemo } from "react"; import { useMemo } from "react";
import { Controller, useForm } from "react-hook-form"; import { Controller, useForm } from "react-hook-form";
import Link from "next/link"; import Link from "next/link";
import { yupResolver } from "@hookform/resolvers/yup"; import { zodResolver } from "@hookform/resolvers/zod";
import * as yup from "yup"; import { z } from "zod";
import { createNotification } from "@app/components/notifications"; import { createNotification } from "@app/components/notifications";
import { import {
@@ -17,20 +17,16 @@ import {
useAddGroupToWorkspace, useAddGroupToWorkspace,
useGetOrganizationGroups, useGetOrganizationGroups,
useGetProjectRoles, useGetProjectRoles,
useGetWorkspaceGroupMemberships, useListWorkspaceGroups,
} from "@app/hooks/api"; } from "@app/hooks/api";
import { UsePopUpState } from "@app/hooks/usePopUp"; import { UsePopUpState } from "@app/hooks/usePopUp";
// TODO: change this to zod const schema = z.object({
slug: z.string(),
role: z.string()
});
const schema = yup export type FormData = z.infer<typeof schema>;
.object({
slug: yup.string().required("Group slug is required"),
role: yup.string()
})
.required();
export type FormData = yup.InferType<typeof schema>;
type Props = { type Props = {
popUp: UsePopUpState<["group"]>; popUp: UsePopUpState<["group"]>;
@@ -48,7 +44,7 @@ export const GroupModal = ({
const workspaceId = currentWorkspace?.id || ""; const workspaceId = currentWorkspace?.id || "";
const { data: groups } = useGetOrganizationGroups(orgId); const { data: groups } = useGetOrganizationGroups(orgId);
const { data: groupMemberships } = useGetWorkspaceGroupMemberships(currentWorkspace?.slug || ""); const { data: groupMemberships } = useListWorkspaceGroups(currentWorkspace?.slug || "");
const { data: roles } = useGetProjectRoles(workspaceId); const { data: roles } = useGetProjectRoles(workspaceId);
@@ -70,7 +66,7 @@ export const GroupModal = ({
reset, reset,
formState: { isSubmitting } formState: { isSubmitting }
} = useForm<FormData>({ } = useForm<FormData>({
resolver: yupResolver(schema) resolver: zodResolver(schema)
}); });
const onFormSubmit = async ({ slug, role }: FormData) => { const onFormSubmit = async ({ slug, role }: FormData) => {
@@ -5,9 +5,10 @@ import { createNotification } from "@app/components/notifications";
import { ProjectPermissionCan } from "@app/components/permissions"; import { ProjectPermissionCan } from "@app/components/permissions";
import { import {
Button, Button,
DeleteActionModal DeleteActionModal,
UpgradePlanModal
} from "@app/components/v2"; } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub,useWorkspace } from "@app/context"; import { ProjectPermissionActions, ProjectPermissionSub, useSubscription,useWorkspace } from "@app/context";
import { usePopUp } from "@app/hooks"; import { usePopUp } from "@app/hooks";
import { useDeleteGroupFromWorkspace } from "@app/hooks/api"; import { useDeleteGroupFromWorkspace } from "@app/hooks/api";
@@ -15,6 +16,7 @@ import { GroupModal } from "./GroupModal";
import { GroupTable } from "./GroupsTable"; import { GroupTable } from "./GroupsTable";
export const GroupsSection = () => { export const GroupsSection = () => {
const { subscription } = useSubscription();
const { currentWorkspace } = useWorkspace(); const { currentWorkspace } = useWorkspace();
const { mutateAsync: deleteMutateAsync } = useDeleteGroupFromWorkspace(); const { mutateAsync: deleteMutateAsync } = useDeleteGroupFromWorkspace();
@@ -25,6 +27,16 @@ export const GroupsSection = () => {
"upgradePlan" "upgradePlan"
] as const); ] as const);
const handleAddGroupModal = () => {
if (!subscription?.groups) {
handlePopUpOpen("upgradePlan", {
description: "You can manage users more efficiently with groups if you upgrade your Infisical plan."
});
} else {
handlePopUpOpen("group");
}
}
const onRemoveGroupSubmit = async (groupSlug: string) => { const onRemoveGroupSubmit = async (groupSlug: string) => {
try { try {
await deleteMutateAsync({ await deleteMutateAsync({
@@ -60,7 +72,7 @@ export const GroupsSection = () => {
colorSchema="primary" colorSchema="primary"
type="submit" type="submit"
leftIcon={<FontAwesomeIcon icon={faPlus} />} leftIcon={<FontAwesomeIcon icon={faPlus} />}
onClick={() => handlePopUpOpen("group")} onClick={() => handleAddGroupModal()}
isDisabled={!isAllowed} isDisabled={!isAllowed}
> >
Add Group Add Group
@@ -83,6 +95,11 @@ export const GroupsSection = () => {
) )
} }
/> />
<UpgradePlanModal
isOpen={popUp.upgradePlan.isOpen}
onOpenChange={(isOpen) => handlePopUpToggle("upgradePlan", isOpen)}
text={(popUp.upgradePlan?.data as { description: string })?.description}
/>
</div> </div>
); );
} }
@@ -16,7 +16,7 @@ import {
Tr Tr
} from "@app/components/v2"; } from "@app/components/v2";
import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context"; import { ProjectPermissionActions, ProjectPermissionSub, useWorkspace } from "@app/context";
import { useGetWorkspaceGroupMemberships } from "@app/hooks/api"; import { useListWorkspaceGroups } from "@app/hooks/api";
import { UsePopUpState } from "@app/hooks/usePopUp"; import { UsePopUpState } from "@app/hooks/usePopUp";
import { GroupRoles } from "./GroupRoles"; import { GroupRoles } from "./GroupRoles";
@@ -33,7 +33,7 @@ type Props = {
export const GroupTable = ({ handlePopUpOpen }: Props) => { export const GroupTable = ({ handlePopUpOpen }: Props) => {
const { currentWorkspace } = useWorkspace(); const { currentWorkspace } = useWorkspace();
const { data, isLoading } = useGetWorkspaceGroupMemberships(currentWorkspace?.slug || ""); const { data, isLoading } = useListWorkspaceGroups(currentWorkspace?.slug || "");
return ( return (
<TableContainer> <TableContainer>
<Table> <Table>