From abbeb67b95d1e91290fdf6affeff7eb04c1b5196 Mon Sep 17 00:00:00 2001 From: Akhil Mohan Date: Thu, 2 Nov 2023 14:39:13 +0530 Subject: [PATCH] fix: resolved error in org settings and integrations page alert hidden on no integrations --- .../src/ee/controllers/v1/roleController.ts | 12 +- .../permissions/OrgPermissionCan.tsx | 2 +- .../OrgPermissionContext.tsx | 6 +- .../src/hoc/withPermission/withPermission.tsx | 2 +- frontend/src/hooks/api/roles/queries.tsx | 18 ++- .../IntegrationsSection.tsx | 7 +- .../OrgDeleteSection/OrgDeleteSection.tsx | 127 ++++++++---------- .../OrgGeneralTab/OrgGeneralTab.tsx | 13 +- .../OrgIncidentContactsSection.tsx | 2 +- 9 files changed, 91 insertions(+), 98 deletions(-) diff --git a/backend/src/ee/controllers/v1/roleController.ts b/backend/src/ee/controllers/v1/roleController.ts index d80ef281..edc31273 100644 --- a/backend/src/ee/controllers/v1/roleController.ts +++ b/backend/src/ee/controllers/v1/roleController.ts @@ -212,12 +212,13 @@ export const getUserPermissions = async (req: Request, res: Response) => { const { params: { orgId } } = await validateRequest(GetUserPermission, req); - - const { permission } = await getUserOrgPermissions(req.user._id, orgId); + + const { permission, membership } = await getUserOrgPermissions(req.user._id, orgId); res.status(200).json({ data: { - permissions: packRules(permission.rules) + permissions: packRules(permission.rules), + membership } }); }; @@ -226,11 +227,12 @@ export const getUserWorkspacePermissions = async (req: Request, res: Response) = const { params: { workspaceId } } = await validateRequest(GetUserProjectPermission, req); - const { permission } = await getUserProjectPermissions(req.user._id, workspaceId); + const { permission, membership } = await getUserProjectPermissions(req.user._id, workspaceId); res.status(200).json({ data: { - permissions: packRules(permission.rules) + permissions: packRules(permission.rules), + membership } }); }; diff --git a/frontend/src/components/permissions/OrgPermissionCan.tsx b/frontend/src/components/permissions/OrgPermissionCan.tsx index 4366110a..006d4323 100644 --- a/frontend/src/components/permissions/OrgPermissionCan.tsx +++ b/frontend/src/components/permissions/OrgPermissionCan.tsx @@ -21,7 +21,7 @@ export const OrgPermissionCan: FunctionComponent = ({ allowedLabel, ...props }) => { - const permission = useOrgPermission(); + const { permission } = useOrgPermission(); return ( diff --git a/frontend/src/context/OrgPermissionContext/OrgPermissionContext.tsx b/frontend/src/context/OrgPermissionContext/OrgPermissionContext.tsx index 5320ece6..312ae043 100644 --- a/frontend/src/context/OrgPermissionContext/OrgPermissionContext.tsx +++ b/frontend/src/context/OrgPermissionContext/OrgPermissionContext.tsx @@ -1,6 +1,7 @@ import { createContext, ReactNode, useContext } from "react"; import { useGetUserOrgPermissions } from "@app/hooks/api"; +import { OrgUser } from "@app/hooks/api/types"; import { useOrganization } from "../OrganizationContext"; import { TOrgPermission } from "./types"; @@ -9,7 +10,10 @@ type Props = { children: ReactNode; }; -const OrgPermissionContext = createContext(null); +const OrgPermissionContext = createContext(null); export const OrgPermissionProvider = ({ children }: Props): JSX.Element => { const { currentOrg } = useOrganization(); diff --git a/frontend/src/hoc/withPermission/withPermission.tsx b/frontend/src/hoc/withPermission/withPermission.tsx index e0c402af..389d8509 100644 --- a/frontend/src/hoc/withPermission/withPermission.tsx +++ b/frontend/src/hoc/withPermission/withPermission.tsx @@ -21,7 +21,7 @@ export const withPermission = ( { action, subject, className, containerClassName }: Props["abilities"]> ) => { const HOC = (hocProps: T) => { - const permission = useOrgPermission(); + const { permission } = useOrgPermission(); // akhilmhdh: Set as any due to casl/react ts type bug // REASON: casl due to its type checking can't seem to union even if union intersection is applied diff --git a/frontend/src/hooks/api/roles/queries.tsx b/frontend/src/hooks/api/roles/queries.tsx index 3e68aa57..5694ccfd 100644 --- a/frontend/src/hooks/api/roles/queries.tsx +++ b/frontend/src/hooks/api/roles/queries.tsx @@ -8,6 +8,7 @@ import { apiRequest } from "@app/config/request"; import { OrgPermissionSet } from "@app/context/OrgPermissionContext/types"; import { ProjectPermissionSet } from "@app/context/ProjectPermissionContext/types"; +import { OrgUser } from "../users/types"; import { TGetRolesDTO, TGetUserOrgPermissionsDTO, @@ -63,13 +64,16 @@ export const useGetRoles = ({ orgId, workspaceId }: TGetRolesDTO) => }); const getUserOrgPermissions = async ({ orgId }: TGetUserOrgPermissionsDTO) => { - if (orgId === "") return []; + if (orgId === "") return { permissions: [], membership: null }; const { data } = await apiRequest.get<{ - data: { permissions: PackRule>>[] }; - }>(`/api/v1/roles/organization/${orgId}/permissions`, {}); - - return data.data.permissions; + data: { + permissions: PackRule>>[]; + membership: OrgUser; + }; + }>(`/api/v1/roles/organization/${orgId}/permissions`); + + return data.data; }; export const useGetUserOrgPermissions = ({ orgId }: TGetUserOrgPermissionsDTO) => @@ -78,9 +82,9 @@ export const useGetUserOrgPermissions = ({ orgId }: TGetUserOrgPermissionsDTO) = queryFn: () => getUserOrgPermissions({ orgId }), // enabled: Boolean(orgId), select: (data) => { - const rule = unpackRules>>(data); + const rule = unpackRules>>(data.permissions); const ability = createMongoAbility(rule, { conditionsMatcher }); - return ability; + return { permission: ability, membership: data.membership }; } }); diff --git a/frontend/src/views/IntegrationsPage/components/IntegrationsSection/IntegrationsSection.tsx b/frontend/src/views/IntegrationsPage/components/IntegrationsSection/IntegrationsSection.tsx index 9e23e790..7a15c072 100644 --- a/frontend/src/views/IntegrationsPage/components/IntegrationsSection/IntegrationsSection.tsx +++ b/frontend/src/views/IntegrationsPage/components/IntegrationsSection/IntegrationsSection.tsx @@ -54,7 +54,7 @@ export const IntegrationsSection = ({ )} - {!isBotActive && ( + {!isBotActive && Boolean(integrations.length) && (
@@ -119,7 +119,7 @@ export const IntegrationsSection = ({ {integrationSlugNameMapping[integration.integration]}
- {(integration.integration === "qovery") && ( + {integration.integration === "qovery" && (
@@ -162,7 +162,8 @@ export const IntegrationsSection = ({
)} - {((integration.integration === "checkly") || (integration.integration === "github")) && ( + {(integration.integration === "checkly" || + integration.integration === "github") && (
diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgDeleteSection/OrgDeleteSection.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgDeleteSection/OrgDeleteSection.tsx index dd810f1a..a336355d 100644 --- a/frontend/src/views/Settings/OrgSettingsPage/components/OrgDeleteSection/OrgDeleteSection.tsx +++ b/frontend/src/views/Settings/OrgSettingsPage/components/OrgDeleteSection/OrgDeleteSection.tsx @@ -1,81 +1,70 @@ import { useRouter } from "next/router"; import { useNotificationContext } from "@app/components/context/Notifications/NotificationProvider"; -import { - Button, - DeleteActionModal -} from "@app/components/v2"; -import { useOrganization, useUser } from "@app/context"; -import { - useDeleteOrgById, - useGetOrgUsers -} from "@app/hooks/api"; +import { Button, DeleteActionModal } from "@app/components/v2"; +import { useOrganization, useOrgPermission } from "@app/context"; +import { useDeleteOrgById } from "@app/hooks/api"; import { usePopUp } from "@app/hooks/usePopUp"; import { navigateUserToOrg } from "@app/views/Login/Login.utils"; export const OrgDeleteSection = () => { - const router = useRouter(); - const { currentOrg } = useOrganization(); - const { user } = useUser(); - const { createNotification } = useNotificationContext(); - const { data: members } = useGetOrgUsers(currentOrg?._id ?? ""); - - const membershipOrg = members?.find((member) => member.user._id === user._id); + const router = useRouter(); + const { currentOrg } = useOrganization(); + const { createNotification } = useNotificationContext(); + const { membership } = useOrgPermission(); - const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([ - "deleteOrg" - ] as const); + const { popUp, handlePopUpOpen, handlePopUpClose, handlePopUpToggle } = usePopUp([ + "deleteOrg" + ] as const); - const { mutateAsync, isLoading } = useDeleteOrgById(); - - const handleDeleteOrgSubmit = async () => { - try { - if (!currentOrg?._id) return; - - await mutateAsync({ - organizationId: currentOrg?._id - }); - - createNotification({ - text: "Successfully deleted organization", - type: "success" - }); + const { mutateAsync, isLoading } = useDeleteOrgById(); - await navigateUserToOrg(router); - - handlePopUpClose("deleteOrg"); - } catch (err) { - console.error(err); - createNotification({ - text: "Failed to delete organization", - type: "error" - }); - } + const handleDeleteOrgSubmit = async () => { + try { + if (!currentOrg?._id) return; + + await mutateAsync({ + organizationId: currentOrg?._id + }); + + createNotification({ + text: "Successfully deleted organization", + type: "success" + }); + + await navigateUserToOrg(router); + + handlePopUpClose("deleteOrg"); + } catch (err) { + console.error(err); + createNotification({ + text: "Failed to delete organization", + type: "error" + }); } + }; - return ( -
-

- Danger Zone -

- - handlePopUpToggle("deleteOrg", isOpen)} - deleteKey="confirm" - onDeleteApproved={handleDeleteOrgSubmit} - /> -
- ); -} \ No newline at end of file + return ( +
+

Danger Zone

+ + handlePopUpToggle("deleteOrg", isOpen)} + deleteKey="confirm" + onDeleteApproved={handleDeleteOrgSubmit} + /> +
+ ); +}; diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgGeneralTab/OrgGeneralTab.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgGeneralTab/OrgGeneralTab.tsx index d8e48966..9c8279ca 100644 --- a/frontend/src/views/Settings/OrgSettingsPage/components/OrgGeneralTab/OrgGeneralTab.tsx +++ b/frontend/src/views/Settings/OrgSettingsPage/components/OrgGeneralTab/OrgGeneralTab.tsx @@ -1,24 +1,17 @@ -import { useOrganization, useUser } from "@app/context"; -import { useGetOrgUsers } from "@app/hooks/api"; +import { useOrgPermission } from "@app/context"; import { OrgDeleteSection } from "../OrgDeleteSection"; import { OrgIncidentContactsSection } from "../OrgIncidentContactsSection"; import { OrgNameChangeSection } from "../OrgNameChangeSection"; export const OrgGeneralTab = () => { - const { currentOrg } = useOrganization(); - const { user } = useUser(); - const { data: members } = useGetOrgUsers(currentOrg?._id ?? ""); - - const membershipOrg = members?.find((member) => member.user._id === user?._id); + const { membership } = useOrgPermission(); return (
- {(membershipOrg && membershipOrg.role === "admin") && ( - - )} + {membership && membership.role === "admin" && }
); }; diff --git a/frontend/src/views/Settings/OrgSettingsPage/components/OrgIncidentContactsSection/OrgIncidentContactsSection.tsx b/frontend/src/views/Settings/OrgSettingsPage/components/OrgIncidentContactsSection/OrgIncidentContactsSection.tsx index bc254752..fbb4987a 100644 --- a/frontend/src/views/Settings/OrgSettingsPage/components/OrgIncidentContactsSection/OrgIncidentContactsSection.tsx +++ b/frontend/src/views/Settings/OrgSettingsPage/components/OrgIncidentContactsSection/OrgIncidentContactsSection.tsx @@ -15,7 +15,7 @@ export const OrgIncidentContactsSection = () => { const { handlePopUpToggle, popUp, handlePopUpOpen, handlePopUpClose } = usePopUp([ "addContact" ] as const); - const permission = useOrgPermission(); + const { permission } = useOrgPermission(); return (