From 0238a8adc8a094e8d7d3496aa3e10fa4865e2136 Mon Sep 17 00:00:00 2001 From: Rudraprasad Das Date: Wed, 8 Nov 2023 15:26:45 +0530 Subject: [PATCH] fix: adding git admin permissions (#28719) ## Description - Derives isGitAdmin from workspace permissions - Disables connect to git if not git admin - Disables disconnect, default branch and branch protection if not git admin #### PR fixes following issue(s) Fixes #28020 #### Media image #### Type of change - New feature (non-breaking change which adds functionality) ## Testing > #### How Has This Been Tested? > Please describe the tests that you ran to verify your changes. Also list any relevant details for your test configuration. > Delete anything that is not relevant - [x] Manual - [ ] JUnit - [ ] Jest - [ ] Cypress > > #### Test Plan > Add Testsmith test cases links that relate to this PR > > #### Issues raised during DP testing > Link issues raised during DP testing for better visiblity and tracking (copy link from comments dropped on this PR) > > > ## Checklist: #### Dev activity - [ ] My code follows the style guidelines of this project - [ ] I have performed a self-review of my own code - [ ] I have commented my code, particularly in hard-to-understand areas - [ ] I have made corresponding changes to the documentation - [ ] My changes generate no new warnings - [ ] I have added tests that prove my fix is effective or that my feature works - [ ] New and existing unit tests pass locally with my changes - [ ] PR is being merged under a feature flag #### QA activity: - [ ] [Speedbreak features](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#speedbreakers-) have been covered - [ ] Test plan covers all impacted features and [areas of interest](https://github.com/appsmithorg/TestSmith/wiki/Guidelines-for-test-plans#areas-of-interest-) - [ ] Test plan has been peer reviewed by project stakeholders and other QA members - [ ] Manually tested functionality on DP - [ ] We had an implementation alignment call with stakeholders post QA Round 2 - [ ] Cypress test cases have been added and approved by SDET/manual QA - [ ] Added `Test Plan Approved` label after Cypress tests were reviewed - [ ] Added `Test Plan Approved` label after JUnit tests were reviewed --- app/client/src/ce/constants/messages.ts | 2 + .../appsmith/header/DeployLinkButton.tsx | 4 +- .../Editor/gitSync/QuickGitActions/index.tsx | 43 +++++++++++++------ .../Tabs/GitSettings/GitDisconnect.tsx | 7 ++- .../gitSync/Tabs/GitSettings/index.test.tsx | 19 ++++++++ .../Editor/gitSync/Tabs/GitSettings/index.tsx | 7 ++- .../Editor/gitSync/hooks/useIsGitAdmin.ts | 15 +++++++ 7 files changed, 80 insertions(+), 17 deletions(-) create mode 100644 app/client/src/pages/Editor/gitSync/Tabs/GitSettings/index.test.tsx create mode 100644 app/client/src/pages/Editor/gitSync/hooks/useIsGitAdmin.ts diff --git a/app/client/src/ce/constants/messages.ts b/app/client/src/ce/constants/messages.ts index 9e607a573a..834c749f47 100644 --- a/app/client/src/ce/constants/messages.ts +++ b/app/client/src/ce/constants/messages.ts @@ -1088,6 +1088,8 @@ export const NOW_PROTECT_BRANCH = () => export const APPSMITH_ENTERPRISE = () => "Appsmith Enterprise"; export const PROTECT_BRANCH_SUCCESS = () => "Changed protected branches"; export const UPDATE_DEFAULT_BRANCH_SUCCESS = () => "Updated default branch"; +export const CONTACT_ADMIN_FOR_GIT = () => + "Please contact your workspace admin to connect your app to a git repo"; // Git Branch Protection end export const NAV_DESCRIPTION = () => diff --git a/app/client/src/components/designSystems/appsmith/header/DeployLinkButton.tsx b/app/client/src/components/designSystems/appsmith/header/DeployLinkButton.tsx index 8853985a15..93ca6edc78 100644 --- a/app/client/src/components/designSystems/appsmith/header/DeployLinkButton.tsx +++ b/app/client/src/components/designSystems/appsmith/header/DeployLinkButton.tsx @@ -12,6 +12,7 @@ import { } from "@appsmith/constants/messages"; import { Button } from "design-system"; import { KBEditorMenuItem } from "@appsmith/pages/Editor/KnowledgeBase/KBEditorMenuItem"; +import { useIsGitAdmin } from "pages/Editor/gitSync/hooks/useIsGitAdmin"; interface Props { trigger: ReactNode; @@ -21,6 +22,7 @@ interface Props { export const DeployLinkButton = (props: Props) => { const dispatch = useDispatch(); const isGitConnected = useSelector(getIsGitConnected); + const isGitAdmin = useIsGitAdmin(); const goToGitConnectionPopup = () => { AnalyticsUtil.logEvent("GS_CONNECT_GIT_CLICK", { @@ -46,7 +48,7 @@ export const DeployLinkButton = (props: Props) => { /> - {!isGitConnected && ( + {!isGitConnected && isGitAdmin && ( -
{createMessage(NOT_LIVE_FOR_YOU_YET)}
-
{createMessage(COMING_SOON)}
- - ) : ( - <> -
{createMessage(CONNECTING_TO_REPO_DISABLED)}
-
{createMessage(DURING_ONBOARDING_TOUR)}
- - ); + const isGitAdmin = useIsGitAdmin(); + const isTooltipEnabled = isInGuidedTour || !isGitAdmin; + const tooltipContent = useMemo(() => { + if (!isGitAdmin) { + return {createMessage(CONTACT_ADMIN_FOR_GIT)}; + } + if (isInGuidedTour) { + return ( + <> +
{createMessage(CONNECTING_TO_REPO_DISABLED)}
+
{createMessage(DURING_ONBOARDING_TOUR)}
+ + ); + } + return ( + <> +
{createMessage(NOT_LIVE_FOR_YOU_YET)}
+
{createMessage(COMING_SOON)}
+ + ); + }, [isInGuidedTour, isGitAdmin]); + const isGitConnectionEnabled = !isInGuidedTour; return ( @@ -265,6 +281,7 @@ function ConnectGitPlaceholder() { {isGitConnectionEnabled ? ( diff --git a/app/client/src/pages/Editor/gitSync/Tabs/GitSettings/index.test.tsx b/app/client/src/pages/Editor/gitSync/Tabs/GitSettings/index.test.tsx new file mode 100644 index 0000000000..97cfecd713 --- /dev/null +++ b/app/client/src/pages/Editor/gitSync/Tabs/GitSettings/index.test.tsx @@ -0,0 +1,19 @@ +/* eslint-disable jest/no-focused-tests */ +import React from "react"; +import { render, screen } from "test/testUtils"; +import GitSettings from "."; +import type { AppState } from "@appsmith/reducers"; + +jest.mock("../../hooks/useIsGitAdmin", () => ({ + useIsGitAdmin: () => false, +})); + +describe("GitSettings test for git admin disabled", () => { + it("Branch protection, default branch and disconnect disabled when not ", () => { + const initialState: Partial = {}; + render(, { initialState }); + expect(screen.queryByTestId("t--git-protected-branches-select")).toBe(null); + expect(screen.queryByTestId("t--git-default-branch-select")).toBe(null); + expect(screen.queryByTestId("t--git-disconnect-btn")).toBe(null); + }); +}); diff --git a/app/client/src/pages/Editor/gitSync/Tabs/GitSettings/index.tsx b/app/client/src/pages/Editor/gitSync/Tabs/GitSettings/index.tsx index ce72c2db9f..48f7eaf01d 100644 --- a/app/client/src/pages/Editor/gitSync/Tabs/GitSettings/index.tsx +++ b/app/client/src/pages/Editor/gitSync/Tabs/GitSettings/index.tsx @@ -7,6 +7,7 @@ import GitDefaultBranch from "./GitDefaultBranch"; import GitProtectedBranches from "./GitProtectedBranches"; import { useSelector } from "react-redux"; import { getIsGitProtectedFeatureEnabled } from "selectors/gitSyncSelectors"; +import { useIsGitAdmin } from "../../hooks/useIsGitAdmin"; const Container = styled.div` overflow: auto; @@ -23,18 +24,20 @@ function GitSettings() { const isGitProtectedFeatureEnabled = useSelector( getIsGitProtectedFeatureEnabled, ); + const isGitAdmin = useIsGitAdmin(); + return ( - {isGitProtectedFeatureEnabled ? ( + {isGitProtectedFeatureEnabled && isGitAdmin ? ( <> ) : null} - + {isGitAdmin && } ); diff --git a/app/client/src/pages/Editor/gitSync/hooks/useIsGitAdmin.ts b/app/client/src/pages/Editor/gitSync/hooks/useIsGitAdmin.ts new file mode 100644 index 0000000000..b78282426a --- /dev/null +++ b/app/client/src/pages/Editor/gitSync/hooks/useIsGitAdmin.ts @@ -0,0 +1,15 @@ +import { FEATURE_FLAG } from "@appsmith/entities/FeatureFlag"; +import { getTenantPermissions } from "@appsmith/selectors/tenantSelectors"; +import { getHasCreateWorkspacePermission } from "@appsmith/utils/BusinessFeatures/permissionPageHelpers"; +import { useSelector } from "react-redux"; +import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; + +export const useIsGitAdmin = () => { + const isFeatureEnabled = useFeatureFlag(FEATURE_FLAG.license_gac_enabled); + const tenantPermissions = useSelector(getTenantPermissions); + const canCreateWorkspace = getHasCreateWorkspacePermission( + isFeatureEnabled, + tenantPermissions, + ); + return canCreateWorkspace; +};