From aaabb154f88ba2c8e7890c1fff18cfef916fdc9c Mon Sep 17 00:00:00 2001 From: Hetu Nandu Date: Mon, 30 Dec 2024 10:41:52 +0530 Subject: [PATCH 01/13] chore: Side by Side exits beta phase (#38347) --- .../cypress/support/Objects/Registry.ts | 35 ++++++++++++ app/client/cypress/support/commands.js | 2 + .../design-system/ads/src/Popover/Popover.tsx | 3 +- .../ads/src/Popover/Popover.types.ts | 2 + app/client/src/IDE/Components/Nudge/Nudge.tsx | 57 +++++++++++++++++++ app/client/src/IDE/Components/Nudge/index.ts | 1 + app/client/src/IDE/Components/Nudge/styles.ts | 49 ++++++++++++++++ .../EditorPane/components/Announcement.tsx | 11 ++++ .../IDE/EditorTabs/ScreenModeToggle.tsx | 49 ++++++++++++---- app/client/src/pages/Editor/IDE/hooks.ts | 28 +++++++++ app/client/src/utils/localStorage.tsx | 3 + 11 files changed, 228 insertions(+), 12 deletions(-) create mode 100644 app/client/src/IDE/Components/Nudge/Nudge.tsx create mode 100644 app/client/src/IDE/Components/Nudge/index.ts create mode 100644 app/client/src/IDE/Components/Nudge/styles.ts diff --git a/app/client/cypress/support/Objects/Registry.ts b/app/client/cypress/support/Objects/Registry.ts index ebc61b8413a8..3b43cf5c8cce 100644 --- a/app/client/cypress/support/Objects/Registry.ts +++ b/app/client/cypress/support/Objects/Registry.ts @@ -35,6 +35,7 @@ import { AnvilSnapshot } from "../Pages/Anvil/AnvilSnapshot"; export class ObjectsRegistry { private static aggregateHelper__: AggregateHelper; + static get AggregateHelper(): AggregateHelper { if (ObjectsRegistry.aggregateHelper__ === undefined) { ObjectsRegistry.aggregateHelper__ = new AggregateHelper(); @@ -43,6 +44,7 @@ export class ObjectsRegistry { } private static assertHelper__: AssertHelper; + static get AssertHelper(): AssertHelper { if (ObjectsRegistry.assertHelper__ === undefined) { ObjectsRegistry.assertHelper__ = new AssertHelper(); @@ -51,6 +53,7 @@ export class ObjectsRegistry { } private static jsEditor__: JSEditor; + static get JSEditor(): JSEditor { if (ObjectsRegistry.jsEditor__ === undefined) { ObjectsRegistry.jsEditor__ = new JSEditor(); @@ -59,6 +62,7 @@ export class ObjectsRegistry { } private static commonLocators__: CommonLocators; + static get CommonLocators(): CommonLocators { if (ObjectsRegistry.commonLocators__ === undefined) { ObjectsRegistry.commonLocators__ = new CommonLocators(); @@ -67,6 +71,7 @@ export class ObjectsRegistry { } private static entityExplorer__: EntityExplorer; + static get EntityExplorer(): EntityExplorer { if (ObjectsRegistry.entityExplorer__ === undefined) { ObjectsRegistry.entityExplorer__ = new EntityExplorer(); @@ -75,6 +80,7 @@ export class ObjectsRegistry { } private static apiPage__: ApiPage; + static get ApiPage(): ApiPage { if (ObjectsRegistry.apiPage__ === undefined) { ObjectsRegistry.apiPage__ = new ApiPage(); @@ -83,6 +89,7 @@ export class ObjectsRegistry { } private static adminSettings__: AdminSettings; + static get AdminSettings(): AdminSettings { if (ObjectsRegistry.adminSettings__ === undefined) { ObjectsRegistry.adminSettings__ = new AdminSettings(); @@ -91,6 +98,7 @@ export class ObjectsRegistry { } private static homePage__: HomePage; + static get HomePage(): HomePage { if (ObjectsRegistry.homePage__ === undefined) { ObjectsRegistry.homePage__ = new HomePage(); @@ -99,6 +107,7 @@ export class ObjectsRegistry { } private static dataSources__: DataSources; + static get DataSources(): DataSources { if (ObjectsRegistry.dataSources__ === undefined) { ObjectsRegistry.dataSources__ = new DataSources(); @@ -107,6 +116,7 @@ export class ObjectsRegistry { } private static table__: Table; + static get Table(): Table { if (ObjectsRegistry.table__ === undefined) { ObjectsRegistry.table__ = new Table(); @@ -115,6 +125,7 @@ export class ObjectsRegistry { } private static tabs__: Tabs; + static get Tabs(): Tabs { if (ObjectsRegistry.tabs__ === undefined) { ObjectsRegistry.tabs__ = new Tabs(); @@ -123,6 +134,7 @@ export class ObjectsRegistry { } private static propertyPane__: PropertyPane; + static get PropertyPane(): PropertyPane { if (ObjectsRegistry.propertyPane__ === undefined) { ObjectsRegistry.propertyPane__ = new PropertyPane(); @@ -131,6 +143,7 @@ export class ObjectsRegistry { } private static deployMode__: DeployMode; + static get DeployMode(): DeployMode { if (ObjectsRegistry.deployMode__ === undefined) { ObjectsRegistry.deployMode__ = new DeployMode(); @@ -139,6 +152,7 @@ export class ObjectsRegistry { } private static gitSync__: GitSync; + static get GitSync(): GitSync { if (ObjectsRegistry.gitSync__ === undefined) { ObjectsRegistry.gitSync__ = new GitSync(); @@ -147,6 +161,7 @@ export class ObjectsRegistry { } private static fakerHelper__: FakerHelper; + static get FakerHelper(): FakerHelper { if (ObjectsRegistry.fakerHelper__ === undefined) { ObjectsRegistry.fakerHelper__ = new FakerHelper(); @@ -155,6 +170,7 @@ export class ObjectsRegistry { } private static debuggerHelper__: DebuggerHelper; + static get DebuggerHelper(): DebuggerHelper { if (ObjectsRegistry.debuggerHelper__ === undefined) { ObjectsRegistry.debuggerHelper__ = new DebuggerHelper(); @@ -163,6 +179,7 @@ export class ObjectsRegistry { } private static appSettings__: AppSettings; + static get AppSettings(): AppSettings { if (ObjectsRegistry.appSettings__ === undefined) { ObjectsRegistry.appSettings__ = new AppSettings(); @@ -171,6 +188,7 @@ export class ObjectsRegistry { } private static generalSettings__: GeneralSettings; + static get GeneralSettings(): GeneralSettings { if (ObjectsRegistry.generalSettings__ === undefined) { ObjectsRegistry.generalSettings__ = new GeneralSettings(); @@ -179,6 +197,7 @@ export class ObjectsRegistry { } private static pageSettings__: PageSettings; + static get PageSettings(): PageSettings { if (ObjectsRegistry.pageSettings__ === undefined) { ObjectsRegistry.pageSettings__ = new PageSettings(); @@ -187,6 +206,7 @@ export class ObjectsRegistry { } private static themeSettings__: ThemeSettings; + static get ThemeSettings(): ThemeSettings { if (ObjectsRegistry.themeSettings__ === undefined) { ObjectsRegistry.themeSettings__ = new ThemeSettings(); @@ -195,6 +215,7 @@ export class ObjectsRegistry { } private static embedSettings__: EmbedSettings; + static get EmbedSettings(): EmbedSettings { if (ObjectsRegistry.embedSettings__ === undefined) { ObjectsRegistry.embedSettings__ = new EmbedSettings(); @@ -203,6 +224,7 @@ export class ObjectsRegistry { } private static LibraryInstaller__: LibraryInstaller; + static get LibraryInstaller(): LibraryInstaller { if (ObjectsRegistry.LibraryInstaller__ === undefined) { ObjectsRegistry.LibraryInstaller__ = new LibraryInstaller(); @@ -211,6 +233,7 @@ export class ObjectsRegistry { } private static peekOverlay__: PeekOverlay; + static get PeekOverlay(): PeekOverlay { if (ObjectsRegistry.peekOverlay__ === undefined) { ObjectsRegistry.peekOverlay__ = new PeekOverlay(); @@ -219,6 +242,7 @@ export class ObjectsRegistry { } private static inviteModal__: InviteModal; + static get InviteModal(): InviteModal { if (ObjectsRegistry.inviteModal__ === undefined) { ObjectsRegistry.inviteModal__ = new InviteModal(); @@ -227,6 +251,7 @@ export class ObjectsRegistry { } private static templates__: Templates; + static get Templates(): Templates { if (ObjectsRegistry.templates__ === undefined) { ObjectsRegistry.templates__ = new Templates(); @@ -235,6 +260,7 @@ export class ObjectsRegistry { } private static onboarding__: Onboarding; + static get Onboarding(): Onboarding { if (ObjectsRegistry.onboarding__ === undefined) { ObjectsRegistry.onboarding__ = new Onboarding(); @@ -243,6 +269,7 @@ export class ObjectsRegistry { } private static autoLayout__: AutoLayout; + static get AutoLayout(): AutoLayout { if (ObjectsRegistry.autoLayout__ === undefined) { ObjectsRegistry.autoLayout__ = new AutoLayout(); @@ -251,6 +278,7 @@ export class ObjectsRegistry { } private static anvilLayout__: AnvilLayout; + static get AnvilLayout(): AnvilLayout { if (ObjectsRegistry.anvilLayout__ === undefined) { ObjectsRegistry.anvilLayout__ = new AnvilLayout(); @@ -259,6 +287,7 @@ export class ObjectsRegistry { } private static wdsWidgets__: WDSWidgets; + static get WDSWidgets(): WDSWidgets { if (ObjectsRegistry.wdsWidgets__ === undefined) { ObjectsRegistry.wdsWidgets__ = new WDSWidgets(); @@ -267,6 +296,7 @@ export class ObjectsRegistry { } private static anvilSnapshot__: AnvilSnapshot; + static get AnvilSnapshot(): AnvilSnapshot { if (ObjectsRegistry.anvilSnapshot__ === undefined) { ObjectsRegistry.anvilSnapshot__ = new AnvilSnapshot(); @@ -275,6 +305,7 @@ export class ObjectsRegistry { } private static dataManager__: DataManager; + static get DataManager(): DataManager { if (ObjectsRegistry.dataManager__ === undefined) { ObjectsRegistry.dataManager__ = new DataManager(); @@ -283,6 +314,7 @@ export class ObjectsRegistry { } private static gsheetHelper__: GsheetHelper; + static get GSheetHelper(): GsheetHelper { if (ObjectsRegistry.gsheetHelper__ === undefined) { ObjectsRegistry.gsheetHelper__ = new GsheetHelper(); @@ -291,6 +323,7 @@ export class ObjectsRegistry { } private static communityTemplates__: CommunityTemplates; + static get CommunityTemplates(): CommunityTemplates { if (ObjectsRegistry.communityTemplates__ === undefined) { ObjectsRegistry.communityTemplates__ = new CommunityTemplates(); @@ -299,6 +332,7 @@ export class ObjectsRegistry { } private static partialImportExport__: PartialImportExport; + static get PartialImportExport(): PartialImportExport { if (ObjectsRegistry.partialImportExport__ === undefined) { ObjectsRegistry.partialImportExport__ = new PartialImportExport(); @@ -311,6 +345,7 @@ export const initLocalstorageRegistry = () => { cy.window().then((window) => { window.localStorage.setItem("ShowCommentsButtonToolTip", ""); window.localStorage.setItem("updateDismissed", "true"); + window.localStorage.setItem("NUDGE_SHOWN_SPLIT_PANE", "true"); }); localStorage.setItem("inDeployedMode", "false"); }; diff --git a/app/client/cypress/support/commands.js b/app/client/cypress/support/commands.js index 75dab1611597..74294b336c73 100644 --- a/app/client/cypress/support/commands.js +++ b/app/client/cypress/support/commands.js @@ -19,6 +19,7 @@ import { v4 as uuidv4 } from "uuid"; const dayjs = require("dayjs"); const loginPage = require("../locators/LoginPage.json"); import homePage from "../locators/HomePage"; + dayjs.extend(advancedFormat); const commonlocators = require("../locators/commonlocators.json"); @@ -54,6 +55,7 @@ export const initLocalstorage = () => { cy.window().then((window) => { window.localStorage.setItem("ShowCommentsButtonToolTip", ""); window.localStorage.setItem("updateDismissed", "true"); + window.localStorage.setItem("NUDGE_SHOWN_SPLIT_PANE", "true"); }); }; diff --git a/app/client/packages/design-system/ads/src/Popover/Popover.tsx b/app/client/packages/design-system/ads/src/Popover/Popover.tsx index 34fc8d7ef27a..44270713da4f 100644 --- a/app/client/packages/design-system/ads/src/Popover/Popover.tsx +++ b/app/client/packages/design-system/ads/src/Popover/Popover.tsx @@ -1,6 +1,6 @@ import React from "react"; import type { PopoverTriggerProps } from "@radix-ui/react-popover"; -import { Close, Root, Trigger, Portal } from "@radix-ui/react-popover"; +import { Close, Root, Trigger, Portal, Arrow } from "@radix-ui/react-popover"; import type { PopoverHeaderProps, PopoverContentProps } from "./Popover.types"; import { @@ -60,6 +60,7 @@ function PopoverContent({ size = "sm", ...props }: PopoverContentProps) { sideOffset={4} {...props} > + {props.showArrow ? : null} {props.children} diff --git a/app/client/packages/design-system/ads/src/Popover/Popover.types.ts b/app/client/packages/design-system/ads/src/Popover/Popover.types.ts index c3e61cd2ce20..f78414b2f55b 100644 --- a/app/client/packages/design-system/ads/src/Popover/Popover.types.ts +++ b/app/client/packages/design-system/ads/src/Popover/Popover.types.ts @@ -20,4 +20,6 @@ export type PopoverContentProps = { className?: string; /** the minimum size of the popover */ size?: PopoverSize; + /** render an arrow pointing to the trigger */ + showArrow?: boolean; } & RadixPopoverContentProps; diff --git a/app/client/src/IDE/Components/Nudge/Nudge.tsx b/app/client/src/IDE/Components/Nudge/Nudge.tsx new file mode 100644 index 000000000000..d32eb14adf20 --- /dev/null +++ b/app/client/src/IDE/Components/Nudge/Nudge.tsx @@ -0,0 +1,57 @@ +import React, { useEffect, useState } from "react"; +import { Flex, Popover, Text } from "@appsmith/ads"; +import * as Styled from "./styles"; +import type { Align, Side } from "@radix-ui/react-popper"; + +interface Props { + trigger: React.ReactNode; + onDismissClick: () => void; + message: string; + align?: Align; + side?: Side; + delayOpen?: number; +} + +export const Nudge = (props: Props) => { + const [open, setOpen] = useState(false); + + useEffect( + function handleDelayOpenOnMount() { + const timer = setTimeout(() => { + setOpen(true); + }, props.delayOpen || 0); + + return () => clearTimeout(timer); + }, + [props.delayOpen], + ); + + return ( + + + {props.trigger} + + + + + {props.message} + + + + + + ); +}; diff --git a/app/client/src/IDE/Components/Nudge/index.ts b/app/client/src/IDE/Components/Nudge/index.ts new file mode 100644 index 000000000000..166ded472e56 --- /dev/null +++ b/app/client/src/IDE/Components/Nudge/index.ts @@ -0,0 +1 @@ +export { Nudge } from "./Nudge"; diff --git a/app/client/src/IDE/Components/Nudge/styles.ts b/app/client/src/IDE/Components/Nudge/styles.ts new file mode 100644 index 000000000000..081c6ed10cf2 --- /dev/null +++ b/app/client/src/IDE/Components/Nudge/styles.ts @@ -0,0 +1,49 @@ +import styled from "styled-components"; +import { + Icon, + PopoverContent as ADSPopoverContent, + PopoverTrigger as ADSPopoverTrigger, +} from "@appsmith/ads"; + +export const PopoverContent = styled(ADSPopoverContent)` + background: var(--ads-v2-color-bg-emphasis-max); + box-shadow: 0 1px 20px 0 #4c56641c; + border: none; + transform-origin: var(--radix-popover-content-transform-origin); + animation: fadeIn 0.2s cubic-bezier(0, 0, 0.58, 1); + + @keyframes fadeIn { + from { + opacity: 0; + } + to { + opacity: 1; + } + } +`; + +export const PopoverTrigger = styled(ADSPopoverTrigger)` + border: 2px solid transparent !important; + + &[data-active="true"] { + border: 2px solid var(--ads-v2-color-blue-300) !important; + } + + transition: border 0.2s cubic-bezier(0, 0, 0.58, 1); +`; + +export const CloseIcon = styled(Icon)` + svg { + path { + fill: var(--ads-v2-color-bg); + } + } + + padding: var(--ads-v2-spaces-2); + cursor: pointer; + border-radius: var(--ads-v2-border-radius); + + &:hover { + background-color: #ffffff33; + } +`; diff --git a/app/client/src/pages/Editor/IDE/EditorPane/components/Announcement.tsx b/app/client/src/pages/Editor/IDE/EditorPane/components/Announcement.tsx index 354a70a481a0..54181cab50b4 100644 --- a/app/client/src/pages/Editor/IDE/EditorPane/components/Announcement.tsx +++ b/app/client/src/pages/Editor/IDE/EditorPane/components/Announcement.tsx @@ -4,6 +4,8 @@ import localStorage, { LOCAL_STORAGE_KEYS } from "utils/localStorage"; import { SPLITPANE_ANNOUNCEMENT, createMessage } from "ee/constants/messages"; import { getAssetUrl } from "ee/utils/airgapHelpers"; import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants"; +import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; +import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; const Announcement = () => { const localStorageFlag = @@ -22,6 +24,10 @@ const Announcement = () => { ); }; + const featureIsOutOfBeta = useFeatureFlag( + FEATURE_FLAG.release_actions_redesign_enabled, + ); + const modalFooter = () => ( <> - - - + + + + + + + + + + + + ); } -export default ConnectSuccess; +export default ConnectSuccessModalView; diff --git a/app/client/src/git/components/ConnectSuccessModal/index.tsx b/app/client/src/git/components/ConnectSuccessModal/index.tsx new file mode 100644 index 000000000000..c492e5aa4bb3 --- /dev/null +++ b/app/client/src/git/components/ConnectSuccessModal/index.tsx @@ -0,0 +1,29 @@ +import React from "react"; +import ConnectSuccessModalView from "./ConnectSuccessModalView"; +import useMetadata from "git/hooks/useMetadata"; +import useConnect from "git/hooks/useConnect"; +import useSettings from "git/hooks/useSettings"; + +function ConnectSuccessModal() { + const { isConnectSuccessModalOpen, toggleConnectSuccessModal } = useConnect(); + const { toggleSettingsModal } = useSettings(); + + const { metadata } = useMetadata(); + + const remoteUrl = metadata?.remoteUrl ?? null; + const repoName = metadata?.repoName ?? null; + const defaultBranch = metadata?.defaultBranchName ?? null; + + return ( + + ); +} + +export default ConnectSuccessModal; diff --git a/app/client/src/git/components/DeployMenuItems/DeployMenuItemsView.tsx b/app/client/src/git/components/DeployMenuItems/DeployMenuItemsView.tsx new file mode 100644 index 000000000000..09ce5be3178a --- /dev/null +++ b/app/client/src/git/components/DeployMenuItems/DeployMenuItemsView.tsx @@ -0,0 +1,32 @@ +import React, { useCallback } from "react"; +import { MenuItem } from "@appsmith/ads"; +import { CONNECT_TO_GIT_OPTION, createMessage } from "ee/constants/messages"; +import AnalyticsUtil from "ee/utils/AnalyticsUtil"; +import noop from "lodash/noop"; + +interface DeployMenuItemsViewProps { + toggleConnectModal: (open: boolean) => void; +} + +function DeployMenuItemsView({ + toggleConnectModal = noop, +}: DeployMenuItemsViewProps) { + const handleClickOnConnect = useCallback(() => { + AnalyticsUtil.logEvent("GS_CONNECT_GIT_CLICK", { + source: "Deploy button", + }); + toggleConnectModal(true); + }, [toggleConnectModal]); + + return ( + + {createMessage(CONNECT_TO_GIT_OPTION)} + + ); +} + +export default DeployMenuItemsView; diff --git a/app/client/src/git/components/DeployMenuItems/index.tsx b/app/client/src/git/components/DeployMenuItems/index.tsx new file mode 100644 index 000000000000..de6c61f9af9b --- /dev/null +++ b/app/client/src/git/components/DeployMenuItems/index.tsx @@ -0,0 +1,11 @@ +import useConnect from "git/hooks/useConnect"; +import React from "react"; +import DeployMenuItemsView from "./DeployMenuItemsView"; + +function DeployMenuItems() { + const { toggleConnectModal } = useConnect(); + + return ; +} + +export default DeployMenuItems; diff --git a/app/client/src/git/components/GitContextProvider/index.tsx b/app/client/src/git/components/GitContextProvider/index.tsx index 4d4b88b4f6ad..89736de113eb 100644 --- a/app/client/src/git/components/GitContextProvider/index.tsx +++ b/app/client/src/git/components/GitContextProvider/index.tsx @@ -2,14 +2,12 @@ import React, { createContext, useCallback, useContext, useMemo } from "react"; import type { GitArtifactType } from "git/constants/enums"; import type { ApplicationPayload } from "entities/Application"; import type { FetchStatusResponseData } from "git/requests/fetchStatusRequest.types"; -import type { StatusTreeStruct } from "../StatusChanges/StatusTree"; import { useDispatch } from "react-redux"; +import type { GitArtifactDef } from "git/store/types"; +import type { StatusTreeStruct } from "../StatusChanges/types"; export interface GitContextValue { - artifactDef: { - artifactType: keyof typeof GitArtifactType; - baseArtifactId: string; - }; + artifactDef: GitArtifactDef | null; artifact: ApplicationPayload | null; statusTransformer: ( status: FetchStatusResponseData, @@ -27,8 +25,8 @@ export const useGitContext = () => { }; interface GitContextProviderProps { - artifactType: keyof typeof GitArtifactType; - baseArtifactId: string; + artifactType: keyof typeof GitArtifactType | null; + baseArtifactId: string | null; artifact: ApplicationPayload | null; isCreateArtifactPermitted: boolean; setWorkspaceIdForImport: (params: { @@ -50,10 +48,13 @@ export default function GitContextProvider({ setWorkspaceIdForImport, statusTransformer, }: GitContextProviderProps) { - const artifactDef = useMemo( - () => ({ artifactType, baseArtifactId }), - [artifactType, baseArtifactId], - ); + const artifactDef = useMemo(() => { + if (artifactType && baseArtifactId) { + return { artifactType, baseArtifactId }; + } + + return null; + }, [artifactType, baseArtifactId]); const dispatch = useDispatch(); diff --git a/app/client/src/git/components/GlobalProfile/GlobalProfileView.tsx b/app/client/src/git/components/GlobalProfile/GlobalProfileView.tsx new file mode 100644 index 000000000000..ddb2d7935387 --- /dev/null +++ b/app/client/src/git/components/GlobalProfile/GlobalProfileView.tsx @@ -0,0 +1,148 @@ +import React, { useCallback, useEffect, useState } from "react"; +import { + createMessage, + AUTHOR_EMAIL, + AUTHOR_NAME, + SUBMIT, +} from "ee/constants/messages"; +import { Classes } from "@blueprintjs/core"; +import { Button, Input, toast } from "@appsmith/ads"; +import { emailValidator } from "@appsmith/ads-old"; +import styled from "styled-components"; +import type { FetchGlobalProfileResponseData } from "git/requests/fetchGlobalProfileRequest.types"; +import type { UpdateGlobalProfileInitPayload } from "git/store/actions/updateGlobalProfileActions"; +import noop from "lodash/noop"; + +const Wrapper = styled.div` + width: 320px; + & > div { + margin-bottom: 16px; + } +`; + +const FieldWrapper = styled.div` + .user-profile-image-picker { + width: 166px; + margin-top: 4px; + } +`; + +const Loader = styled.div` + height: 38px; + width: 320px; + border-radius: 0; +`; + +interface GlobalProfileViewProps { + globalProfile: FetchGlobalProfileResponseData | null; + isFetchGlobalProfileLoading: boolean; + isUpdateGlobalProfileLoading: boolean; + updateGlobalProfile: (data: UpdateGlobalProfileInitPayload) => void; +} + +export default function GlobalProfileView({ + globalProfile = null, + isFetchGlobalProfileLoading = false, + isUpdateGlobalProfileLoading = false, + updateGlobalProfile = noop, +}: GlobalProfileViewProps) { + const [areFormValuesUpdated, setAreFormValuesUpdated] = useState(false); + + const [authorName, setAuthorNameInState] = useState( + globalProfile?.authorName, + ); + const [authorEmail, setAuthorEmailInState] = useState( + globalProfile?.authorEmail, + ); + + const isSubmitDisabled = !authorName || !authorEmail || !areFormValuesUpdated; + + const isLoading = isFetchGlobalProfileLoading || isUpdateGlobalProfileLoading; + + const setAuthorName = useCallback( + (value: string) => { + setAuthorNameInState(value); + + if (authorName) setAreFormValuesUpdated(true); + }, + [authorName], + ); + + const setAuthorEmail = useCallback( + (value: string) => { + setAuthorEmailInState(value); + + if (authorEmail) setAreFormValuesUpdated(true); + }, + [authorEmail], + ); + + const onClickUpdate = useCallback(() => { + if (authorName && authorEmail && emailValidator(authorEmail).isValid) { + setAreFormValuesUpdated(false); + updateGlobalProfile({ authorName, authorEmail }); + } else { + toast.show("Please enter valid user details"); + } + }, [authorEmail, authorName, updateGlobalProfile]); + + useEffect( + function resetOnInitEffect() { + setAreFormValuesUpdated(false); + setAuthorNameInState(globalProfile?.authorName ?? ""); + setAuthorEmailInState(globalProfile?.authorEmail ?? ""); + }, + [globalProfile], + ); + + return ( + + + {isLoading && } + {!isLoading && ( + + )} + + + {isLoading && } + {!isLoading && ( + + )} + + +
+ +
+
+
+ ); +} diff --git a/app/client/src/git/components/GlobalProfile/index.tsx b/app/client/src/git/components/GlobalProfile/index.tsx new file mode 100644 index 000000000000..5ecc06e70c87 --- /dev/null +++ b/app/client/src/git/components/GlobalProfile/index.tsx @@ -0,0 +1,23 @@ +import useGlobalProfile from "git/hooks/useGlobalProfile"; +import React from "react"; +import GlobalProfileView from "./GlobalProfileView"; + +function GlobalProfile() { + const { + globalProfile, + isFetchGlobalProfileLoading, + isUpdateGlobalProfileLoading, + updateGlobalProfile, + } = useGlobalProfile(); + + return ( + + ); +} + +export default GlobalProfile; diff --git a/app/client/src/git/components/ImportModal/index.tsx b/app/client/src/git/components/ImportModal/index.tsx index f55a468d702b..8192fa9e88a7 100644 --- a/app/client/src/git/components/ImportModal/index.tsx +++ b/app/client/src/git/components/ImportModal/index.tsx @@ -1,8 +1,51 @@ -import React from "react"; -import ConnectModal from "../ConnectModal"; +import React, { useCallback } from "react"; +import ConnectModalView from "../ConnectModal/ConnectModalView"; +import type { GitImportRequestParams } from "git/requests/gitImportRequest.types"; +import useImport from "git/hooks/useImport"; +import useGlobalSSHKey from "git/hooks/useGlobalSSHKey"; +import noop from "lodash/noop"; function ImportModal() { - return ; + const { + gitImport, + gitImportError, + isGitImportLoading, + isImportModalOpen, + toggleImportModal, + } = useImport(); + const { + fetchGlobalSSHKey, + globalSSHKey, + isFetchGlobalSSHKeyLoading, + resetGlobalSSHKey, + } = useGlobalSSHKey(); + + const sshPublicKey = globalSSHKey?.publicKey ?? null; + + const onSubmit = useCallback( + (params: GitImportRequestParams) => { + gitImport(params); + }, + [gitImport], + ); + + return ( + + ); } export default ImportModal; diff --git a/app/client/src/git/components/OpsModal/TabDeploy/DeployPreview.tsx b/app/client/src/git/components/OpsModal/TabDeploy/DeployPreview.tsx index 79abbe1439dc..311019abdc24 100644 --- a/app/client/src/git/components/OpsModal/TabDeploy/DeployPreview.tsx +++ b/app/client/src/git/components/OpsModal/TabDeploy/DeployPreview.tsx @@ -1,4 +1,4 @@ -import React from "react"; +import React, { useCallback, useEffect, useState } from "react"; import styled from "styled-components"; import { useSelector } from "react-redux"; @@ -15,32 +15,47 @@ import SuccessTick from "pages/common/SuccessTick"; import { howMuchTimeBeforeText } from "utils/helpers"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import { viewerURL } from "ee/RouteBuilder"; -import { Link, Text } from "@appsmith/ads"; -import { importSvg } from "@appsmith/ads-old"; +import { Icon, Link, Text } from "@appsmith/ads"; -const CloudyIcon = importSvg( - async () => import("assets/icons/ads/cloudy-line.svg"), -); +const StyledIcon = styled(Icon)` + svg { + width: 30px; + height: 30px; + } +`; const Container = styled.div` display: flex; flex: 1; flex-direction: row; gap: ${(props) => props.theme.spaces[6]}px; - - .cloud-icon { - stroke: var(--ads-v2-color-fg); - } `; -export default function DeployPreview() { - // ! case: should reset after timer - const showSuccess = false; +interface DeployPreviewProps { + isCommitSuccess: boolean; +} + +export default function DeployPreview({ isCommitSuccess }: DeployPreviewProps) { + const [showSuccess, setShowSuccess] = useState(false); + + useEffect( + function startTimerForCommitSuccessEffect() { + if (isCommitSuccess) { + setShowSuccess(true); + const timer = setTimeout(() => { + setShowSuccess(false); + }, 5000); + + return () => clearTimeout(timer); + } + }, + [isCommitSuccess], + ); const basePageId = useSelector(getCurrentBasePageId); const lastDeployedAt = useSelector(getApplicationLastDeployedAt); - const showDeployPreview = () => { + const showDeployPreview = useCallback(() => { AnalyticsUtil.logEvent("GS_LAST_DEPLOYED_PREVIEW_LINK_CLICK", { source: "GIT_DEPLOY_MODAL", }); @@ -49,7 +64,7 @@ export default function DeployPreview() { }); window.open(path, "_blank"); - }; + }, [basePageId]); const lastDeployedAtMsg = lastDeployedAt ? `${createMessage(LATEST_DP_SUBTITLE)} ${howMuchTimeBeforeText( @@ -66,7 +81,7 @@ export default function DeployPreview() { {showSuccess ? ( ) : ( - + )}
diff --git a/app/client/src/git/components/OpsModal/TabDeploy/TabDeployView.tsx b/app/client/src/git/components/OpsModal/TabDeploy/TabDeployView.tsx index d22c93f79b97..a2db0f28805d 100644 --- a/app/client/src/git/components/OpsModal/TabDeploy/TabDeployView.tsx +++ b/app/client/src/git/components/OpsModal/TabDeploy/TabDeployView.tsx @@ -108,6 +108,7 @@ function TabDeployView({ statusBehindCount = 0, statusIsClean = false, }: TabDeployViewProps) { + const [hasSubmitted, setHasSubmitted] = useState(false); const hasChangesToCommit = !statusIsClean; const commitInputRef = useRef(null); const [commitMessage, setCommitMessage] = useState( @@ -157,6 +158,10 @@ function TabDeployView({ ((pullRequired && !isConflicting) || (statusBehindCount > 0 && statusIsClean)); + const isCommitSuccess = useMemo(() => { + return hasSubmitted && !isCommitLoading; + }, [isCommitLoading, hasSubmitted]); + useEffect( function focusCommitInputEffect() { if (!commitInputDisabled && commitInputRef.current) { @@ -200,6 +205,7 @@ function TabDeployView({ }); if (currentBranch) { + setHasSubmitted(true); commit(commitMessage.trim()); } }, [commit, commitMessage, currentBranch]); @@ -353,7 +359,9 @@ function TabDeployView({ /> )} - {!pullRequired && !isConflicting && } + {!pullRequired && !isConflicting && ( + + )}
diff --git a/app/client/src/git/components/OpsModal/index.tsx b/app/client/src/git/components/OpsModal/index.tsx index 114439c29902..66ea3ddf0182 100644 --- a/app/client/src/git/components/OpsModal/index.tsx +++ b/app/client/src/git/components/OpsModal/index.tsx @@ -1,14 +1,15 @@ import React from "react"; import OpsModalView from "./OpsModalView"; -import useProtectedBranches from "git/hooks/useProtectedBranches"; import useMetadata from "git/hooks/useMetadata"; import useStatus from "git/hooks/useStatus"; import useOps from "git/hooks/useOps"; +import useProtectedMode from "git/hooks/useProtectedMode"; +import { GitOpsTab } from "git/constants/enums"; export default function OpsModal() { - const { opsModalOpen, opsModalTab, toggleOpsModal } = useOps(); + const { isOpsModalOpen, opsModalTab, toggleOpsModal } = useOps(); const { fetchStatus } = useStatus(); - const { isProtectedMode } = useProtectedBranches(); + const isProtectedMode = useProtectedMode(); const { metadata } = useMetadata(); @@ -17,9 +18,9 @@ export default function OpsModal() { return ( diff --git a/app/client/src/git/components/ProtectedBranchCallout/ProtectedBranchCalloutView.tsx b/app/client/src/git/components/ProtectedBranchCallout/ProtectedBranchCalloutView.tsx new file mode 100644 index 000000000000..89b37bbfa239 --- /dev/null +++ b/app/client/src/git/components/ProtectedBranchCallout/ProtectedBranchCalloutView.tsx @@ -0,0 +1,85 @@ +import React, { useCallback, useMemo } from "react"; +import { Callout } from "@appsmith/ads"; +import styled from "styled-components"; +import { + BRANCH_PROTECTION_CALLOUT_CREATE_BRANCH, + BRANCH_PROTECTION_CALLOUT_MSG, + BRANCH_PROTECTION_CALLOUT_UNPROTECT, + BRANCH_PROTECTION_CALLOUT_UNPROTECT_LOADING, + createMessage, +} from "ee/constants/messages"; +import { noop } from "lodash"; +import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types"; + +export const PROTECTED_CALLOUT_HEIGHT = 70; + +const StyledCallout = styled(Callout)` + height: ${PROTECTED_CALLOUT_HEIGHT}px; + overflow-y: hidden; +`; + +interface ProtectedBranchCalloutViewProps { + currentBranch: string | null; + isUpdateProtectedBranchesLoading: boolean; + protectedBranches: FetchProtectedBranchesResponseData | null; + toggleBranchPopup: (isOpen: boolean) => void; + updateProtectedBranches: (branches: string[]) => void; +} + +function ProtectedBranchCalloutView({ + currentBranch = null, + isUpdateProtectedBranchesLoading = false, + protectedBranches = null, + toggleBranchPopup = noop, + updateProtectedBranches = noop, +}: ProtectedBranchCalloutViewProps) { + const handleClickOnNewBranch = useCallback(() => { + toggleBranchPopup(true); + }, [toggleBranchPopup]); + + const handleClickOnUnprotect = useCallback(() => { + const allBranches = protectedBranches || []; + const remainingBranches = allBranches.filter( + (protectedBranch) => protectedBranch !== currentBranch, + ); + + updateProtectedBranches(remainingBranches); + }, [currentBranch, protectedBranches, updateProtectedBranches]); + + const links = useMemo( + () => [ + { + key: "create-branch", + "data-testid": "t--git-protected-create-branch-cta", + children: createMessage(BRANCH_PROTECTION_CALLOUT_CREATE_BRANCH), + onClick: handleClickOnNewBranch, + }, + { + key: "unprotect", + "data-testid": "t--git-protected-unprotect-branch-cta", + children: isUpdateProtectedBranchesLoading + ? createMessage(BRANCH_PROTECTION_CALLOUT_UNPROTECT_LOADING) + : createMessage(BRANCH_PROTECTION_CALLOUT_UNPROTECT), + onClick: handleClickOnUnprotect, + isDisabled: isUpdateProtectedBranchesLoading, + }, + ], + [ + handleClickOnNewBranch, + handleClickOnUnprotect, + isUpdateProtectedBranchesLoading, + ], + ); + + return ( + + {createMessage(BRANCH_PROTECTION_CALLOUT_MSG)} + + ); +} + +export default ProtectedBranchCalloutView; diff --git a/app/client/src/git/components/ProtectedBranchCallout/index.tsx b/app/client/src/git/components/ProtectedBranchCallout/index.tsx new file mode 100644 index 000000000000..aca08dfc1e87 --- /dev/null +++ b/app/client/src/git/components/ProtectedBranchCallout/index.tsx @@ -0,0 +1,33 @@ +import React from "react"; +import ProtectedBranchCalloutView from "./ProtectedBranchCalloutView"; +import useProtectedBranches from "git/hooks/useProtectedBranches"; +import useCurrentBranch from "git/hooks/useCurrentBranch"; +import useBranches from "git/hooks/useBranches"; +import useProtectedMode from "git/hooks/useProtectedMode"; + +function ProtectedBranchCallout() { + const isProtectedMode = useProtectedMode(); + const currentBranch = useCurrentBranch(); + const { toggleBranchPopup } = useBranches(); + const { + isUpdateProtectedBranchesLoading, + protectedBranches, + updateProtectedBranches, + } = useProtectedBranches(); + + if (!isProtectedMode) { + return null; + } + + return ( + + ); +} + +export default ProtectedBranchCallout; diff --git a/app/client/src/git/components/QuickActions/QuickActionsView.test.tsx b/app/client/src/git/components/QuickActions/QuickActionsView.test.tsx index 6e696ddffe55..f6bc193bfc7e 100644 --- a/app/client/src/git/components/QuickActions/QuickActionsView.test.tsx +++ b/app/client/src/git/components/QuickActions/QuickActionsView.test.tsx @@ -29,7 +29,7 @@ describe("QuickActionsView Component", () => { isConnectPermitted: true, isDiscardLoading: false, isFetchStatusLoading: false, - isGitConnected: false, + isConnected: false, isProtectedMode: false, isPullFailing: false, isPullLoading: false, @@ -48,7 +48,7 @@ describe("QuickActionsView Component", () => { jest.clearAllMocks(); }); - it("should render ConnectButton when isGitConnected is false", () => { + it("should render ConnectButton when isConnected is false", () => { render( @@ -57,10 +57,10 @@ describe("QuickActionsView Component", () => { expect(screen.getByTestId("connect-button")).toBeInTheDocument(); }); - it("should render QuickActionButtons when isGitConnected is true", () => { + it("should render QuickActionButtons when isConnected is true", () => { const props = { ...defaultProps, - isGitConnected: true, + isConnected: true, }; const { container } = render( @@ -86,7 +86,7 @@ describe("QuickActionsView Component", () => { it("should render Statusbar when isAutocommitEnabled and isPollingAutocommit are true", () => { const props = { ...defaultProps, - isGitConnected: true, + isConnected: true, isAutocommitEnabled: true, isAutocommitPolling: true, }; @@ -106,7 +106,7 @@ describe("QuickActionsView Component", () => { it("should call onCommitClick when commit button is clicked", () => { const props = { ...defaultProps, - isGitConnected: true, + isConnected: true, }; const { container } = render( @@ -131,7 +131,7 @@ describe("QuickActionsView Component", () => { it("should call onPullClick when pull button is clicked", () => { const props = { ...defaultProps, - isGitConnected: true, + isConnected: true, isDiscardLoading: false, isPullLoading: false, isFetchStatusLoading: false, @@ -159,7 +159,7 @@ describe("QuickActionsView Component", () => { it("should call onMerge when merge button is clicked", () => { const props = { ...defaultProps, - isGitConnected: true, + isConnected: true, }; const { container } = render( @@ -184,7 +184,7 @@ describe("QuickActionsView Component", () => { it("should call onSettingsClick when settings button is clicked", () => { const props = { ...defaultProps, - isGitConnected: true, + isConnected: true, }; const { container } = render( @@ -209,7 +209,7 @@ describe("QuickActionsView Component", () => { it("should disable commit button when isProtectedMode is true", () => { const props = { ...defaultProps, - isGitConnected: true, + isConnected: true, isProtectedMode: true, }; @@ -228,7 +228,7 @@ describe("QuickActionsView Component", () => { it("should show loading state on pull button when showPullLoadingState is true", () => { const props = { ...defaultProps, - isGitConnected: true, + isConnected: true, isPullLoading: true, }; @@ -250,7 +250,7 @@ describe("QuickActionsView Component", () => { it("should display changesToCommit count on commit button", () => { const props = { ...defaultProps, - isGitConnected: true, + isConnected: true, statusChangeCount: 5, }; @@ -267,7 +267,7 @@ describe("QuickActionsView Component", () => { it("should not display count on commit button when isProtectedMode is true", () => { const props = { ...defaultProps, - isGitConnected: true, + isConnected: true, isProtectedMode: true, statusChangeCount: 5, }; @@ -292,7 +292,7 @@ describe("QuickActionsView Component", () => { const props = { ...defaultProps, - isGitConnected: true, + isConnected: true, }; const { container } = render( @@ -310,7 +310,7 @@ describe("QuickActionsView Component", () => { it("should show behindCount on pull button", () => { const props = { ...defaultProps, - isGitConnected: true, + isConnected: true, statusBehindCount: 3, statusIsClean: true, }; diff --git a/app/client/src/git/components/QuickActions/QuickActionsView.tsx b/app/client/src/git/components/QuickActions/QuickActionsView.tsx index 396984788015..274dd00f3dba 100644 --- a/app/client/src/git/components/QuickActions/QuickActionsView.tsx +++ b/app/client/src/git/components/QuickActions/QuickActionsView.tsx @@ -33,7 +33,7 @@ interface QuickActionsViewProps { isConnectPermitted: boolean; isDiscardLoading: boolean; isFetchStatusLoading: boolean; - isGitConnected: boolean; + isConnected: boolean; isProtectedMode: boolean; isPullFailing: boolean; isPullLoading: boolean; @@ -57,10 +57,10 @@ function QuickActionsView({ isAutocommitEnabled = false, isAutocommitPolling = false, isBranchPopupOpen = false, + isConnected = false, isConnectPermitted = false, isDiscardLoading = false, isFetchStatusLoading = false, - isGitConnected = false, isProtectedMode = false, isPullFailing = false, isPullLoading = false, @@ -131,7 +131,7 @@ function QuickActionsView({ toggleConnectModal(true); }, [toggleConnectModal]); - return isGitConnected ? ( + return isConnected ? ( ); diff --git a/app/client/src/git/components/StatusChanges/StatusChangesView.tsx b/app/client/src/git/components/StatusChanges/StatusChangesView.tsx index c3768c0d866c..f8e6f0c41dfa 100644 --- a/app/client/src/git/components/StatusChanges/StatusChangesView.tsx +++ b/app/client/src/git/components/StatusChanges/StatusChangesView.tsx @@ -1,14 +1,19 @@ import type { FetchStatusResponseData } from "git/requests/fetchStatusRequest.types"; import React, { useMemo } from "react"; -import type { StatusTreeStruct } from "./StatusTree"; import StatusTree from "./StatusTree"; -import { Text } from "@appsmith/ads"; +import { Callout, Text } from "@appsmith/ads"; import { createMessage } from "@appsmith/ads-old"; import { CHANGES_SINCE_LAST_DEPLOYMENT, FETCH_GIT_STATUS, } from "ee/constants/messages"; -import StatusLoader from "pages/Editor/gitSync/components/StatusLoader"; +import StatusLoader from "./StatusLoader"; +import type { StatusTreeStruct } from "./types"; +import styled from "styled-components"; + +const CalloutContainer = styled.div` + margin-top: 16px; +`; const noopStatusTransformer = () => null; @@ -49,6 +54,11 @@ export default function StatusChangesView({ {createMessage(CHANGES_SINCE_LAST_DEPLOYMENT)} + {status.migrationMessage ? ( + + {status.migrationMessage} + + ) : null} ); } diff --git a/app/client/src/git/components/StatusChanges/StatusLoader.tsx b/app/client/src/git/components/StatusChanges/StatusLoader.tsx index bc0427bd6521..9026b75b38fa 100644 --- a/app/client/src/git/components/StatusChanges/StatusLoader.tsx +++ b/app/client/src/git/components/StatusChanges/StatusLoader.tsx @@ -6,16 +6,18 @@ const LoaderWrapper = styled.div` display: flex; flex-direction: row; align-items: center; - margin-top: ${(props) => `${props.theme.spaces[3]}px`}; + margin-bottom: 8px; +`; + +const LoaderText = styled(Text)` + margin-left: 8px; `; function StatusLoader({ loaderMsg }: { loaderMsg: string }) { return ( - - {loaderMsg} - + {loaderMsg} ); } diff --git a/app/client/src/git/components/StatusChanges/StatusTree.tsx b/app/client/src/git/components/StatusChanges/StatusTree.tsx index 289d2d28b796..437163d394df 100644 --- a/app/client/src/git/components/StatusChanges/StatusTree.tsx +++ b/app/client/src/git/components/StatusChanges/StatusTree.tsx @@ -7,12 +7,17 @@ import { Text, } from "@appsmith/ads"; import clsx from "clsx"; +import styled from "styled-components"; +import type { StatusTreeStruct } from "./types"; -export interface StatusTreeStruct { - icon: string; - message: string; - children?: StatusTreeStruct[]; -} +const StyledCollapsible = styled(Collapsible)` + gap: 0; +`; + +const StyledCollapsibleHeader = styled(CollapsibleHeader)` + padding-top: 0; + padding-bottom: 0; +`; interface StatusTreeNodeProps { icon: string; @@ -43,29 +48,31 @@ interface SingleStatusTreeProps { function SingleStatusTree({ depth = 1, tree }: SingleStatusTreeProps) { if (!tree) return null; + const noEmphasis = depth > 1 && !tree.children; + if (!tree.children) { return ( 2} + noEmphasis={noEmphasis} /> ); } return ( - - + + - + {tree.children.map((child, index) => ( ))} - + ); } diff --git a/app/client/src/git/components/StatusChanges/types.ts b/app/client/src/git/components/StatusChanges/types.ts new file mode 100644 index 000000000000..61a8e074714b --- /dev/null +++ b/app/client/src/git/components/StatusChanges/types.ts @@ -0,0 +1,5 @@ +export interface StatusTreeStruct { + icon: string; + message: string; + children?: StatusTreeStruct[]; +} diff --git a/app/client/src/git/components/index.tsx b/app/client/src/git/components/index.tsx deleted file mode 100644 index c3a1640dbd01..000000000000 --- a/app/client/src/git/components/index.tsx +++ /dev/null @@ -1,3 +0,0 @@ -export { default as GitModals } from "git/ee/components/GitModals"; -export { default as GitImportModal } from "./ImportModal"; -export { default as GitQuickActions } from "./QuickActions"; diff --git a/app/client/src/git/hooks/useArtifactSelector.ts b/app/client/src/git/hooks/useArtifactSelector.ts new file mode 100644 index 000000000000..dba2a0808bf3 --- /dev/null +++ b/app/client/src/git/hooks/useArtifactSelector.ts @@ -0,0 +1,29 @@ +import { useGitContext } from "git/components/GitContextProvider"; +import type { GitArtifactDef, GitRootState } from "git/store/types"; +import { useSelector } from "react-redux"; +import type { Tail } from "redux-saga/effects"; + +/** + * This hook is used to select data from the redux store based on the artifactDef. + **/ +export default function useArtifactSelector< + // need any type to properly infer the return type + /* eslint-disable @typescript-eslint/no-explicit-any */ + Fn extends (state: any, artifactDef: GitArtifactDef, ...args: any[]) => any, +>(selector: Fn, ...args: Tail>>): ReturnType | null { + const { artifactDef } = useGitContext(); + + return useSelector((state: GitRootState) => { + if (typeof selector !== "function" || !artifactDef) { + return null; + } + + const { artifactType, baseArtifactId } = artifactDef; + + if (!state.git?.artifacts?.[artifactType]?.[baseArtifactId]) { + return null; + } + + return selector(state, artifactDef, ...args); + }); +} diff --git a/app/client/src/git/hooks/useAutocommit.ts b/app/client/src/git/hooks/useAutocommit.ts index 73d7d955caca..91ad0e8aaae5 100644 --- a/app/client/src/git/hooks/useAutocommit.ts +++ b/app/client/src/git/hooks/useAutocommit.ts @@ -6,50 +6,50 @@ import { selectAutocommitPolling, selectToggleAutocommitState, selectTriggerAutocommitState, -} from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; +} from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; export default function useAutocommit() { const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const toggleAutocommitState = useSelector((state: GitRootState) => - selectToggleAutocommitState(state, artifactDef), + const toggleAutocommitState = useArtifactSelector( + selectToggleAutocommitState, ); - const triggerAutocommitState = useSelector((state: GitRootState) => - selectTriggerAutocommitState(state, artifactDef), + const triggerAutocommitState = useArtifactSelector( + selectTriggerAutocommitState, ); const toggleAutocommit = useCallback(() => { - dispatch(gitArtifactActions.toggleAutocommitInit(artifactDef)); + if (artifactDef) { + dispatch(gitArtifactActions.toggleAutocommitInit({ artifactDef })); + } }, [artifactDef, dispatch]); - const isAutocommitDisableModalOpen = useSelector((state: GitRootState) => - selectAutocommitDisableModalOpen(state, artifactDef), + const isAutocommitDisableModalOpen = useArtifactSelector( + selectAutocommitDisableModalOpen, ); const toggleAutocommitDisableModal = useCallback( (open: boolean) => { - dispatch( - gitArtifactActions.toggleAutocommitDisableModal({ - ...artifactDef, - open, - }), - ); + if (artifactDef) { + dispatch( + gitArtifactActions.toggleAutocommitDisableModal({ + artifactDef, + open, + }), + ); + } }, [artifactDef, dispatch], ); - const isAutocommitEnabled = useSelector((state: GitRootState) => - selectAutocommitEnabled(state, artifactDef), - ); + const isAutocommitEnabled = useArtifactSelector(selectAutocommitEnabled); - const isAutocommitPolling = useSelector((state: GitRootState) => - selectAutocommitPolling(state, artifactDef), - ); + const isAutocommitPolling = useArtifactSelector(selectAutocommitPolling); return { isToggleAutocommitLoading: toggleAutocommitState?.loading ?? false, @@ -57,9 +57,9 @@ export default function useAutocommit() { toggleAutocommit, isTriggerAutocommitLoading: triggerAutocommitState?.loading ?? false, triggerAutocommitError: triggerAutocommitState?.error ?? null, - isAutocommitDisableModalOpen, + isAutocommitDisableModalOpen: isAutocommitDisableModalOpen ?? false, toggleAutocommitDisableModal, - isAutocommitEnabled, - isAutocommitPolling, + isAutocommitEnabled: isAutocommitEnabled ?? false, + isAutocommitPolling: isAutocommitPolling ?? false, }; } diff --git a/app/client/src/git/hooks/useBranches.ts b/app/client/src/git/hooks/useBranches.ts index 4a0ecead44d7..fe85a318b8d4 100644 --- a/app/client/src/git/hooks/useBranches.ts +++ b/app/client/src/git/hooks/useBranches.ts @@ -8,103 +8,105 @@ import { selectCreateBranchState, selectDeleteBranchState, selectCurrentBranch, -} from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; +} from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; export default function useBranches() { - const { artifactDef } = useGitContext(); + const { artifact, artifactDef } = useGitContext(); + const artifactId = artifact?.id; const dispatch = useDispatch(); // fetch branches - const branchesState = useSelector((state: GitRootState) => - selectFetchBranchesState(state, artifactDef), - ); + const branchesState = useArtifactSelector(selectFetchBranchesState); + const fetchBranches = useCallback(() => { - dispatch( - gitArtifactActions.fetchBranchesInit({ - ...artifactDef, - pruneBranches: true, - }), - ); - }, [artifactDef, dispatch]); + if (artifactDef && artifactId) { + dispatch( + gitArtifactActions.fetchBranchesInit({ + artifactId, + artifactDef, + pruneBranches: true, + }), + ); + } + }, [artifactDef, artifactId, dispatch]); // create branch - const createBranchState = useSelector((state: GitRootState) => - selectCreateBranchState(state, artifactDef), - ); + const createBranchState = useArtifactSelector(selectCreateBranchState); const createBranch = useCallback( (branchName: string) => { - dispatch( - gitArtifactActions.createBranchInit({ - ...artifactDef, - branchName, - }), - ); + if (artifactDef && artifactId) { + dispatch( + gitArtifactActions.createBranchInit({ + artifactDef, + artifactId, + branchName, + }), + ); + } }, - [artifactDef, dispatch], + [artifactDef, artifactId, dispatch], ); // delete branch - const deleteBranchState = useSelector((state: GitRootState) => - selectDeleteBranchState(state, artifactDef), - ); + const deleteBranchState = useArtifactSelector(selectDeleteBranchState); const deleteBranch = useCallback( (branchName: string) => { - dispatch( - gitArtifactActions.deleteBranchInit({ - ...artifactDef, - branchName, - }), - ); + if (artifactDef && artifactId) { + dispatch( + gitArtifactActions.deleteBranchInit({ + artifactId, + artifactDef, + branchName, + }), + ); + } }, - [artifactDef, dispatch], + [artifactDef, artifactId, dispatch], ); // checkout branch - const checkoutBranchState = useSelector((state: GitRootState) => - selectCheckoutBranchState(state, artifactDef), - ); + const checkoutBranchState = useArtifactSelector(selectCheckoutBranchState); const checkoutBranch = useCallback( (branchName: string) => { - dispatch( - gitArtifactActions.checkoutBranchInit({ - ...artifactDef, - branchName, - }), - ); + if (artifactDef && artifactId) { + dispatch( + gitArtifactActions.checkoutBranchInit({ + artifactDef, + artifactId, + branchName, + }), + ); + } }, - [artifactDef, dispatch], + [artifactDef, artifactId, dispatch], ); - const checkoutDestBranch = useSelector((state: GitRootState) => - selectCheckoutDestBranch(state, artifactDef), - ); + const checkoutDestBranch = useArtifactSelector(selectCheckoutDestBranch); // derived - const currentBranch = useSelector((state: GitRootState) => - selectCurrentBranch(state, artifactDef), - ); + const currentBranch = useArtifactSelector(selectCurrentBranch); // git branch list popup - const isBranchPopupOpen = useSelector((state: GitRootState) => - selectBranchPopupOpen(state, artifactDef), - ); + const isBranchPopupOpen = useArtifactSelector(selectBranchPopupOpen); const toggleBranchPopup = useCallback( (open: boolean) => { - dispatch( - gitArtifactActions.toggleBranchPopup({ - ...artifactDef, - open, - }), - ); + if (artifactDef) { + dispatch( + gitArtifactActions.toggleBranchPopup({ + artifactDef, + open, + }), + ); + } }, [artifactDef, dispatch], ); return { - branches: branchesState?.value, + branches: branchesState?.value ?? null, isFetchBranchesLoading: branchesState?.loading ?? false, fetchBranchesError: branchesState?.error ?? null, fetchBranches, @@ -119,7 +121,7 @@ export default function useBranches() { checkoutBranch, checkoutDestBranch, currentBranch: currentBranch ?? null, - isBranchPopupOpen, + isBranchPopupOpen: isBranchPopupOpen ?? false, toggleBranchPopup, }; } diff --git a/app/client/src/git/hooks/useCommit.ts b/app/client/src/git/hooks/useCommit.ts index 56f78cc11bcd..6a468046a84b 100644 --- a/app/client/src/git/hooks/useCommit.ts +++ b/app/client/src/git/hooks/useCommit.ts @@ -1,38 +1,43 @@ import { useGitContext } from "git/components/GitContextProvider"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; -import { selectCommitState } from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; +import { selectCommitState } from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; export default function useCommit() { - const { artifactDef } = useGitContext(); + const { artifact, artifactDef } = useGitContext(); + const artifactId = artifact?.id; + const dispatch = useDispatch(); - const commitState = useSelector((state: GitRootState) => - selectCommitState(state, artifactDef), - ); + const commitState = useArtifactSelector(selectCommitState); const commit = useCallback( (commitMessage: string) => { - dispatch( - gitArtifactActions.commitInit({ - ...artifactDef, - commitMessage, - doPush: true, - }), - ); + if (artifactDef && artifactId) { + dispatch( + gitArtifactActions.commitInit({ + artifactId, + artifactDef, + commitMessage, + doPush: true, + }), + ); + } }, - [artifactDef, dispatch], + [artifactDef, artifactId, dispatch], ); const clearCommitError = useCallback(() => { - dispatch(gitArtifactActions.clearCommitError(artifactDef)); + if (artifactDef) { + dispatch(gitArtifactActions.clearCommitError({ artifactDef })); + } }, [artifactDef, dispatch]); return { isCommitLoading: commitState?.loading ?? false, - commitError: commitState?.error, + commitError: commitState?.error ?? null, commit, clearCommitError, }; diff --git a/app/client/src/git/hooks/useConnect.ts b/app/client/src/git/hooks/useConnect.ts index 1064ce7ff26e..884addac0fd7 100644 --- a/app/client/src/git/hooks/useConnect.ts +++ b/app/client/src/git/hooks/useConnect.ts @@ -4,82 +4,53 @@ import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { selectConnectModalOpen, selectConnectState, - selectFetchSSHKeysState, - selectGenerateSSHKeyState, - selectGitImportState, -} from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; + selectConnectSuccessModalOpen, +} from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; import { useDispatch } from "react-redux"; -import { useSelector } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; export default function useConnect() { const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const connectState = useSelector((state: GitRootState) => - selectConnectState(state, artifactDef), - ); + const connectState = useArtifactSelector(selectConnectState); const connect = useCallback( (params: ConnectRequestParams) => { - dispatch(gitArtifactActions.connectInit({ ...artifactDef, ...params })); - }, - [artifactDef, dispatch], - ); - - const gitImportState = useSelector((state: GitRootState) => - selectGitImportState(state, artifactDef), - ); - - const gitImport = useCallback( - (params) => { - dispatch(gitArtifactActions.gitImportInit({ ...artifactDef, ...params })); + if (artifactDef) { + dispatch(gitArtifactActions.connectInit({ artifactDef, ...params })); + } }, [artifactDef, dispatch], ); - const fetchSSHKeyState = useSelector((state: GitRootState) => - selectFetchSSHKeysState(state, artifactDef), - ); - - const fetchSSHKey = useCallback(() => { - dispatch(gitArtifactActions.fetchSSHKeyInit(artifactDef)); - }, [artifactDef, dispatch]); - - const resetFetchSSHKey = useCallback(() => { - dispatch(gitArtifactActions.resetFetchSSHKey(artifactDef)); - }, [artifactDef, dispatch]); - - const generateSSHKeyState = useSelector((state: GitRootState) => - selectGenerateSSHKeyState(state, artifactDef), - ); + const isConnectModalOpen = useArtifactSelector(selectConnectModalOpen); - const generateSSHKey = useCallback( - (keyType: string, isImport: boolean = false) => { - dispatch( - gitArtifactActions.generateSSHKeyInit({ - ...artifactDef, - keyType, - isImport, - }), - ); + const toggleConnectModal = useCallback( + (open: boolean) => { + if (artifactDef) { + dispatch(gitArtifactActions.toggleConnectModal({ artifactDef, open })); + } }, [artifactDef, dispatch], ); - const resetGenerateSSHKey = useCallback(() => { - dispatch(gitArtifactActions.resetGenerateSSHKey(artifactDef)); - }, [artifactDef, dispatch]); - - const isConnectModalOpen = useSelector((state: GitRootState) => - selectConnectModalOpen(state, artifactDef), + const isConnectSuccessModalOpen = useArtifactSelector( + selectConnectSuccessModalOpen, ); - const toggleConnectModal = useCallback( + const toggleConnectSuccessModal = useCallback( (open: boolean) => { - dispatch(gitArtifactActions.toggleConnectModal({ ...artifactDef, open })); + if (artifactDef) { + dispatch( + gitArtifactActions.toggleConnectSuccessModal({ + artifactDef, + open, + }), + ); + } }, [artifactDef, dispatch], ); @@ -88,19 +59,9 @@ export default function useConnect() { isConnectLoading: connectState?.loading ?? false, connectError: connectState?.error ?? null, connect, - isGitImportLoading: gitImportState?.loading ?? false, - gitImportError: gitImportState?.error ?? null, - gitImport, - sshKey: fetchSSHKeyState?.value ?? null, - isFetchSSHKeyLoading: fetchSSHKeyState?.loading ?? false, - fetchSSHKeyError: fetchSSHKeyState?.error ?? null, - fetchSSHKey, - resetFetchSSHKey, - isGenerateSSHKeyLoading: generateSSHKeyState?.loading ?? false, - generateSSHKeyError: generateSSHKeyState?.error ?? null, - generateSSHKey, - resetGenerateSSHKey, - isConnectModalOpen, + isConnectModalOpen: isConnectModalOpen ?? false, toggleConnectModal, + isConnectSuccessModalOpen: isConnectSuccessModalOpen ?? false, + toggleConnectSuccessModal, }; } diff --git a/app/client/src/git/hooks/useConnected.ts b/app/client/src/git/hooks/useConnected.ts new file mode 100644 index 000000000000..39cfa55ca245 --- /dev/null +++ b/app/client/src/git/hooks/useConnected.ts @@ -0,0 +1,8 @@ +import { selectConnected } from "git/store/selectors/gitArtifactSelectors"; +import useArtifactSelector from "./useArtifactSelector"; + +export default function useConnected() { + const isConnected = useArtifactSelector(selectConnected); + + return isConnected ?? false; +} diff --git a/app/client/src/git/hooks/useCurrentBranch.ts b/app/client/src/git/hooks/useCurrentBranch.ts new file mode 100644 index 000000000000..797d8d598ba5 --- /dev/null +++ b/app/client/src/git/hooks/useCurrentBranch.ts @@ -0,0 +1,8 @@ +import { selectCurrentBranch } from "git/store/selectors/gitArtifactSelectors"; +import useArtifactSelector from "./useArtifactSelector"; + +export default function useCurrentBranch() { + const currentBranch = useArtifactSelector(selectCurrentBranch); + + return currentBranch; +} diff --git a/app/client/src/git/hooks/useDiscard.ts b/app/client/src/git/hooks/useDiscard.ts index 2f71c11608f9..19818cb7f8fa 100644 --- a/app/client/src/git/hooks/useDiscard.ts +++ b/app/client/src/git/hooks/useDiscard.ts @@ -1,24 +1,26 @@ import { useGitContext } from "git/components/GitContextProvider"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; -import { selectDiscardState } from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; +import { selectDiscardState } from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; export default function useDiscard() { const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const discardState = useSelector((state: GitRootState) => - selectDiscardState(state, artifactDef), - ); + const discardState = useArtifactSelector(selectDiscardState); const discard = useCallback(() => { - dispatch(gitArtifactActions.discardInit(artifactDef)); + if (artifactDef) { + dispatch(gitArtifactActions.discardInit({ artifactDef })); + } }, [artifactDef, dispatch]); const clearDiscardError = useCallback(() => { - dispatch(gitArtifactActions.clearDiscardError(artifactDef)); + if (artifactDef) { + dispatch(gitArtifactActions.clearDiscardError({ artifactDef })); + } }, [artifactDef, dispatch]); return { diff --git a/app/client/src/git/hooks/useDisconnect.ts b/app/client/src/git/hooks/useDisconnect.ts index 36dfd2cf8cf9..42fd878319fd 100644 --- a/app/client/src/git/hooks/useDisconnect.ts +++ b/app/client/src/git/hooks/useDisconnect.ts @@ -4,10 +4,10 @@ import { selectDisconnectArtifactName, selectDisconnectBaseArtifactId, selectDisconnectState, -} from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; +} from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; export default function useDisconnect() { const { artifact, artifactDef } = useGitContext(); @@ -15,30 +15,38 @@ export default function useDisconnect() { const dispatch = useDispatch(); - const disconnectState = useSelector((state: GitRootState) => - selectDisconnectState(state, artifactDef), - ); + const disconnectState = useArtifactSelector(selectDisconnectState); const disconnect = useCallback(() => { - dispatch(gitArtifactActions.disconnectInit(artifactDef)); + if (artifactDef) { + dispatch( + gitArtifactActions.disconnectInit({ + artifactDef, + }), + ); + } }, [artifactDef, dispatch]); - const disconnectBaseArtifactId = useSelector((state: GitRootState) => - selectDisconnectBaseArtifactId(state, artifactDef), + const disconnectBaseArtifactId = useArtifactSelector( + selectDisconnectBaseArtifactId, ); - const disconnectArtifactName = useSelector((state: GitRootState) => - selectDisconnectArtifactName(state, artifactDef), + const disconnectArtifactName = useArtifactSelector( + selectDisconnectArtifactName, ); const openDisconnectModal = useCallback(() => { - dispatch( - gitArtifactActions.openDisconnectModal({ ...artifactDef, artifactName }), - ); + if (artifactDef) { + dispatch( + gitArtifactActions.openDisconnectModal({ artifactDef, artifactName }), + ); + } }, [artifactDef, artifactName, dispatch]); const closeDisconnectModal = useCallback(() => { - dispatch(gitArtifactActions.closeDisconnectModal(artifactDef)); + if (artifactDef) { + dispatch(gitArtifactActions.closeDisconnectModal({ artifactDef })); + } }, [artifactDef, dispatch]); return { diff --git a/app/client/src/git/hooks/useGitPermissions.ts b/app/client/src/git/hooks/useGitPermissions.ts index 3279dcd3e00e..13ca2404a161 100644 --- a/app/client/src/git/hooks/useGitPermissions.ts +++ b/app/client/src/git/hooks/useGitPermissions.ts @@ -10,47 +10,46 @@ import { useMemo } from "react"; export default function useGitPermissions() { const { artifact, artifactDef } = useGitContext(); - const { artifactType } = artifactDef; const isConnectPermitted = useMemo(() => { if (artifact) { - if (artifactType === GitArtifactType.Application) { + if (artifactDef?.artifactType === GitArtifactType.Application) { return hasConnectToGitPermission(artifact.userPermissions); } } return false; - }, [artifact, artifactType]); + }, [artifact, artifactDef?.artifactType]); const isManageDefaultBranchPermitted = useMemo(() => { if (artifact) { - if (artifactType === GitArtifactType.Application) { + if (artifactDef?.artifactType === GitArtifactType.Application) { return hasManageDefaultBranchPermission(artifact.userPermissions); } } return false; - }, [artifact, artifactType]); + }, [artifact, artifactDef?.artifactType]); const isManageProtectedBranchesPermitted = useMemo(() => { if (artifact) { - if (artifactType === GitArtifactType.Application) { + if (artifactDef?.artifactType === GitArtifactType.Application) { return hasManageProtectedBranchesPermission(artifact.userPermissions); } } return false; - }, [artifact, artifactType]); + }, [artifact, artifactDef?.artifactType]); const isManageAutocommitPermitted = useMemo(() => { if (artifact) { - if (artifactType === GitArtifactType.Application) { + if (artifactDef?.artifactType === GitArtifactType.Application) { return hasManageAutoCommitPermission(artifact.userPermissions); } } return false; - }, [artifact, artifactType]); + }, [artifact, artifactDef?.artifactType]); return { isConnectPermitted, diff --git a/app/client/src/git/hooks/useGlobalProfile.ts b/app/client/src/git/hooks/useGlobalProfile.ts index f319f9c1f5db..3cc3a80aad98 100644 --- a/app/client/src/git/hooks/useGlobalProfile.ts +++ b/app/client/src/git/hooks/useGlobalProfile.ts @@ -1,9 +1,9 @@ import type { UpdateGlobalProfileRequestParams } from "git/requests/updateGlobalProfileRequest.types"; -import { gitConfigActions } from "git/store/gitConfigSlice"; +import { gitGlobalActions } from "git/store/gitGlobalSlice"; import { selectFetchGlobalProfileState, selectUpdateGlobalProfileState, -} from "git/store/selectors/gitConfigSelectors"; +} from "git/store/selectors/gitGlobalSelectors"; import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; @@ -16,7 +16,7 @@ export default function useGlobalProfile() { ); const fetchGlobalProfile = useCallback(() => { - dispatch(gitConfigActions.fetchGlobalProfileInit()); + dispatch(gitGlobalActions.fetchGlobalProfileInit()); }, [dispatch]); const updateGlobalProfileState = useSelector((state: GitRootState) => @@ -25,7 +25,7 @@ export default function useGlobalProfile() { const updateGlobalProfile = useCallback( (params: UpdateGlobalProfileRequestParams) => { - dispatch(gitConfigActions.updateGlobalProfileInit(params)); + dispatch(gitGlobalActions.updateGlobalProfileInit(params)); }, [dispatch], ); diff --git a/app/client/src/git/hooks/useGlobalSSHKey.ts b/app/client/src/git/hooks/useGlobalSSHKey.ts new file mode 100644 index 000000000000..ac7216045a6a --- /dev/null +++ b/app/client/src/git/hooks/useGlobalSSHKey.ts @@ -0,0 +1,29 @@ +import { useCallback } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { selectFetchGlobalSSHKeyState } from "git/store/selectors/gitGlobalSelectors"; +import { gitGlobalActions } from "git/store/gitGlobalSlice"; + +export default function useGlobalSSHKey() { + const dispatch = useDispatch(); + + const globalSSHKeyState = useSelector(selectFetchGlobalSSHKeyState); + + const fetchGlobalSSHKey = useCallback( + (keyType: string) => { + dispatch(gitGlobalActions.fetchGlobalSSHKeyInit({ keyType })); + }, + [dispatch], + ); + + const resetGlobalSSHKey = useCallback(() => { + dispatch(gitGlobalActions.resetGlobalSSHKey()); + }, [dispatch]); + + return { + globalSSHKey: globalSSHKeyState?.value ?? null, + globalSSHKeyError: globalSSHKeyState?.error ?? null, + isFetchGlobalSSHKeyLoading: globalSSHKeyState?.loading ?? false, + fetchGlobalSSHKey, + resetGlobalSSHKey, + }; +} diff --git a/app/client/src/git/hooks/useImport.ts b/app/client/src/git/hooks/useImport.ts new file mode 100644 index 000000000000..62069b888d68 --- /dev/null +++ b/app/client/src/git/hooks/useImport.ts @@ -0,0 +1,38 @@ +import { useCallback } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { + selectGitImportState, + selectImportModalOpen, +} from "git/store/selectors/gitGlobalSelectors"; +import { gitGlobalActions } from "git/store/gitGlobalSlice"; +import type { GitImportRequestParams } from "git/requests/gitImportRequest.types"; + +export default function useImport() { + const dispatch = useDispatch(); + + const gitImportState = useSelector(selectGitImportState); + + const gitImport = useCallback( + (params: GitImportRequestParams) => { + dispatch(gitGlobalActions.gitImportInit(params)); + }, + [dispatch], + ); + + const isImportModalOpen = useSelector(selectImportModalOpen); + + const toggleImportModal = useCallback( + (open: boolean) => { + dispatch(gitGlobalActions.toggleImportModal({ open })); + }, + [dispatch], + ); + + return { + isGitImportLoading: gitImportState?.loading ?? false, + gitImportError: gitImportState?.error ?? null, + gitImport, + isImportModalOpen: isImportModalOpen ?? false, + toggleImportModal, + }; +} diff --git a/app/client/src/git/hooks/useLocalProfile.ts b/app/client/src/git/hooks/useLocalProfile.ts index e770ad6356bc..8d77899a7602 100644 --- a/app/client/src/git/hooks/useLocalProfile.ts +++ b/app/client/src/git/hooks/useLocalProfile.ts @@ -4,36 +4,40 @@ import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { selectFetchLocalProfileState, selectUpdateLocalProfileState, -} from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; +} from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; export default function useLocalProfile() { const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const fetchLocalProfileState = useSelector((state: GitRootState) => - selectFetchLocalProfileState(state, artifactDef), + const fetchLocalProfileState = useArtifactSelector( + selectFetchLocalProfileState, ); const fetchLocalProfile = useCallback(() => { - dispatch(gitArtifactActions.fetchLocalProfileInit(artifactDef)); + if (artifactDef) { + dispatch(gitArtifactActions.fetchLocalProfileInit({ artifactDef })); + } }, [artifactDef, dispatch]); - const updateLocalProfileState = useSelector((state: GitRootState) => - selectUpdateLocalProfileState(state, artifactDef), + const updateLocalProfileState = useArtifactSelector( + selectUpdateLocalProfileState, ); const updateLocalProfile = useCallback( (params: UpdateLocalProfileRequestParams) => { - dispatch( - gitArtifactActions.updateLocalProfileInit({ - ...artifactDef, - ...params, - }), - ); + if (artifactDef) { + dispatch( + gitArtifactActions.updateLocalProfileInit({ + artifactDef, + ...params, + }), + ); + } }, [artifactDef, dispatch], ); diff --git a/app/client/src/git/hooks/useMerge.ts b/app/client/src/git/hooks/useMerge.ts index f7394601b191..8fa79b16049f 100644 --- a/app/client/src/git/hooks/useMerge.ts +++ b/app/client/src/git/hooks/useMerge.ts @@ -3,10 +3,10 @@ import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { selectMergeState, selectMergeStatusState, -} from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; +} from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; export default function useMerge() { const { artifact, artifactDef } = useGitContext(); @@ -14,44 +14,46 @@ export default function useMerge() { const dispatch = useDispatch(); // merge - const mergeState = useSelector((state: GitRootState) => - selectMergeState(state, artifactDef), - ); + const mergeState = useArtifactSelector(selectMergeState); const merge = useCallback(() => { - dispatch(gitArtifactActions.mergeInit(artifactDef)); + if (artifactDef) { + dispatch(gitArtifactActions.mergeInit({ artifactDef })); + } }, [artifactDef, dispatch]); // merge status - const mergeStatusState = useSelector((state: GitRootState) => - selectMergeStatusState(state, artifactDef), - ); + const mergeStatusState = useArtifactSelector(selectMergeStatusState); const fetchMergeStatus = useCallback( (sourceBranch: string, destinationBranch: string) => { - dispatch( - gitArtifactActions.fetchMergeStatusInit({ - ...artifactDef, - artifactId: artifactId ?? "", - sourceBranch, - destinationBranch, - }), - ); + if (artifactDef) { + dispatch( + gitArtifactActions.fetchMergeStatusInit({ + artifactDef, + artifactId: artifactId ?? "", + sourceBranch, + destinationBranch, + }), + ); + } }, [artifactId, artifactDef, dispatch], ); const clearMergeStatus = useCallback(() => { - dispatch(gitArtifactActions.clearMergeStatus(artifactDef)); + if (artifactDef) { + dispatch(gitArtifactActions.clearMergeStatus({ artifactDef })); + } }, [artifactDef, dispatch]); return { isMergeLoading: mergeState?.loading ?? false, - mergeError: mergeState?.error, + mergeError: mergeState?.error ?? null, merge, - mergeStatus: mergeStatusState?.value, + mergeStatus: mergeStatusState?.value ?? null, isFetchMergeStatusLoading: mergeStatusState?.loading ?? false, - fetchMergeStatusError: mergeStatusState?.error, + fetchMergeStatusError: mergeStatusState?.error ?? null, fetchMergeStatus, clearMergeStatus, }; diff --git a/app/client/src/git/hooks/useMetadata.ts b/app/client/src/git/hooks/useMetadata.ts index 9bd5356ad763..2ccd15d7ec89 100644 --- a/app/client/src/git/hooks/useMetadata.ts +++ b/app/client/src/git/hooks/useMetadata.ts @@ -1,26 +1,12 @@ -import { useGitContext } from "git/components/GitContextProvider"; -import { - selectGitConnected, - selectMetadataState, -} from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; -import { useSelector } from "react-redux"; +import { selectMetadataState } from "git/store/selectors/gitArtifactSelectors"; +import useArtifactSelector from "./useArtifactSelector"; export default function useMetadata() { - const { artifactDef } = useGitContext(); - - const metadataState = useSelector((state: GitRootState) => - selectMetadataState(state, artifactDef), - ); - - const isGitConnected = useSelector((state: GitRootState) => - selectGitConnected(state, artifactDef), - ); + const metadataState = useArtifactSelector(selectMetadataState); return { metadata: metadataState?.value ?? null, isFetchMetadataLoading: metadataState?.loading ?? false, fetchMetadataError: metadataState?.error ?? null, - isGitConnected, }; } diff --git a/app/client/src/git/hooks/useOps.ts b/app/client/src/git/hooks/useOps.ts index 32eec997cf25..9b15bd035d85 100644 --- a/app/client/src/git/hooks/useOps.ts +++ b/app/client/src/git/hooks/useOps.ts @@ -5,10 +5,10 @@ import { selectConflictErrorModalOpen, selectOpsModalOpen, selectOpsModalTab, -} from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; +} from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; export default function useOps() { const { artifactDef } = useGitContext(); @@ -16,42 +16,40 @@ export default function useOps() { const dispatch = useDispatch(); // ops modal - const opsModalOpen = useSelector((state: GitRootState) => - selectOpsModalOpen(state, artifactDef), - ); + const opsModalOpen = useArtifactSelector(selectOpsModalOpen); - const opsModalTab = useSelector((state: GitRootState) => - selectOpsModalTab(state, artifactDef), - ); + const opsModalTab = useArtifactSelector(selectOpsModalTab); const toggleOpsModal = useCallback( (open: boolean, tab: keyof typeof GitOpsTab = GitOpsTab.Deploy) => { - dispatch( - gitArtifactActions.toggleOpsModal({ ...artifactDef, open, tab }), - ); + if (artifactDef) { + dispatch(gitArtifactActions.toggleOpsModal({ artifactDef, open, tab })); + } }, [artifactDef, dispatch], ); // conflict error modal - const conflictErrorModalOpen = useSelector((state: GitRootState) => - selectConflictErrorModalOpen(state, artifactDef), + const conflictErrorModalOpen = useArtifactSelector( + selectConflictErrorModalOpen, ); const toggleConflictErrorModal = useCallback( (open: boolean) => { - dispatch( - gitArtifactActions.toggleConflictErrorModal({ ...artifactDef, open }), - ); + if (artifactDef) { + dispatch( + gitArtifactActions.toggleConflictErrorModal({ artifactDef, open }), + ); + } }, [artifactDef, dispatch], ); return { opsModalTab, - opsModalOpen, + isOpsModalOpen: opsModalOpen ?? false, toggleOpsModal, - conflictErrorModalOpen, + isConflictErrorModalOpen: conflictErrorModalOpen ?? false, toggleConflictErrorModal, }; } diff --git a/app/client/src/git/hooks/useProtectedBranches.ts b/app/client/src/git/hooks/useProtectedBranches.ts index fa3b2ef89307..6ec68ee23b74 100644 --- a/app/client/src/git/hooks/useProtectedBranches.ts +++ b/app/client/src/git/hooks/useProtectedBranches.ts @@ -2,55 +2,55 @@ import { useGitContext } from "git/components/GitContextProvider"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { selectFetchProtectedBranchesState, - selectProtectedMode, selectUpdateProtectedBranchesState, -} from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; +} from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; function useProtectedBranches() { const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const fetchProtectedBranchesState = useSelector((state: GitRootState) => - selectFetchProtectedBranchesState(state, artifactDef), + const fetchProtectedBranchesState = useArtifactSelector( + selectFetchProtectedBranchesState, ); const fetchProtectedBranches = useCallback(() => { - dispatch(gitArtifactActions.fetchProtectedBranchesInit(artifactDef)); + if (artifactDef) { + dispatch(gitArtifactActions.fetchProtectedBranchesInit({ artifactDef })); + } }, [dispatch, artifactDef]); - const updateProtectedBranchesState = useSelector((state: GitRootState) => - selectUpdateProtectedBranchesState(state, artifactDef), + const updateProtectedBranchesState = useArtifactSelector( + selectUpdateProtectedBranchesState, ); const updateProtectedBranches = useCallback( (branches: string[]) => { - dispatch( - gitArtifactActions.updateProtectedBranchesInit({ - ...artifactDef, - branchNames: branches, - }), - ); + if (artifactDef) { + dispatch( + gitArtifactActions.updateProtectedBranchesInit({ + artifactDef, + branchNames: branches, + }), + ); + } }, [dispatch, artifactDef], ); - const isProtectedMode = useSelector((state: GitRootState) => - selectProtectedMode(state, artifactDef), - ); - return { - protectedBranches: fetchProtectedBranchesState.value, - isFetchProtectedBranchesLoading: fetchProtectedBranchesState.loading, - fetchProtectedBranchesError: fetchProtectedBranchesState.error, + protectedBranches: fetchProtectedBranchesState?.value ?? null, + isFetchProtectedBranchesLoading: + fetchProtectedBranchesState?.loading ?? false, + fetchProtectedBranchesError: fetchProtectedBranchesState?.error ?? null, fetchProtectedBranches, - isUpdateProtectedBranchesLoading: updateProtectedBranchesState.loading, - updateProtectedBranchesError: updateProtectedBranchesState.error, + isUpdateProtectedBranchesLoading: + updateProtectedBranchesState?.loading ?? false, + updateProtectedBranchesError: updateProtectedBranchesState?.error ?? null, updateProtectedBranches, - isProtectedMode, }; } diff --git a/app/client/src/git/hooks/useProtectedMode.ts b/app/client/src/git/hooks/useProtectedMode.ts new file mode 100644 index 000000000000..e8e86e9f04a2 --- /dev/null +++ b/app/client/src/git/hooks/useProtectedMode.ts @@ -0,0 +1,8 @@ +import { selectProtectedMode } from "git/store/selectors/gitArtifactSelectors"; +import useArtifactSelector from "./useArtifactSelector"; + +export default function useProtectedMode() { + const isProtectedMode = useArtifactSelector(selectProtectedMode); + + return isProtectedMode ?? false; +} diff --git a/app/client/src/git/hooks/usePull.ts b/app/client/src/git/hooks/usePull.ts index 992866f2c277..19900c98f38e 100644 --- a/app/client/src/git/hooks/usePull.ts +++ b/app/client/src/git/hooks/usePull.ts @@ -1,26 +1,26 @@ import { useGitContext } from "git/components/GitContextProvider"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; -import { selectPullState } from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; +import { selectPullState } from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; export default function usePull() { const { artifact, artifactDef } = useGitContext(); const artifactId = artifact?.id; const dispatch = useDispatch(); - const pullState = useSelector((state: GitRootState) => - selectPullState(state, artifactDef), - ); + const pullState = useArtifactSelector(selectPullState); const pull = useCallback(() => { - dispatch( - gitArtifactActions.pullInit({ - ...artifactDef, - artifactId: artifactId ?? "", - }), - ); + if (artifactDef) { + dispatch( + gitArtifactActions.pullInit({ + artifactDef, + artifactId: artifactId ?? "", + }), + ); + } }, [artifactDef, artifactId, dispatch]); return { diff --git a/app/client/src/git/hooks/useSSHKey.ts b/app/client/src/git/hooks/useSSHKey.ts new file mode 100644 index 000000000000..93c95ade8d31 --- /dev/null +++ b/app/client/src/git/hooks/useSSHKey.ts @@ -0,0 +1,63 @@ +import { useGitContext } from "git/components/GitContextProvider"; +import { gitArtifactActions } from "git/store/gitArtifactSlice"; +import { + selectFetchSSHKeysState, + selectGenerateSSHKeyState, +} from "git/store/selectors/gitArtifactSelectors"; +import { useCallback } from "react"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; + +export default function useSSHKey() { + const { artifactDef } = useGitContext(); + + const dispatch = useDispatch(); + + const fetchSSHKeyState = useArtifactSelector(selectFetchSSHKeysState); + + const fetchSSHKey = useCallback(() => { + if (artifactDef) { + dispatch(gitArtifactActions.fetchSSHKeyInit({ artifactDef })); + } + }, [artifactDef, dispatch]); + + const resetFetchSSHKey = useCallback(() => { + if (artifactDef) { + dispatch(gitArtifactActions.resetFetchSSHKey({ artifactDef })); + } + }, [artifactDef, dispatch]); + + const generateSSHKeyState = useArtifactSelector(selectGenerateSSHKeyState); + + const generateSSHKey = useCallback( + (keyType: string) => { + if (artifactDef) { + dispatch( + gitArtifactActions.generateSSHKeyInit({ + artifactDef, + keyType, + }), + ); + } + }, + [artifactDef, dispatch], + ); + + const resetGenerateSSHKey = useCallback(() => { + if (artifactDef) { + dispatch(gitArtifactActions.resetGenerateSSHKey({ artifactDef })); + } + }, [artifactDef, dispatch]); + + return { + sshKey: fetchSSHKeyState?.value ?? null, + isFetchSSHKeyLoading: fetchSSHKeyState?.loading ?? false, + fetchSSHKeyError: fetchSSHKeyState?.error ?? null, + fetchSSHKey, + resetFetchSSHKey, + isGenerateSSHKeyLoading: generateSSHKeyState?.loading ?? false, + generateSSHKeyError: generateSSHKeyState?.error ?? null, + generateSSHKey, + resetGenerateSSHKey, + }; +} diff --git a/app/client/src/git/hooks/useSettings.ts b/app/client/src/git/hooks/useSettings.ts index d94f9c0e530b..0a8b48aa368c 100644 --- a/app/client/src/git/hooks/useSettings.ts +++ b/app/client/src/git/hooks/useSettings.ts @@ -4,39 +4,37 @@ import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { selectSettingsModalOpen, selectSettingsModalTab, -} from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; +} from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; export default function useSettings() { const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const settingsModalOpen = useSelector((state: GitRootState) => - selectSettingsModalOpen(state, artifactDef), - ); + const settingsModalOpen = useArtifactSelector(selectSettingsModalOpen); - const settingsModalTab = useSelector((state: GitRootState) => - selectSettingsModalTab(state, artifactDef), - ); + const settingsModalTab = useArtifactSelector(selectSettingsModalTab); const toggleSettingsModal = useCallback( ( open: boolean, tab: keyof typeof GitSettingsTab = GitSettingsTab.General, ) => { - dispatch( - gitArtifactActions.toggleSettingsModal({ ...artifactDef, open, tab }), - ); + if (artifactDef) { + dispatch( + gitArtifactActions.toggleSettingsModal({ artifactDef, open, tab }), + ); + } }, [artifactDef, dispatch], ); return { isSettingsModalOpen: settingsModalOpen ?? false, - settingsModalTab: settingsModalTab ?? GitSettingsTab.General, + settingsModalTab: settingsModalTab, toggleSettingsModal, }; } diff --git a/app/client/src/git/hooks/useStatus.ts b/app/client/src/git/hooks/useStatus.ts index 97b09b57498a..37a5584911aa 100644 --- a/app/client/src/git/hooks/useStatus.ts +++ b/app/client/src/git/hooks/useStatus.ts @@ -1,31 +1,33 @@ import { useGitContext } from "git/components/GitContextProvider"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; -import { selectStatusState } from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitRootState } from "git/store/types"; +import { selectStatusState } from "git/store/selectors/gitArtifactSelectors"; import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; +import { useDispatch } from "react-redux"; +import useArtifactSelector from "./useArtifactSelector"; export default function useStatus() { - const { artifactDef } = useGitContext(); + const { artifact, artifactDef } = useGitContext(); + const artifactId = artifact?.id; const dispatch = useDispatch(); - const statusState = useSelector((state: GitRootState) => - selectStatusState(state, artifactDef), - ); + const statusState = useArtifactSelector(selectStatusState); const fetchStatus = useCallback(() => { - dispatch( - gitArtifactActions.fetchStatusInit({ - ...artifactDef, - compareRemote: true, - }), - ); - }, [artifactDef, dispatch]); + if (artifactDef && artifactId) { + dispatch( + gitArtifactActions.fetchStatusInit({ + artifactId, + artifactDef, + compareRemote: true, + }), + ); + } + }, [artifactDef, artifactId, dispatch]); return { - status: statusState?.value, + status: statusState?.value ?? null, isFetchStatusLoading: statusState?.loading ?? false, - fetchStatusError: statusState?.error, + fetchStatusError: statusState?.error ?? null, fetchStatus, }; } diff --git a/app/client/src/git/index.ts b/app/client/src/git/index.ts new file mode 100644 index 000000000000..892ca77d7f43 --- /dev/null +++ b/app/client/src/git/index.ts @@ -0,0 +1,39 @@ +// enums +export { GitArtifactType, GitOpsTab } from "./constants/enums"; + +// components +export { default as GitContextProvider } from "./components/GitContextProvider"; +export { default as GitModals } from "./ee/components/GitModals"; +export { default as GitImportModal } from "./components/ImportModal"; +export { default as GitQuickActions } from "./components/QuickActions"; +export { default as GitProtectedBranchCallout } from "./components/ProtectedBranchCallout"; +export { default as GitGlobalProfile } from "./components/GlobalProfile"; +export { default as GitDeployMenuItems } from "./components/DeployMenuItems"; + +// hooks +export { default as useGitCurrentBranch } from "./hooks/useCurrentBranch"; +export { default as useGitProtectedMode } from "./hooks/useProtectedMode"; +export { default as useGitConnected } from "./hooks/useConnected"; +export { default as useGitOps } from "./hooks/useOps"; + +// actions +import { gitGlobalActions } from "./store/gitGlobalSlice"; +export const fetchGitGlobalProfile = gitGlobalActions.fetchGlobalProfileInit; +export const toggleGitImportModal = gitGlobalActions.toggleImportModal; + +import { gitArtifactActions } from "./store/gitArtifactSlice"; +export const gitConnectSuccess = gitArtifactActions.connectSuccess; + +// selectors +export { + selectCurrentBranch as selectGitCurrentBranch, + selectProtectedMode as selectGitProtectedMode, +} from "./store/selectors/gitArtifactSelectors"; + +// types +export type { + GitArtifactDef, + GitArtifactRootReduxState, + GitGlobalReduxState, +} from "./store/types"; +export type { ConnectSuccessPayload as GitConnectSuccessPayload } from "./store/actions/connectActions"; diff --git a/app/client/src/git/requests/connectRequest.types.ts b/app/client/src/git/requests/connectRequest.types.ts index 7e31cf32bf82..d47cc4114b21 100644 --- a/app/client/src/git/requests/connectRequest.types.ts +++ b/app/client/src/git/requests/connectRequest.types.ts @@ -1,4 +1,5 @@ import type { ApiResponse } from "api/types"; +import type { ApplicationPayload } from "entities/Application"; export interface ConnectRequestParams { remoteUrl: string; @@ -9,20 +10,6 @@ export interface ConnectRequestParams { }; } -export interface ConnectResponseData { - id: string; - baseId: string; - gitApplicationMetadata: { - branchName: string; - browserSupportedRemoteUrl: string; - defaultApplicationId: string; - defaultArtifactId: string; - defaultBranchName: string; - isRepoPrivate: boolean; - lastCommitedAt: string; - remoteUrl: string; - repoName: string; - }; -} +export interface ConnectResponseData extends ApplicationPayload {} export type ConnectResponse = ApiResponse; diff --git a/app/client/src/git/requests/disconnectRequest.types.ts b/app/client/src/git/requests/disconnectRequest.types.ts index 2cbf5969ccca..b1cd5827d951 100644 --- a/app/client/src/git/requests/disconnectRequest.types.ts +++ b/app/client/src/git/requests/disconnectRequest.types.ts @@ -1,7 +1,6 @@ import type { ApiResponse } from "api/types"; +import type { ApplicationPayload } from "entities/Application"; -export interface DisconnectResponseData { - [key: string]: string; -} +export interface DisconnectResponseData extends ApplicationPayload {} export type DisconnectResponse = ApiResponse; diff --git a/app/client/src/git/requests/fetchGlobalSSHKeyRequest.ts b/app/client/src/git/requests/fetchGlobalSSHKeyRequest.ts new file mode 100644 index 000000000000..00d900637f42 --- /dev/null +++ b/app/client/src/git/requests/fetchGlobalSSHKeyRequest.ts @@ -0,0 +1,15 @@ +import type { AxiosPromise } from "axios"; +import { GIT_BASE_URL } from "./constants"; +import Api from "api/Api"; +import type { + FetchGlobalSSHKeyRequestParams, + FetchGlobalSSHKeyResponse, +} from "./fetchGlobalSSHKeyRequest.types"; + +export default async function fetchGlobalSSHKeyRequest( + params: FetchGlobalSSHKeyRequestParams, +): AxiosPromise { + const url = `${GIT_BASE_URL}/import/keys?keyType=${params.keyType}`; + + return Api.get(url); +} diff --git a/app/client/src/git/requests/fetchGlobalSSHKeyRequest.types.ts b/app/client/src/git/requests/fetchGlobalSSHKeyRequest.types.ts new file mode 100644 index 000000000000..7b092ceccff2 --- /dev/null +++ b/app/client/src/git/requests/fetchGlobalSSHKeyRequest.types.ts @@ -0,0 +1,15 @@ +import type { ApiResponse } from "api/types"; + +export interface FetchGlobalSSHKeyRequestParams { + keyType: string; +} + +export interface FetchGlobalSSHKeyResponseData { + publicKey: string; + docUrl: string; + isRegeneratedKey: boolean; + regeneratedKey: boolean; +} + +export type FetchGlobalSSHKeyResponse = + ApiResponse; diff --git a/app/client/src/git/requests/fetchStatusRequest.types.ts b/app/client/src/git/requests/fetchStatusRequest.types.ts index c4400688b794..feb064d3618d 100644 --- a/app/client/src/git/requests/fetchStatusRequest.types.ts +++ b/app/client/src/git/requests/fetchStatusRequest.types.ts @@ -24,6 +24,7 @@ export interface FetchStatusResponseData { modifiedDatasources: number; modifiedJSLibs: number; modifiedJSObjects: number; + modifiedPackages: number; modifiedModuleInstances: number; modifiedModules: number; modifiedPages: number; diff --git a/app/client/src/git/requests/generateSSHKeyRequest.ts b/app/client/src/git/requests/generateSSHKeyRequest.ts index 896426347f30..b0bea4f20ff8 100644 --- a/app/client/src/git/requests/generateSSHKeyRequest.ts +++ b/app/client/src/git/requests/generateSSHKeyRequest.ts @@ -3,16 +3,14 @@ import type { GenerateSSHKeyRequestParams, GenerateSSHKeyResponse, } from "./generateSSHKeyRequest.types"; -import { APPLICATION_BASE_URL, GIT_BASE_URL } from "./constants"; +import { APPLICATION_BASE_URL } from "./constants"; import Api from "api/Api"; export default async function generateSSHKeyRequest( baseApplicationId: string, params: GenerateSSHKeyRequestParams, ): AxiosPromise { - const url = params.isImport - ? `${GIT_BASE_URL}/import/keys?keyType=${params.keyType}` - : `${APPLICATION_BASE_URL}/ssh-keypair/${baseApplicationId}?keyType=${params.keyType}`; + const url = `${APPLICATION_BASE_URL}/ssh-keypair/${baseApplicationId}?keyType=${params.keyType}`; - return params.isImport ? Api.get(url) : Api.post(url); + return Api.post(url); } diff --git a/app/client/src/git/requests/generateSSHKeyRequest.types.ts b/app/client/src/git/requests/generateSSHKeyRequest.types.ts index 45374e42d5b1..fbc4a4c0e959 100644 --- a/app/client/src/git/requests/generateSSHKeyRequest.types.ts +++ b/app/client/src/git/requests/generateSSHKeyRequest.types.ts @@ -2,7 +2,6 @@ import type { ApiResponse } from "api/types"; export interface GenerateSSHKeyRequestParams { keyType: string; - isImport: boolean; } export interface GenerateSSHKeyResponseData { diff --git a/app/client/src/git/requests/gitImportRequest.types.ts b/app/client/src/git/requests/gitImportRequest.types.ts index 9f76b379c9cc..4eb29b11a88b 100644 --- a/app/client/src/git/requests/gitImportRequest.types.ts +++ b/app/client/src/git/requests/gitImportRequest.types.ts @@ -1,4 +1,6 @@ import type { ApiResponse } from "api/types"; +import type { ApplicationResponsePayload } from "ee/api/ApplicationApi"; +import type { Datasource } from "entities/Datasource"; export interface GitImportRequestParams { remoteUrl: string; @@ -10,19 +12,9 @@ export interface GitImportRequestParams { } export interface GitImportResponseData { - id: string; - baseId: string; - gitApplicationMetadata: { - branchName: string; - browserSupportedRemoteUrl: string; - defaultApplicationId: string; - defaultArtifactId: string; - defaultBranchName: string; - isRepoPrivate: boolean; - lastCommitedAt: string; - remoteUrl: string; - repoName: string; - }; + application: ApplicationResponsePayload; + isPartialImport: boolean; + unconfiguredDatasourceList?: Datasource[]; } export type GitImportResponse = ApiResponse; diff --git a/app/client/src/git/sagas/checkoutBranchSaga.ts b/app/client/src/git/sagas/checkoutBranchSaga.ts index 34e48434626c..7fc454f36bc0 100644 --- a/app/client/src/git/sagas/checkoutBranchSaga.ts +++ b/app/client/src/git/sagas/checkoutBranchSaga.ts @@ -25,8 +25,7 @@ import { captureException } from "@sentry/react"; export default function* checkoutBranchSaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId, branchName } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef, artifactId, branchName } = action.payload; let response: CheckoutBranchResponse | undefined; try { @@ -34,12 +33,12 @@ export default function* checkoutBranchSaga( branchName, }; - response = yield call(checkoutBranchRequest, baseArtifactId, params); + response = yield call(checkoutBranchRequest, artifactId, params); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { - if (artifactType === GitArtifactType.Application) { - yield put(gitArtifactActions.checkoutBranchSuccess(basePayload)); + if (artifactDef.artifactType === GitArtifactType.Application) { + yield put(gitArtifactActions.checkoutBranchSuccess({ artifactDef })); const trimmedBranch = branchName.replace(/^origin\//, ""); const destinationHref = addBranchParam(trimmedBranch); @@ -49,7 +48,7 @@ export default function* checkoutBranchSaga( yield put( gitArtifactActions.toggleBranchPopup({ - ...basePayload, + artifactDef, open: false, }), ); @@ -118,7 +117,7 @@ export default function* checkoutBranchSaga( yield put( gitArtifactActions.checkoutBranchError({ - ...basePayload, + artifactDef, error, }), ); diff --git a/app/client/src/git/sagas/commitSaga.ts b/app/client/src/git/sagas/commitSaga.ts index 159021acc145..7ebcb70b9a71 100644 --- a/app/client/src/git/sagas/commitSaga.ts +++ b/app/client/src/git/sagas/commitSaga.ts @@ -17,8 +17,7 @@ import { validateResponse } from "sagas/ErrorSagas"; export default function* commitSaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef, artifactId } = action.payload; let response: CommitResponse | undefined; @@ -28,20 +27,21 @@ export default function* commitSaga( doPush: action.payload.doPush, }; - response = yield call(commitRequest, baseArtifactId, params); + response = yield call(commitRequest, artifactId, params); const isValidResponse: boolean = yield validateResponse(response, false); if (isValidResponse) { - yield put(gitArtifactActions.commitSuccess(basePayload)); + yield put(gitArtifactActions.commitSuccess({ artifactDef })); yield put( gitArtifactActions.fetchStatusInit({ - ...basePayload, + artifactDef, + artifactId, compareRemote: true, }), ); - if (artifactType === GitArtifactType.Application) { + if (artifactDef.artifactType === GitArtifactType.Application) { // ! case for updating lastDeployedAt in application manually? } } @@ -52,13 +52,13 @@ export default function* commitSaga( if (error.code === GitErrorCodes.REPO_LIMIT_REACHED) { yield put( gitArtifactActions.toggleRepoLimitErrorModal({ - ...basePayload, + artifactDef, open: true, }), ); } - yield put(gitArtifactActions.commitError({ ...basePayload, error })); + yield put(gitArtifactActions.commitError({ artifactDef, error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/connectSaga.ts b/app/client/src/git/sagas/connectSaga.ts index b13c2f6c2c2a..b6de0cdea53e 100644 --- a/app/client/src/git/sagas/connectSaga.ts +++ b/app/client/src/git/sagas/connectSaga.ts @@ -8,7 +8,7 @@ import { GitArtifactType, GitErrorCodes } from "../constants/enums"; import type { GitArtifactPayloadAction } from "../store/types"; import type { ConnectInitPayload } from "../store/actions/connectActions"; -import { call, put } from "redux-saga/effects"; +import { call, put, select } from "redux-saga/effects"; // Internal dependencies import { validateResponse } from "sagas/ErrorSagas"; @@ -17,12 +17,12 @@ import history from "utils/history"; import { addBranchParam } from "constants/routes"; import log from "loglevel"; import { captureException } from "@sentry/react"; +import { getCurrentPageId } from "selectors/editorSelectors"; export default function* connectSaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef } = action.payload; let response: ConnectResponse | undefined; @@ -32,34 +32,50 @@ export default function* connectSaga( gitProfile: action.payload.gitProfile, }; - response = yield call(connectRequest, baseArtifactId, params); + response = yield call(connectRequest, artifactDef.baseArtifactId, params); const isValidResponse: boolean = yield validateResponse(response, false); if (response && isValidResponse) { - yield put(gitArtifactActions.connectSuccess(basePayload)); + yield put( + gitArtifactActions.connectSuccess({ + artifactDef, + responseData: response.data, + }), + ); // needs to happen only when artifactType is application - if (artifactType === GitArtifactType.Application) { - const { branchedPageId } = action.payload; + if (artifactDef.artifactType === GitArtifactType.Application) { + const pageId: string = yield select(getCurrentPageId); - if (branchedPageId) { - yield put(fetchPageAction(branchedPageId)); - } + yield put(fetchPageAction(pageId)); + + const branch = response.data?.gitApplicationMetadata?.branchName; + + if (branch) { + const newUrl = addBranchParam(branch); - const branch = response.data.gitApplicationMetadata.branchName; - const newUrl = addBranchParam(branch); + history.replace(newUrl); + } - history.replace(newUrl); // ! case for updating lastDeployedAt in application manually? } yield put( gitArtifactActions.initGitForEditor({ - ...basePayload, + artifactDef, artifact: response.data, }), ); + yield put( + gitArtifactActions.toggleConnectModal({ artifactDef, open: false }), + ); + yield put( + gitArtifactActions.toggleConnectSuccessModal({ + artifactDef, + open: true, + }), + ); } } catch (e) { if (response && response.responseMeta.error) { @@ -68,13 +84,13 @@ export default function* connectSaga( if (GitErrorCodes.REPO_LIMIT_REACHED === error.code) { yield put( gitArtifactActions.toggleRepoLimitErrorModal({ - ...basePayload, + artifactDef, open: true, }), ); } - yield put(gitArtifactActions.connectError({ ...basePayload, error })); + yield put(gitArtifactActions.connectError({ artifactDef, error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/createBranchSaga.ts b/app/client/src/git/sagas/createBranchSaga.ts index 7796f43d74bd..d8aa65418977 100644 --- a/app/client/src/git/sagas/createBranchSaga.ts +++ b/app/client/src/git/sagas/createBranchSaga.ts @@ -16,8 +16,8 @@ import log from "loglevel"; export default function* createBranchSaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef, artifactId } = action.payload; + const basePayload = { artifactDef }; let response: CreateBranchResponse | undefined; try { @@ -25,27 +25,29 @@ export default function* createBranchSaga( branchName: action.payload.branchName, }; - response = yield call(createBranchRequest, baseArtifactId, params); + response = yield call(createBranchRequest, artifactId, params); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { yield put(gitArtifactActions.createBranchSuccess(basePayload)); yield put( gitArtifactActions.toggleBranchPopup({ - ...basePayload, + artifactDef, open: false, }), ); yield put( gitArtifactActions.fetchBranchesInit({ - ...basePayload, + artifactDef, + artifactId, pruneBranches: true, }), ); yield put( gitArtifactActions.checkoutBranchInit({ - ...basePayload, + artifactDef, + artifactId, branchName: action.payload.branchName, }), ); @@ -56,7 +58,7 @@ export default function* createBranchSaga( yield put( gitArtifactActions.createBranchError({ - ...basePayload, + artifactDef, error, }), ); diff --git a/app/client/src/git/sagas/deleteBranchSaga.ts b/app/client/src/git/sagas/deleteBranchSaga.ts index 4f6bdde2f7fc..ecf560889f1c 100644 --- a/app/client/src/git/sagas/deleteBranchSaga.ts +++ b/app/client/src/git/sagas/deleteBranchSaga.ts @@ -16,8 +16,7 @@ import { captureException } from "@sentry/react"; export default function* deleteBranchSaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef, artifactId } = action.payload; let response: DeleteBranchResponse | undefined; try { @@ -25,14 +24,19 @@ export default function* deleteBranchSaga( branchName: action.payload.branchName, }; - response = yield call(deleteBranchRequest, baseArtifactId, params); + response = yield call( + deleteBranchRequest, + artifactDef.baseArtifactId, + params, + ); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { - yield put(gitArtifactActions.deleteBranchSuccess(basePayload)); + yield put(gitArtifactActions.deleteBranchSuccess({ artifactDef })); yield put( gitArtifactActions.fetchBranchesInit({ - ...basePayload, + artifactDef, + artifactId, pruneBranches: true, }), ); @@ -41,12 +45,7 @@ export default function* deleteBranchSaga( if (response && response.responseMeta.error) { const { error } = response.responseMeta; - yield put( - gitArtifactActions.deleteBranchError({ - ...basePayload, - error, - }), - ); + yield put(gitArtifactActions.deleteBranchError({ artifactDef, error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/disconnectSaga.ts b/app/client/src/git/sagas/disconnectSaga.ts index 3dc25f1ff079..ef6315c25cd5 100644 --- a/app/client/src/git/sagas/disconnectSaga.ts +++ b/app/client/src/git/sagas/disconnectSaga.ts @@ -12,26 +12,30 @@ import { validateResponse } from "sagas/ErrorSagas"; import history from "utils/history"; export default function* disconnectSaga(action: GitArtifactPayloadAction) { - const { artifactType, baseArtifactId } = action.payload; - const artifactDef = { artifactType, baseArtifactId }; + const { artifactDef } = action.payload; let response: DisconnectResponse | undefined; try { - response = yield call(disconnectRequest, baseArtifactId); + response = yield call(disconnectRequest, artifactDef.baseArtifactId); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { - yield put(gitArtifactActions.disconnectSuccess(artifactDef)); + yield put(gitArtifactActions.disconnectSuccess({ artifactDef })); const url = new URL(window.location.href); url.searchParams.delete(GIT_BRANCH_QUERY_KEY); - history.push(url.toString().slice(url.origin.length)); - yield put(gitArtifactActions.closeDisconnectModal(artifactDef)); - // !case: why? - // yield put(importAppViaGitStatusReset()); + history.replace(url.toString().slice(url.origin.length)); + yield put(gitArtifactActions.unmount({ artifactDef })); + yield put( + gitArtifactActions.initGitForEditor({ + artifactDef, + artifact: response.data, + }), + ); + yield put(gitArtifactActions.closeDisconnectModal({ artifactDef })); yield put( gitArtifactActions.toggleOpsModal({ - ...artifactDef, + artifactDef, open: false, tab: GitOpsTab.Deploy, }), @@ -52,7 +56,7 @@ export default function* disconnectSaga(action: GitArtifactPayloadAction) { if (response && response.responseMeta.error) { const { error } = response.responseMeta; - yield put(gitArtifactActions.disconnectError({ ...artifactDef, error })); + yield put(gitArtifactActions.disconnectError({ artifactDef, error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/fetchBranchesSaga.ts b/app/client/src/git/sagas/fetchBranchesSaga.ts index 465310e01a4f..5141db03e34f 100644 --- a/app/client/src/git/sagas/fetchBranchesSaga.ts +++ b/app/client/src/git/sagas/fetchBranchesSaga.ts @@ -14,8 +14,7 @@ import { captureException } from "@sentry/react"; export default function* fetchBranchesSaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef, artifactId } = action.payload; let response: FetchBranchesResponse | undefined; try { @@ -23,13 +22,13 @@ export default function* fetchBranchesSaga( pruneBranches: action.payload.pruneBranches, }; - response = yield call(fetchBranchesRequest, baseArtifactId, params); + response = yield call(fetchBranchesRequest, artifactId, params); const isValidResponse: boolean = yield validateResponse(response, false); if (response && isValidResponse) { yield put( gitArtifactActions.fetchBranchesSuccess({ - ...basePayload, + artifactDef, responseData: response.data, }), ); @@ -40,7 +39,7 @@ export default function* fetchBranchesSaga( yield put( gitArtifactActions.fetchBranchesError({ - ...basePayload, + artifactDef, error, }), ); diff --git a/app/client/src/git/sagas/fetchGlobalProfileSaga.ts b/app/client/src/git/sagas/fetchGlobalProfileSaga.ts index 71e7ca1a9c29..86713acf8787 100644 --- a/app/client/src/git/sagas/fetchGlobalProfileSaga.ts +++ b/app/client/src/git/sagas/fetchGlobalProfileSaga.ts @@ -1,12 +1,12 @@ import { call, put } from "redux-saga/effects"; import fetchGlobalProfileRequest from "../requests/fetchGlobalProfileRequest"; import type { FetchGlobalProfileResponse } from "../requests/fetchGlobalProfileRequest.types"; -import { gitConfigActions } from "../store/gitConfigSlice"; // internal dependencies import { validateResponse } from "sagas/ErrorSagas"; import log from "loglevel"; import { captureException } from "@sentry/react"; +import { gitGlobalActions } from "git/store/gitGlobalSlice"; export default function* fetchGlobalProfileSaga() { let response: FetchGlobalProfileResponse | undefined; @@ -18,7 +18,7 @@ export default function* fetchGlobalProfileSaga() { if (response && isValidResponse) { yield put( - gitConfigActions.fetchGlobalProfileSuccess({ + gitGlobalActions.fetchGlobalProfileSuccess({ responseData: response.data, }), ); @@ -28,7 +28,7 @@ export default function* fetchGlobalProfileSaga() { const { error } = response.responseMeta; yield put( - gitConfigActions.fetchGlobalProfileError({ + gitGlobalActions.fetchGlobalProfileError({ error, }), ); diff --git a/app/client/src/git/sagas/fetchGlobalSSHKeySaga.ts b/app/client/src/git/sagas/fetchGlobalSSHKeySaga.ts new file mode 100644 index 000000000000..e72711961844 --- /dev/null +++ b/app/client/src/git/sagas/fetchGlobalSSHKeySaga.ts @@ -0,0 +1,44 @@ +import { captureException } from "@sentry/react"; +import fetchGlobalSSHKeyRequest from "git/requests/fetchGlobalSSHKeyRequest"; +import type { + GenerateSSHKeyRequestParams, + GenerateSSHKeyResponse, +} from "git/requests/generateSSHKeyRequest.types"; +import type { FetchGlobalSSHKeyInitPayload } from "git/store/actions/fetchGlobalSSHKeyActions"; +import { gitGlobalActions } from "git/store/gitGlobalSlice"; +import type { GitArtifactPayloadAction } from "git/store/types"; +import log from "loglevel"; +import { call, put } from "redux-saga/effects"; +import { validateResponse } from "sagas/ErrorSagas"; + +export function* fetchGlobalSSHKeySaga( + action: GitArtifactPayloadAction, +) { + let response: GenerateSSHKeyResponse | undefined; + + try { + const params: GenerateSSHKeyRequestParams = { + keyType: action.payload.keyType, + }; + + response = yield call(fetchGlobalSSHKeyRequest, params); + const isValidResponse: boolean = yield validateResponse(response); + + if (response && isValidResponse) { + yield put( + gitGlobalActions.fetchGlobalSSHKeySuccess({ + responseData: response.data, + }), + ); + } + } catch (e) { + if (response && response.responseMeta.error) { + const { error } = response.responseMeta; + + yield put(gitGlobalActions.fetchGlobalSSHKeyError({ error })); + } else { + log.error(e); + captureException(e); + } + } +} diff --git a/app/client/src/git/sagas/fetchLocalProfileSaga.ts b/app/client/src/git/sagas/fetchLocalProfileSaga.ts index c568129beab9..28f24ef2198d 100644 --- a/app/client/src/git/sagas/fetchLocalProfileSaga.ts +++ b/app/client/src/git/sagas/fetchLocalProfileSaga.ts @@ -10,18 +10,17 @@ import { captureException } from "@sentry/react"; export default function* fetchLocalProfileSaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef } = action.payload; let response: FetchLocalProfileResponse | undefined; try { - response = yield call(fetchLocalProfileRequest, baseArtifactId); + response = yield call(fetchLocalProfileRequest, artifactDef.baseArtifactId); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { yield put( gitArtifactActions.fetchLocalProfileSuccess({ - ...basePayload, + artifactDef, responseData: response.data, }), ); @@ -31,7 +30,7 @@ export default function* fetchLocalProfileSaga( const { error } = response.responseMeta; yield put( - gitArtifactActions.fetchLocalProfileError({ ...basePayload, error }), + gitArtifactActions.fetchLocalProfileError({ artifactDef, error }), ); } else { log.error(e); diff --git a/app/client/src/git/sagas/fetchMergeStatusSaga.ts b/app/client/src/git/sagas/fetchMergeStatusSaga.ts index 684233de206d..024954b017c5 100644 --- a/app/client/src/git/sagas/fetchMergeStatusSaga.ts +++ b/app/client/src/git/sagas/fetchMergeStatusSaga.ts @@ -14,8 +14,7 @@ import { validateResponse } from "sagas/ErrorSagas"; export default function* fetchMergeStatusSaga( action: GitArtifactPayloadAction, ) { - const { artifactId, artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef, artifactId } = action.payload; let response: FetchMergeStatusResponse | undefined; try { @@ -30,7 +29,7 @@ export default function* fetchMergeStatusSaga( if (response && isValidResponse) { yield put( gitArtifactActions.fetchMergeStatusSuccess({ - ...basePayload, + artifactDef, responseData: response.data, }), ); @@ -40,10 +39,7 @@ export default function* fetchMergeStatusSaga( const { error } = response.responseMeta; yield put( - gitArtifactActions.fetchMergeStatusError({ - ...basePayload, - error, - }), + gitArtifactActions.fetchMergeStatusError({ artifactDef, error }), ); } else { log.error(e); diff --git a/app/client/src/git/sagas/fetchMetadataSaga.ts b/app/client/src/git/sagas/fetchMetadataSaga.ts index 3e2029b6c6b8..9f8285847ee7 100644 --- a/app/client/src/git/sagas/fetchMetadataSaga.ts +++ b/app/client/src/git/sagas/fetchMetadataSaga.ts @@ -8,18 +8,17 @@ import { call, put } from "redux-saga/effects"; import { validateResponse } from "sagas/ErrorSagas"; export default function* fetchMetadataSaga(action: GitArtifactPayloadAction) { - const { artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef } = action.payload; let response: FetchMetadataResponse | undefined; try { - response = yield call(fetchMetadataRequest, baseArtifactId); + response = yield call(fetchMetadataRequest, artifactDef.baseArtifactId); const isValidResponse: boolean = yield validateResponse(response, false); if (response && isValidResponse) { yield put( gitArtifactActions.fetchMetadataSuccess({ - ...basePayload, + artifactDef, responseData: response.data, }), ); @@ -30,7 +29,7 @@ export default function* fetchMetadataSaga(action: GitArtifactPayloadAction) { yield put( gitArtifactActions.fetchMetadataError({ - ...basePayload, + artifactDef, error, }), ); diff --git a/app/client/src/git/sagas/fetchProtectedBranchesSaga.ts b/app/client/src/git/sagas/fetchProtectedBranchesSaga.ts index 9c81123ea26f..62f36f8ce93c 100644 --- a/app/client/src/git/sagas/fetchProtectedBranchesSaga.ts +++ b/app/client/src/git/sagas/fetchProtectedBranchesSaga.ts @@ -10,19 +10,21 @@ import { validateResponse } from "sagas/ErrorSagas"; export default function* fetchProtectedBranchesSaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef } = action.payload; let response: FetchProtectedBranchesResponse | undefined; try { - response = yield call(fetchProtectedBranchesRequest, baseArtifactId); + response = yield call( + fetchProtectedBranchesRequest, + artifactDef.baseArtifactId, + ); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { yield put( gitArtifactActions.fetchProtectedBranchesSuccess({ - ...basePayload, + artifactDef, responseData: response.data, }), ); @@ -33,7 +35,7 @@ export default function* fetchProtectedBranchesSaga( yield put( gitArtifactActions.fetchProtectedBranchesError({ - ...basePayload, + artifactDef, error, }), ); diff --git a/app/client/src/git/sagas/fetchSSHKeySaga.ts b/app/client/src/git/sagas/fetchSSHKeySaga.ts index 02f797edae66..16736e92f5d1 100644 --- a/app/client/src/git/sagas/fetchSSHKeySaga.ts +++ b/app/client/src/git/sagas/fetchSSHKeySaga.ts @@ -8,18 +8,17 @@ import { call, put } from "redux-saga/effects"; import { validateResponse } from "sagas/ErrorSagas"; export function* fetchSSHKeySaga(action: GitArtifactPayloadAction) { - const { artifactType, baseArtifactId } = action.payload; - const artifactDef = { artifactType, baseArtifactId }; + const { artifactDef } = action.payload; let response: FetchSSHKeyResponse | undefined; try { - response = yield call(fetchSSHKeyRequest, baseArtifactId); + response = yield call(fetchSSHKeyRequest, artifactDef.baseArtifactId); const isValidResponse: boolean = yield validateResponse(response, false); if (response && isValidResponse) { yield put( gitArtifactActions.fetchSSHKeySuccess({ - ...artifactDef, + artifactDef, responseData: response.data, }), ); @@ -28,7 +27,7 @@ export function* fetchSSHKeySaga(action: GitArtifactPayloadAction) { if (response && response.responseMeta.error) { const { error } = response.responseMeta; - yield put(gitArtifactActions.fetchSSHKeyError({ ...artifactDef, error })); + yield put(gitArtifactActions.fetchSSHKeyError({ artifactDef, error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/fetchStatusSaga.ts b/app/client/src/git/sagas/fetchStatusSaga.ts index 4c714a22c0da..733f18cce776 100644 --- a/app/client/src/git/sagas/fetchStatusSaga.ts +++ b/app/client/src/git/sagas/fetchStatusSaga.ts @@ -11,18 +11,17 @@ import { validateResponse } from "sagas/ErrorSagas"; export default function* fetchStatusSaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef, artifactId } = action.payload; let response: FetchStatusResponse | undefined; try { - response = yield call(fetchStatusRequest, baseArtifactId); + response = yield call(fetchStatusRequest, artifactId); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { yield put( gitArtifactActions.fetchStatusSuccess({ - ...basePayload, + artifactDef, responseData: response.data, }), ); @@ -33,7 +32,7 @@ export default function* fetchStatusSaga( yield put( gitArtifactActions.fetchStatusError({ - ...basePayload, + artifactDef, error, }), ); diff --git a/app/client/src/git/sagas/generateSSHKeySaga.ts b/app/client/src/git/sagas/generateSSHKeySaga.ts index 09773f9dc0d4..afbccf24b2e6 100644 --- a/app/client/src/git/sagas/generateSSHKeySaga.ts +++ b/app/client/src/git/sagas/generateSSHKeySaga.ts @@ -15,23 +15,25 @@ import { validateResponse } from "sagas/ErrorSagas"; export function* generateSSHKeySaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId } = action.payload; - const artifactDef = { artifactType, baseArtifactId }; + const { artifactDef } = action.payload; let response: GenerateSSHKeyResponse | undefined; try { const params: GenerateSSHKeyRequestParams = { keyType: action.payload.keyType, - isImport: action.payload.isImport, }; - response = yield call(generateSSHKeyRequest, baseArtifactId, params); + response = yield call( + generateSSHKeyRequest, + artifactDef.baseArtifactId, + params, + ); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { yield put( gitArtifactActions.generateSSHKeySuccess({ - ...artifactDef, + artifactDef, responseData: response.data, }), ); @@ -43,15 +45,13 @@ export function* generateSSHKeySaga( if (GitErrorCodes.REPO_LIMIT_REACHED === error.code) { yield put( gitArtifactActions.toggleRepoLimitErrorModal({ - ...artifactDef, + artifactDef, open: true, }), ); } - yield put( - gitArtifactActions.generateSSHKeyError({ ...artifactDef, error }), - ); + yield put(gitArtifactActions.generateSSHKeyError({ artifactDef, error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/gitImportSaga.ts b/app/client/src/git/sagas/gitImportSaga.ts new file mode 100644 index 000000000000..ecf3d718ae08 --- /dev/null +++ b/app/client/src/git/sagas/gitImportSaga.ts @@ -0,0 +1,92 @@ +import log from "loglevel"; +import { call, put, select } from "redux-saga/effects"; +import { validateResponse } from "sagas/ErrorSagas"; +import history from "utils/history"; +import { toast } from "@appsmith/ads"; +import type { PayloadAction } from "@reduxjs/toolkit"; +import { captureException } from "@sentry/react"; +import gitImportRequest from "git/requests/gitImportRequest"; +import type { GitImportResponse } from "git/requests/gitImportRequest.types"; +import type { GitImportInitPayload } from "git/store/actions/gitImportActions"; +import { gitGlobalActions } from "git/store/gitGlobalSlice"; +import { createMessage, IMPORT_APP_SUCCESSFUL } from "ee/constants/messages"; +import { builderURL } from "ee/RouteBuilder"; +import { getWorkspaceIdForImport } from "ee/selectors/applicationSelectors"; +import { showReconnectDatasourceModal } from "ee/actions/applicationActions"; +import type { Workspace } from "ee/constants/workspaceConstants"; +import { getFetchedWorkspaces } from "ee/selectors/workspaceSelectors"; + +export default function* gitImportSaga( + action: PayloadAction, +) { + const { ...params } = action.payload; + const workspaceId: string = yield select(getWorkspaceIdForImport); + + let response: GitImportResponse | undefined; + + try { + response = yield call(gitImportRequest, workspaceId, params); + const isValidResponse: boolean = yield validateResponse(response); + + if (response && isValidResponse) { + const allWorkspaces: Workspace[] = yield select(getFetchedWorkspaces); + const currentWorkspace = allWorkspaces.filter( + (el: Workspace) => el.id === workspaceId, + ); + + if (currentWorkspace.length > 0) { + const { application, isPartialImport, unconfiguredDatasourceList } = + response.data; + + yield put(gitGlobalActions.gitImportSuccess()); + yield put(gitGlobalActions.toggleImportModal({ open: false })); + + // there is configuration-missing datasources + if (isPartialImport) { + yield put( + showReconnectDatasourceModal({ + application: application, + unConfiguredDatasourceList: unconfiguredDatasourceList ?? [], + workspaceId, + }), + ); + } else { + let basePageId = ""; + + if (application.pages && application.pages.length > 0) { + const defaultPage = application.pages.find( + (eachPage) => !!eachPage.isDefault, + ); + + basePageId = defaultPage ? defaultPage.baseId : ""; + } + + const pageURL = builderURL({ + basePageId, + }); + + history.push(pageURL); + toast.show(createMessage(IMPORT_APP_SUCCESSFUL), { + kind: "success", + }); + } + } + } + } catch (e) { + // const isRepoLimitReachedError: boolean = yield call( + // handleRepoLimitReachedError, + // response, + // ); + + // if (isRepoLimitReachedError) return; + + if (response?.responseMeta?.error) { + yield put( + gitGlobalActions.gitImportError({ error: response.responseMeta.error }), + ); + } else { + log.error(e); + captureException(e); + } + } +} diff --git a/app/client/src/git/sagas/index.ts b/app/client/src/git/sagas/index.ts index 13e19bd4c9f8..61c0a0747330 100644 --- a/app/client/src/git/sagas/index.ts +++ b/app/client/src/git/sagas/index.ts @@ -8,7 +8,6 @@ import { import type { TakeableChannel } from "redux-saga"; import type { PayloadAction } from "@reduxjs/toolkit"; import { objectKeys } from "@appsmith/utils"; -import { gitConfigActions } from "../store/gitConfigSlice"; import { gitArtifactActions } from "../store/gitArtifactSlice"; import connectSaga from "./connectSaga"; import commitSaga from "./commitSaga"; @@ -37,6 +36,9 @@ import { blockingActionSagas as blockingActionSagasExtended, nonBlockingActionSagas as nonBlockingActionSagasExtended, } from "git/ee/sagas"; +import { gitGlobalActions } from "git/store/gitGlobalSlice"; +import { fetchGlobalSSHKeySaga } from "./fetchGlobalSSHKeySaga"; +import gitImportSaga from "./gitImportSaga"; const blockingActionSagas: Record< string, @@ -50,6 +52,9 @@ const blockingActionSagas: Record< [gitArtifactActions.connectInit.type]: connectSaga, [gitArtifactActions.disconnectInit.type]: disconnectSaga, + // import + [gitGlobalActions.gitImportInit.type]: gitImportSaga, + // ops [gitArtifactActions.commitInit.type]: commitSaga, [gitArtifactActions.fetchStatusInit.type]: fetchStatusSaga, @@ -65,8 +70,8 @@ const blockingActionSagas: Record< // user profiles [gitArtifactActions.fetchLocalProfileInit.type]: fetchLocalProfileSaga, [gitArtifactActions.updateLocalProfileInit.type]: updateLocalProfileSaga, - [gitConfigActions.fetchGlobalProfileInit.type]: fetchGlobalProfileSaga, - [gitConfigActions.updateGlobalProfileInit.type]: updateGlobalProfileSaga, + [gitGlobalActions.fetchGlobalProfileInit.type]: fetchGlobalProfileSaga, + [gitGlobalActions.updateGlobalProfileInit.type]: updateGlobalProfileSaga, // protected branches [gitArtifactActions.fetchProtectedBranchesInit.type]: @@ -93,6 +98,7 @@ const nonBlockingActionSagas: Record< // ssh key [gitArtifactActions.fetchSSHKeyInit.type]: fetchSSHKeySaga, [gitArtifactActions.generateSSHKeyInit.type]: generateSSHKeySaga, + [gitGlobalActions.fetchGlobalSSHKeyInit.type]: fetchGlobalSSHKeySaga, // EE ...nonBlockingActionSagasExtended, diff --git a/app/client/src/git/sagas/initGitSaga.ts b/app/client/src/git/sagas/initGitSaga.ts index aa50efce17b1..b880b1854c41 100644 --- a/app/client/src/git/sagas/initGitSaga.ts +++ b/app/client/src/git/sagas/initGitSaga.ts @@ -7,24 +7,25 @@ import { put, take } from "redux-saga/effects"; export default function* initGitForEditorSaga( action: GitArtifactPayloadAction, ) { - const { artifact, artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifact, artifactDef } = action.payload; + const artifactId = artifact?.id; - yield put(gitArtifactActions.mount(basePayload)); + yield put(gitArtifactActions.mount({ artifactDef })); - if (artifactType === GitArtifactType.Application) { - if (!!artifact.gitApplicationMetadata?.remoteUrl) { - yield put(gitArtifactActions.fetchMetadataInit(basePayload)); + if (artifactId && artifactDef.artifactType === GitArtifactType.Application) { + if (!!artifact?.gitApplicationMetadata?.remoteUrl) { + yield put(gitArtifactActions.fetchMetadataInit({ artifactDef })); yield take(gitArtifactActions.fetchMetadataSuccess.type); yield put( - gitArtifactActions.triggerAutocommitInit({ - ...basePayload, - artifactId: artifact.id, - }), + gitArtifactActions.triggerAutocommitInit({ artifactDef, artifactId }), + ); + yield put( + gitArtifactActions.fetchBranchesInit({ artifactDef, artifactId }), + ); + yield put(gitArtifactActions.fetchProtectedBranchesInit({ artifactDef })); + yield put( + gitArtifactActions.fetchStatusInit({ artifactDef, artifactId }), ); - yield put(gitArtifactActions.fetchBranchesInit(basePayload)); - yield put(gitArtifactActions.fetchProtectedBranchesInit(basePayload)); - yield put(gitArtifactActions.fetchStatusInit(basePayload)); } } } diff --git a/app/client/src/git/sagas/pullSaga.ts b/app/client/src/git/sagas/pullSaga.ts index eafb4a5c098b..07347326e3e0 100644 --- a/app/client/src/git/sagas/pullSaga.ts +++ b/app/client/src/git/sagas/pullSaga.ts @@ -4,7 +4,7 @@ import type { PullResponse } from "git/requests/pullRequest.types"; import type { PullInitPayload } from "git/store/actions/pullActions"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; import type { GitArtifactPayloadAction } from "git/store/types"; -import { selectCurrentBranch } from "git/store/selectors/gitSingleArtifactSelectors"; +import { selectCurrentBranch } from "git/store/selectors/gitArtifactSelectors"; // internal dependencies import { validateResponse } from "sagas/ErrorSagas"; @@ -17,8 +17,7 @@ import { captureException } from "@sentry/react"; export default function* pullSaga( action: GitArtifactPayloadAction, ) { - const { artifactId, artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef, artifactId } = action.payload; let response: PullResponse | undefined; try { @@ -26,12 +25,12 @@ export default function* pullSaga( const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { - yield put(gitArtifactActions.pullSuccess(basePayload)); + yield put(gitArtifactActions.pullSuccess({ artifactDef })); const currentBasePageId: string = yield select(getCurrentBasePageId); const currentBranch: string = yield select( selectCurrentBranch, - basePayload, + artifactDef, ); yield put( @@ -51,7 +50,7 @@ export default function* pullSaga( // yield put(setIsGitErrorPopupVisible({ isVisible: true })); // } - yield put(gitArtifactActions.pullError({ ...basePayload, error })); + yield put(gitArtifactActions.pullError({ artifactDef, error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/toggleAutocommitSaga.ts b/app/client/src/git/sagas/toggleAutocommitSaga.ts index cf8b0e923c67..4f97d0289543 100644 --- a/app/client/src/git/sagas/toggleAutocommitSaga.ts +++ b/app/client/src/git/sagas/toggleAutocommitSaga.ts @@ -10,24 +10,23 @@ import { validateResponse } from "sagas/ErrorSagas"; export default function* toggleAutocommitSaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId } = action.payload; - const artifactDef = { artifactType, baseArtifactId }; + const { artifactDef } = action.payload; let response: ToggleAutocommitResponse | undefined; try { - response = yield call(toggleAutocommitRequest, baseArtifactId); + response = yield call(toggleAutocommitRequest, artifactDef.baseArtifactId); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { - yield put(gitArtifactActions.toggleAutocommitSuccess(artifactDef)); - yield put(gitArtifactActions.fetchMetadataInit(artifactDef)); + yield put(gitArtifactActions.toggleAutocommitSuccess({ artifactDef })); + yield put(gitArtifactActions.fetchMetadataInit({ artifactDef })); } } catch (e) { if (response && response.responseMeta.error) { const { error } = response.responseMeta; yield put( - gitArtifactActions.toggleAutocommitError({ ...artifactDef, error }), + gitArtifactActions.toggleAutocommitError({ artifactDef, error }), ); } else { log.error(e); diff --git a/app/client/src/git/sagas/triggerAutocommitSaga.ts b/app/client/src/git/sagas/triggerAutocommitSaga.ts index d0b316f594ec..6725fb0d59f9 100644 --- a/app/client/src/git/sagas/triggerAutocommitSaga.ts +++ b/app/client/src/git/sagas/triggerAutocommitSaga.ts @@ -1,8 +1,5 @@ import { triggerAutocommitSuccessAction } from "actions/gitSyncActions"; -import { - AutocommitStatusState, - type GitArtifactType, -} from "git/constants/enums"; +import { AutocommitStatusState } from "git/constants/enums"; import fetchAutocommitProgressRequest from "git/requests/fetchAutocommitProgressRequest"; import type { FetchAutocommitProgressResponse, @@ -15,8 +12,8 @@ import type { } from "git/requests/triggerAutocommitRequest.types"; import type { TriggerAutocommitInitPayload } from "git/store/actions/triggerAutocommitActions"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; -import { selectAutocommitEnabled } from "git/store/selectors/gitSingleArtifactSelectors"; -import type { GitArtifactPayloadAction } from "git/store/types"; +import { selectAutocommitEnabled } from "git/store/selectors/gitArtifactSelectors"; +import type { GitArtifactDef, GitArtifactPayloadAction } from "git/store/types"; import { call, cancel, @@ -39,8 +36,7 @@ const AUTOCOMMIT_WHITELISTED_STATES = [ ]; interface PollAutocommitProgressParams { - artifactType: keyof typeof GitArtifactType; - baseArtifactId: string; + artifactDef: GitArtifactDef; artifactId: string; } @@ -57,8 +53,7 @@ function isAutocommitHappening( } function* pollAutocommitProgressSaga(params: PollAutocommitProgressParams) { - const { artifactId, artifactType, baseArtifactId } = params; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef, artifactId } = params; let triggerResponse: TriggerAutocommitResponse | undefined; try { @@ -66,14 +61,14 @@ function* pollAutocommitProgressSaga(params: PollAutocommitProgressParams) { const isValidResponse: boolean = yield validateResponse(triggerResponse); if (triggerResponse && isValidResponse) { - yield put(gitArtifactActions.triggerAutocommitSuccess(basePayload)); + yield put(gitArtifactActions.triggerAutocommitSuccess({ artifactDef })); } } catch (e) { if (triggerResponse && triggerResponse.responseMeta.error) { const { error } = triggerResponse.responseMeta; yield put( - gitArtifactActions.triggerAutocommitError({ ...basePayload, error }), + gitArtifactActions.triggerAutocommitError({ artifactDef, error }), ); } else { log.error(e); @@ -85,39 +80,47 @@ function* pollAutocommitProgressSaga(params: PollAutocommitProgressParams) { try { if (isAutocommitHappening(triggerResponse?.data)) { - yield put(gitArtifactActions.pollAutocommitProgressStart(basePayload)); + yield put( + gitArtifactActions.pollAutocommitProgressStart({ artifactDef }), + ); while (true) { - yield put(gitArtifactActions.fetchAutocommitProgressInit(basePayload)); + yield put( + gitArtifactActions.fetchAutocommitProgressInit({ artifactDef }), + ); progressResponse = yield call( fetchAutocommitProgressRequest, - baseArtifactId, + artifactDef.baseArtifactId, ); const isValidResponse: boolean = yield validateResponse(progressResponse); if (isValidResponse && !isAutocommitHappening(progressResponse?.data)) { - yield put(gitArtifactActions.pollAutocommitProgressStop(basePayload)); + yield put( + gitArtifactActions.pollAutocommitProgressStop({ artifactDef }), + ); } if (!isValidResponse) { - yield put(gitArtifactActions.pollAutocommitProgressStop(basePayload)); + yield put( + gitArtifactActions.pollAutocommitProgressStop({ artifactDef }), + ); } yield delay(AUTOCOMMIT_POLL_DELAY); } } else { - yield put(gitArtifactActions.pollAutocommitProgressStop(basePayload)); + yield put(gitArtifactActions.pollAutocommitProgressStop({ artifactDef })); } } catch (e) { - yield put(gitArtifactActions.pollAutocommitProgressStop(basePayload)); + yield put(gitArtifactActions.pollAutocommitProgressStop({ artifactDef })); if (progressResponse && progressResponse.responseMeta.error) { const { error } = progressResponse.responseMeta; yield put( gitArtifactActions.fetchAutocommitProgressError({ - ...basePayload, + artifactDef, error, }), ); @@ -131,15 +134,14 @@ function* pollAutocommitProgressSaga(params: PollAutocommitProgressParams) { export default function* triggerAutocommitSaga( action: GitArtifactPayloadAction, ) { - const { artifactId, artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef, artifactId } = action.payload; const isAutocommitEnabled: boolean = yield select( selectAutocommitEnabled, - basePayload, + artifactDef, ); if (isAutocommitEnabled) { - const params = { artifactType, baseArtifactId, artifactId }; + const params = { artifactDef, artifactId }; const pollTask: Task = yield fork(pollAutocommitProgressSaga, params); yield take(gitArtifactActions.pollAutocommitProgressStop.type); diff --git a/app/client/src/git/sagas/updateGlobalProfileSaga.ts b/app/client/src/git/sagas/updateGlobalProfileSaga.ts index 2ce98fe47fb4..d7466b1ed007 100644 --- a/app/client/src/git/sagas/updateGlobalProfileSaga.ts +++ b/app/client/src/git/sagas/updateGlobalProfileSaga.ts @@ -6,12 +6,12 @@ import type { UpdateGlobalProfileRequestParams, UpdateGlobalProfileResponse, } from "../requests/updateGlobalProfileRequest.types"; -import { gitConfigActions } from "../store/gitConfigSlice"; // internal dependencies import { validateResponse } from "sagas/ErrorSagas"; import log from "loglevel"; import { captureException } from "@sentry/react"; +import { gitGlobalActions } from "git/store/gitGlobalSlice"; export default function* updateGlobalProfileSaga( action: PayloadAction, @@ -29,14 +29,14 @@ export default function* updateGlobalProfileSaga( const isValidResponse: boolean = yield validateResponse(response, true); if (response && isValidResponse) { - yield put(gitConfigActions.updateGlobalProfileSuccess()); - yield put(gitConfigActions.fetchGlobalProfileInit()); + yield put(gitGlobalActions.updateGlobalProfileSuccess()); + yield put(gitGlobalActions.fetchGlobalProfileInit()); } } catch (e) { if (response && response.responseMeta.error) { const { error } = response.responseMeta; - yield put(gitConfigActions.updateGlobalProfileError({ error })); + yield put(gitGlobalActions.updateGlobalProfileError({ error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/updateLocalProfileSaga.ts b/app/client/src/git/sagas/updateLocalProfileSaga.ts index 74579562b058..3b7253a391fe 100644 --- a/app/client/src/git/sagas/updateLocalProfileSaga.ts +++ b/app/client/src/git/sagas/updateLocalProfileSaga.ts @@ -14,8 +14,7 @@ import { captureException } from "@sentry/react"; export default function* updateLocalProfileSaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId } = action.payload; - const basePayload = { artifactType, baseArtifactId }; + const { artifactDef } = action.payload; let response: UpdateLocalProfileResponse | undefined; try { @@ -25,20 +24,24 @@ export default function* updateLocalProfileSaga( useGlobalProfile: action.payload.useGlobalProfile, }; - response = yield call(updateLocalProfileRequest, baseArtifactId, params); + response = yield call( + updateLocalProfileRequest, + artifactDef.baseArtifactId, + params, + ); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { - yield put(gitArtifactActions.updateLocalProfileSuccess(basePayload)); - yield put(gitArtifactActions.fetchLocalProfileInit(basePayload)); + yield put(gitArtifactActions.updateLocalProfileSuccess({ artifactDef })); + yield put(gitArtifactActions.fetchLocalProfileInit({ artifactDef })); } } catch (e) { if (response && response.responseMeta.error) { const { error } = response.responseMeta; yield put( - gitArtifactActions.updateLocalProfileError({ ...basePayload, error }), + gitArtifactActions.updateLocalProfileError({ artifactDef, error }), ); } else { log.error(e); diff --git a/app/client/src/git/sagas/updateProtectedBranchesSaga.ts b/app/client/src/git/sagas/updateProtectedBranchesSaga.ts index 3f7bd121270e..f24b20ee9290 100644 --- a/app/client/src/git/sagas/updateProtectedBranchesSaga.ts +++ b/app/client/src/git/sagas/updateProtectedBranchesSaga.ts @@ -14,8 +14,7 @@ import { validateResponse } from "sagas/ErrorSagas"; export default function* updateProtectedBranchesSaga( action: GitArtifactPayloadAction, ) { - const { artifactType, baseArtifactId } = action.payload; - const artifactDef = { artifactType, baseArtifactId }; + const { artifactDef } = action.payload; let response: UpdateProtectedBranchesResponse | undefined; try { @@ -25,14 +24,16 @@ export default function* updateProtectedBranchesSaga( response = yield call( updateProtectedBranchesRequest, - baseArtifactId, + artifactDef.baseArtifactId, params, ); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { - yield put(gitArtifactActions.updateProtectedBranchesSuccess(artifactDef)); - yield put(gitArtifactActions.fetchProtectedBranchesInit(artifactDef)); + yield put( + gitArtifactActions.updateProtectedBranchesSuccess({ artifactDef }), + ); + yield put(gitArtifactActions.fetchProtectedBranchesInit({ artifactDef })); } } catch (e) { if (response && response.responseMeta.error) { @@ -40,7 +41,7 @@ export default function* updateProtectedBranchesSaga( yield put( gitArtifactActions.updateProtectedBranchesError({ - ...artifactDef, + artifactDef, error, }), ); diff --git a/app/client/src/git/store/actions/checkoutBranchActions.ts b/app/client/src/git/store/actions/checkoutBranchActions.ts index c771d1887e34..e9451a614d7f 100644 --- a/app/client/src/git/store/actions/checkoutBranchActions.ts +++ b/app/client/src/git/store/actions/checkoutBranchActions.ts @@ -1,12 +1,13 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; import type { CheckoutBranchRequestParams } from "git/requests/checkoutBranchRequest.types"; -export interface CheckoutBranchInitPayload - extends CheckoutBranchRequestParams {} +export interface CheckoutBranchInitPayload extends CheckoutBranchRequestParams { + artifactId: string; +} export const checkoutBranchInitAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { state.apiResponses.checkoutBranch.loading = true; state.apiResponses.checkoutBranch.error = null; state.ui.checkoutDestBranch = action.payload.branchName; @@ -14,18 +15,16 @@ export const checkoutBranchInitAction = return state; }); -export const checkoutBranchSuccessAction = createSingleArtifactAction( - (state) => { - state.apiResponses.checkoutBranch.loading = false; - state.apiResponses.checkoutBranch.error = null; - state.ui.checkoutDestBranch = null; +export const checkoutBranchSuccessAction = createArtifactAction((state) => { + state.apiResponses.checkoutBranch.loading = false; + state.apiResponses.checkoutBranch.error = null; + state.ui.checkoutDestBranch = null; - return state; - }, -); + return state; +}); export const checkoutBranchErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.checkoutBranch.loading = false; diff --git a/app/client/src/git/store/actions/commitActions.ts b/app/client/src/git/store/actions/commitActions.ts index 9ebb8d37db60..876463e803a9 100644 --- a/app/client/src/git/store/actions/commitActions.ts +++ b/app/client/src/git/store/actions/commitActions.ts @@ -1,10 +1,12 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; import type { CommitRequestParams } from "git/requests/commitRequest.types"; -export interface CommitInitPayload extends CommitRequestParams {} +export interface CommitInitPayload extends CommitRequestParams { + artifactId: string; +} -export const commitInitAction = createSingleArtifactAction( +export const commitInitAction = createArtifactAction( (state) => { state.apiResponses.commit.loading = true; state.apiResponses.commit.error = null; @@ -13,23 +15,24 @@ export const commitInitAction = createSingleArtifactAction( }, ); -export const commitSuccessAction = createSingleArtifactAction((state) => { +export const commitSuccessAction = createArtifactAction((state) => { state.apiResponses.commit.loading = false; return state; }); -export const commitErrorAction = - createSingleArtifactAction((state, action) => { +export const commitErrorAction = createArtifactAction( + (state, action) => { const { error } = action.payload; state.apiResponses.commit.loading = false; state.apiResponses.commit.error = error; return state; - }); + }, +); -export const clearCommitErrorAction = createSingleArtifactAction((state) => { +export const clearCommitErrorAction = createArtifactAction((state) => { state.apiResponses.commit.error = null; return state; diff --git a/app/client/src/git/store/actions/connectActions.ts b/app/client/src/git/store/actions/connectActions.ts index 7fed98500000..9e5e2bcf10b1 100644 --- a/app/client/src/git/store/actions/connectActions.ts +++ b/app/client/src/git/store/actions/connectActions.ts @@ -1,12 +1,13 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; -import type { GitAsyncErrorPayload } from "../types"; -import type { ConnectRequestParams } from "git/requests/connectRequest.types"; +import { createArtifactAction } from "../helpers/createArtifactAction"; +import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; +import type { + ConnectRequestParams, + ConnectResponseData, +} from "git/requests/connectRequest.types"; -export interface ConnectInitPayload extends ConnectRequestParams { - branchedPageId?: string; -} +export interface ConnectInitPayload extends ConnectRequestParams {} -export const connectInitAction = createSingleArtifactAction( +export const connectInitAction = createArtifactAction( (state) => { state.apiResponses.connect.loading = true; state.apiResponses.connect.error = null; @@ -15,18 +16,24 @@ export const connectInitAction = createSingleArtifactAction( }, ); -export const connectSuccessAction = createSingleArtifactAction((state) => { - state.apiResponses.connect.loading = false; +export interface ConnectSuccessPayload + extends GitAsyncSuccessPayload {} - return state; -}); +export const connectSuccessAction = createArtifactAction( + (state) => { + state.apiResponses.connect.loading = false; + + return state; + }, +); -export const connectErrorAction = - createSingleArtifactAction((state, action) => { +export const connectErrorAction = createArtifactAction( + (state, action) => { const { error } = action.payload; state.apiResponses.connect.loading = false; state.apiResponses.connect.error = error; return state; - }); + }, +); diff --git a/app/client/src/git/store/actions/createBranchActions.ts b/app/client/src/git/store/actions/createBranchActions.ts index be0e08445de2..010a7550888f 100644 --- a/app/client/src/git/store/actions/createBranchActions.ts +++ b/app/client/src/git/store/actions/createBranchActions.ts @@ -1,25 +1,27 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; import type { CreateBranchRequestParams } from "git/requests/createBranchRequest.types"; -export interface CreateBranchInitPayload extends CreateBranchRequestParams {} +export interface CreateBranchInitPayload extends CreateBranchRequestParams { + artifactId: string; +} export const createBranchInitAction = - createSingleArtifactAction((state) => { + createArtifactAction((state) => { state.apiResponses.createBranch.loading = true; state.apiResponses.createBranch.error = null; return state; }); -export const createBranchSuccessAction = createSingleArtifactAction((state) => { +export const createBranchSuccessAction = createArtifactAction((state) => { state.apiResponses.createBranch.loading = false; return state; }); export const createBranchErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.createBranch.loading = false; diff --git a/app/client/src/git/store/actions/deleteBranchActions.ts b/app/client/src/git/store/actions/deleteBranchActions.ts index 09296625f0d6..0656886f39d4 100644 --- a/app/client/src/git/store/actions/deleteBranchActions.ts +++ b/app/client/src/git/store/actions/deleteBranchActions.ts @@ -1,25 +1,27 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; import type { DeleteBranchRequestParams } from "../../requests/deleteBranchRequest.types"; -export interface DeleteBranchInitPayload extends DeleteBranchRequestParams {} +export interface DeleteBranchInitPayload extends DeleteBranchRequestParams { + artifactId: string; +} export const deleteBranchInitAction = - createSingleArtifactAction((state) => { + createArtifactAction((state) => { state.apiResponses.deleteBranch.loading = true; state.apiResponses.deleteBranch.error = null; return state; }); -export const deleteBranchSuccessAction = createSingleArtifactAction((state) => { +export const deleteBranchSuccessAction = createArtifactAction((state) => { state.apiResponses.deleteBranch.loading = false; return state; }); export const deleteBranchErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.deleteBranch.loading = false; diff --git a/app/client/src/git/store/actions/discardActions.ts b/app/client/src/git/store/actions/discardActions.ts index 35d37c0a6d0e..0f514cd0e585 100644 --- a/app/client/src/git/store/actions/discardActions.ts +++ b/app/client/src/git/store/actions/discardActions.ts @@ -1,20 +1,20 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitArtifactErrorPayloadAction } from "../types"; -export const discardInitAction = createSingleArtifactAction((state) => { +export const discardInitAction = createArtifactAction((state) => { state.apiResponses.discard.loading = true; state.apiResponses.discard.error = null; return state; }); -export const discardSuccessAction = createSingleArtifactAction((state) => { +export const discardSuccessAction = createArtifactAction((state) => { state.apiResponses.discard.loading = false; return state; }); -export const discardErrorAction = createSingleArtifactAction( +export const discardErrorAction = createArtifactAction( (state, action: GitArtifactErrorPayloadAction) => { const { error } = action.payload; @@ -25,7 +25,7 @@ export const discardErrorAction = createSingleArtifactAction( }, ); -export const clearDiscardErrorAction = createSingleArtifactAction((state) => { +export const clearDiscardErrorAction = createArtifactAction((state) => { state.apiResponses.discard.error = null; return state; diff --git a/app/client/src/git/store/actions/disconnectActions.ts b/app/client/src/git/store/actions/disconnectActions.ts index dba26c0de629..082aa91b7970 100644 --- a/app/client/src/git/store/actions/disconnectActions.ts +++ b/app/client/src/git/store/actions/disconnectActions.ts @@ -1,20 +1,20 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitArtifactErrorPayloadAction } from "../types"; -export const disconnectInitAction = createSingleArtifactAction((state) => { +export const disconnectInitAction = createArtifactAction((state) => { state.apiResponses.disconnect.loading = true; state.apiResponses.disconnect.error = null; return state; }); -export const disconnectSuccessAction = createSingleArtifactAction((state) => { +export const disconnectSuccessAction = createArtifactAction((state) => { state.apiResponses.disconnect.loading = false; return state; }); -export const disconnectErrorAction = createSingleArtifactAction( +export const disconnectErrorAction = createArtifactAction( (state, action: GitArtifactErrorPayloadAction) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/fetchAutocommitProgressActions.ts b/app/client/src/git/store/actions/fetchAutocommitProgressActions.ts index a7d92793e4aa..bbde6e4dd649 100644 --- a/app/client/src/git/store/actions/fetchAutocommitProgressActions.ts +++ b/app/client/src/git/store/actions/fetchAutocommitProgressActions.ts @@ -1,7 +1,7 @@ import type { GitAsyncErrorPayload } from "../types"; -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; -export const fetchAutocommitProgressInitAction = createSingleArtifactAction( +export const fetchAutocommitProgressInitAction = createArtifactAction( (state) => { state.apiResponses.autocommitProgress.loading = true; state.apiResponses.autocommitProgress.error = null; @@ -10,7 +10,7 @@ export const fetchAutocommitProgressInitAction = createSingleArtifactAction( }, ); -export const fetchAutocommitProgressSuccessAction = createSingleArtifactAction( +export const fetchAutocommitProgressSuccessAction = createArtifactAction( (state) => { state.apiResponses.autocommitProgress.loading = false; @@ -19,7 +19,7 @@ export const fetchAutocommitProgressSuccessAction = createSingleArtifactAction( ); export const fetchAutocommitProgressErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.autocommitProgress.loading = false; diff --git a/app/client/src/git/store/actions/fetchBranchesActions.ts b/app/client/src/git/store/actions/fetchBranchesActions.ts index e83ce0325e59..6758ad918eb0 100644 --- a/app/client/src/git/store/actions/fetchBranchesActions.ts +++ b/app/client/src/git/store/actions/fetchBranchesActions.ts @@ -3,19 +3,21 @@ import type { FetchBranchesResponseData, } from "../../requests/fetchBranchesRequest.types"; import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; -export interface FetchBranchesInitPayload extends FetchBranchesRequestParams {} +export interface FetchBranchesInitPayload extends FetchBranchesRequestParams { + artifactId: string; +} export const fetchBranchesInitAction = - createSingleArtifactAction((state) => { + createArtifactAction((state) => { state.apiResponses.branches.loading = true; state.apiResponses.branches.error = null; return state; }); -export const fetchBranchesSuccessAction = createSingleArtifactAction< +export const fetchBranchesSuccessAction = createArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.branches.loading = false; @@ -25,7 +27,7 @@ export const fetchBranchesSuccessAction = createSingleArtifactAction< }); export const fetchBranchesErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.branches.loading = false; diff --git a/app/client/src/git/store/actions/fetchGlobalProfileActions.ts b/app/client/src/git/store/actions/fetchGlobalProfileActions.ts index 7cfb2390b021..bc2d0b6b92a3 100644 --- a/app/client/src/git/store/actions/fetchGlobalProfileActions.ts +++ b/app/client/src/git/store/actions/fetchGlobalProfileActions.ts @@ -2,11 +2,11 @@ import type { FetchGlobalProfileResponseData } from "git/requests/fetchGlobalPro import type { GitAsyncSuccessPayload, GitAsyncErrorPayload, - GitConfigReduxState, + GitGlobalReduxState, } from "../types"; import type { PayloadAction } from "@reduxjs/toolkit"; -export const fetchGlobalProfileInitAction = (state: GitConfigReduxState) => { +export const fetchGlobalProfileInitAction = (state: GitGlobalReduxState) => { state.globalProfile.loading = true; state.globalProfile.error = null; @@ -14,7 +14,7 @@ export const fetchGlobalProfileInitAction = (state: GitConfigReduxState) => { }; export const fetchGlobalProfileSuccessAction = ( - state: GitConfigReduxState, + state: GitGlobalReduxState, action: PayloadAction>, ) => { state.globalProfile.loading = false; @@ -24,7 +24,7 @@ export const fetchGlobalProfileSuccessAction = ( }; export const fetchGlobalProfileErrorAction = ( - state: GitConfigReduxState, + state: GitGlobalReduxState, action: PayloadAction, ) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/fetchGlobalSSHKeyActions.ts b/app/client/src/git/store/actions/fetchGlobalSSHKeyActions.ts new file mode 100644 index 000000000000..de9add1c5ee0 --- /dev/null +++ b/app/client/src/git/store/actions/fetchGlobalSSHKeyActions.ts @@ -0,0 +1,55 @@ +import type { + FetchGlobalSSHKeyRequestParams, + FetchGlobalSSHKeyResponseData, +} from "git/requests/fetchGlobalSSHKeyRequest.types"; +import type { + GitAsyncSuccessPayload, + GitAsyncErrorPayload, + GitGlobalReduxState, +} from "../types"; +import type { PayloadAction } from "@reduxjs/toolkit"; + +export interface FetchGlobalSSHKeyInitPayload + extends FetchGlobalSSHKeyRequestParams {} + +export const fetchGlobalSSHKeyInitAction = ( + state: GitGlobalReduxState, + // need action to better define action type + // eslint-disable-next-line @typescript-eslint/no-unused-vars + action: PayloadAction, +) => { + state.globalSSHKey.loading = true; + state.globalSSHKey.error = null; + + return state; +}; + +export const fetchGlobalSSHKeySuccessAction = ( + state: GitGlobalReduxState, + action: PayloadAction>, +) => { + state.globalSSHKey.loading = false; + state.globalSSHKey.value = action.payload.responseData; + + return state; +}; + +export const fetchGlobalSSHKeyErrorAction = ( + state: GitGlobalReduxState, + action: PayloadAction, +) => { + const { error } = action.payload; + + state.globalSSHKey.loading = false; + state.globalSSHKey.error = error; + + return state; +}; + +export const resetGlobalSSHKeyAction = (state: GitGlobalReduxState) => { + state.globalSSHKey.loading = false; + state.globalSSHKey.value = null; + state.globalSSHKey.error = null; + + return state; +}; diff --git a/app/client/src/git/store/actions/fetchLocalProfileActions.ts b/app/client/src/git/store/actions/fetchLocalProfileActions.ts index 3559a2814c35..33a62514f44c 100644 --- a/app/client/src/git/store/actions/fetchLocalProfileActions.ts +++ b/app/client/src/git/store/actions/fetchLocalProfileActions.ts @@ -3,18 +3,16 @@ import type { GitArtifactErrorPayloadAction, GitAsyncSuccessPayload, } from "../types"; -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; -export const fetchLocalProfileInitAction = createSingleArtifactAction( - (state) => { - state.apiResponses.localProfile.loading = true; - state.apiResponses.localProfile.error = null; +export const fetchLocalProfileInitAction = createArtifactAction((state) => { + state.apiResponses.localProfile.loading = true; + state.apiResponses.localProfile.error = null; - return state; - }, -); + return state; +}); -export const fetchLocalProfileSuccessAction = createSingleArtifactAction< +export const fetchLocalProfileSuccessAction = createArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.localProfile.loading = false; @@ -23,7 +21,7 @@ export const fetchLocalProfileSuccessAction = createSingleArtifactAction< return state; }); -export const fetchLocalProfileErrorAction = createSingleArtifactAction( +export const fetchLocalProfileErrorAction = createArtifactAction( (state, action: GitArtifactErrorPayloadAction) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/fetchMergeStatusActions.ts b/app/client/src/git/store/actions/fetchMergeStatusActions.ts index 65ed313114cb..26b72829fadd 100644 --- a/app/client/src/git/store/actions/fetchMergeStatusActions.ts +++ b/app/client/src/git/store/actions/fetchMergeStatusActions.ts @@ -1,5 +1,5 @@ import type { GitAsyncSuccessPayload, GitAsyncErrorPayload } from "../types"; -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { FetchMergeStatusRequestParams, FetchMergeStatusResponseData, @@ -11,14 +11,14 @@ export interface FetchMergeStatusInitPayload } export const fetchMergeStatusInitAction = - createSingleArtifactAction((state) => { + createArtifactAction((state) => { state.apiResponses.mergeStatus.loading = true; state.apiResponses.mergeStatus.error = null; return state; }); -export const fetchMergeStatusSuccessAction = createSingleArtifactAction< +export const fetchMergeStatusSuccessAction = createArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.mergeStatus.loading = false; @@ -28,7 +28,7 @@ export const fetchMergeStatusSuccessAction = createSingleArtifactAction< }); export const fetchMergeStatusErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.mergeStatus.loading = false; @@ -37,7 +37,7 @@ export const fetchMergeStatusErrorAction = return state; }); -export const clearMergeStatusAction = createSingleArtifactAction((state) => { +export const clearMergeStatusAction = createArtifactAction((state) => { state.apiResponses.mergeStatus.loading = false; state.apiResponses.mergeStatus.error = null; state.apiResponses.mergeStatus.value = null; diff --git a/app/client/src/git/store/actions/fetchMetadataActions.ts b/app/client/src/git/store/actions/fetchMetadataActions.ts index 176413dfbaaa..6e7a9f2f1e3d 100644 --- a/app/client/src/git/store/actions/fetchMetadataActions.ts +++ b/app/client/src/git/store/actions/fetchMetadataActions.ts @@ -1,15 +1,15 @@ import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { FetchMetadataResponseData } from "git/requests/fetchMetadataRequest.types"; -export const fetchMetadataInitAction = createSingleArtifactAction((state) => { +export const fetchMetadataInitAction = createArtifactAction((state) => { state.apiResponses.metadata.loading = true; state.apiResponses.metadata.error = null; return state; }); -export const fetchMetadataSuccessAction = createSingleArtifactAction< +export const fetchMetadataSuccessAction = createArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.metadata.loading = false; @@ -19,7 +19,7 @@ export const fetchMetadataSuccessAction = createSingleArtifactAction< }); export const fetchMetadataErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.metadata.loading = false; diff --git a/app/client/src/git/store/actions/fetchProtectedBranchesActions.ts b/app/client/src/git/store/actions/fetchProtectedBranchesActions.ts index dc66ff2290c0..1ad38bf4096c 100644 --- a/app/client/src/git/store/actions/fetchProtectedBranchesActions.ts +++ b/app/client/src/git/store/actions/fetchProtectedBranchesActions.ts @@ -1,8 +1,8 @@ import type { GitAsyncSuccessPayload, GitAsyncErrorPayload } from "../types"; -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types"; -export const fetchProtectedBranchesInitAction = createSingleArtifactAction( +export const fetchProtectedBranchesInitAction = createArtifactAction( (state) => { state.apiResponses.protectedBranches.loading = true; state.apiResponses.protectedBranches.error = null; @@ -11,7 +11,7 @@ export const fetchProtectedBranchesInitAction = createSingleArtifactAction( }, ); -export const fetchProtectedBranchesSuccessAction = createSingleArtifactAction< +export const fetchProtectedBranchesSuccessAction = createArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.protectedBranches.loading = false; @@ -21,7 +21,7 @@ export const fetchProtectedBranchesSuccessAction = createSingleArtifactAction< }); export const fetchProtectedBranchesErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.protectedBranches.loading = false; diff --git a/app/client/src/git/store/actions/fetchSSHKeyActions.ts b/app/client/src/git/store/actions/fetchSSHKeyActions.ts index 828cf6ebcb75..386dd4643411 100644 --- a/app/client/src/git/store/actions/fetchSSHKeyActions.ts +++ b/app/client/src/git/store/actions/fetchSSHKeyActions.ts @@ -1,15 +1,15 @@ import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { FetchSSHKeyResponseData } from "git/requests/fetchSSHKeyRequest.types"; -export const fetchSSHKeyInitAction = createSingleArtifactAction((state) => { +export const fetchSSHKeyInitAction = createArtifactAction((state) => { state.apiResponses.sshKey.loading = true; state.apiResponses.sshKey.error = null; return state; }); -export const fetchSSHKeySuccessAction = createSingleArtifactAction< +export const fetchSSHKeySuccessAction = createArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.sshKey.loading = false; @@ -20,7 +20,7 @@ export const fetchSSHKeySuccessAction = createSingleArtifactAction< }); export const fetchSSHKeyErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.sshKey.loading = false; @@ -29,7 +29,7 @@ export const fetchSSHKeyErrorAction = return state; }); -export const resetFetchSSHKeyAction = createSingleArtifactAction((state) => { +export const resetFetchSSHKeyAction = createArtifactAction((state) => { state.apiResponses.sshKey.loading = false; state.apiResponses.sshKey.error = null; state.apiResponses.sshKey.value = null; diff --git a/app/client/src/git/store/actions/fetchStatusActions.ts b/app/client/src/git/store/actions/fetchStatusActions.ts index 1121e368d012..47097593260b 100644 --- a/app/client/src/git/store/actions/fetchStatusActions.ts +++ b/app/client/src/git/store/actions/fetchStatusActions.ts @@ -3,19 +3,21 @@ import type { FetchStatusResponseData, } from "git/requests/fetchStatusRequest.types"; import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; -export interface FetchStatusInitPayload extends FetchStatusRequestParams {} +export interface FetchStatusInitPayload extends FetchStatusRequestParams { + artifactId: string; +} export const fetchStatusInitAction = - createSingleArtifactAction((state) => { + createArtifactAction((state) => { state.apiResponses.status.loading = true; state.apiResponses.status.error = null; return state; }); -export const fetchStatusSuccessAction = createSingleArtifactAction< +export const fetchStatusSuccessAction = createArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.status.loading = false; @@ -25,7 +27,7 @@ export const fetchStatusSuccessAction = createSingleArtifactAction< }); export const fetchStatusErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.status.loading = false; diff --git a/app/client/src/git/store/actions/generateSSHKeyActions.ts b/app/client/src/git/store/actions/generateSSHKeyActions.ts index fa70c3a1ba28..569d7d9995c2 100644 --- a/app/client/src/git/store/actions/generateSSHKeyActions.ts +++ b/app/client/src/git/store/actions/generateSSHKeyActions.ts @@ -2,21 +2,21 @@ import type { GenerateSSHKeyRequestParams, GenerateSSHKeyResponseData, } from "git/requests/generateSSHKeyRequest.types"; -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; export interface GenerateSSHKeyInitPayload extends GenerateSSHKeyRequestParams {} export const generateSSHKeyInitAction = - createSingleArtifactAction((state) => { + createArtifactAction((state) => { state.apiResponses.generateSSHKey.loading = true; state.apiResponses.generateSSHKey.error = null; return state; }); -export const generateSSHKeySuccessAction = createSingleArtifactAction< +export const generateSSHKeySuccessAction = createArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.generateSSHKey.loading = false; @@ -27,7 +27,7 @@ export const generateSSHKeySuccessAction = createSingleArtifactAction< }); export const generateSSHKeyErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.generateSSHKey.loading = false; @@ -36,7 +36,7 @@ export const generateSSHKeyErrorAction = return state; }); -export const resetGenerateSSHKeyAction = createSingleArtifactAction((state) => { +export const resetGenerateSSHKeyAction = createArtifactAction((state) => { state.apiResponses.generateSSHKey.loading = false; state.apiResponses.generateSSHKey.error = null; diff --git a/app/client/src/git/store/actions/gitImportActions.ts b/app/client/src/git/store/actions/gitImportActions.ts index 49411b55dd55..30e9c7417b2d 100644 --- a/app/client/src/git/store/actions/gitImportActions.ts +++ b/app/client/src/git/store/actions/gitImportActions.ts @@ -1,25 +1,35 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; -import type { GitAsyncErrorPayload } from "../types"; +import type { PayloadAction } from "@reduxjs/toolkit"; +import type { GitAsyncErrorPayload, GitGlobalReduxState } from "../types"; +import type { GitImportRequestParams } from "git/requests/gitImportRequest.types"; -export const gitImportInitAction = createSingleArtifactAction((state) => { - state.apiResponses.gitImport.loading = true; - state.apiResponses.gitImport.error = null; +export interface GitImportInitPayload extends GitImportRequestParams {} + +export const gitImportInitAction = ( + state: GitGlobalReduxState, + // need type for better import + // eslint-disable-next-line @typescript-eslint/no-unused-vars + action: PayloadAction, +) => { + state.gitImport.loading = true; + state.gitImport.error = null; return state; -}); +}; -export const gitImportSuccessAction = createSingleArtifactAction((state) => { - state.apiResponses.gitImport.loading = false; +export const gitImportSuccessAction = (state: GitGlobalReduxState) => { + state.gitImport.loading = false; return state; -}); +}; -export const gitImportErrorAction = - createSingleArtifactAction((state, action) => { - const { error } = action.payload; +export const gitImportErrorAction = ( + state: GitGlobalReduxState, + action: PayloadAction, +) => { + const { error } = action.payload; - state.apiResponses.gitImport.loading = false; - state.apiResponses.gitImport.error = error; + state.gitImport.loading = false; + state.gitImport.error = error; - return state; - }); + return state; +}; diff --git a/app/client/src/git/store/actions/initGitActions.ts b/app/client/src/git/store/actions/initGitActions.ts index d93cf955eeec..ebe588555a24 100644 --- a/app/client/src/git/store/actions/initGitActions.ts +++ b/app/client/src/git/store/actions/initGitActions.ts @@ -1,15 +1,11 @@ -import type { FetchMetadataResponseData } from "git/requests/fetchMetadataRequest.types"; -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; +import type { ApplicationPayload } from "entities/Application"; export interface InitGitForEditorPayload { - artifact: { - id: string; - baseId: string; - gitApplicationMetadata?: Partial; - }; + artifact: ApplicationPayload | null; } export const initGitForEditorAction = - createSingleArtifactAction((state) => { + createArtifactAction((state) => { return state; }); diff --git a/app/client/src/git/store/actions/mergeActions.ts b/app/client/src/git/store/actions/mergeActions.ts index 5bb17a351ce6..0d4e67eea8fe 100644 --- a/app/client/src/git/store/actions/mergeActions.ts +++ b/app/client/src/git/store/actions/mergeActions.ts @@ -1,20 +1,20 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitArtifactErrorPayloadAction } from "../types"; -export const mergeInitAction = createSingleArtifactAction((state) => { +export const mergeInitAction = createArtifactAction((state) => { state.apiResponses.merge.loading = true; state.apiResponses.merge.error = null; return state; }); -export const mergeSuccessAction = createSingleArtifactAction((state) => { +export const mergeSuccessAction = createArtifactAction((state) => { state.apiResponses.merge.loading = false; return state; }); -export const mergeErrorAction = createSingleArtifactAction( +export const mergeErrorAction = createArtifactAction( (state, action: GitArtifactErrorPayloadAction) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/mountActions.ts b/app/client/src/git/store/actions/mountActions.ts index 07a08ee2b566..8d35126d9502 100644 --- a/app/client/src/git/store/actions/mountActions.ts +++ b/app/client/src/git/store/actions/mountActions.ts @@ -1,26 +1,31 @@ import type { PayloadAction } from "@reduxjs/toolkit"; -import type { GitArtifactBasePayload, GitArtifactReduxState } from "../types"; -import { gitSingleArtifactInitialState } from "../helpers/gitSingleArtifactInitialState"; +import type { + GitArtifactBasePayload, + GitArtifactRootReduxState, +} from "../types"; +import { gitArtifactInitialState } from "../helpers/initialState"; // ! This might be removed later export const mountAction = ( - state: GitArtifactReduxState, + state: GitArtifactRootReduxState, action: PayloadAction, ) => { - const { artifactType, baseArtifactId } = action.payload; + const { artifactDef } = action.payload; + const { artifactType, baseArtifactId } = artifactDef; state[artifactType] ??= {}; - state[artifactType][baseArtifactId] ??= gitSingleArtifactInitialState; + state[artifactType][baseArtifactId] ??= gitArtifactInitialState; return state; }; export const unmountAction = ( - state: GitArtifactReduxState, + state: GitArtifactRootReduxState, action: PayloadAction, ) => { - const { artifactType, baseArtifactId } = action.payload; + const { artifactDef } = action.payload; + const { artifactType, baseArtifactId } = artifactDef; delete state?.[artifactType]?.[baseArtifactId]; diff --git a/app/client/src/git/store/actions/pullActions.ts b/app/client/src/git/store/actions/pullActions.ts index 00a0d00f2033..48d3398e18c6 100644 --- a/app/client/src/git/store/actions/pullActions.ts +++ b/app/client/src/git/store/actions/pullActions.ts @@ -1,26 +1,24 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; export interface PullInitPayload { artifactId: string; } -export const pullInitAction = createSingleArtifactAction( - (state) => { - state.apiResponses.pull.loading = true; - state.apiResponses.pull.error = null; +export const pullInitAction = createArtifactAction((state) => { + state.apiResponses.pull.loading = true; + state.apiResponses.pull.error = null; - return state; - }, -); + return state; +}); -export const pullSuccessAction = createSingleArtifactAction((state) => { +export const pullSuccessAction = createArtifactAction((state) => { state.apiResponses.pull.loading = false; return state; }); -export const pullErrorAction = createSingleArtifactAction( +export const pullErrorAction = createArtifactAction( (state, action) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/repoLimitErrorModalActions.ts b/app/client/src/git/store/actions/repoLimitErrorModalActions.ts index b1867c1d5926..a2c96bac7721 100644 --- a/app/client/src/git/store/actions/repoLimitErrorModalActions.ts +++ b/app/client/src/git/store/actions/repoLimitErrorModalActions.ts @@ -1,16 +1,14 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; interface ToggleRepoLimitModalActionPayload { open: boolean; } export const toggleRepoLimitErrorModalAction = - createSingleArtifactAction( - (state, action) => { - const { open } = action.payload; + createArtifactAction((state, action) => { + const { open } = action.payload; - state.ui.repoLimitErrorModalOpen = open; + state.ui.repoLimitErrorModalOpen = open; - return state; - }, - ); + return state; + }); diff --git a/app/client/src/git/store/actions/toggleAutocommitActions.ts b/app/client/src/git/store/actions/toggleAutocommitActions.ts index 96721698196f..d9c700cbb457 100644 --- a/app/client/src/git/store/actions/toggleAutocommitActions.ts +++ b/app/client/src/git/store/actions/toggleAutocommitActions.ts @@ -1,24 +1,20 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitArtifactErrorPayloadAction } from "../types"; -export const toggleAutocommitInitAction = createSingleArtifactAction( - (state) => { - state.apiResponses.toggleAutocommit.loading = true; - state.apiResponses.toggleAutocommit.error = null; +export const toggleAutocommitInitAction = createArtifactAction((state) => { + state.apiResponses.toggleAutocommit.loading = true; + state.apiResponses.toggleAutocommit.error = null; - return state; - }, -); + return state; +}); -export const toggleAutocommitSuccessAction = createSingleArtifactAction( - (state) => { - state.apiResponses.toggleAutocommit.loading = false; +export const toggleAutocommitSuccessAction = createArtifactAction((state) => { + state.apiResponses.toggleAutocommit.loading = false; - return state; - }, -); + return state; +}); -export const toggleAutocommitErrorAction = createSingleArtifactAction( +export const toggleAutocommitErrorAction = createArtifactAction( (state, action: GitArtifactErrorPayloadAction) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/triggerAutocommitActions.ts b/app/client/src/git/store/actions/triggerAutocommitActions.ts index 28e88ecd2f16..da8075bc347f 100644 --- a/app/client/src/git/store/actions/triggerAutocommitActions.ts +++ b/app/client/src/git/store/actions/triggerAutocommitActions.ts @@ -1,4 +1,4 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; export interface TriggerAutocommitInitPayload { @@ -6,23 +6,21 @@ export interface TriggerAutocommitInitPayload { } export const triggerAutocommitInitAction = - createSingleArtifactAction((state) => { + createArtifactAction((state) => { state.apiResponses.triggerAutocommit.loading = true; state.apiResponses.triggerAutocommit.error = null; return state; }); -export const triggerAutocommitSuccessAction = createSingleArtifactAction( - (state) => { - state.apiResponses.triggerAutocommit.loading = false; +export const triggerAutocommitSuccessAction = createArtifactAction((state) => { + state.apiResponses.triggerAutocommit.loading = false; - return state; - }, -); + return state; +}); export const triggerAutocommitErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.triggerAutocommit.loading = false; @@ -31,7 +29,7 @@ export const triggerAutocommitErrorAction = return state; }); -export const pollAutocommitProgressStartAction = createSingleArtifactAction( +export const pollAutocommitProgressStartAction = createArtifactAction( (state) => { state.ui.autocommitPolling = true; @@ -39,7 +37,7 @@ export const pollAutocommitProgressStartAction = createSingleArtifactAction( }, ); -export const pollAutocommitProgressStopAction = createSingleArtifactAction( +export const pollAutocommitProgressStopAction = createArtifactAction( (state) => { state.ui.autocommitPolling = false; diff --git a/app/client/src/git/store/actions/uiActions.ts b/app/client/src/git/store/actions/uiActions.ts index 577d1dfa3d10..162382c3b876 100644 --- a/app/client/src/git/store/actions/uiActions.ts +++ b/app/client/src/git/store/actions/uiActions.ts @@ -1,5 +1,7 @@ import type { GitOpsTab, GitSettingsTab } from "git/constants/enums"; -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; +import type { GitGlobalReduxState } from "../types"; +import type { PayloadAction } from "@reduxjs/toolkit"; // connect modal export interface ToggleConnectModalPayload { @@ -7,7 +9,7 @@ export interface ToggleConnectModalPayload { } export const toggleConnectModalAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { open } = action.payload; state.ui.connectModalOpen = open; @@ -15,27 +17,54 @@ export const toggleConnectModalAction = return state; }); +export interface ToggleConnectSuccessModalPayload { + open: boolean; +} + +export const toggleConnectSuccessModalAction = + createArtifactAction((state, action) => { + const { open } = action.payload; + + state.ui.connectSuccessModalOpen = open; + + return state; + }); + +export interface ToggleImportModalPayload { + open: boolean; +} + +export const toggleImportModalAction = ( + state: GitGlobalReduxState, + action: PayloadAction, +) => { + const { open } = action.payload; + + state.isImportModalOpen = open; + + return state; +}; + // disconnect modal export interface OpenDisconnectModalPayload { artifactName: string; } export const openDisconnectModalAction = - createSingleArtifactAction((state, action) => { - state.ui.disconnectBaseArtifactId = action.payload.baseArtifactId; + createArtifactAction((state, action) => { + state.ui.disconnectBaseArtifactId = + action.payload.artifactDef.baseArtifactId; state.ui.disconnectArtifactName = action.payload.artifactName; return state; }); -export const closeDisconnectModalAction = createSingleArtifactAction( - (state) => { - state.ui.disconnectBaseArtifactId = null; - state.ui.disconnectArtifactName = null; +export const closeDisconnectModalAction = createArtifactAction((state) => { + state.ui.disconnectBaseArtifactId = null; + state.ui.disconnectArtifactName = null; - return state; - }, -); + return state; +}); // ops modal @@ -44,15 +73,16 @@ export interface ToggleOpsModalPayload { tab: keyof typeof GitOpsTab; } -export const toggleOpsModalAction = - createSingleArtifactAction((state, action) => { +export const toggleOpsModalAction = createArtifactAction( + (state, action) => { const { open, tab } = action.payload; state.ui.opsModalOpen = open; state.ui.opsModalTab = tab; return state; - }); + }, +); // settings modal export interface ToggleSettingsModalPayload { @@ -61,7 +91,7 @@ export interface ToggleSettingsModalPayload { } export const toggleSettingsModalAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { open, tab } = action.payload; state.ui.settingsModalOpen = open; @@ -76,29 +106,28 @@ interface ToggleAutocommitDisableModalPayload { } export const toggleAutocommitDisableModalAction = - createSingleArtifactAction( - (state, action) => { - const { open } = action.payload; + createArtifactAction((state, action) => { + const { open } = action.payload; - state.ui.autocommitDisableModalOpen = open; + state.ui.autocommitDisableModalOpen = open; - return state; - }, - ); + return state; + }); // branch popup interface BranchPopupPayload { open: boolean; } -export const toggleBranchPopupAction = - createSingleArtifactAction((state, action) => { +export const toggleBranchPopupAction = createArtifactAction( + (state, action) => { const { open } = action.payload; state.ui.branchPopupOpen = open; return state; - }); + }, +); // error modals interface ToggleRepoLimitModalPayload { @@ -106,7 +135,7 @@ interface ToggleRepoLimitModalPayload { } export const toggleRepoLimitErrorModalAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { open } = action.payload; state.ui.repoLimitErrorModalOpen = open; @@ -119,12 +148,10 @@ interface ToggleConflictErrorModalPayload { } export const toggleConflictErrorModalAction = - createSingleArtifactAction( - (state, action) => { - const { open } = action.payload; + createArtifactAction((state, action) => { + const { open } = action.payload; - state.ui.conflictErrorModalOpen = open; + state.ui.conflictErrorModalOpen = open; - return state; - }, - ); + return state; + }); diff --git a/app/client/src/git/store/actions/updateGlobalProfileActions.ts b/app/client/src/git/store/actions/updateGlobalProfileActions.ts index b4d25b0b57d7..3549672deb56 100644 --- a/app/client/src/git/store/actions/updateGlobalProfileActions.ts +++ b/app/client/src/git/store/actions/updateGlobalProfileActions.ts @@ -1,14 +1,14 @@ import type { UpdateGlobalProfileRequestParams } from "git/requests/updateGlobalProfileRequest.types"; -import type { GitAsyncErrorPayload, GitConfigReduxState } from "../types"; +import type { GitAsyncErrorPayload, GitGlobalReduxState } from "../types"; import type { PayloadAction } from "@reduxjs/toolkit"; export interface UpdateGlobalProfileInitPayload extends UpdateGlobalProfileRequestParams {} type UpdateGlobalProfileInitAction = ( - state: GitConfigReduxState, + state: GitGlobalReduxState, action: PayloadAction, -) => GitConfigReduxState; +) => GitGlobalReduxState; export const updateGlobalProfileInitAction: UpdateGlobalProfileInitAction = ( state, @@ -20,7 +20,7 @@ export const updateGlobalProfileInitAction: UpdateGlobalProfileInitAction = ( }; export const updateGlobalProfileSuccessAction = ( - state: GitConfigReduxState, + state: GitGlobalReduxState, ) => { state.updateGlobalProfile.loading = false; @@ -28,7 +28,7 @@ export const updateGlobalProfileSuccessAction = ( }; export const updateGlobalProfileErrorAction = ( - state: GitConfigReduxState, + state: GitGlobalReduxState, action: PayloadAction, ) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/updateLocalProfileActions.ts b/app/client/src/git/store/actions/updateLocalProfileActions.ts index 717bb388cb9b..84ac561a5026 100644 --- a/app/client/src/git/store/actions/updateLocalProfileActions.ts +++ b/app/client/src/git/store/actions/updateLocalProfileActions.ts @@ -1,4 +1,4 @@ -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; import type { UpdateLocalProfileRequestParams } from "git/requests/updateLocalProfileRequest.types"; @@ -6,23 +6,21 @@ export interface UpdateLocalProfileInitPayload extends UpdateLocalProfileRequestParams {} export const updateLocalProfileInitAction = - createSingleArtifactAction((state) => { + createArtifactAction((state) => { state.apiResponses.updateLocalProfile.loading = true; state.apiResponses.updateLocalProfile.error = null; return state; }); -export const updateLocalProfileSuccessAction = createSingleArtifactAction( - (state) => { - state.apiResponses.updateLocalProfile.loading = false; +export const updateLocalProfileSuccessAction = createArtifactAction((state) => { + state.apiResponses.updateLocalProfile.loading = false; - return state; - }, -); + return state; +}); export const updateLocalProfileErrorAction = - createSingleArtifactAction((state, action) => { + createArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.updateLocalProfile.loading = false; diff --git a/app/client/src/git/store/actions/updateProtectedBranchesActions.ts b/app/client/src/git/store/actions/updateProtectedBranchesActions.ts index 6e45bf0dcca5..a19926b673f9 100644 --- a/app/client/src/git/store/actions/updateProtectedBranchesActions.ts +++ b/app/client/src/git/store/actions/updateProtectedBranchesActions.ts @@ -1,19 +1,19 @@ import type { UpdateProtectedBranchesRequestParams } from "git/requests/updateProtectedBranchesRequest.types"; -import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import { createArtifactAction } from "../helpers/createArtifactAction"; import type { GitArtifactErrorPayloadAction } from "../types"; export interface UpdateProtectedBranchesInitPayload extends UpdateProtectedBranchesRequestParams {} export const updateProtectedBranchesInitAction = - createSingleArtifactAction((state) => { + createArtifactAction((state) => { state.apiResponses.updateProtectedBranches.loading = true; state.apiResponses.updateProtectedBranches.error = null; return state; }); -export const updateProtectedBranchesSuccessAction = createSingleArtifactAction( +export const updateProtectedBranchesSuccessAction = createArtifactAction( (state) => { state.apiResponses.updateProtectedBranches.loading = false; @@ -21,7 +21,7 @@ export const updateProtectedBranchesSuccessAction = createSingleArtifactAction( }, ); -export const updateProtectedBranchesErrorAction = createSingleArtifactAction( +export const updateProtectedBranchesErrorAction = createArtifactAction( (state, action: GitArtifactErrorPayloadAction) => { const { error } = action.payload; diff --git a/app/client/src/git/store/gitArtifactSlice.ts b/app/client/src/git/store/gitArtifactSlice.ts index 924785f80c76..15bbb4de65d2 100644 --- a/app/client/src/git/store/gitArtifactSlice.ts +++ b/app/client/src/git/store/gitArtifactSlice.ts @@ -1,5 +1,5 @@ import { createSlice } from "@reduxjs/toolkit"; -import type { GitArtifactReduxState } from "./types"; +import type { GitArtifactRootReduxState } from "./types"; import { mountAction, unmountAction } from "./actions/mountActions"; import { connectErrorAction, @@ -62,6 +62,7 @@ import { openDisconnectModalAction, closeDisconnectModalAction, toggleAutocommitDisableModalAction, + toggleConnectSuccessModalAction, } from "./actions/uiActions"; import { checkoutBranchErrorAction, @@ -119,11 +120,6 @@ import { disconnectInitAction, disconnectSuccessAction, } from "./actions/disconnectActions"; -import { - gitImportErrorAction, - gitImportInitAction, - gitImportSuccessAction, -} from "./actions/gitImportActions"; import { fetchSSHKeyErrorAction, fetchSSHKeyInitAction, @@ -137,7 +133,7 @@ import { resetGenerateSSHKeyAction, } from "./actions/generateSSHKeyActions"; -const initialState: GitArtifactReduxState = {}; +const initialState: GitArtifactRootReduxState = {}; export const gitArtifactSlice = createSlice({ name: "git/artifact", @@ -156,9 +152,6 @@ export const gitArtifactSlice = createSlice({ connectInit: connectInitAction, connectSuccess: connectSuccessAction, connectError: connectErrorAction, - gitImportInit: gitImportInitAction, - gitImportSuccess: gitImportSuccessAction, - gitImportError: gitImportErrorAction, fetchSSHKeyInit: fetchSSHKeyInitAction, fetchSSHKeySuccess: fetchSSHKeySuccessAction, fetchSSHKeyError: fetchSSHKeyErrorAction, @@ -171,6 +164,7 @@ export const gitArtifactSlice = createSlice({ disconnectSuccess: disconnectSuccessAction, disconnectError: disconnectErrorAction, toggleConnectModal: toggleConnectModalAction, + toggleConnectSuccessModal: toggleConnectSuccessModalAction, openDisconnectModal: openDisconnectModalAction, closeDisconnectModal: closeDisconnectModalAction, toggleRepoLimitErrorModal: toggleRepoLimitErrorModalAction, diff --git a/app/client/src/git/store/gitConfigSlice.ts b/app/client/src/git/store/gitConfigSlice.ts deleted file mode 100644 index a07a45d9730b..000000000000 --- a/app/client/src/git/store/gitConfigSlice.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { createSlice } from "@reduxjs/toolkit"; -import { - fetchGlobalProfileErrorAction, - fetchGlobalProfileInitAction, - fetchGlobalProfileSuccessAction, -} from "./actions/fetchGlobalProfileActions"; -import { - updateGlobalProfileErrorAction, - updateGlobalProfileInitAction, - updateGlobalProfileSuccessAction, -} from "./actions/updateGlobalProfileActions"; -import { gitConfigInitialState } from "./helpers/gitConfigInitialState"; - -export const gitConfigSlice = createSlice({ - name: "git/config", - initialState: gitConfigInitialState, - reducers: { - fetchGlobalProfileInit: fetchGlobalProfileInitAction, - fetchGlobalProfileSuccess: fetchGlobalProfileSuccessAction, - fetchGlobalProfileError: fetchGlobalProfileErrorAction, - updateGlobalProfileInit: updateGlobalProfileInitAction, - updateGlobalProfileSuccess: updateGlobalProfileSuccessAction, - updateGlobalProfileError: updateGlobalProfileErrorAction, - }, -}); - -export const gitConfigActions = gitConfigSlice.actions; - -export const gitConfigReducer = gitConfigSlice.reducer; diff --git a/app/client/src/git/store/gitGlobalSlice.ts b/app/client/src/git/store/gitGlobalSlice.ts new file mode 100644 index 000000000000..4a26f5d6132f --- /dev/null +++ b/app/client/src/git/store/gitGlobalSlice.ts @@ -0,0 +1,49 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { + fetchGlobalProfileErrorAction, + fetchGlobalProfileInitAction, + fetchGlobalProfileSuccessAction, +} from "./actions/fetchGlobalProfileActions"; +import { + updateGlobalProfileErrorAction, + updateGlobalProfileInitAction, + updateGlobalProfileSuccessAction, +} from "./actions/updateGlobalProfileActions"; +import { gitGlobalInitialState } from "./helpers/initialState"; +import { toggleImportModalAction } from "./actions/uiActions"; +import { + gitImportErrorAction, + gitImportInitAction, + gitImportSuccessAction, +} from "./actions/gitImportActions"; +import { + fetchGlobalSSHKeyErrorAction, + fetchGlobalSSHKeyInitAction, + fetchGlobalSSHKeySuccessAction, + resetGlobalSSHKeyAction, +} from "./actions/fetchGlobalSSHKeyActions"; + +export const gitGlobalSlice = createSlice({ + name: "git/config", + initialState: gitGlobalInitialState, + reducers: { + fetchGlobalProfileInit: fetchGlobalProfileInitAction, + fetchGlobalProfileSuccess: fetchGlobalProfileSuccessAction, + fetchGlobalProfileError: fetchGlobalProfileErrorAction, + updateGlobalProfileInit: updateGlobalProfileInitAction, + updateGlobalProfileSuccess: updateGlobalProfileSuccessAction, + updateGlobalProfileError: updateGlobalProfileErrorAction, + fetchGlobalSSHKeyInit: fetchGlobalSSHKeyInitAction, + fetchGlobalSSHKeySuccess: fetchGlobalSSHKeySuccessAction, + fetchGlobalSSHKeyError: fetchGlobalSSHKeyErrorAction, + resetGlobalSSHKey: resetGlobalSSHKeyAction, + gitImportInit: gitImportInitAction, + gitImportSuccess: gitImportSuccessAction, + gitImportError: gitImportErrorAction, + toggleImportModal: toggleImportModalAction, + }, +}); + +export const gitGlobalActions = gitGlobalSlice.actions; + +export const gitGlobalReducer = gitGlobalSlice.reducer; diff --git a/app/client/src/git/store/helpers/createArtifactAction.ts b/app/client/src/git/store/helpers/createArtifactAction.ts new file mode 100644 index 000000000000..c138af710d53 --- /dev/null +++ b/app/client/src/git/store/helpers/createArtifactAction.ts @@ -0,0 +1,35 @@ +import type { + GitArtifactBasePayload, + GitArtifactPayloadAction, + GitArtifactReduxState, + GitArtifactRootReduxState, +} from "../types"; +import { gitArtifactInitialState } from "./initialState"; + +type ArtifactStateCb = ( + artifactState: GitArtifactReduxState, + action: GitArtifactPayloadAction, +) => GitArtifactReduxState; + +export const createArtifactAction = ( + artifactStateCb: ArtifactStateCb, +) => { + return ( + state: GitArtifactRootReduxState, + action: GitArtifactPayloadAction, + ) => { + const { artifactType, baseArtifactId } = action.payload.artifactDef; + + state[artifactType] ??= {}; + state[artifactType][baseArtifactId] ??= gitArtifactInitialState; + + const artifactState = state[artifactType][baseArtifactId]; + + state[artifactType][baseArtifactId] = artifactStateCb( + artifactState, + action, + ); + + return state; + }; +}; diff --git a/app/client/src/git/store/helpers/createSingleArtifactAction.ts b/app/client/src/git/store/helpers/createSingleArtifactAction.ts deleted file mode 100644 index 2e0642959be8..000000000000 --- a/app/client/src/git/store/helpers/createSingleArtifactAction.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { - GitArtifactBasePayload, - GitArtifactPayloadAction, - GitArtifactReduxState, - GitSingleArtifactReduxState, -} from "../types"; -import { gitSingleArtifactInitialState } from "./gitSingleArtifactInitialState"; - -type SingleArtifactStateCb = ( - singleArtifactState: GitSingleArtifactReduxState, - action: GitArtifactPayloadAction, -) => GitSingleArtifactReduxState; - -export const createSingleArtifactAction = ( - singleArtifactStateCb: SingleArtifactStateCb, -) => { - return ( - state: GitArtifactReduxState, - action: GitArtifactPayloadAction, - ) => { - const { artifactType, baseArtifactId } = action.payload; - - state[artifactType] ??= {}; - state[artifactType][baseArtifactId] ??= gitSingleArtifactInitialState; - - const singleArtifactState = state[artifactType][baseArtifactId]; - - state[artifactType][baseArtifactId] = singleArtifactStateCb( - singleArtifactState, - action, - ); - - return state; - }; -}; diff --git a/app/client/src/git/store/helpers/gitConfigInitialState.ts b/app/client/src/git/store/helpers/gitConfigInitialState.ts deleted file mode 100644 index 7017399dfb16..000000000000 --- a/app/client/src/git/store/helpers/gitConfigInitialState.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { GitConfigReduxState } from "../types"; - -export const gitConfigInitialState: GitConfigReduxState = { - globalProfile: { - value: null, - loading: false, - error: null, - }, - updateGlobalProfile: { - loading: false, - error: null, - }, -}; diff --git a/app/client/src/git/store/helpers/gitSingleArtifactInitialState.ts b/app/client/src/git/store/helpers/gitSingleArtifactInitialState.ts deleted file mode 100644 index b17c93a126cb..000000000000 --- a/app/client/src/git/store/helpers/gitSingleArtifactInitialState.ts +++ /dev/null @@ -1,138 +0,0 @@ -import { - gitArtifactAPIResponsesInitialState as gitArtifactAPIResponsesInitialStateExtended, - gitArtifactUIInitialState as gitArtifactUIInitialStateExtended, -} from "git/ee/store/helpers/initialState"; -import { GitOpsTab, GitSettingsTab } from "../../constants/enums"; -import type { - GitSingleArtifactAPIResponsesReduxState, - GitSingleArtifactUIReduxState, - GitSingleArtifactReduxState, -} from "../types"; - -const gitSingleArtifactInitialUIState: GitSingleArtifactUIReduxState = { - connectModalOpen: false, - disconnectBaseArtifactId: null, - disconnectArtifactName: null, - branchPopupOpen: false, - checkoutDestBranch: null, - opsModalOpen: false, - opsModalTab: GitOpsTab.Deploy, - settingsModalOpen: false, - settingsModalTab: GitSettingsTab.General, - autocommitDisableModalOpen: false, - autocommitPolling: false, - conflictErrorModalOpen: false, - repoLimitErrorModalOpen: false, - // EE - ...gitArtifactUIInitialStateExtended, -}; - -const gitSingleArtifactInitialAPIResponses: GitSingleArtifactAPIResponsesReduxState = - { - metadata: { - value: null, - loading: false, - error: null, - }, - connect: { - loading: false, - error: null, - }, - gitImport: { - loading: false, - error: null, - }, - status: { - value: null, - loading: false, - error: null, - }, - commit: { - loading: false, - error: null, - }, - pull: { - loading: false, - error: null, - }, - discard: { - loading: false, - error: null, - }, - mergeStatus: { - value: null, - loading: false, - error: null, - }, - merge: { - loading: false, - error: null, - }, - branches: { - value: null, - loading: false, - error: null, - }, - checkoutBranch: { - loading: false, - error: null, - }, - createBranch: { - loading: false, - error: null, - }, - deleteBranch: { - loading: false, - error: null, - }, - localProfile: { - value: null, - loading: false, - error: null, - }, - updateLocalProfile: { - loading: false, - error: null, - }, - disconnect: { - loading: false, - error: null, - }, - protectedBranches: { - value: null, - loading: false, - error: null, - }, - updateProtectedBranches: { - loading: false, - error: null, - }, - autocommitProgress: { - loading: false, - error: null, - }, - toggleAutocommit: { - loading: false, - error: null, - }, - triggerAutocommit: { - loading: false, - error: null, - }, - generateSSHKey: { - loading: false, - error: null, - }, - sshKey: { - value: null, - loading: false, - error: null, - }, - // EE - ...gitArtifactAPIResponsesInitialStateExtended, - }; - -export const gitSingleArtifactInitialState: GitSingleArtifactReduxState = { - ui: gitSingleArtifactInitialUIState, - apiResponses: gitSingleArtifactInitialAPIResponses, -}; diff --git a/app/client/src/git/store/helpers/initialState.ts b/app/client/src/git/store/helpers/initialState.ts new file mode 100644 index 000000000000..382833be2782 --- /dev/null +++ b/app/client/src/git/store/helpers/initialState.ts @@ -0,0 +1,157 @@ +import { + gitArtifactAPIResponsesInitialState as gitArtifactAPIResponsesInitialStateExtended, + gitArtifactUIInitialState as gitArtifactUIInitialStateExtended, +} from "git/ee/store/helpers/initialState"; +import { GitOpsTab, GitSettingsTab } from "../../constants/enums"; +import type { + GitArtifactAPIResponsesReduxState, + GitArtifactUIReduxState, + GitArtifactReduxState, + GitGlobalReduxState, +} from "../types"; + +const gitArtifactInitialUIState: GitArtifactUIReduxState = { + connectModalOpen: false, + connectSuccessModalOpen: false, + disconnectBaseArtifactId: null, + disconnectArtifactName: null, + branchPopupOpen: false, + checkoutDestBranch: null, + opsModalOpen: false, + opsModalTab: GitOpsTab.Deploy, + settingsModalOpen: false, + settingsModalTab: GitSettingsTab.General, + autocommitDisableModalOpen: false, + autocommitPolling: false, + conflictErrorModalOpen: false, + repoLimitErrorModalOpen: false, + // EE + ...gitArtifactUIInitialStateExtended, +}; + +const gitArtifactInitialAPIResponses: GitArtifactAPIResponsesReduxState = { + metadata: { + value: null, + loading: false, + error: null, + }, + connect: { + loading: false, + error: null, + }, + status: { + value: null, + loading: false, + error: null, + }, + commit: { + loading: false, + error: null, + }, + pull: { + loading: false, + error: null, + }, + discard: { + loading: false, + error: null, + }, + mergeStatus: { + value: null, + loading: false, + error: null, + }, + merge: { + loading: false, + error: null, + }, + branches: { + value: null, + loading: false, + error: null, + }, + checkoutBranch: { + loading: false, + error: null, + }, + createBranch: { + loading: false, + error: null, + }, + deleteBranch: { + loading: false, + error: null, + }, + localProfile: { + value: null, + loading: false, + error: null, + }, + updateLocalProfile: { + loading: false, + error: null, + }, + disconnect: { + loading: false, + error: null, + }, + protectedBranches: { + value: null, + loading: false, + error: null, + }, + updateProtectedBranches: { + loading: false, + error: null, + }, + autocommitProgress: { + loading: false, + error: null, + }, + toggleAutocommit: { + loading: false, + error: null, + }, + triggerAutocommit: { + loading: false, + error: null, + }, + generateSSHKey: { + loading: false, + error: null, + }, + sshKey: { + value: null, + loading: false, + error: null, + }, + // EE + ...gitArtifactAPIResponsesInitialStateExtended, +}; + +export const gitArtifactInitialState: GitArtifactReduxState = { + ui: gitArtifactInitialUIState, + apiResponses: gitArtifactInitialAPIResponses, +}; + +export const gitGlobalInitialState: GitGlobalReduxState = { + globalProfile: { + value: null, + loading: false, + error: null, + }, + updateGlobalProfile: { + loading: false, + error: null, + }, + globalSSHKey: { + value: null, + loading: false, + error: null, + }, + gitImport: { + loading: false, + error: null, + }, + isImportModalOpen: false, +}; diff --git a/app/client/src/git/store/index.ts b/app/client/src/git/store/index.ts index f5337e564f97..6d210139ada4 100644 --- a/app/client/src/git/store/index.ts +++ b/app/client/src/git/store/index.ts @@ -1,8 +1,8 @@ import { combineReducers } from "@reduxjs/toolkit"; import { gitArtifactReducer } from "./gitArtifactSlice"; -import { gitConfigReducer } from "./gitConfigSlice"; +import { gitGlobalReducer } from "./gitGlobalSlice"; export const gitReducer = combineReducers({ artifacts: gitArtifactReducer, - config: gitConfigReducer, + global: gitGlobalReducer, }); diff --git a/app/client/src/git/store/selectors/gitSingleArtifactSelectors.ts b/app/client/src/git/store/selectors/gitArtifactSelectors.ts similarity index 92% rename from app/client/src/git/store/selectors/gitSingleArtifactSelectors.ts rename to app/client/src/git/store/selectors/gitArtifactSelectors.ts index 845a2cfe41fe..5bf8267df889 100644 --- a/app/client/src/git/store/selectors/gitSingleArtifactSelectors.ts +++ b/app/client/src/git/store/selectors/gitArtifactSelectors.ts @@ -1,10 +1,4 @@ -import type { GitArtifactType } from "git/constants/enums"; -import type { GitRootState } from "../types"; - -export interface GitArtifactDef { - artifactType: keyof typeof GitArtifactType; - baseArtifactId: string; -} +import type { GitArtifactDef, GitRootState } from "../types"; export const selectGitArtifact = ( state: GitRootState, @@ -21,7 +15,7 @@ export const selectMetadataState = ( artifactDef: GitArtifactDef, ) => selectGitArtifact(state, artifactDef)?.apiResponses.metadata; -export const selectGitConnected = ( +export const selectConnected = ( state: GitRootState, artifactDef: GitArtifactDef, ) => !!selectMetadataState(state, artifactDef)?.value; @@ -32,11 +26,6 @@ export const selectConnectState = ( artifactDef: GitArtifactDef, ) => selectGitArtifact(state, artifactDef)?.apiResponses.connect; -export const selectGitImportState = ( - state: GitRootState, - artifactDef: GitArtifactDef, -) => selectGitArtifact(state, artifactDef)?.apiResponses.gitImport; - export const selectFetchSSHKeysState = ( state: GitRootState, artifactDef: GitArtifactDef, @@ -52,6 +41,11 @@ export const selectConnectModalOpen = ( artifactDef: GitArtifactDef, ) => selectGitArtifact(state, artifactDef)?.ui.connectModalOpen; +export const selectConnectSuccessModalOpen = ( + state: GitRootState, + artifactDef: GitArtifactDef, +) => selectGitArtifact(state, artifactDef)?.ui.connectSuccessModalOpen; + export const selectDisconnectState = ( state: GitRootState, artifactDef: GitArtifactDef, @@ -117,11 +111,14 @@ export const selectConflictErrorModalOpen = ( export const selectCurrentBranch = ( state: GitRootState, + // need this to preserve interface + // eslint-disable-next-line @typescript-eslint/no-unused-vars artifactDef: GitArtifactDef, ) => { - const gitMetadataState = selectMetadataState(state, artifactDef).value; - - return gitMetadataState?.branchName; + return ( + state?.ui?.applications?.currentApplication?.gitApplicationMetadata + ?.branchName ?? null + ); }; export const selectFetchBranchesState = ( @@ -220,10 +217,8 @@ export const selectProtectedMode = ( artifactDef: GitArtifactDef, ) => { const currentBranch = selectCurrentBranch(state, artifactDef); - const protectedBranches = selectFetchProtectedBranchesState( - state, - artifactDef, - ).value; + const protectedBranches = + selectFetchProtectedBranchesState(state, artifactDef)?.value ?? []; return protectedBranches?.includes(currentBranch ?? "") ?? false; }; diff --git a/app/client/src/git/store/selectors/gitConfigSelectors.ts b/app/client/src/git/store/selectors/gitConfigSelectors.ts deleted file mode 100644 index be31a23cda5e..000000000000 --- a/app/client/src/git/store/selectors/gitConfigSelectors.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { GitRootState } from "../types"; - -export const selectGitConfig = (state: GitRootState) => { - return state.git.config; -}; - -// global profile -export const selectFetchGlobalProfileState = (state: GitRootState) => - selectGitConfig(state).globalProfile; - -export const selectUpdateGlobalProfileState = (state: GitRootState) => - selectGitConfig(state).updateGlobalProfile; diff --git a/app/client/src/git/store/selectors/gitGlobalSelectors.ts b/app/client/src/git/store/selectors/gitGlobalSelectors.ts new file mode 100644 index 000000000000..1d1fdb555d0c --- /dev/null +++ b/app/client/src/git/store/selectors/gitGlobalSelectors.ts @@ -0,0 +1,21 @@ +import type { GitRootState } from "../types"; + +export const selectGitGlobal = (state: GitRootState) => { + return state.git.global; +}; + +// global profile +export const selectFetchGlobalProfileState = (state: GitRootState) => + selectGitGlobal(state).globalProfile; + +export const selectUpdateGlobalProfileState = (state: GitRootState) => + selectGitGlobal(state).updateGlobalProfile; + +export const selectImportModalOpen = (state: GitRootState) => + selectGitGlobal(state).isImportModalOpen; + +export const selectGitImportState = (state: GitRootState) => + selectGitGlobal(state).gitImport; + +export const selectFetchGlobalSSHKeyState = (state: GitRootState) => + selectGitGlobal(state).globalSSHKey; diff --git a/app/client/src/git/store/types.ts b/app/client/src/git/store/types.ts index ccb67a2e7a8b..90a2e72998a5 100644 --- a/app/client/src/git/store/types.ts +++ b/app/client/src/git/store/types.ts @@ -17,6 +17,7 @@ import type { GitArtifactAPIResponsesReduxState as GitArtifactAPIResponsesReduxStateExtended, GitArtifactUIReduxState as GitArtifactUIReduxStateExtended, } from "git/ee/store/types"; +import type { FetchGlobalSSHKeyResponseData } from "git/requests/fetchGlobalSSHKeyRequest.types"; export interface GitApiError extends ApiResponseError { errorType?: string; @@ -33,11 +34,10 @@ export interface GitAsyncStateWithoutValue { loading: boolean; error: GitApiError | null; } -export interface GitSingleArtifactAPIResponsesReduxState +export interface GitArtifactAPIResponsesReduxState extends GitArtifactAPIResponsesReduxStateExtended { metadata: GitAsyncState; connect: GitAsyncStateWithoutValue; - gitImport: GitAsyncStateWithoutValue; status: GitAsyncState; commit: GitAsyncStateWithoutValue; pull: GitAsyncStateWithoutValue; @@ -60,9 +60,10 @@ export interface GitSingleArtifactAPIResponsesReduxState generateSSHKey: GitAsyncStateWithoutValue; } -export interface GitSingleArtifactUIReduxState +export interface GitArtifactUIReduxState extends GitArtifactUIReduxStateExtended { connectModalOpen: boolean; + connectSuccessModalOpen: boolean; disconnectBaseArtifactId: string | null; disconnectArtifactName: string | null; branchPopupOpen: boolean; @@ -76,30 +77,51 @@ export interface GitSingleArtifactUIReduxState conflictErrorModalOpen: boolean; repoLimitErrorModalOpen: boolean; } -export interface GitSingleArtifactReduxState { - ui: GitSingleArtifactUIReduxState; - apiResponses: GitSingleArtifactAPIResponsesReduxState; -} +export interface GitArtifactDef { + artifactType: keyof typeof GitArtifactType; + baseArtifactId: string; +} export interface GitArtifactReduxState { - [key: string]: Record; + ui: GitArtifactUIReduxState; + apiResponses: GitArtifactAPIResponsesReduxState; } -export interface GitConfigReduxState { +export interface GitGlobalReduxState { globalProfile: GitAsyncState; updateGlobalProfile: GitAsyncStateWithoutValue; + gitImport: GitAsyncStateWithoutValue; + globalSSHKey: GitAsyncState; + // ui + isImportModalOpen: boolean; +} + +export type GitArtifactRootReduxState = Record< + string, + Record +>; + +export interface GitReduxState { + artifacts: GitArtifactRootReduxState; + global: GitGlobalReduxState; } export interface GitRootState { - git: { - artifacts: GitArtifactReduxState; - config: GitConfigReduxState; + // will have to remove this later, once metadata is fixed + ui: { + applications: { + currentApplication?: { + gitApplicationMetadata?: { + branchName: string; + }; + }; + }; }; + git: GitReduxState; } export interface GitArtifactBasePayload { - artifactType: keyof typeof GitArtifactType; - baseArtifactId: string; + artifactDef: GitArtifactDef; } export interface GitAsyncErrorPayload { diff --git a/app/client/src/layoutSystems/anvil/common/hooks/detachedWidgetHooks.ts b/app/client/src/layoutSystems/anvil/common/hooks/detachedWidgetHooks.ts index c3ad4a82bd8d..6bf86d26a55d 100644 --- a/app/client/src/layoutSystems/anvil/common/hooks/detachedWidgetHooks.ts +++ b/app/client/src/layoutSystems/anvil/common/hooks/detachedWidgetHooks.ts @@ -1,7 +1,6 @@ import { useWidgetBorderStyles } from "./useWidgetBorderStyles"; import { useDispatch, useSelector } from "react-redux"; import { useWidgetSelection } from "utils/hooks/useWidgetSelection"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { SELECT_ANVIL_WIDGET_CUSTOM_EVENT } from "layoutSystems/anvil/utils/constants"; import log from "loglevel"; import { useEffect, useMemo } from "react"; @@ -9,6 +8,7 @@ import { getAnvilWidgetDOMId } from "layoutSystems/common/utils/LayoutElementPos import { getCurrentlyOpenAnvilDetachedWidgets } from "layoutSystems/anvil/integrations/modalSelectors"; import { getCanvasWidgetsStructure } from "ee/selectors/entitiesSelector"; import type { CanvasWidgetStructure } from "WidgetProvider/constants"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; /** * This hook is used to select and focus on a detached widget * As detached widgets are outside of the layout flow, we need to access the correct element in the DOM @@ -17,7 +17,7 @@ import type { CanvasWidgetStructure } from "WidgetProvider/constants"; */ export function useHandleDetachedWidgetSelect(widgetId: string) { const dispatch = useDispatch(); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const className = getAnvilWidgetDOMId(widgetId); const element = document.querySelector(`.${className}`); diff --git a/app/client/src/layoutSystems/anvil/common/hooks/useWidgetBorderStyles.ts b/app/client/src/layoutSystems/anvil/common/hooks/useWidgetBorderStyles.ts index fea0cc19424c..1213f9134b3a 100644 --- a/app/client/src/layoutSystems/anvil/common/hooks/useWidgetBorderStyles.ts +++ b/app/client/src/layoutSystems/anvil/common/hooks/useWidgetBorderStyles.ts @@ -7,8 +7,8 @@ import { getWidgetsDistributingSpace, } from "layoutSystems/anvil/integrations/selectors"; import { useSelector } from "react-redux"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { isWidgetFocused, isWidgetSelected } from "selectors/widgetSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export function useWidgetBorderStyles(widgetId: string, widgetType: string) { /** Selectors */ @@ -32,7 +32,7 @@ export function useWidgetBorderStyles(widgetId: string, widgetType: string) { const widgetsEffectedBySpaceDistribution = useSelector( getWidgetsDistributingSpace, ); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); /** EO selectors */ diff --git a/app/client/src/layoutSystems/anvil/editor/AnvilEditorWidgetOnion.tsx b/app/client/src/layoutSystems/anvil/editor/AnvilEditorWidgetOnion.tsx index f5a6505a2be2..839c055f0f40 100644 --- a/app/client/src/layoutSystems/anvil/editor/AnvilEditorWidgetOnion.tsx +++ b/app/client/src/layoutSystems/anvil/editor/AnvilEditorWidgetOnion.tsx @@ -4,7 +4,7 @@ import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC"; import { AnvilWidgetComponent } from "../common/widgetComponent/AnvilWidgetComponent"; import { getWidgetSizeConfiguration } from "../utils/widgetUtils"; import { useSelector } from "react-redux"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import { AnvilEditorFlexComponent } from "./AnvilEditorFlexComponent"; import { AnvilFlexComponent } from "../common/AnvilFlexComponent"; import { SKELETON_WIDGET_TYPE } from "constants/WidgetConstants"; @@ -25,7 +25,7 @@ import { SKELETON_WIDGET_TYPE } from "constants/WidgetConstants"; * @returns Enhanced Widget */ export const AnvilEditorWidgetOnion = (props: BaseWidgetProps) => { - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const { widgetSize, WidgetWrapper } = useMemo(() => { return { widgetSize: getWidgetSizeConfiguration(props.type, props, isPreviewMode), diff --git a/app/client/src/layoutSystems/anvil/editor/hooks/useAnvilWidgetHover.ts b/app/client/src/layoutSystems/anvil/editor/hooks/useAnvilWidgetHover.ts index abdb88561f68..e51d921bf1bd 100644 --- a/app/client/src/layoutSystems/anvil/editor/hooks/useAnvilWidgetHover.ts +++ b/app/client/src/layoutSystems/anvil/editor/hooks/useAnvilWidgetHover.ts @@ -2,7 +2,7 @@ import type { AppState } from "ee/reducers"; import { getAnvilSpaceDistributionStatus } from "layoutSystems/anvil/integrations/selectors"; import { useCallback, useEffect } from "react"; import { useSelector } from "react-redux"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import { isWidgetFocused } from "selectors/widgetSelectors"; import { useWidgetSelection } from "utils/hooks/useWidgetSelection"; @@ -12,7 +12,7 @@ export const useAnvilWidgetHover = ( ) => { // Retrieve state from the Redux store const isFocused = useSelector(isWidgetFocused(widgetId)); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isDistributingSpace = useSelector(getAnvilSpaceDistributionStatus); const isDragging = useSelector( (state: AppState) => state.ui.widgetDragResize.isDragging, diff --git a/app/client/src/layoutSystems/anvil/integrations/sagas/LayoutElementPositionsSaga.ts b/app/client/src/layoutSystems/anvil/integrations/sagas/LayoutElementPositionsSaga.ts index a882919710b1..2cddcc974bc8 100644 --- a/app/client/src/layoutSystems/anvil/integrations/sagas/LayoutElementPositionsSaga.ts +++ b/app/client/src/layoutSystems/anvil/integrations/sagas/LayoutElementPositionsSaga.ts @@ -8,7 +8,7 @@ import log from "loglevel"; import type { AppState } from "ee/reducers"; import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; import { APP_MODE } from "entities/App"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import { getAppMode } from "ee/selectors/entitiesSelector"; import type { RefObject } from "react"; import { getAnvilSpaceDistributionStatus } from "../selectors"; @@ -87,7 +87,7 @@ function* readAndUpdateLayoutElementPositions() { // The positions are used only in the editor, so we should not be running this saga // in the viewer or the preview mode. - const isPreviewMode: boolean = yield select(combinedPreviewModeSelector); + const isPreviewMode: boolean = yield select(selectCombinedPreviewMode); const appMode: APP_MODE = yield select(getAppMode); if (isPreviewMode || appMode === APP_MODE.PUBLISHED) { diff --git a/app/client/src/layoutSystems/anvil/layoutComponents/components/zone/useZoneMinWidth.ts b/app/client/src/layoutSystems/anvil/layoutComponents/components/zone/useZoneMinWidth.ts index fe49ee655230..c8ba600c5fb6 100644 --- a/app/client/src/layoutSystems/anvil/layoutComponents/components/zone/useZoneMinWidth.ts +++ b/app/client/src/layoutSystems/anvil/layoutComponents/components/zone/useZoneMinWidth.ts @@ -3,22 +3,20 @@ import { ChildrenMapContext } from "layoutSystems/anvil/context/childrenMapConte import type { WidgetProps } from "widgets/BaseWidget"; import { RenderModes } from "constants/WidgetConstants"; import { useSelector } from "react-redux"; -import { - combinedPreviewModeSelector, - getRenderMode, -} from "selectors/editorSelectors"; +import { getRenderMode } from "selectors/editorSelectors"; import type { SizeConfig } from "WidgetProvider/constants"; import { getWidgetSizeConfiguration } from "layoutSystems/anvil/utils/widgetUtils"; import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer"; import { getWidgets } from "sagas/selectors"; import isObject from "lodash/isObject"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export function useZoneMinWidth() { const childrenMap: Record = useContext(ChildrenMapContext); const widgets: CanvasWidgetsReduxState = useSelector(getWidgets); const renderMode: RenderModes = useSelector(getRenderMode); - const isPreviewMode: boolean = useSelector(combinedPreviewModeSelector); + const isPreviewMode: boolean = useSelector(selectCombinedPreviewMode); if (renderMode === RenderModes.CANVAS && !isPreviewMode) return "auto"; diff --git a/app/client/src/layoutSystems/anvil/sectionSpaceDistributor/SectionSpaceDistributor.tsx b/app/client/src/layoutSystems/anvil/sectionSpaceDistributor/SectionSpaceDistributor.tsx index fd719bfd1f6f..25e94d38d9e8 100644 --- a/app/client/src/layoutSystems/anvil/sectionSpaceDistributor/SectionSpaceDistributor.tsx +++ b/app/client/src/layoutSystems/anvil/sectionSpaceDistributor/SectionSpaceDistributor.tsx @@ -2,7 +2,7 @@ import { getLayoutElementPositions } from "layoutSystems/common/selectors"; import type { LayoutElementPosition } from "layoutSystems/common/types"; import React, { useMemo } from "react"; import { useSelector } from "react-redux"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import type { WidgetLayoutProps } from "../utils/anvilTypes"; import { getWidgetByID } from "sagas/selectors"; import { getDefaultSpaceDistributed } from "./utils/spaceRedistributionSagaUtils"; @@ -113,7 +113,7 @@ export const SectionSpaceDistributor = ( props: SectionSpaceDistributorProps, ) => { const { zones } = props; - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isWidgetSelectionBlocked = useSelector(getWidgetSelectionBlock); const isDragging = useSelector( (state) => state.ui.widgetDragResize.isDragging, diff --git a/app/client/src/layoutSystems/anvil/viewer/AnvilViewerWidgetOnion.tsx b/app/client/src/layoutSystems/anvil/viewer/AnvilViewerWidgetOnion.tsx index 99ca7dddf492..763785755918 100644 --- a/app/client/src/layoutSystems/anvil/viewer/AnvilViewerWidgetOnion.tsx +++ b/app/client/src/layoutSystems/anvil/viewer/AnvilViewerWidgetOnion.tsx @@ -5,7 +5,7 @@ import { AnvilWidgetComponent } from "../common/widgetComponent/AnvilWidgetCompo import type { SizeConfig } from "WidgetProvider/constants"; import { getWidgetSizeConfiguration } from "../utils/widgetUtils"; import { useSelector } from "react-redux"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; /** * AnvilViewerWidgetOnion @@ -20,7 +20,7 @@ import { combinedPreviewModeSelector } from "selectors/editorSelectors"; * @returns Enhanced Widget */ export const AnvilViewerWidgetOnion = (props: BaseWidgetProps) => { - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const widgetSize: SizeConfig = useMemo( () => getWidgetSizeConfiguration(props.type, props, isPreviewMode), [isPreviewMode, props.type], diff --git a/app/client/src/layoutSystems/autolayout/common/FlexComponent.tsx b/app/client/src/layoutSystems/autolayout/common/FlexComponent.tsx index 20edbf4ce0d8..334ca9fd95ec 100644 --- a/app/client/src/layoutSystems/autolayout/common/FlexComponent.tsx +++ b/app/client/src/layoutSystems/autolayout/common/FlexComponent.tsx @@ -4,10 +4,7 @@ import styled from "styled-components"; import { WIDGET_PADDING } from "constants/WidgetConstants"; import { useSelector } from "react-redux"; -import { - combinedPreviewModeSelector, - snipingModeSelector, -} from "selectors/editorSelectors"; +import { snipingModeSelector } from "selectors/editorSelectors"; import { getIsResizing } from "selectors/widgetSelectors"; import { useClickToSelectWidget } from "utils/hooks/useClickToSelectWidget"; import { usePositionedContainerZIndex } from "utils/hooks/usePositionedContainerZIndex"; @@ -16,6 +13,7 @@ import { RESIZE_BORDER_BUFFER } from "layoutSystems/common/resizer/common"; import { checkIsDropTarget } from "WidgetProvider/factory/helpers"; import type { FlexComponentProps } from "../../autolayout/utils/types"; import { useHoverToFocusWidget } from "utils/hooks/useHoverToFocusWidget"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; const FlexWidget = styled.div` position: relative; @@ -58,7 +56,7 @@ export function FlexComponent(props: FlexComponentProps) { )} t--widget-${props.widgetName.toLowerCase()}`, [props.parentId, props.widgetId, props.widgetType, props.widgetName], ); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isResizing = useSelector(getIsResizing); const widgetDimensionsViewCss = { diff --git a/app/client/src/layoutSystems/common/dropTarget/DropTargetComponent.tsx b/app/client/src/layoutSystems/common/dropTarget/DropTargetComponent.tsx index d1df63825448..fcb93c9205a6 100644 --- a/app/client/src/layoutSystems/common/dropTarget/DropTargetComponent.tsx +++ b/app/client/src/layoutSystems/common/dropTarget/DropTargetComponent.tsx @@ -21,10 +21,7 @@ import { } from "actions/autoHeightActions"; import { useDispatch } from "react-redux"; import { getDragDetails } from "sagas/selectors"; -import { - combinedPreviewModeSelector, - getOccupiedSpacesSelectorForContainer, -} from "selectors/editorSelectors"; +import { getOccupiedSpacesSelectorForContainer } from "selectors/editorSelectors"; import { getCanvasSnapRows } from "utils/WidgetPropsUtils"; import { useAutoHeightUIState } from "utils/hooks/autoHeightUIHooks"; import { useShowPropertyPane } from "utils/hooks/dragResizeHooks"; @@ -42,6 +39,7 @@ import { import DragLayerComponent from "./DragLayerComponent"; import Onboarding from "./OnBoarding"; import { isDraggingBuildingBlockToCanvas } from "selectors/buildingBlocksSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export type DropTargetComponentProps = PropsWithChildren<{ snapColumnSpace: number; @@ -196,7 +194,7 @@ function useUpdateRows( export function DropTargetComponent(props: DropTargetComponentProps) { // Get if this is in preview mode. - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/layoutSystems/common/resizer/ModalResizableLayer.tsx b/app/client/src/layoutSystems/common/resizer/ModalResizableLayer.tsx index 559556bbbf42..1a516b9623fe 100644 --- a/app/client/src/layoutSystems/common/resizer/ModalResizableLayer.tsx +++ b/app/client/src/layoutSystems/common/resizer/ModalResizableLayer.tsx @@ -19,11 +19,9 @@ import { } from "./ResizeStyledComponents"; import type { UIElementSize } from "./ResizableUtils"; import { useModalWidth } from "widgets/ModalWidget/component/useModalWidth"; -import { - combinedPreviewModeSelector, - snipingModeSelector, -} from "selectors/editorSelectors"; +import { snipingModeSelector } from "selectors/editorSelectors"; import { getWidgetSelectionBlock } from "../../../selectors/ui"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; const minSize = 100; /** @@ -101,7 +99,7 @@ export const ModalResizableLayer = ({ widgetType: "MODAL_WIDGET", }); }; - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isSnipingMode = useSelector(snipingModeSelector); const isWidgetSelectionBlocked = useSelector(getWidgetSelectionBlock); const enableResizing = diff --git a/app/client/src/layoutSystems/common/resizer/ResizableComponent.tsx b/app/client/src/layoutSystems/common/resizer/ResizableComponent.tsx index f0336f382b87..fb5aca05d16f 100644 --- a/app/client/src/layoutSystems/common/resizer/ResizableComponent.tsx +++ b/app/client/src/layoutSystems/common/resizer/ResizableComponent.tsx @@ -17,10 +17,7 @@ import { FixedLayoutResizable } from "layoutSystems/fixedlayout/common/resizer/F import { SelectionRequestType } from "sagas/WidgetSelectUtils"; import { getIsAutoLayout } from "selectors/canvasSelectors"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; -import { - combinedPreviewModeSelector, - snipingModeSelector, -} from "selectors/editorSelectors"; +import { snipingModeSelector } from "selectors/editorSelectors"; import { getParentToOpenSelector, isWidgetFocused, @@ -69,6 +66,7 @@ import { getAltBlockWidgetSelection, getWidgetSelectionBlock, } from "selectors/ui"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export type ResizableComponentProps = WidgetProps & { paddingOffset: number; @@ -83,7 +81,7 @@ export const ResizableComponent = memo(function ResizableComponent( const isAutoLayout = useSelector(getIsAutoLayout); const Resizable = isAutoLayout ? AutoLayoutResizable : FixedLayoutResizable; const isSnipingMode = useSelector(snipingModeSelector); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isWidgetSelectionBlock = useSelector(getWidgetSelectionBlock); const isAltWidgetSelectionBlock = useSelector(getAltBlockWidgetSelection); const isAppSettingsPaneWithNavigationTabOpen: boolean = useSelector( diff --git a/app/client/src/layoutSystems/common/utils/LayoutElementPositionsObserver/usePositionObserver.ts b/app/client/src/layoutSystems/common/utils/LayoutElementPositionsObserver/usePositionObserver.ts index 1d5a9c38f354..9c981c66f397 100644 --- a/app/client/src/layoutSystems/common/utils/LayoutElementPositionsObserver/usePositionObserver.ts +++ b/app/client/src/layoutSystems/common/utils/LayoutElementPositionsObserver/usePositionObserver.ts @@ -3,7 +3,7 @@ import { useEffect } from "react"; import { positionObserver } from "."; import { APP_MODE } from "entities/App"; import { useSelector } from "react-redux"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import { getAppMode } from "ee/selectors/entitiesSelector"; import { getAnvilLayoutDOMId, getAnvilWidgetDOMId } from "./utils"; import { LayoutComponentTypes } from "layoutSystems/anvil/utils/anvilTypes"; @@ -13,7 +13,7 @@ export function useObserveDetachedWidget(widgetId: string) { // We don't need the observer in preview mode or the published app // This is because the positions need to be observed only to enable // editor features - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const appMode = useSelector(getAppMode); if (isPreviewMode || appMode === APP_MODE.PUBLISHED) { @@ -54,7 +54,7 @@ export function usePositionObserver( }, ref: RefObject, ) { - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const appMode = useSelector(getAppMode); useEffect(() => { diff --git a/app/client/src/layoutSystems/common/widgetName/index.tsx b/app/client/src/layoutSystems/common/widgetName/index.tsx index bb8c265946e5..8d5770b995a0 100644 --- a/app/client/src/layoutSystems/common/widgetName/index.tsx +++ b/app/client/src/layoutSystems/common/widgetName/index.tsx @@ -8,7 +8,6 @@ import { SelectionRequestType } from "sagas/WidgetSelectUtils"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; import { hideErrors } from "selectors/debuggerSelectors"; import { - combinedPreviewModeSelector, getIsAutoLayout, snipingModeSelector, } from "selectors/editorSelectors"; @@ -31,6 +30,7 @@ import { RESIZE_BORDER_BUFFER } from "layoutSystems/common/resizer/common"; import { Layers } from "constants/Layers"; import memoize from "micro-memoize"; import { NavigationMethod } from "utils/history"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; const WidgetTypes = WidgetFactory.widgetTypes; @@ -78,7 +78,7 @@ interface WidgetNameComponentProps { export function WidgetNameComponent(props: WidgetNameComponentProps) { const dispatch = useDispatch(); const isSnipingMode = useSelector(snipingModeSelector); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/layoutSystems/fixedlayout/common/autoHeightOverlay/index.tsx b/app/client/src/layoutSystems/fixedlayout/common/autoHeightOverlay/index.tsx index 89519283f7cb..48015d2efff1 100644 --- a/app/client/src/layoutSystems/fixedlayout/common/autoHeightOverlay/index.tsx +++ b/app/client/src/layoutSystems/fixedlayout/common/autoHeightOverlay/index.tsx @@ -3,7 +3,7 @@ import type { CSSProperties } from "react"; import React, { memo } from "react"; import { useSelector } from "react-redux"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import type { WidgetProps } from "widgets/BaseWidget"; import AutoHeightOverlayWithStateContext from "./AutoHeightOverlayWithStateContext"; @@ -31,7 +31,7 @@ const AutoHeightOverlayContainer: React.FC = selectedWidgets, } = useSelector((state: AppState) => state.ui.widgetDragResize); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/CanvasSelectionArena.tsx b/app/client/src/layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/CanvasSelectionArena.tsx index c0cf29167981..c299eaef18db 100644 --- a/app/client/src/layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/CanvasSelectionArena.tsx +++ b/app/client/src/layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/CanvasSelectionArena.tsx @@ -21,7 +21,6 @@ import { getIsDraggingForSelection, } from "selectors/canvasSelectors"; import { - combinedPreviewModeSelector, getCurrentApplicationLayout, getCurrentPageId, } from "selectors/editorSelectors"; @@ -31,6 +30,7 @@ import type { XYCord } from "layoutSystems/common/canvasArenas/ArenaTypes"; import { useCanvasDragToScroll } from "layoutSystems/common/canvasArenas/useCanvasDragToScroll"; import { StickyCanvasArena } from "layoutSystems/common/canvasArenas/StickyCanvasArena"; import { getWidgetSelectionBlock } from "../../../../selectors/ui"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export interface SelectedArenaDimensions { top: number; @@ -71,7 +71,7 @@ export function CanvasSelectionArena({ (parentWidget && parentWidget.detachFromLayout) ); const appMode = useSelector(getAppMode); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isWidgetSelectionBlocked = useSelector(getWidgetSelectionBlock); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, diff --git a/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx b/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx index 3b6b80aa7328..5ad23ff2e567 100644 --- a/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx +++ b/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx @@ -12,10 +12,7 @@ import ShareButton from "./components/ShareButton"; import PrimaryCTA from "../PrimaryCTA"; import { useHref } from "pages/Editor/utils"; import { builderURL } from "ee/RouteBuilder"; -import { - combinedPreviewModeSelector, - getCurrentBasePageId, -} from "selectors/editorSelectors"; +import { getCurrentBasePageId } from "selectors/editorSelectors"; import type { User } from "constants/userConstants"; import SidebarProfileComponent from "./components/SidebarProfileComponent"; import CollapseButton from "./components/CollapseButton"; @@ -36,6 +33,7 @@ import MenuItemContainer from "./components/MenuItemContainer"; import BackToAppsButton from "./components/BackToAppsButton"; import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; import { BOTTOM_BAR_HEIGHT } from "components/BottomBar/constants"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; interface SidebarProps { currentApplicationDetails?: ApplicationPayload; @@ -81,7 +79,7 @@ export function Sidebar(props: SidebarProps) { const isPinned = useSelector(getAppSidebarPinned); const [isOpen, setIsOpen] = useState(true); const { x } = useMouse(); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/pages/AppViewer/Navigation/TopInline.tsx b/app/client/src/pages/AppViewer/Navigation/TopInline.tsx index f15dd093ff21..af09e8497fd1 100644 --- a/app/client/src/pages/AppViewer/Navigation/TopInline.tsx +++ b/app/client/src/pages/AppViewer/Navigation/TopInline.tsx @@ -5,14 +5,12 @@ import MenuItem from "./components/MenuItem"; import { Container } from "./TopInline.styled"; import MenuItemContainer from "./components/MenuItemContainer"; import MoreDropdownButton from "./components/MoreDropdownButton"; -import { - combinedPreviewModeSelector, - getCanvasWidth, -} from "selectors/editorSelectors"; +import { getCanvasWidth } from "selectors/editorSelectors"; import { useSelector } from "react-redux"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; import { throttle } from "lodash"; import type { NavigationProps } from "./constants"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export function TopInline(props: NavigationProps) { const { currentApplicationDetails, pages } = props; @@ -23,7 +21,7 @@ export function TopInline(props: NavigationProps) { const maxMenuItemWidth = 220; const [maxMenuItemsThatCanFit, setMaxMenuItemsThatCanFit] = useState(0); const { width: screenWidth } = useWindowSizeHooks(); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/pages/AppViewer/PrimaryCTA.test.tsx b/app/client/src/pages/AppViewer/PrimaryCTA.test.tsx index 3b03a559fbfb..63b76d0e0fcc 100644 --- a/app/client/src/pages/AppViewer/PrimaryCTA.test.tsx +++ b/app/client/src/pages/AppViewer/PrimaryCTA.test.tsx @@ -7,6 +7,11 @@ import { lightTheme } from "selectors/themeSelectors"; import PrimaryCTA from "./PrimaryCTA"; import configureStore from "redux-mock-store"; +jest.mock("pages/Editor/gitSync/hooks/modHooks", () => ({ + ...jest.requireActual("pages/Editor/gitSync/hooks/modHooks"), + useGitProtectedMode: jest.fn(() => false), +})); + jest.mock("react-router", () => ({ ...jest.requireActual("react-router"), useHistory: () => ({ push: jest.fn() }), diff --git a/app/client/src/pages/AppViewer/PrimaryCTA.tsx b/app/client/src/pages/AppViewer/PrimaryCTA.tsx index 9e2816166454..97d0363bbf5f 100644 --- a/app/client/src/pages/AppViewer/PrimaryCTA.tsx +++ b/app/client/src/pages/AppViewer/PrimaryCTA.tsx @@ -25,8 +25,8 @@ import { Icon, Tooltip } from "@appsmith/ads"; import { getApplicationNameTextColor } from "./utils"; import { ButtonVariantTypes } from "components/constants"; import { setPreviewModeInitAction } from "actions/editorActions"; -import { protectedModeSelector } from "selectors/gitSyncSelectors"; import { getCurrentApplication } from "ee/selectors/applicationSelectors"; +import { useGitProtectedMode } from "pages/Editor/gitSync/hooks/modHooks"; /** * --------------------------------------------------------------------------------------------------- @@ -67,7 +67,7 @@ function PrimaryCTA(props: Props) { const canEdit = isPermitted(userPermissions, permissionRequired); const [isForkModalOpen, setIsForkModalOpen] = useState(false); const isPreviewMode = useSelector(previewModeSelector); - const isProtectedMode = useSelector(protectedModeSelector); + const isProtectedMode = useGitProtectedMode(); const dispatch = useDispatch(); const location = useLocation(); const queryParams = new URLSearchParams(location.search); diff --git a/app/client/src/pages/Editor/AppSettingsPane/AppSettings/ImportAppSettings.tsx b/app/client/src/pages/Editor/AppSettingsPane/AppSettings/ImportAppSettings.tsx index 8da3b25343c3..b721e7c5c7af 100644 --- a/app/client/src/pages/Editor/AppSettingsPane/AppSettings/ImportAppSettings.tsx +++ b/app/client/src/pages/Editor/AppSettingsPane/AppSettings/ImportAppSettings.tsx @@ -8,8 +8,8 @@ import ImportModal from "pages/common/ImportModal"; import React from "react"; import { useSelector } from "react-redux"; import { getCurrentApplicationId } from "selectors/editorSelectors"; -import { getIsGitConnected } from "selectors/gitSyncSelectors"; import styled from "styled-components"; +import { useGitConnected } from "pages/Editor/gitSync/hooks/modHooks"; const SettingWrapper = styled.div` display: flex; @@ -21,7 +21,7 @@ const SettingWrapper = styled.div` export function ImportAppSettings() { const appId = useSelector(getCurrentApplicationId); const workspace = useSelector(getCurrentAppWorkspace); - const isGitConnected = useSelector(getIsGitConnected); + const isGitConnected = useGitConnected(); const [isModalOpen, setIsModalOpen] = React.useState(false); function handleClose() { diff --git a/app/client/src/pages/Editor/Canvas.tsx b/app/client/src/pages/Editor/Canvas.tsx index 742e6d8a74b1..c34f2fc358c8 100644 --- a/app/client/src/pages/Editor/Canvas.tsx +++ b/app/client/src/pages/Editor/Canvas.tsx @@ -5,7 +5,7 @@ import * as Sentry from "@sentry/react"; import { useDispatch, useSelector } from "react-redux"; import type { CanvasWidgetStructure } from "WidgetProvider/constants"; import useWidgetFocus from "utils/hooks/useWidgetFocus"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import { getSelectedAppTheme } from "selectors/appThemingSelectors"; import { getViewportClassName } from "layoutSystems/autolayout/utils/AutoLayoutUtils"; import { @@ -44,7 +44,7 @@ const Wrapper = styled.section<{ `; const Canvas = (props: CanvasProps) => { const { canvasWidth } = props; - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/pages/Editor/GlobalHotKeys/GlobalHotKeys.tsx b/app/client/src/pages/Editor/GlobalHotKeys/GlobalHotKeys.tsx index 651f57e792c0..1e01349df831 100644 --- a/app/client/src/pages/Editor/GlobalHotKeys/GlobalHotKeys.tsx +++ b/app/client/src/pages/Editor/GlobalHotKeys/GlobalHotKeys.tsx @@ -45,8 +45,8 @@ import { toast } from "@appsmith/ads"; import { showDebuggerFlag } from "selectors/debuggerSelectors"; import { getIsFirstTimeUserOnboardingEnabled } from "selectors/onboardingSelectors"; import WalkthroughContext from "components/featureWalkthrough/walkthroughContext"; -import { protectedModeSelector } from "selectors/gitSyncSelectors"; import { setPreviewModeInitAction } from "actions/editorActions"; +import { selectGitApplicationProtectedMode } from "selectors/gitModSelectors"; interface Props { copySelectedWidget: () => void; @@ -372,15 +372,17 @@ class GlobalHotKeys extends React.Component { } } -const mapStateToProps = (state: AppState) => ({ - selectedWidget: getLastSelectedWidget(state), - selectedWidgets: getSelectedWidgets(state), - isDebuggerOpen: showDebuggerFlag(state), - appMode: getAppMode(state), - isPreviewMode: previewModeSelector(state), - isProtectedMode: protectedModeSelector(state), - isSignpostingEnabled: getIsFirstTimeUserOnboardingEnabled(state), -}); +const mapStateToProps = (state: AppState) => { + return { + selectedWidget: getLastSelectedWidget(state), + selectedWidgets: getSelectedWidgets(state), + isDebuggerOpen: showDebuggerFlag(state), + appMode: getAppMode(state), + isPreviewMode: previewModeSelector(state), + isProtectedMode: selectGitApplicationProtectedMode(state), + isSignpostingEnabled: getIsFirstTimeUserOnboardingEnabled(state), + }; +}; // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/app/client/src/pages/Editor/IDE/Header/DeployButton.tsx b/app/client/src/pages/Editor/IDE/Header/DeployButton.tsx new file mode 100644 index 000000000000..843da728dddf --- /dev/null +++ b/app/client/src/pages/Editor/IDE/Header/DeployButton.tsx @@ -0,0 +1,131 @@ +import { Button, Tooltip } from "@appsmith/ads"; +import { objectKeys } from "@appsmith/utils"; +import { showConnectGitModal } from "actions/gitSyncActions"; +import { publishApplication } from "ee/actions/applicationActions"; +import { getCurrentApplication } from "ee/selectors/applicationSelectors"; +import type { NavigationSetting } from "constants/AppConstants"; +import { + createMessage, + DEPLOY_BUTTON_TOOLTIP, + DEPLOY_MENU_OPTION, + PACKAGE_UPGRADING_ACTION_STATUS, +} from "ee/constants/messages"; +import { getIsPackageUpgrading } from "ee/selectors/packageSelectors"; +import AnalyticsUtil from "ee/utils/AnalyticsUtil"; +import { useGitOps, useGitProtectedMode } from "git"; +import { + useGitConnected, + useGitModEnabled, +} from "pages/Editor/gitSync/hooks/modHooks"; +import React, { useCallback } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { + getCurrentApplicationId, + getIsPublishingApplication, +} from "selectors/editorSelectors"; +import styled from "styled-components"; + +// This wrapper maintains pointer events for tooltips when the child button is disabled. +// Without this, disabled buttons won't trigger tooltips because they have pointer-events: none +const StyledTooltipTarget = styled.span` + display: inline-block; +`; + +function DeployButton() { + const applicationId = useSelector(getCurrentApplicationId); + const currentApplication = useSelector(getCurrentApplication); + const isPackageUpgrading = useSelector(getIsPackageUpgrading); + const isProtectedMode = useGitProtectedMode(); + const isDeployDisabled = isPackageUpgrading || isProtectedMode; + const isPublishing = useSelector(getIsPublishingApplication); + const isGitConnected = useGitConnected(); + const isGitModEnabled = useGitModEnabled(); + const { toggleOpsModal } = useGitOps(); + + const deployTooltipText = isPackageUpgrading + ? createMessage(PACKAGE_UPGRADING_ACTION_STATUS, "deploy this app") + : createMessage(DEPLOY_BUTTON_TOOLTIP); + + const dispatch = useDispatch(); + + const handlePublish = useCallback(() => { + if (applicationId) { + dispatch(publishApplication(applicationId)); + + const appName = currentApplication ? currentApplication.name : ""; + const pageCount = currentApplication?.pages?.length; + const navigationSettingsWithPrefix: Record< + string, + NavigationSetting[keyof NavigationSetting] + > = {}; + + if (currentApplication?.applicationDetail?.navigationSetting) { + const settingKeys = objectKeys( + currentApplication.applicationDetail.navigationSetting, + ) as Array; + + settingKeys.map((key: keyof NavigationSetting) => { + if (currentApplication?.applicationDetail?.navigationSetting?.[key]) { + const value: NavigationSetting[keyof NavigationSetting] = + currentApplication.applicationDetail.navigationSetting[key]; + + navigationSettingsWithPrefix[`navigationSetting_${key}`] = value; + } + }); + } + + AnalyticsUtil.logEvent("PUBLISH_APP", { + appId: applicationId, + appName, + pageCount, + ...navigationSettingsWithPrefix, + isPublic: !!currentApplication?.isPublic, + templateTitle: currentApplication?.forkedFromTemplateTitle, + }); + } + }, [applicationId, currentApplication, dispatch]); + + const handleClickDeploy = useCallback(() => { + if (isGitConnected) { + if (isGitModEnabled) { + toggleOpsModal(true); + } else { + dispatch(showConnectGitModal()); + } + + AnalyticsUtil.logEvent("GS_DEPLOY_GIT_CLICK", { + source: "Deploy button", + }); + } else { + handlePublish(); + } + }, [ + dispatch, + handlePublish, + isGitConnected, + isGitModEnabled, + toggleOpsModal, + ]); + + return ( + + + + + + ); +} + +export default DeployButton; diff --git a/app/client/src/pages/Editor/IDE/Header/index.tsx b/app/client/src/pages/Editor/IDE/Header/index.tsx index f8e75cda9db7..c26b641ba40d 100644 --- a/app/client/src/pages/Editor/IDE/Header/index.tsx +++ b/app/client/src/pages/Editor/IDE/Header/index.tsx @@ -1,7 +1,6 @@ -import React, { useCallback, useState } from "react"; +import React, { useState } from "react"; import { Flex, - Tooltip, Divider, Modal, ModalContent, @@ -11,7 +10,6 @@ import { TabsList, Tab, TabPanel, - Button, Link, IDEHeader, IDEHeaderTitle, @@ -24,19 +22,15 @@ import { APPLICATION_INVITE, COMMUNITY_TEMPLATES, createMessage, - DEPLOY_BUTTON_TOOLTIP, - DEPLOY_MENU_OPTION, IN_APP_EMBED_SETTING, INVITE_TAB, HEADER_TITLES, - PACKAGE_UPGRADING_ACTION_STATUS, } from "ee/constants/messages"; import EditorName from "pages/Editor/EditorName"; import { getCurrentApplicationId, getCurrentPageId, getIsPageSaving, - getIsPublishingApplication, getPageById, getPageSavingError, } from "selectors/editorSelectors"; @@ -46,10 +40,7 @@ import { getIsErroredSavingAppName, getIsSavingAppName, } from "ee/selectors/applicationSelectors"; -import { - publishApplication, - updateApplication, -} from "ee/actions/applicationActions"; +import { updateApplication } from "ee/actions/applicationActions"; import { getCurrentAppWorkspace } from "ee/selectors/selectedWorkspaceSelectors"; import { Omnibar } from "pages/Editor/commons/Omnibar"; import ToggleModeButton from "pages/Editor/ToggleModeButton"; @@ -62,13 +53,6 @@ import DeployLinkButtonDialog from "components/designSystems/appsmith/header/Dep import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; import { getAppsmithConfigs } from "ee/configs"; -import { - getIsGitConnected, - protectedModeSelector, -} from "selectors/gitSyncSelectors"; -import { showConnectGitModal } from "actions/gitSyncActions"; -import AnalyticsUtil from "ee/utils/AnalyticsUtil"; -import type { NavigationSetting } from "constants/AppConstants"; import { useHref } from "pages/Editor/utils"; import { viewerURL } from "ee/RouteBuilder"; import HelpBar from "components/editorComponents/GlobalSearch/HelpBar"; @@ -80,7 +64,8 @@ import { APPLICATIONS_URL } from "constants/routes"; import { useNavigationMenuData } from "../../EditorName/useNavigationMenuData"; import useLibraryHeaderTitle from "ee/pages/Editor/IDE/Header/useLibraryHeaderTitle"; import { AppsmithLink } from "pages/Editor/AppsmithLink"; -import { getIsPackageUpgrading } from "ee/selectors/packageSelectors"; +import DeployButton from "./DeployButton"; +import GitApplicationContextProvider from "components/gitContexts/GitApplicationContextProvider"; const StyledDivider = styled(Divider)` height: 50%; @@ -88,12 +73,6 @@ const StyledDivider = styled(Divider)` margin-right: 8px; `; -// This wrapper maintains pointer events for tooltips when the child button is disabled. -// Without this, disabled buttons won't trigger tooltips because they have pointer-events: none -const StyledTooltipTarget = styled.span` - display: inline-block; -`; - const { cloudHosting } = getAppsmithConfigs(); interface HeaderTitleProps { @@ -137,19 +116,11 @@ const Header = () => { const currentApplication = useSelector(getCurrentApplication); const isErroredSavingName = useSelector(getIsErroredSavingAppName); const applicationList = useSelector(getApplicationList); - const isProtectedMode = useSelector(protectedModeSelector); - const isPackageUpgrading = useSelector(getIsPackageUpgrading); - const isPublishing = useSelector(getIsPublishingApplication); - const isGitConnected = useSelector(getIsGitConnected); const pageId = useSelector(getCurrentPageId) as string; const currentPage = useSelector(getPageById(pageId)); const appState = useCurrentAppState(); const isSaving = useSelector(getIsPageSaving); const pageSaveError = useSelector(getPageSavingError); - const isDeployDisabled = isPackageUpgrading || isProtectedMode; - const deployTooltipText = isPackageUpgrading - ? createMessage(PACKAGE_UPGRADING_ACTION_STATUS, "deploy this app") - : createMessage(DEPLOY_BUTTON_TOOLTIP); // states const [isPopoverOpen, setIsPopoverOpen] = useState(false); const [showModal, setShowModal] = useState(false); @@ -179,56 +150,8 @@ const Header = () => { dispatch(updateApplication(id, data)); }; - const handlePublish = useCallback(() => { - if (applicationId) { - dispatch(publishApplication(applicationId)); - - const appName = currentApplication ? currentApplication.name : ""; - const pageCount = currentApplication?.pages?.length; - const navigationSettingsWithPrefix: Record< - string, - NavigationSetting[keyof NavigationSetting] - > = {}; - - if (currentApplication?.applicationDetail?.navigationSetting) { - const settingKeys = Object.keys( - currentApplication.applicationDetail.navigationSetting, - ) as Array; - - settingKeys.map((key: keyof NavigationSetting) => { - if (currentApplication?.applicationDetail?.navigationSetting?.[key]) { - const value: NavigationSetting[keyof NavigationSetting] = - currentApplication.applicationDetail.navigationSetting[key]; - - navigationSettingsWithPrefix[`navigationSetting_${key}`] = value; - } - }); - } - - AnalyticsUtil.logEvent("PUBLISH_APP", { - appId: applicationId, - appName, - pageCount, - ...navigationSettingsWithPrefix, - isPublic: !!currentApplication?.isPublic, - templateTitle: currentApplication?.forkedFromTemplateTitle, - }); - } - }, [applicationId, currentApplication, dispatch]); - - const handleClickDeploy = useCallback(() => { - if (isGitConnected) { - dispatch(showConnectGitModal()); - AnalyticsUtil.logEvent("GS_DEPLOY_GIT_CLICK", { - source: "Deploy button", - }); - } else { - handlePublish(); - } - }, [dispatch, handlePublish, isGitConnected]); - return ( - <> + }> @@ -338,30 +261,13 @@ const Header = () => { showModal={showPublishCommunityTemplateModal} />
- - - - - - +
- +
); }; diff --git a/app/client/src/pages/Editor/IDE/Layout/AnimatedLayout.tsx b/app/client/src/pages/Editor/IDE/Layout/AnimatedLayout.tsx index 952b3542c3f8..d58e70910a3f 100644 --- a/app/client/src/pages/Editor/IDE/Layout/AnimatedLayout.tsx +++ b/app/client/src/pages/Editor/IDE/Layout/AnimatedLayout.tsx @@ -2,7 +2,6 @@ import React from "react"; import { useGridLayoutTemplate } from "./hooks/useGridLayoutTemplate"; import EditorWrapperContainer from "pages/Editor/commons/EditorWrapperContainer"; import { AnimatedGridLayout, LayoutArea } from "components/AnimatedGridLayout"; -import { useSelector } from "react-redux"; import BottomBar from "components/BottomBar"; import Sidebar from "../Sidebar"; import LeftPane from "../LeftPane"; @@ -10,10 +9,28 @@ import MainPane from "../MainPane"; import RightPane from "../RightPane"; import { Areas } from "./constants"; import ProtectedCallout from "../ProtectedCallout"; -import { protectedModeSelector } from "selectors/gitSyncSelectors"; +import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks"; +import { + GitProtectedBranchCallout as GitProtectedBranchCalloutNew, + useGitProtectedMode, +} from "git"; + +function GitProtectedBranchCallout() { + const isGitModEnabled = useGitModEnabled(); + const isProtectedMode = useGitProtectedMode(); + + if (isGitModEnabled) { + return ; + } + + if (isProtectedMode) { + return ; + } + + return null; +} function AnimatedLayout() { - const isProtectedMode = useSelector(protectedModeSelector); const { areas, columns, rows } = useGridLayoutTemplate(); if (columns.length === 0) { @@ -22,7 +39,7 @@ function AnimatedLayout() { return ( <> - {isProtectedMode && } + ; + } + + if (isProtectedMode) { + return ; + } + + return null; +} const GridContainer = styled.div` display: grid; @@ -26,14 +44,13 @@ const LayoutContainer = styled.div<{ name: string }>` `; export const StaticLayout = React.memo(() => { - const isProtectedMode = useSelector(protectedModeSelector); const { areas, columns } = useGridLayoutTemplate(); const isSidebarVisible = columns[0] !== "0px"; return ( <> - {isProtectedMode && } + { const [windowWidth] = useWindowDimensions(); @@ -20,7 +20,7 @@ export const useEditorStateLeftPaneWidth = (): number => { const { segment } = useCurrentEditorState(); const propertyPaneWidth = useSelector(getPropertyPaneWidth); const isPreviewMode = useSelector(previewModeSelector); - const isProtectedMode = useSelector(protectedModeSelector); + const isProtectedMode = useGitProtectedMode(); useEffect( function updateWidth() { diff --git a/app/client/src/pages/Editor/IDE/Layout/hooks/useGridLayoutTemplate.ts b/app/client/src/pages/Editor/IDE/Layout/hooks/useGridLayoutTemplate.ts index b2dc0558af59..bf97ce71790b 100644 --- a/app/client/src/pages/Editor/IDE/Layout/hooks/useGridLayoutTemplate.ts +++ b/app/client/src/pages/Editor/IDE/Layout/hooks/useGridLayoutTemplate.ts @@ -7,7 +7,6 @@ import { useCurrentAppState } from "../../hooks/useCurrentAppState"; import { getPropertyPaneWidth } from "selectors/propertyPaneSelectors"; import { previewModeSelector } from "selectors/editorSelectors"; import { getIDEViewMode } from "selectors/ideSelectors"; -import { protectedModeSelector } from "selectors/gitSyncSelectors"; import { EditorEntityTab, EditorState, @@ -20,6 +19,7 @@ import { } from "constants/AppConstants"; import { useEditorStateLeftPaneWidth } from "./useEditorStateLeftPaneWidth"; import { type Area, Areas, SIDEBAR_WIDTH } from "../constants"; +import { useGitProtectedMode } from "pages/Editor/gitSync/hooks/modHooks"; interface ReturnValue { areas: Area[][]; @@ -43,7 +43,7 @@ function useGridLayoutTemplate(): ReturnValue { const appState = useCurrentAppState(); const isPreviewMode = useSelector(previewModeSelector); const editorMode = useSelector(getIDEViewMode); - const isProtectedMode = useSelector(protectedModeSelector); + const isProtectedMode = useGitProtectedMode(); React.useEffect( function updateIDEColumns() { diff --git a/app/client/src/pages/Editor/IDE/ProtectedCallout.test.tsx b/app/client/src/pages/Editor/IDE/ProtectedCallout.test.tsx index 2a60c70f3f86..d735d5663d88 100644 --- a/app/client/src/pages/Editor/IDE/ProtectedCallout.test.tsx +++ b/app/client/src/pages/Editor/IDE/ProtectedCallout.test.tsx @@ -3,11 +3,11 @@ import { render } from "@testing-library/react"; import { merge } from "lodash"; import { Provider } from "react-redux"; import configureStore from "redux-mock-store"; -import IDE from "."; import { BrowserRouter } from "react-router-dom"; import "@testing-library/jest-dom"; import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; import store from "store"; +import ProtectedCallout from "./ProtectedCallout"; // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -64,7 +64,7 @@ describe("Protected callout test cases", () => { const { getByTestId } = render( - + , ); @@ -72,33 +72,6 @@ describe("Protected callout test cases", () => { expect(getByTestId("t--git-protected-branch-callout")).toBeInTheDocument(); }); - it("should not render the protected view if branch is not protected", () => { - const store = getMockStore({ - ui: { - applications: { - currentApplication: { - gitApplicationMetadata: { - branchName: "branch-1", - }, - }, - }, - gitSync: { - protectedBranches: ["main"], - }, - }, - }); - const { queryByTestId } = render( - - - - - , - ); - - expect( - queryByTestId("t--git-protected-branch-callout"), - ).not.toBeInTheDocument(); - }); it("should unprotect only the current branch if clicked on unprotect cta", () => { const store = getMockStore({ ui: { @@ -117,7 +90,7 @@ describe("Protected callout test cases", () => { const { queryByTestId } = render( - + , ); diff --git a/app/client/src/pages/Editor/IDE/hooks.test.tsx b/app/client/src/pages/Editor/IDE/hooks.test.tsx index 0a12538bf260..9e5e40d6e98f 100644 --- a/app/client/src/pages/Editor/IDE/hooks.test.tsx +++ b/app/client/src/pages/Editor/IDE/hooks.test.tsx @@ -6,6 +6,12 @@ import { useGetPageFocusUrl } from "./hooks"; // eslint-disable-next-line @typescript-eslint/no-restricted-imports import { createEditorFocusInfo } from "../../../ce/navigation/FocusStrategy/AppIDEFocusStrategy"; +const mockUseGitCurrentBranch = jest.fn(() => null); + +jest.mock("../gitSync/hooks/modHooks", () => ({ + useGitCurrentBranch: () => mockUseGitCurrentBranch(), +})); + describe("useGetPageFocusUrl", () => { const pages = PageFactory.buildList(4); @@ -42,6 +48,7 @@ describe("useGetPageFocusUrl", () => { const wrapper = hookWrapper({ initialState: state }); it("works for JS focus history", () => { + mockUseGitCurrentBranch.mockReturnValue(null); const { result } = renderHook(() => useGetPageFocusUrl(pages[0].pageId), { wrapper, }); @@ -83,10 +90,13 @@ describe("useGetPageFocusUrl", () => { it("returns correct state when branches exist", () => { const branch = "featureBranch"; + + mockUseGitCurrentBranch.mockReturnValue(branch); const page1FocusHistoryWithBranch = createEditorFocusInfo( pages[0].pageId, branch, ); + const state = getIDETestState({ pages, focusHistory: { diff --git a/app/client/src/pages/Editor/IDE/hooks.ts b/app/client/src/pages/Editor/IDE/hooks.ts index 178a02e94222..6d356af8626b 100644 --- a/app/client/src/pages/Editor/IDE/hooks.ts +++ b/app/client/src/pages/Editor/IDE/hooks.ts @@ -15,7 +15,6 @@ import { widgetListURL, } from "ee/RouteBuilder"; import { getCurrentFocusInfo } from "selectors/focusHistorySelectors"; -import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import { getIsAltFocusWidget, getWidgetSelectionBlock } from "selectors/ui"; import { altFocusWidget, setWidgetSelectionBlock } from "actions/widgetActions"; import { useJSAdd } from "ee/pages/Editor/IDE/EditorPane/JS/hooks"; @@ -27,6 +26,7 @@ import { closeJSActionTab } from "actions/jsActionActions"; import { closeQueryActionTab } from "actions/pluginActionActions"; import { getCurrentBasePageId } from "selectors/editorSelectors"; import { getCurrentEntityInfo } from "../utils"; +import { useGitCurrentBranch } from "../gitSync/hooks/modHooks"; import { useEditorType } from "ee/hooks"; import { useParentEntityInfo } from "ee/hooks/datasourceEditorHooks"; import { useBoolean } from "usehooks-ts"; @@ -102,7 +102,8 @@ export const useSegmentNavigation = (): { export const useGetPageFocusUrl = (basePageId: string): string => { const [focusPageUrl, setFocusPageUrl] = useState(builderURL({ basePageId })); - const branch = useSelector(getCurrentGitBranch); + const branch = useGitCurrentBranch(); + const editorStateFocusInfo = useSelector((appState) => getCurrentFocusInfo(appState, createEditorFocusInfoKey(basePageId, branch)), ); diff --git a/app/client/src/pages/Editor/WidgetsEditor/components/LayoutSystemBasedPageViewer.tsx b/app/client/src/pages/Editor/WidgetsEditor/components/LayoutSystemBasedPageViewer.tsx index a430ed2fd02e..935e67cd90f0 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/components/LayoutSystemBasedPageViewer.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/components/LayoutSystemBasedPageViewer.tsx @@ -8,9 +8,9 @@ import { getCurrentPageId, previewModeSelector, } from "selectors/editorSelectors"; -import { protectedModeSelector } from "selectors/gitSyncSelectors"; import { getAppSettingsPaneContext } from "selectors/appSettingsPaneSelectors"; import { useShowSnapShotBanner } from "pages/Editor/CanvasLayoutConversion/hooks/useShowSnapShotBanner"; +import { useGitProtectedMode } from "pages/Editor/gitSync/hooks/modHooks"; /** * LayoutSystemBasedPageViewer @@ -25,7 +25,7 @@ export const LayoutSystemBasedPageViewer = ({ }) => { const currentPageId = useSelector(getCurrentPageId); const isPreviewMode = useSelector(previewModeSelector); - const isProtectedMode = useSelector(protectedModeSelector); + const isProtectedMode = useGitProtectedMode(); const appSettingsPaneContext = useSelector(getAppSettingsPaneContext); const canvasWidth = useSelector(getCanvasWidth); const shouldShowSnapShotBanner = useShowSnapShotBanner( diff --git a/app/client/src/pages/Editor/WidgetsEditor/components/NavigationAdjustedPageViewer.tsx b/app/client/src/pages/Editor/WidgetsEditor/components/NavigationAdjustedPageViewer.tsx index 7ec7cdd62ec4..6eb0f1ff10a6 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/components/NavigationAdjustedPageViewer.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/components/NavigationAdjustedPageViewer.tsx @@ -4,7 +4,7 @@ import { EditorState } from "ee/entities/IDE/constants"; import { useCurrentAppState } from "pages/Editor/IDE/hooks/useCurrentAppState"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; import { useSelector } from "react-redux"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import { PageViewWrapper } from "pages/AppViewer/AppPage"; import classNames from "classnames"; import { APP_MODE } from "entities/App"; @@ -27,7 +27,7 @@ import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; export const NavigationAdjustedPageViewer = (props: { children: ReactNode; }) => { - const isPreview = useSelector(combinedPreviewModeSelector); + const isPreview = useSelector(selectCombinedPreviewMode); const currentApplicationDetails = useSelector(getCurrentApplication); const isAppSidebarPinned = useSelector(getAppSidebarPinned); const sidebarWidth = useSelector(getSidebarWidth); diff --git a/app/client/src/pages/Editor/WidgetsEditor/components/NavigationPreview.tsx b/app/client/src/pages/Editor/WidgetsEditor/components/NavigationPreview.tsx index 0478d6f63439..8f2aa0e23c24 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/components/NavigationPreview.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/components/NavigationPreview.tsx @@ -2,7 +2,7 @@ import type { LegacyRef } from "react"; import React, { forwardRef } from "react"; import classNames from "classnames"; import { useSelector } from "react-redux"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import { Navigation } from "pages/AppViewer/Navigation"; import { useCurrentAppState } from "pages/Editor/IDE/hooks/useCurrentAppState"; import { EditorState } from "ee/entities/IDE/constants"; @@ -22,7 +22,7 @@ const NavigationPreview = forwardRef( const appState = useCurrentAppState(); const isAppSettingsPaneWithNavigationTabOpen = appState === EditorState.SETTINGS && isNavigationSelectedInSettings; - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); return (
{ const allowDragToSelect = useAllowEditorDragToSelect(); const { isAutoHeightWithLimitsChanging } = useAutoHeightUIState(); const dispatch = useDispatch(); - const isCombinedPreviewMode = useSelector(combinedPreviewModeSelector); + const isCombinedPreviewMode = useSelector(selectCombinedPreviewMode); const handleWrapperClick = useCallback( (e) => { diff --git a/app/client/src/pages/Editor/WidgetsEditor/components/WidgetEditorNavigation.tsx b/app/client/src/pages/Editor/WidgetsEditor/components/WidgetEditorNavigation.tsx index 852c210685ee..d7b7d2869271 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/components/WidgetEditorNavigation.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/components/WidgetEditorNavigation.tsx @@ -7,7 +7,7 @@ import { getIsAppSettingsPaneWithNavigationTabOpen, } from "selectors/appSettingsPaneSelectors"; import { useSelector } from "react-redux"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import { getCurrentApplication } from "ee/selectors/applicationSelectors"; /** @@ -20,7 +20,7 @@ import { getCurrentApplication } from "ee/selectors/applicationSelectors"; export const useNavigationPreviewHeight = () => { const [navigationHeight, setNavigationHeight] = useState(0); const navigationPreviewRef = useRef(null); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const appSettingsPaneContext = useSelector(getAppSettingsPaneContext); const currentApplicationDetails = useSelector(getCurrentApplication); @@ -54,7 +54,7 @@ type DivRef = React.Ref; */ export const WidgetEditorNavigation = forwardRef( (props, navigationPreviewRef: DivRef) => { - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isNavigationSelectedInSettings = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/pages/Editor/commons/EditorWrapperContainer.tsx b/app/client/src/pages/Editor/commons/EditorWrapperContainer.tsx index 990004cbbec5..3b34d1beecd4 100644 --- a/app/client/src/pages/Editor/commons/EditorWrapperContainer.tsx +++ b/app/client/src/pages/Editor/commons/EditorWrapperContainer.tsx @@ -2,11 +2,11 @@ import React from "react"; import styled from "styled-components"; import classNames from "classnames"; import { useSelector } from "react-redux"; -import { combinedPreviewModeSelector } from "../../../selectors/editorSelectors"; -import { protectedModeSelector } from "selectors/gitSyncSelectors"; import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; import { BOTTOM_BAR_HEIGHT } from "../../../components/BottomBar/constants"; import { PROTECTED_CALLOUT_HEIGHT } from "../IDE/ProtectedCallout"; +import { useGitProtectedMode } from "../gitSync/hooks/modHooks"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; interface EditorWrapperContainerProps { children: React.ReactNode; @@ -25,8 +25,8 @@ const Wrapper = styled.div<{ `; function EditorWrapperContainer({ children }: EditorWrapperContainerProps) { - const isCombinedPreviewMode = useSelector(combinedPreviewModeSelector); - const isProtectedMode = useSelector(protectedModeSelector); + const isCombinedPreviewMode = useSelector(selectCombinedPreviewMode); + const isProtectedMode = useGitProtectedMode(); return (
{props.showSuccess ? ( diff --git a/app/client/src/pages/Editor/gitSync/hooks/modHooks.ts b/app/client/src/pages/Editor/gitSync/hooks/modHooks.ts new file mode 100644 index 000000000000..e4d4b7fb4b7a --- /dev/null +++ b/app/client/src/pages/Editor/gitSync/hooks/modHooks.ts @@ -0,0 +1,44 @@ +// temp file will be removed after git mod is fully rolled out + +import { useSelector } from "react-redux"; +import { + getCurrentGitBranch, + getIsGitConnected, + protectedModeSelector, +} from "selectors/gitSyncSelectors"; +import { + useGitProtectedMode as useGitProtectedModeNew, + useGitCurrentBranch as useGitCurrentBranchNew, + useGitConnected as useGitConnectedNew, +} from "git"; +import { selectGitModEnabled } from "selectors/gitModSelectors"; + +export function useGitModEnabled() { + const isGitModEnabled = useSelector(selectGitModEnabled); + + return isGitModEnabled; +} + +export function useGitCurrentBranch() { + const isGitModEnabled = useGitModEnabled(); + const currentBranchOld = useSelector(getCurrentGitBranch) ?? null; + const currentBranchNew = useGitCurrentBranchNew(); + + return isGitModEnabled ? currentBranchNew : currentBranchOld; +} + +export function useGitProtectedMode() { + const isGitModEnabled = useGitModEnabled(); + const isProtectedModeOld = useSelector(protectedModeSelector); + const isProtectedModeNew = useGitProtectedModeNew(); + + return isGitModEnabled ? isProtectedModeNew : isProtectedModeOld; +} + +export function useGitConnected() { + const isGitModEnabled = useGitModEnabled(); + const isGitConnectedOld = useSelector(getIsGitConnected); + const isGitConnectedNew = useGitConnectedNew(); + + return isGitModEnabled ? isGitConnectedNew : isGitConnectedOld; +} diff --git a/app/client/src/pages/Editor/index.tsx b/app/client/src/pages/Editor/index.tsx index a7bfff34f2cb..746b7ca56733 100644 --- a/app/client/src/pages/Editor/index.tsx +++ b/app/client/src/pages/Editor/index.tsx @@ -25,12 +25,9 @@ import { getTheme, ThemeMode } from "selectors/themeSelectors"; import { ThemeProvider } from "styled-components"; import type { Theme } from "constants/DefaultTheme"; import GlobalHotKeys from "./GlobalHotKeys"; -import GitSyncModal from "pages/Editor/gitSync/GitSyncModal"; -import DisconnectGitModal from "pages/Editor/gitSync/DisconnectGitModal"; import { setupPageAction, updateCurrentPage } from "actions/pageActions"; import { getCurrentPageId } from "selectors/editorSelectors"; import { getSearchQuery } from "utils/helpers"; -import RepoLimitExceededErrorModal from "./gitSync/RepoLimitExceededErrorModal"; import ImportedApplicationSuccessModal from "./gitSync/ImportSuccessModal"; import { getIsBranchUpdated } from "../utils"; import { APP_MODE } from "entities/App"; @@ -42,16 +39,40 @@ import SignpostingOverlay from "pages/Editor/FirstTimeUserOnboarding/Overlay"; import { editorInitializer } from "../../utils/editor/EditorUtils"; import { widgetInitialisationSuccess } from "../../actions/widgetActions"; import urlBuilder from "ee/entities/URLRedirect/URLAssembly"; -import DisableAutocommitModal from "./gitSync/DisableAutocommitModal"; -import GitSettingsModal from "./gitSync/GitSettingsModal"; -import ReconfigureCDKeyModal from "ee/components/gitComponents/ReconfigureCDKeyModal"; -import DisableCDModal from "ee/components/gitComponents/DisableCDModal"; import { PartialExportModal } from "components/editorComponents/PartialImportExport/PartialExportModal"; import { PartialImportModal } from "components/editorComponents/PartialImportExport/PartialImportModal"; import type { Page } from "entities/Page"; import { AppCURLImportModal } from "ee/pages/Editor/CurlImport"; import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; import GeneratePageModal from "./GeneratePage"; +import { GitModals as NewGitModals } from "git"; +import GitSyncModal from "./gitSync/GitSyncModal"; +import GitSettingsModal from "./gitSync/GitSettingsModal"; +import DisconnectGitModal from "./gitSync/DisconnectGitModal"; +import DisableAutocommitModal from "./gitSync/DisableAutocommitModal"; +import ReconfigureCDKeyModal from "ee/components/gitComponents/ReconfigureCDKeyModal"; +import DisableCDModal from "ee/components/gitComponents/DisableCDModal"; +import RepoLimitExceededErrorModal from "./gitSync/RepoLimitExceededErrorModal"; +import { useGitModEnabled } from "./gitSync/hooks/modHooks"; +import GitApplicationContextProvider from "components/gitContexts/GitApplicationContextProvider"; + +function GitModals() { + const isGitModEnabled = useGitModEnabled(); + + return isGitModEnabled ? ( + + ) : ( + <> + + + + + + + + + ); +} interface EditorProps { currentApplicationId?: string; @@ -195,24 +216,20 @@ class Editor extends Component { {`${this.props.currentApplicationName} | Editor | Appsmith`} - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + +
diff --git a/app/client/src/pages/UserProfile/index.tsx b/app/client/src/pages/UserProfile/index.tsx index a715171bc31d..f77d74fedb50 100644 --- a/app/client/src/pages/UserProfile/index.tsx +++ b/app/client/src/pages/UserProfile/index.tsx @@ -3,12 +3,23 @@ import PageWrapper from "pages/common/PageWrapper"; import styled from "styled-components"; import { Tabs, Tab, TabsList, TabPanel } from "@appsmith/ads"; import General from "./General"; -import GitConfig from "./GitConfig"; +import OldGitConfig from "./GitConfig"; import { useLocation } from "react-router"; import { GIT_PROFILE_ROUTE } from "constants/routes"; import { BackButton } from "components/utils/helperComponents"; import { useDispatch } from "react-redux"; import { fetchGlobalGitConfigInit } from "actions/gitSyncActions"; +import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks"; +import { + fetchGitGlobalProfile, + GitGlobalProfile as GitGlobalProfileNew, +} from "git"; + +function GitGlobalProfile() { + const isGitModEnabled = useGitModEnabled(); + + return isGitModEnabled ? : ; +} const ProfileWrapper = styled.div` width: 978px; @@ -25,6 +36,7 @@ const ProfileWrapper = styled.div` function UserProfile() { const location = useLocation(); const dispatch = useDispatch(); + const isGitModEnabled = useGitModEnabled(); let initialTab = "general"; const tabs = [ @@ -39,7 +51,7 @@ function UserProfile() { tabs.push({ key: "gitConfig", title: "Git user config", - panelComponent: , + panelComponent: , icon: "git-branch", }); @@ -49,10 +61,16 @@ function UserProfile() { const [selectedTab, setSelectedTab] = useState(initialTab); - useEffect(() => { - // onMount Fetch Global config - dispatch(fetchGlobalGitConfigInit()); - }, []); + useEffect( + function fetchGlobalGitConfigOnInitEffect() { + if (isGitModEnabled) { + dispatch(fetchGitGlobalProfile()); + } else { + dispatch(fetchGlobalGitConfigInit()); + } + }, + [dispatch, isGitModEnabled], + ); return ( diff --git a/app/client/src/pages/common/ImportModal.tsx b/app/client/src/pages/common/ImportModal.tsx index b19974788529..12cefc5dec8c 100644 --- a/app/client/src/pages/common/ImportModal.tsx +++ b/app/client/src/pages/common/ImportModal.tsx @@ -30,6 +30,8 @@ import { import useMessages from "ee/hooks/importModal/useMessages"; import useMethods from "ee/hooks/importModal/useMethods"; import { getIsAnvilLayoutEnabled } from "layoutSystems/anvil/integrations/selectors"; +import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks"; +import { toggleGitImportModal } from "git"; const TextWrapper = styled.div` padding: 0; @@ -203,6 +205,7 @@ function ImportModal(props: ImportModalProps) { toEditor = false, workspaceId, } = props; + const isGitModEnabled = useGitModEnabled(); const { mainDescription, title } = useMessages(); const { appFileToBeUploaded, @@ -223,15 +226,21 @@ function ImportModal(props: ImportModalProps) { setWorkspaceIdForImport({ editorId: editorId || "", workspaceId }), ); - dispatch( - setIsGitSyncModalOpen({ - isOpen: true, - tab: GitSyncModalTab.GIT_CONNECTION, - }), - ); - - // dispatch(setIsReconnectingDatasourcesModalOpen({ isOpen: true })); - }, []); + if (isGitModEnabled) { + dispatch( + toggleGitImportModal({ + open: true, + }), + ); + } else { + dispatch( + setIsGitSyncModalOpen({ + isOpen: true, + tab: GitSyncModalTab.GIT_CONNECTION, + }), + ); + } + }, [dispatch, editorId, isGitModEnabled, onClose, workspaceId]); useEffect(() => { // finished of importing application diff --git a/app/client/src/sagas/ActionExecution/StoreActionSaga.ts b/app/client/src/sagas/ActionExecution/StoreActionSaga.ts index 4bcd909aabf0..ee6d99630ffd 100644 --- a/app/client/src/sagas/ActionExecution/StoreActionSaga.ts +++ b/app/client/src/sagas/ActionExecution/StoreActionSaga.ts @@ -4,7 +4,6 @@ import localStorage from "utils/localStorage"; import { updateAppStore } from "actions/pageActions"; import AppsmithConsole from "utils/AppsmithConsole"; import { getAppStoreData } from "ee/selectors/entitiesSelector"; -import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import { getCurrentApplicationId } from "selectors/editorSelectors"; import type { AppStoreState } from "reducers/entityReducers/appReducer"; import { Severity, LOG_CATEGORY } from "entities/AppsmithConsole"; @@ -13,6 +12,7 @@ import type { TRemoveValueDescription, TStoreValueDescription, } from "workers/Evaluation/fns/storeFns"; +import { selectGitApplicationCurrentBranch } from "selectors/gitModSelectors"; type StoreOperation = | TStoreValueDescription @@ -21,7 +21,9 @@ type StoreOperation = export function* handleStoreOperations(triggers: StoreOperation[]) { const applicationId: string = yield select(getCurrentApplicationId); - const branch: string | undefined = yield select(getCurrentGitBranch); + const branch: string | undefined = yield select( + selectGitApplicationCurrentBranch, + ); const appStoreName = getAppStoreName(applicationId, branch); const existingLocalStore = localStorage.getItem(appStoreName) || "{}"; let parsedLocalStore = JSON.parse(existingLocalStore); diff --git a/app/client/src/sagas/DatasourcesSagas.ts b/app/client/src/sagas/DatasourcesSagas.ts index 189fe5b80bc4..841be4eae950 100644 --- a/app/client/src/sagas/DatasourcesSagas.ts +++ b/app/client/src/sagas/DatasourcesSagas.ts @@ -714,6 +714,7 @@ function* redirectAuthorizationCodeSaga( const { contextId, contextType, datasourceId, pluginType } = actionPayload.payload; const isImport: string = yield select(getWorkspaceIdForImport); + // ! git mod - not sure how to handle this, there is no definition for the artifact used here const branchName: string | undefined = yield select(getCurrentGitBranch); if (pluginType === PluginType.API) { diff --git a/app/client/src/sagas/FocusRetentionSaga.ts b/app/client/src/sagas/FocusRetentionSaga.ts index 45232d9560dc..e92be7bae11b 100644 --- a/app/client/src/sagas/FocusRetentionSaga.ts +++ b/app/client/src/sagas/FocusRetentionSaga.ts @@ -18,10 +18,10 @@ import type { AppsmithLocationState } from "utils/history"; import type { Action } from "entities/Action"; import { getAction, getPlugin } from "ee/selectors/entitiesSelector"; import type { Plugin } from "api/PluginApi"; -import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import { getIDETypeByUrl } from "ee/entities/IDE/utils"; import { getIDEFocusStrategy } from "ee/navigation/FocusStrategy"; import { IDE_TYPE } from "ee/entities/IDE/constants"; +import { selectGitApplicationCurrentBranch } from "selectors/gitModSelectors"; export interface FocusPath { key: string; @@ -123,7 +123,9 @@ class FocusRetention { } public *handleRemoveFocusHistory(url: string) { - const branch: string | undefined = yield select(getCurrentGitBranch); + const branch: string | undefined = yield select( + selectGitApplicationCurrentBranch, + ); const removeKeys: string[] = []; const focusEntityInfo = identifyEntityFromPath(url); diff --git a/app/client/src/sagas/GlobalSearchSagas.ts b/app/client/src/sagas/GlobalSearchSagas.ts index 17cf81e719b3..93e29c0b29dc 100644 --- a/app/client/src/sagas/GlobalSearchSagas.ts +++ b/app/client/src/sagas/GlobalSearchSagas.ts @@ -21,19 +21,21 @@ import { } from "selectors/editorSelectors"; import type { RecentEntity } from "components/editorComponents/GlobalSearch/utils"; import log from "loglevel"; -import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import type { FocusEntity, FocusEntityInfo } from "navigation/FocusEntity"; import { convertToPageIdSelector } from "selectors/pageListSelectors"; +import { selectGitApplicationCurrentBranch } from "selectors/gitModSelectors"; const getRecentEntitiesKey = (applicationId: string, branch?: string) => branch ? `${applicationId}-${branch}` : applicationId; export function* updateRecentEntitySaga(entityInfo: FocusEntityInfo) { try { - const branch: string | undefined = yield select(getCurrentGitBranch); - const applicationId: string = yield select(getCurrentApplicationId); + const branch: string | undefined = yield select( + selectGitApplicationCurrentBranch, + ); + const recentEntitiesRestored: boolean = yield select( (state: AppState) => state.ui.globalSearch.recentEntitiesRestored, ); diff --git a/app/client/src/sagas/autoHeightSagas/helpers.ts b/app/client/src/sagas/autoHeightSagas/helpers.ts index da276f65d769..3ac3086a9d53 100644 --- a/app/client/src/sagas/autoHeightSagas/helpers.ts +++ b/app/client/src/sagas/autoHeightSagas/helpers.ts @@ -11,7 +11,7 @@ import type { } from "reducers/entityReducers/canvasWidgetsReducer"; import { select } from "redux-saga/effects"; import { getWidgetMetaProps, getWidgets } from "sagas/selectors"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import { getAppMode } from "ee/selectors/entitiesSelector"; import { isAutoHeightEnabledForWidget } from "widgets/WidgetUtils"; import { getCanvasHeightOffset } from "utils/WidgetSizeUtils"; @@ -20,7 +20,7 @@ import type { DataTree } from "entities/DataTree/dataTreeTypes"; import { getDataTree } from "selectors/dataTreeSelectors"; export function* shouldWidgetsCollapse() { - const isPreviewMode: boolean = yield select(combinedPreviewModeSelector); + const isPreviewMode: boolean = yield select(selectCombinedPreviewMode); const appMode: APP_MODE = yield select(getAppMode); return isPreviewMode || appMode === APP_MODE.PUBLISHED; diff --git a/app/client/src/selectors/debuggerSelectors.tsx b/app/client/src/selectors/debuggerSelectors.tsx index 89c2c46df479..624fae4f290f 100644 --- a/app/client/src/selectors/debuggerSelectors.tsx +++ b/app/client/src/selectors/debuggerSelectors.tsx @@ -11,8 +11,8 @@ import { isWidget, } from "ee/workers/Evaluation/evaluationUtils"; import { getDataTree } from "./dataTreeSelectors"; -import { combinedPreviewModeSelector } from "./editorSelectors"; import type { CanvasDebuggerState } from "reducers/uiReducers/debuggerReducer"; +import { selectCombinedPreviewMode } from "./gitModSelectors"; interface ErrorObejct { [k: string]: Log; @@ -169,7 +169,7 @@ export const getDebuggerOpen = (state: AppState) => state.ui.debugger.isOpen; export const showDebuggerFlag = createSelector( getDebuggerOpen, - combinedPreviewModeSelector, + selectCombinedPreviewMode, (isOpen, isPreview) => isOpen && !isPreview, ); diff --git a/app/client/src/selectors/editorSelectors.tsx b/app/client/src/selectors/editorSelectors.tsx index ee3560dd5034..39bd1d46c1b6 100644 --- a/app/client/src/selectors/editorSelectors.tsx +++ b/app/client/src/selectors/editorSelectors.tsx @@ -990,9 +990,3 @@ export const getGsheetToken = (state: AppState) => export const getGsheetProjectID = (state: AppState) => state.entities.datasources.gsheetProjectID; - -export const combinedPreviewModeSelector = createSelector( - previewModeSelector, - protectedModeSelector, - (isPreviewMode, isProtectedMode) => isPreviewMode || isProtectedMode, -); diff --git a/app/client/src/selectors/gitModSelectors.ts b/app/client/src/selectors/gitModSelectors.ts new file mode 100644 index 000000000000..35fe32fbbff7 --- /dev/null +++ b/app/client/src/selectors/gitModSelectors.ts @@ -0,0 +1,50 @@ +// temp file will be removed after git mod is fully rolled out + +import { selectFeatureFlags } from "ee/selectors/featureFlagsSelectors"; +import { createSelector } from "reselect"; +import { getCurrentGitBranch, protectedModeSelector } from "./gitSyncSelectors"; +import { + selectGitCurrentBranch as selectGitCurrentBranchNew, + selectGitProtectedMode as selectGitProtectedModeNew, +} from "git"; +import { + getCurrentBaseApplicationId, + previewModeSelector, +} from "./editorSelectors"; +import { applicationArtifact } from "git/artifact-helpers/application"; + +export const selectGitModEnabled = createSelector( + selectFeatureFlags, + (featureFlags) => featureFlags.release_git_modularisation_enabled ?? false, +); + +export const selectGitApplicationArtifactDef = createSelector( + getCurrentBaseApplicationId, + (baseApplicationId) => applicationArtifact(baseApplicationId), +); + +export const selectGitApplicationCurrentBranch = createSelector( + selectGitModEnabled, + getCurrentGitBranch, + (state) => + selectGitCurrentBranchNew(state, selectGitApplicationArtifactDef(state)), + (isGitModEnabled, currentBranchOld, currentBranchNew) => { + return isGitModEnabled ? currentBranchNew : currentBranchOld; + }, +); + +export const selectGitApplicationProtectedMode = createSelector( + selectGitModEnabled, + protectedModeSelector, + (state) => + selectGitProtectedModeNew(state, selectGitApplicationArtifactDef(state)), + (isGitModEnabled, protectedModeOld, protectedModeNew) => { + return isGitModEnabled ? protectedModeNew : protectedModeOld; + }, +); + +export const selectCombinedPreviewMode = createSelector( + previewModeSelector, + selectGitApplicationProtectedMode, + (isPreviewMode, isProtectedMode) => isPreviewMode || isProtectedMode, +); diff --git a/app/client/src/selectors/widgetDragSelectors.ts b/app/client/src/selectors/widgetDragSelectors.ts index 0a2b35eb7e1f..21d5848d5175 100644 --- a/app/client/src/selectors/widgetDragSelectors.ts +++ b/app/client/src/selectors/widgetDragSelectors.ts @@ -1,11 +1,9 @@ import type { AppState } from "ee/reducers"; import { createSelector } from "reselect"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "./appSettingsPaneSelectors"; -import { - combinedPreviewModeSelector, - snipingModeSelector, -} from "./editorSelectors"; +import { snipingModeSelector } from "./editorSelectors"; import { getWidgetSelectionBlock } from "./ui"; +import { selectCombinedPreviewMode } from "./gitModSelectors"; export const getIsDragging = (state: AppState) => state.ui.widgetDragResize.isDragging; @@ -23,7 +21,7 @@ export const getShouldAllowDrag = createSelector( getIsResizing, getIsDragging, getIsDraggingDisabledInEditor, - combinedPreviewModeSelector, + selectCombinedPreviewMode, snipingModeSelector, getIsAppSettingsPaneWithNavigationTabOpen, getWidgetSelectionBlock, diff --git a/app/client/src/selectors/widgetSelectors.ts b/app/client/src/selectors/widgetSelectors.ts index 4d45777ef4c9..35d648da50bf 100644 --- a/app/client/src/selectors/widgetSelectors.ts +++ b/app/client/src/selectors/widgetSelectors.ts @@ -21,8 +21,8 @@ import { APP_MODE } from "entities/App"; import { getIsTableFilterPaneVisible } from "selectors/tableFilterSelectors"; import { getIsAutoHeightWithLimitsChanging } from "utils/hooks/autoHeightUIHooks"; import { getIsPropertyPaneVisible } from "./propertyPaneSelectors"; -import { combinedPreviewModeSelector } from "./editorSelectors"; import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; +import { selectCombinedPreviewMode } from "./gitModSelectors"; export const getIsDraggingOrResizing = (state: AppState) => state.ui.widgetDragResize.isResizing || state.ui.widgetDragResize.isDragging; @@ -186,7 +186,7 @@ export const shouldWidgetIgnoreClicksSelector = (widgetId: string) => { (state: AppState) => state.ui.widgetDragResize.isDragging, (state: AppState) => state.ui.canvasSelection.isDraggingForSelection, getAppMode, - combinedPreviewModeSelector, + selectCombinedPreviewMode, getIsAutoHeightWithLimitsChanging, getAltBlockWidgetSelection, ( diff --git a/app/client/src/utils/hooks/useAllowEditorDragToSelect.ts b/app/client/src/utils/hooks/useAllowEditorDragToSelect.ts index e074a099ac70..a09f5492d648 100644 --- a/app/client/src/utils/hooks/useAllowEditorDragToSelect.ts +++ b/app/client/src/utils/hooks/useAllowEditorDragToSelect.ts @@ -1,13 +1,11 @@ import type { AppState } from "ee/reducers"; -import { - snipingModeSelector, - combinedPreviewModeSelector, -} from "selectors/editorSelectors"; +import { snipingModeSelector } from "selectors/editorSelectors"; import { useSelector } from "react-redux"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; import { getLayoutSystemType } from "selectors/layoutSystemSelectors"; import { LayoutSystemTypes } from "layoutSystems/types"; import { getWidgetSelectionBlock } from "../../selectors/ui"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export const useAllowEditorDragToSelect = () => { // This state tells us whether a `ResizableComponent` is resizing @@ -42,7 +40,7 @@ export const useAllowEditorDragToSelect = () => { // True when any widget is dragging or resizing, including this one const isResizingOrDragging = !!isResizing || !!isDragging || !!isSelecting; const isSnipingMode = useSelector(snipingModeSelector); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/utils/hooks/useHoverToFocusWidget.ts b/app/client/src/utils/hooks/useHoverToFocusWidget.ts index 10e5f764f06e..a6cf7962de9a 100644 --- a/app/client/src/utils/hooks/useHoverToFocusWidget.ts +++ b/app/client/src/utils/hooks/useHoverToFocusWidget.ts @@ -2,7 +2,7 @@ import { useWidgetSelection } from "./useWidgetSelection"; import { useSelector } from "react-redux"; import { isWidgetFocused } from "selectors/widgetSelectors"; import { getAnvilSpaceDistributionStatus } from "layoutSystems/anvil/integrations/selectors"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import type { AppState } from "ee/reducers"; import type React from "react"; import { useCurrentAppState } from "pages/Editor/IDE/hooks/useCurrentAppState"; @@ -35,7 +35,7 @@ export const useHoverToFocusWidget = ( const isResizingOrDragging = isResizing || isDragging; // This state tells us whether space redistribution is in process const isDistributingSpace = useSelector(getAnvilSpaceDistributionStatus); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); // When mouse is over this draggable const handleMouseOver = (e: React.MouseEvent) => { focusWidget && diff --git a/app/client/src/widgets/ChartWidget/component/index.test.tsx b/app/client/src/widgets/ChartWidget/component/index.test.tsx index 8c043acb36a3..ee53792993a8 100644 --- a/app/client/src/widgets/ChartWidget/component/index.test.tsx +++ b/app/client/src/widgets/ChartWidget/component/index.test.tsx @@ -22,6 +22,11 @@ import { APP_MODE } from "entities/App"; // eslint-disable-next-line @typescript-eslint/no-explicit-any let container: any; +jest.mock("selectors/gitModSelectors", () => ({ + ...jest.requireActual("selectors/gitModSelectors"), + selectCombinedPreviewMode: jest.fn(() => false), +})); + describe("Chart Widget", () => { const seriesData1: ChartData = { seriesName: "series1", diff --git a/app/client/src/widgets/ChartWidget/component/index.tsx b/app/client/src/widgets/ChartWidget/component/index.tsx index 4ed693b142c3..f2a3280bd7a1 100644 --- a/app/client/src/widgets/ChartWidget/component/index.tsx +++ b/app/client/src/widgets/ChartWidget/component/index.tsx @@ -28,7 +28,7 @@ import { CustomEChartIFrameComponent } from "./CustomEChartIFrameComponent"; import type { AppState } from "ee/reducers"; import { connect } from "react-redux"; import { getWidgetPropsForPropertyPane } from "selectors/propertyPaneSelectors"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import { getAppMode } from "ee/selectors/applicationSelectors"; import { APP_MODE } from "entities/App"; // Leaving this require here. Ref: https://stackoverflow.com/questions/41292559/could-not-find-a-declaration-file-for-module-module-name-path-to-module-nam/42505940#42505940 @@ -406,7 +406,7 @@ export const mapStateToProps = ( state: AppState, ownProps: ChartComponentProps, ) => { - const isPreviewMode = combinedPreviewModeSelector(state); + const isPreviewMode = selectCombinedPreviewMode(state); const appMode = getAppMode(state); return { diff --git a/app/client/src/widgets/CustomWidget/component/index.tsx b/app/client/src/widgets/CustomWidget/component/index.tsx index eb6740b48cd0..a3cf98d4afbb 100644 --- a/app/client/src/widgets/CustomWidget/component/index.tsx +++ b/app/client/src/widgets/CustomWidget/component/index.tsx @@ -19,7 +19,7 @@ import type { BoxShadow } from "components/designSystems/appsmith/WidgetStyleCon import type { Color } from "constants/Colors"; import { connect } from "react-redux"; import type { AppState } from "ee/reducers"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; import { getWidgetPropsForPropertyPane } from "selectors/propertyPaneSelectors"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import { EVENTS } from "./customWidgetscript"; @@ -311,7 +311,7 @@ export const mapStateToProps = ( state: AppState, ownProps: CustomComponentProps, ) => { - const isPreviewMode = combinedPreviewModeSelector(state); + const isPreviewMode = selectCombinedPreviewMode(state); return { needsOverlay: diff --git a/app/client/src/widgets/IframeWidget/component/index.tsx b/app/client/src/widgets/IframeWidget/component/index.tsx index 1958ebd55e36..b16f5bdb2fcb 100644 --- a/app/client/src/widgets/IframeWidget/component/index.tsx +++ b/app/client/src/widgets/IframeWidget/component/index.tsx @@ -9,7 +9,7 @@ import { getAppMode } from "ee/selectors/applicationSelectors"; import { APP_MODE } from "entities/App"; import type { RenderMode } from "constants/WidgetConstants"; import { getAppsmithConfigs } from "ee/configs"; -import { combinedPreviewModeSelector } from "selectors/editorSelectors"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; interface IframeContainerProps { borderColor?: string; @@ -145,7 +145,7 @@ function IframeComponent(props: IframeComponentProps) { }, [srcDoc]); const appMode = useSelector(getAppMode); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const selectedWidget = useSelector(getWidgetPropsForPropertyPane); return ( diff --git a/app/client/src/widgets/withWidgetProps.tsx b/app/client/src/widgets/withWidgetProps.tsx index 73dfd519687b..5a0f13d6c19d 100644 --- a/app/client/src/widgets/withWidgetProps.tsx +++ b/app/client/src/widgets/withWidgetProps.tsx @@ -25,7 +25,6 @@ import { getMetaWidget, getIsAutoLayoutMobileBreakPoint, getCanvasWidth, - combinedPreviewModeSelector, } from "selectors/editorSelectors"; import { createCanvasWidget, @@ -50,6 +49,7 @@ import { isWidgetSelectedForPropertyPane } from "selectors/propertyPaneSelectors import WidgetFactory from "WidgetProvider/factory"; import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; import { endSpan, startRootSpan } from "instrumentation/generateTraces"; +import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; const WIDGETS_WITH_CHILD_WIDGETS = ["LIST_WIDGET", "FORM_WIDGET"]; const WIDGETS_REQUIRING_SELECTED_ANCESTRY = ["MODAL_WIDGET", "TABS_WIDGET"]; @@ -69,7 +69,7 @@ function withWidgetProps(WrappedWidget: typeof BaseWidget) { } = props; const span = startRootSpan("withWidgetProps", { widgetType: type }); - const isPreviewMode = useSelector(combinedPreviewModeSelector); + const isPreviewMode = useSelector(selectCombinedPreviewMode); const canvasWidget = useSelector((state: AppState) => getWidget(state, widgetId), diff --git a/app/client/test/testUtils.tsx b/app/client/test/testUtils.tsx index 9b99d698bb90..0d57bddfc09a 100644 --- a/app/client/test/testUtils.tsx +++ b/app/client/test/testUtils.tsx @@ -49,9 +49,12 @@ interface State { } const setupState = (state?: State) => { let reduxStore = store; + window.history.pushState({}, "Appsmith", state?.url || "/"); + if (state && (state.initialState || state.featureFlags)) { reduxStore = testStore(state.initialState || {}); + if (state.featureFlags) { reduxStore.dispatch( fetchFeatureFlagsSuccess({ @@ -61,10 +64,12 @@ const setupState = (state?: State) => { ); } } + if (state && state.sagasToRun) { reduxStore = testStoreWithTestMiddleWare(reduxStore.getState()); testSagaMiddleware.run(() => rootSaga(state.sagasToRun)); } + const defaultTheme = getCurrentThemeDetails(reduxStore.getState()); return { reduxStore, defaultTheme }; @@ -76,6 +81,7 @@ const customRender = ( options?: Omit, ) => { const { defaultTheme, reduxStore } = setupState(state); + return render( @@ -92,6 +98,7 @@ const customRender = ( const hookWrapper = (state: State) => { return ({ children }: { children: ReactElement }) => { const { defaultTheme, reduxStore } = setupState(state); + return ( From d34775abb0558805f026d0981c8fcbe76076476b Mon Sep 17 00:00:00 2001 From: Sagar Khalasi Date: Mon, 30 Dec 2024 17:50:34 +0530 Subject: [PATCH 07/13] fix: Airgap case handle (#38413) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Exclusion for airgap. Fixes # https://app.zenhub.com/workspaces/stability-pod-6690c4814e31602e25cab7fd/issues/gh/appsmithorg/appsmith/38412 ## Automation /ok-to-test tags="@tag.Sanity,@tag.Settings" ### :mag: Cypress test results > [!TIP] > 🟒 🟒 🟒 All cypress tests have passed! πŸŽ‰ πŸŽ‰ πŸŽ‰ > Workflow run: > Commit: 591f14d4cb1eb6976ec540d9dedb30252c7214fb > Cypress dashboard. > Tags: `@tag.Sanity,@tag.Settings` > Spec: >
Mon, 30 Dec 2024 11:54:12 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No ## Summary by CodeRabbit - **Tests** - Updated Cypress test for Admin Settings page - Added exclusion tag for airgap environments - Refactored test case syntax --- .../AdminSettings/Admin_settings_spec.ts | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/app/client/cypress/e2e/Regression/ClientSide/AdminSettings/Admin_settings_spec.ts b/app/client/cypress/e2e/Regression/ClientSide/AdminSettings/Admin_settings_spec.ts index d7924b495df7..ce16b7bf43c7 100644 --- a/app/client/cypress/e2e/Regression/ClientSide/AdminSettings/Admin_settings_spec.ts +++ b/app/client/cypress/e2e/Regression/ClientSide/AdminSettings/Admin_settings_spec.ts @@ -206,29 +206,33 @@ describe("Admin settings page", { tags: ["@tag.Settings"] }, function () { .then(($text) => expect($text).to.eq("Appsmith")); }); - it("11. Verify all admin setting sections are accessible", () => { - cy.visit("/applications", { timeout: 60000 }); - agHelper.GetNClick(adminSettingsHelper._adminSettingsBtn); - cy.wait("@getEnvVariables"); - agHelper.GetNClick(adminsSettings.generalTab); - agHelper.AssertURL(adminSettingsHelper.routes.GENERAL); - agHelper.GetNClick(adminsSettings.advancedTab); - agHelper.AssertURL(adminSettingsHelper.routes.ADVANCED); - agHelper.GetNClick(adminsSettings.authenticationTab); - agHelper.AssertURL(adminSettingsHelper.routes.AUTHENTICATION); - agHelper.GetNClick(adminsSettings.emailTab); - agHelper.AssertURL(adminSettingsHelper.routes.EMAIL); - agHelper.GetNClick(adminsSettings.developerSettingsTab); - agHelper.AssertURL(adminSettingsHelper.routes.DEVELOPER_SETTINGS); - agHelper.GetNClick(adminsSettings.versionTab); - agHelper.AssertURL(adminSettingsHelper.routes.VERSION); - agHelper.GetNClick(adminsSettings.branding); - agHelper.AssertURL(adminSettingsHelper.routes.BRANDING); - agHelper.GetNClick(adminsSettings.provisioning); - agHelper.AssertURL(adminSettingsHelper.routes.PROVISIONING); - agHelper.GetNClick(adminsSettings.accessControl); - agHelper.AssertURL(adminSettingsHelper.routes.ACCESS_CONTROL); - agHelper.GetNClick(adminsSettings.auditLogs); - agHelper.AssertURL(adminSettingsHelper.routes.AUDIT_LOGS); - }); + it( + "11. Verify all admin setting sections are accessible", + { tags: ["@tag.excludeForAirgap"] }, + () => { + cy.visit("/applications", { timeout: 60000 }); + agHelper.GetNClick(adminSettingsHelper._adminSettingsBtn); + cy.wait("@getEnvVariables"); + agHelper.GetNClick(adminsSettings.generalTab); + agHelper.AssertURL(adminSettingsHelper.routes.GENERAL); + agHelper.GetNClick(adminsSettings.advancedTab); + agHelper.AssertURL(adminSettingsHelper.routes.ADVANCED); + agHelper.GetNClick(adminsSettings.authenticationTab); + agHelper.AssertURL(adminSettingsHelper.routes.AUTHENTICATION); + agHelper.GetNClick(adminsSettings.emailTab); + agHelper.AssertURL(adminSettingsHelper.routes.EMAIL); + agHelper.GetNClick(adminsSettings.developerSettingsTab); + agHelper.AssertURL(adminSettingsHelper.routes.DEVELOPER_SETTINGS); + agHelper.GetNClick(adminsSettings.versionTab); + agHelper.AssertURL(adminSettingsHelper.routes.VERSION); + agHelper.GetNClick(adminsSettings.branding); + agHelper.AssertURL(adminSettingsHelper.routes.BRANDING); + agHelper.GetNClick(adminsSettings.provisioning); + agHelper.AssertURL(adminSettingsHelper.routes.PROVISIONING); + agHelper.GetNClick(adminsSettings.accessControl); + agHelper.AssertURL(adminSettingsHelper.routes.ACCESS_CONTROL); + agHelper.GetNClick(adminsSettings.auditLogs); + agHelper.AssertURL(adminSettingsHelper.routes.AUDIT_LOGS); + }, + ); }); From 39328fbd7f69705152adfafcc275290d1350cda7 Mon Sep 17 00:00:00 2001 From: Manish Kumar <107841575+sondermanish@users.noreply.github.com> Date: Mon, 30 Dec 2024 18:09:06 +0530 Subject: [PATCH 08/13] chore: checkout remote (#38390) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description > [!TIP] > _Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content, marketing, and DevRel team)._ > > _Please also include relevant motivation and context. List any dependencies that are required for this change. Add links to Notion, Figma or any other documents that might be relevant to the PR._ Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="@tag.Git" ### :mag: Cypress test results > [!TIP] > 🟒 🟒 🟒 All cypress tests have passed! πŸŽ‰ πŸŽ‰ πŸŽ‰ > Workflow run: > Commit: 34136a406d619027d82a356896e8a90354292abe > Cypress dashboard. > Tags: `@tag.Git` > Spec: >
Mon, 30 Dec 2024 12:34:51 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit ## Summary by CodeRabbit - **New Features** - Introduced methods for managing protected branches and auto-commit functionalities, including updating and retrieving protected branches, toggling auto-commit, and fetching auto-commit progress. - Added analytics capabilities for tracking changes in protected branches. - Added functionality for pulling artifacts from remote repositories. - **Bug Fixes** - Simplified method signatures for better clarity and functionality. - **Chores** - Updated dependency injections within relevant classes to enhance service integration. --- .../git/central/CentralGitServiceCE.java | 8 +- .../git/central/CentralGitServiceCEImpl.java | 296 ++++++++++++++++-- .../git/central/GitHandlingServiceCE.java | 9 +- .../server/git/fs/GitFSServiceCEImpl.java | 62 +++- 4 files changed, 336 insertions(+), 39 deletions(-) diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCE.java index a084fbc51ff5..23e668a80ea9 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCE.java @@ -9,6 +9,7 @@ import com.appsmith.server.dtos.ArtifactImportDTO; import com.appsmith.server.dtos.AutoCommitResponseDTO; import com.appsmith.server.dtos.GitConnectDTO; +import com.appsmith.server.dtos.GitPullDTO; import reactor.core.publisher.Mono; import java.util.List; @@ -42,13 +43,14 @@ Mono fetchRemoteChanges( Mono getStatus( String branchedArtifactId, boolean compareRemote, ArtifactType artifactType, GitType gitType); + Mono pullArtifact(String branchedArtifactId, ArtifactType artifactType, GitType gitType); + Mono checkoutReference( String referenceArtifactId, - String referenceToBeCheckedOut, + GitRefDTO gitRefDTO, boolean addFileLock, ArtifactType artifactType, - GitType gitType, - RefType refType); + GitType gitType); Mono createReference( String referencedArtifactId, GitRefDTO refDTO, ArtifactType artifactType, GitType gitType); diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java index d235ed7611d7..460be19c7813 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/CentralGitServiceCEImpl.java @@ -3,6 +3,7 @@ import com.appsmith.external.constants.AnalyticsEvents; import com.appsmith.external.dtos.GitRefDTO; import com.appsmith.external.dtos.GitStatusDTO; +import com.appsmith.external.dtos.MergeStatusDTO; import com.appsmith.external.git.constants.GitConstants; import com.appsmith.external.git.constants.GitSpan; import com.appsmith.external.git.constants.ce.RefType; @@ -28,6 +29,7 @@ import com.appsmith.server.dtos.ArtifactImportDTO; import com.appsmith.server.dtos.AutoCommitResponseDTO; import com.appsmith.server.dtos.GitConnectDTO; +import com.appsmith.server.dtos.GitPullDTO; import com.appsmith.server.exceptions.AppsmithError; import com.appsmith.server.exceptions.AppsmithException; import com.appsmith.server.exports.internal.ExportService; @@ -63,6 +65,7 @@ import reactor.util.function.Tuple3; import java.io.IOException; +import java.nio.file.Path; import java.time.Instant; import java.util.ArrayList; import java.util.List; @@ -349,36 +352,40 @@ private boolean checkIsDatasourceNameConflict( @Override public Mono checkoutReference( String referenceArtifactId, - String referenceToBeCheckedOut, + GitRefDTO gitRefDTO, boolean addFileLock, ArtifactType artifactType, - GitType gitType, - RefType refType) { + GitType gitType) { - if (!hasText(referenceToBeCheckedOut)) { + if (gitRefDTO == null || !hasText(gitRefDTO.getRefName())) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.REF_NAME)); } + if (gitRefDTO.getRefType() == null) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, REF_TYPE)); + } + Mono> baseAndBranchedArtifactMono = getBaseAndBranchedArtifacts(referenceArtifactId, artifactType); return baseAndBranchedArtifactMono.flatMap(artifactTuples -> { Artifact sourceArtifact = artifactTuples.getT1(); - return checkoutReference(sourceArtifact, referenceToBeCheckedOut, addFileLock, gitType, refType); + return checkoutReference(sourceArtifact, gitRefDTO, addFileLock, gitType); }); } protected Mono checkoutReference( - Artifact baseArtifact, - String referenceToBeCheckedOut, - boolean addFileLock, - GitType gitType, - RefType refType) { + Artifact baseArtifact, GitRefDTO gitRefDTO, boolean addFileLock, GitType gitType) { - if (!hasText(referenceToBeCheckedOut)) { + if (gitRefDTO == null || !hasText(gitRefDTO.getRefName())) { return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, FieldName.REF_NAME)); } + if (gitRefDTO.getRefType() == null) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_PARAMETER, REF_TYPE)); + } + + RefType refType = gitRefDTO.getRefType(); GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); if (isBaseGitMetadataInvalid(baseGitMetadata, gitType)) { @@ -386,7 +393,7 @@ protected Mono checkoutReference( } String baseArtifactId = baseGitMetadata.getDefaultArtifactId(); - final String finalRefName = referenceToBeCheckedOut.replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT); + final String finalRefName = gitRefDTO.getRefName().replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT); GitArtifactHelper gitArtifactHelper = gitArtifactHelperResolver.getArtifactHelper(baseArtifact.getArtifactType()); @@ -405,24 +412,23 @@ protected Mono checkoutReference( jsonTransformationDTO.setArtifactType(baseArtifact.getArtifactType()); jsonTransformationDTO.setRepoName(baseGitMetadata.getRepoName()); - if (referenceToBeCheckedOut.startsWith(ORIGIN)) { - + if (gitRefDTO.getRefName().startsWith(ORIGIN)) { // checking for local present references first checkedOutArtifactMono = gitHandlingService - .listReferences(jsonTransformationDTO, FALSE, refType) + .listReferences(jsonTransformationDTO, FALSE) .flatMap(gitRefs -> { long branchMatchCount = gitRefs.stream() .filter(gitRef -> gitRef.equals(finalRefName)) .count(); if (branchMatchCount == 0) { - return checkoutRemoteBranch(baseArtifact, finalRefName); + return checkoutRemoteReference(baseArtifact, gitRefDTO, gitType); } return Mono.error(new AppsmithException( AppsmithError.GIT_ACTION_FAILED, "checkout", - referenceToBeCheckedOut + " already exists in local - " + finalRefName)); + gitRefDTO.getRefName() + " already exists in local - " + finalRefName)); }); } else { // TODO refactor method to account for RefName as well @@ -452,9 +458,88 @@ protected Mono checkoutReference( .tap(Micrometer.observation(observationRegistry)); } - // TODO @Manish: add checkout Remote Branch - protected Mono checkoutRemoteBranch(Artifact baseArtifact, String finalRefName) { - return null; + protected Mono checkoutRemoteReference( + String baseArtifactId, GitRefDTO gitRefDTO, ArtifactType artifactType, GitType gitType) { + + GitArtifactHelper gitArtifactHelper = gitArtifactHelperResolver.getArtifactHelper(artifactType); + AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); + + Mono baseArtifactMono = gitArtifactHelper + .getArtifactById(baseArtifactId, artifactEditPermission) + .switchIfEmpty(Mono.error(new AppsmithException(AppsmithError.GIT_GENERIC_ERROR))) + .cache(); + + return baseArtifactMono.flatMap(baseArtifact -> checkoutRemoteReference(baseArtifact, gitRefDTO, gitType)); + } + + private Mono checkoutRemoteReference( + Artifact baseArtifact, GitRefDTO gitRefDTO, GitType gitType) { + + GitHandlingService gitHandlingService = gitHandlingServiceResolver.getGitHandlingService(gitType); + GitArtifactHelper gitArtifactHelper = + gitArtifactHelperResolver.getArtifactHelper(baseArtifact.getArtifactType()); + + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + + if (isBaseGitMetadataInvalid(baseGitMetadata, gitType)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_SSH_CONFIGURATION)); + } + + final String repoName = baseGitMetadata.getRepoName(); + final String baseArtifactId = baseGitMetadata.getDefaultArtifactId(); + final String baseBranchName = baseGitMetadata.getBranchName(); + final String workspaceId = baseArtifact.getWorkspaceId(); + final String finalRemoteRefName = gitRefDTO.getRefName().replaceFirst(ORIGIN, REMOTE_NAME_REPLACEMENT); + + ArtifactJsonTransformationDTO jsonTransformationDTO = new ArtifactJsonTransformationDTO(); + jsonTransformationDTO.setRepoName(repoName); + jsonTransformationDTO.setRefType(gitRefDTO.getRefType()); + jsonTransformationDTO.setRefName(finalRemoteRefName); + jsonTransformationDTO.setWorkspaceId(workspaceId); + jsonTransformationDTO.setBaseArtifactId(baseArtifactId); + jsonTransformationDTO.setArtifactType(baseArtifact.getArtifactType()); + + Mono artifactMono; + if (baseBranchName.equals(finalRemoteRefName)) { + /* + in this case, user deleted the initial default branch and now wants to check out to that branch. + as we didn't delete the application object but only the branch from git repo, + we can just use this existing application without creating a new one. + */ + artifactMono = Mono.just(baseArtifact); + } else { + // create new Artifact + artifactMono = gitArtifactHelper.createNewArtifactForCheckout(baseArtifact, finalRemoteRefName); + } + + Mono checkedOutRemoteArtifactMono = gitHandlingService + .fetchRemoteChanges(jsonTransformationDTO, baseGitMetadata.getGitAuth(), false) + .onErrorResume(error -> Mono.error( + new AppsmithException(AppsmithError.GIT_ACTION_FAILED, "checkout branch", error.getMessage()))) + .flatMap(ignoreRemoteChanges -> { + return gitHandlingService + .reconstructArtifactJsonFromGitRepository(jsonTransformationDTO) + .zipWith(artifactMono); + }) + .flatMap(tuple -> { + // Get the latest artifact mono with all the changes + ArtifactExchangeJson artifactExchangeJson = tuple.getT1(); + Artifact artifact = tuple.getT2(); + return importService.importArtifactInWorkspaceFromGit( + artifact.getWorkspaceId(), artifact.getId(), artifactExchangeJson, finalRemoteRefName); + }) + .flatMap(importedArtifact -> gitArtifactHelper.publishArtifact(importedArtifact, false)) + .flatMap(publishedArtifact -> gitAnalyticsUtils.addAnalyticsForGitOperation( + AnalyticsEvents.GIT_CHECKOUT_REMOTE_BRANCH, + publishedArtifact, + Boolean.TRUE.equals( + publishedArtifact.getGitArtifactMetadata().getIsRepoPrivate()))) + .tag(GitConstants.GitMetricConstants.CHECKOUT_REMOTE, TRUE.toString()) + .name(GitSpan.OPS_CHECKOUT_BRANCH) + .tap(Micrometer.observation(observationRegistry)); + + return Mono.create(sink -> + checkedOutRemoteArtifactMono.subscribe(sink::success, sink::error, null, sink.currentContext())); } @Override @@ -526,7 +611,7 @@ protected Mono createReference( .flatMap(ignoreLockAcquisition -> fetchRemoteMono.onErrorResume( error -> Mono.error(new AppsmithException(AppsmithError.GIT_ACTION_FAILED, "fetch", error)))) .flatMap(ignoreFetchString -> gitHandlingService - .listReferences(jsonTransformationDTO, TRUE, refType) + .listReferences(jsonTransformationDTO, TRUE) .flatMap(refList -> { boolean isDuplicateName = refList.stream() // We are only supporting origin as the remote name so this is safe @@ -1499,6 +1584,175 @@ protected Mono getStatus( .tap(Micrometer.observation(observationRegistry)); } + /** + * Method to pull artifact json files from remote repo, make a commit with the changes present in local DB and + * make a system commit to remote repo + * + * @param branchedArtifactId artifact for which we want to pull remote changes and merge + * @param artifactType + * @return return the status of pull operation + */ + @Override + public Mono pullArtifact(String branchedArtifactId, ArtifactType artifactType, GitType gitType) { + /* + * 1.Dehydrate the artifact from DB so that the file system has the latest artifact data + * 2.Do git pull after the rehydration and merge the remote changes to the current branch + * On Merge conflict - throw exception and ask user to resolve these conflicts on remote + * TODO create new branch and push the changes to remote and ask the user to resolve it on github/gitlab UI + * 3.Then rehydrate from the file system to DB so that the latest changes from remote are rendered to the artifact + * 4.Get the latest artifact from the DB and send it back to client + * */ + + GitArtifactHelper gitArtifactHelper = gitArtifactHelperResolver.getArtifactHelper(artifactType); + AclPermission artifactEditPermission = gitArtifactHelper.getArtifactEditPermission(); + + Mono> baseAndBranchedArtifactMono = + getBaseAndBranchedArtifacts(branchedArtifactId, artifactType, artifactEditPermission); + + return baseAndBranchedArtifactMono.flatMap(artifactTuple -> { + Artifact baseArtifact = artifactTuple.getT1(); + Artifact branchedArtifact = artifactTuple.getT2(); + + return pullArtifact(baseArtifact, branchedArtifact, gitType); + }); + } + + protected Mono pullArtifact(Artifact baseArtifact, Artifact branchedArtifact, GitType gitType) { + + GitArtifactMetadata branchedGitMetadata = branchedArtifact.getGitArtifactMetadata(); + Mono statusMono = getStatus(baseArtifact, branchedArtifact, false, true, gitType); + + Mono pullDTOMono = gitRedisUtils + .acquireGitLock(branchedGitMetadata.getDefaultArtifactId(), GitConstants.GitCommandConstants.PULL, TRUE) + .then(Mono.defer(() -> statusMono)) + .flatMap(status -> { + // Check if the repo is clean + if (!CollectionUtils.isEmpty(status.getModified())) { + return gitRedisUtils + .releaseFileLock(branchedGitMetadata.getDefaultArtifactId(), TRUE) + .then( + Mono.error( + new AppsmithException( + AppsmithError.GIT_ACTION_FAILED, + "pull", + "There are uncommitted changes present in your local. Please commit them first and then try git pull"))); + } + + return pullAndRehydrateArtifact(baseArtifact, branchedArtifact, gitType) + // Release file lock after the pull operation + .flatMap(gitPullDTO -> gitRedisUtils + .releaseFileLock(branchedGitMetadata.getDefaultArtifactId(), TRUE) + .then(Mono.just(gitPullDTO))); + }) + .onErrorResume(error -> { + log.error( + "An error occurred while trying to pull the artifact with base id: {} and branchName: {}", + branchedGitMetadata.getDefaultArtifactId(), + branchedGitMetadata.getBranchName()); + + return gitRedisUtils + .releaseFileLock(branchedGitMetadata.getDefaultArtifactId(), TRUE) + .then(Mono.error(error)); + }) + .name(GitSpan.OPS_PULL) + .tap(Micrometer.observation(observationRegistry)); + + return Mono.create(sink -> pullDTOMono.subscribe(sink::success, sink::error, null, sink.currentContext())); + } + + /** + * Method to pull the files from remote repo and rehydrate the application + * + * @param baseArtifact : base artifact + * @param branchedArtifact : a branch created from branches of base artifact + * @return pull DTO with updated application + */ + private Mono pullAndRehydrateArtifact( + Artifact baseArtifact, Artifact branchedArtifact, GitType gitType) { + /* + 1. Checkout to the concerned branch + 2. Do git pull after + On Merge conflict - throw exception and ask user to resolve these conflicts on remote + TODO create new branch and push the changes to remote and ask the user to resolve it on github/gitlab UI + 3. Rehydrate the application from filesystem so that the latest changes from remote are rendered to the application + */ + + ArtifactType artifactType = baseArtifact.getArtifactType(); + GitArtifactHelper gitArtifactHelper = gitArtifactHelperResolver.getArtifactHelper(artifactType); + GitHandlingService gitHandlingService = gitHandlingServiceResolver.getGitHandlingService(gitType); + + GitArtifactMetadata baseGitMetadata = baseArtifact.getGitArtifactMetadata(); + + if (isBaseGitMetadataInvalid(baseGitMetadata, gitType)) { + return Mono.error(new AppsmithException(AppsmithError.INVALID_GIT_CONFIGURATION, GIT_CONFIG_ERROR)); + } + + GitArtifactMetadata branchedGitMetadata = branchedArtifact.getGitArtifactMetadata(); + + final String workspaceId = branchedArtifact.getWorkspaceId(); + final String baseArtifactId = branchedGitMetadata.getDefaultArtifactId(); + final String repoName = branchedGitMetadata.getRepoName(); + final String branchName = branchedGitMetadata.getBranchName(); + + ArtifactJsonTransformationDTO jsonTransformationDTO = new ArtifactJsonTransformationDTO(); + jsonTransformationDTO.setRepoName(repoName); + jsonTransformationDTO.setRefType(RefType.BRANCH); + jsonTransformationDTO.setRefName(branchName); + jsonTransformationDTO.setWorkspaceId(workspaceId); + jsonTransformationDTO.setBaseArtifactId(baseArtifactId); + jsonTransformationDTO.setArtifactType(baseArtifact.getArtifactType()); + + Path repoSuffix = gitArtifactHelper.getRepoSuffixPath(workspaceId, baseArtifactId, repoName); + + return Mono.defer(() -> { + // Rehydrate the artifact from git system + + Mono mergeStatusDTOMono = gitHandlingService + .pullArtifact(jsonTransformationDTO, baseGitMetadata) + .cache(); + Mono artifactExchangeJsonMono = mergeStatusDTOMono.flatMap(status -> + gitHandlingService.reconstructArtifactJsonFromGitRepository(jsonTransformationDTO)); + + return Mono.zip(mergeStatusDTOMono, artifactExchangeJsonMono); + }) + .flatMap(tuple -> { + MergeStatusDTO status = tuple.getT1(); + ArtifactExchangeJson artifactExchangeJson = tuple.getT2(); + // Get the latest artifact with all the changes + // Commit and push changes to sync with remote + return importService + .importArtifactInWorkspaceFromGit( + workspaceId, branchedArtifact.getId(), artifactExchangeJson, branchName) + .flatMap(importedBranchedArtifact -> gitAnalyticsUtils.addAnalyticsForGitOperation( + AnalyticsEvents.GIT_PULL, + importedBranchedArtifact, + importedBranchedArtifact + .getGitArtifactMetadata() + .getIsRepoPrivate())) + .flatMap(importedBranchedArtifact -> { + CommitDTO commitDTO = new CommitDTO(); + commitDTO.setMessage(DEFAULT_COMMIT_MESSAGE + + GitDefaultCommitMessage.SYNC_WITH_REMOTE_AFTER_PULL.getReason()); + + GitPullDTO gitPullDTO = new GitPullDTO(); + gitPullDTO.setMergeStatus(status); + gitPullDTO.setArtifact(importedBranchedArtifact); + + return gitArtifactHelper + .publishArtifact(importedBranchedArtifact, false) + // TODO: Verify if we need to commit after pulling? (Gonna be a product + // decision, hence got + .then(Mono.defer(() -> commitArtifact( + commitDTO, + baseArtifact, + importedBranchedArtifact, + gitType, + false)) + .thenReturn(gitPullDTO)); + }); + }); + } + public Mono fetchRemoteChanges( Artifact baseArtifact, Artifact refArtifact, boolean isFileLock, GitType gitType, RefType refType) { diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/GitHandlingServiceCE.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/GitHandlingServiceCE.java index ddbb91643550..89b3d7d64a0e 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/GitHandlingServiceCE.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/central/GitHandlingServiceCE.java @@ -2,7 +2,7 @@ import com.appsmith.external.dtos.GitRefDTO; import com.appsmith.external.dtos.GitStatusDTO; -import com.appsmith.external.git.constants.ce.RefType; +import com.appsmith.external.dtos.MergeStatusDTO; import com.appsmith.git.dto.CommitDTO; import com.appsmith.server.domains.Artifact; import com.appsmith.server.domains.GitArtifactMetadata; @@ -48,9 +48,7 @@ Mono> listBranches( Mono> listBranches(ArtifactJsonTransformationDTO artifactJsonTransformationDTO); Mono> listReferences( - ArtifactJsonTransformationDTO artifactJsonTransformationDTO, - Boolean checkRemoteReferences, - RefType refType); + ArtifactJsonTransformationDTO artifactJsonTransformationDTO, Boolean checkRemoteReferences); Mono validateEmptyRepository(ArtifactJsonTransformationDTO artifactJsonTransformationDTO); @@ -82,4 +80,7 @@ Mono recreateArtifactJsonFromLastCommit( Mono deleteGitReference(ArtifactJsonTransformationDTO jsonTransformationDTO); Mono checkoutArtifact(ArtifactJsonTransformationDTO jsonTransformationDTO); + + Mono pullArtifact( + ArtifactJsonTransformationDTO jsonTransformationDTO, GitArtifactMetadata baseMetadata); } diff --git a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/fs/GitFSServiceCEImpl.java b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/fs/GitFSServiceCEImpl.java index 4ba699bc0575..84f772930dc6 100644 --- a/app/server/appsmith-server/src/main/java/com/appsmith/server/git/fs/GitFSServiceCEImpl.java +++ b/app/server/appsmith-server/src/main/java/com/appsmith/server/git/fs/GitFSServiceCEImpl.java @@ -4,6 +4,7 @@ import com.appsmith.external.dtos.GitBranchDTO; import com.appsmith.external.dtos.GitRefDTO; import com.appsmith.external.dtos.GitStatusDTO; +import com.appsmith.external.dtos.MergeStatusDTO; import com.appsmith.external.git.constants.GitConstants; import com.appsmith.external.git.constants.GitSpan; import com.appsmith.external.git.constants.ce.RefType; @@ -294,14 +295,12 @@ public Mono> listBranches( @Override public Mono> listReferences( - ArtifactJsonTransformationDTO artifactJsonTransformationDTO, - Boolean checkRemoteReferences, - RefType refType) { - if (RefType.BRANCH.equals(refType)) { - listBranches(artifactJsonTransformationDTO, checkRemoteReferences); + ArtifactJsonTransformationDTO artifactJsonTransformationDTO, Boolean checkRemoteReferences) { + if (RefType.BRANCH.equals(artifactJsonTransformationDTO.getRefType())) { + return listBranches(artifactJsonTransformationDTO, checkRemoteReferences); } - // TODO: include ref type for tags in fsGit Handler + // TODO: Add logic for other reference types (e.g., tags) return Mono.just(List.of()); } @@ -619,13 +618,13 @@ public Mono fetchRemoteChanges( GitArtifactHelper gitArtifactHelper = gitArtifactHelperResolver.getArtifactHelper(artifactType); Path repoSuffix = gitArtifactHelper.getRepoSuffixPath(workspaceId, baseArtifactId, repoName); - Path repoPath = fsGitHandler.createRepoPath(repoSuffix); - Mono checkoutBranchMono = fsGitHandler.checkoutToBranch(repoSuffix, refName); - Mono fetchRemoteMono = fsGitHandler.fetchRemote( - repoPath, gitAuth.getPublicKey(), gitAuth.getPrivateKey(), true, refName, isFetchAll); + repoSuffix, gitAuth.getPublicKey(), gitAuth.getPrivateKey(), false, refName, isFetchAll); - return checkoutBranchMono.then(Mono.defer(() -> fetchRemoteMono)); + // TODO : check if we require to checkout the reference + Mono checkoutBranchMono = fsGitHandler.checkoutToBranch(repoSuffix, refName); + + return fetchRemoteMono.flatMap(remoteFetched -> checkoutBranchMono.thenReturn(remoteFetched)); } @Override @@ -719,4 +718,45 @@ public Mono checkoutArtifact(ArtifactJsonTransformationDTO jsonTransfor // Tags and branch checkout with the same mechanism. return fsGitHandler.checkoutToBranch(repoSuffix, jsonTransformationDTO.getRefName()); } + + @Override + public Mono pullArtifact( + ArtifactJsonTransformationDTO jsonTransformationDTO, GitArtifactMetadata baseMetadata) { + GitArtifactHelper gitArtifactHelper = + gitArtifactHelperResolver.getArtifactHelper(jsonTransformationDTO.getArtifactType()); + + Path repoSuffix = gitArtifactHelper.getRepoSuffixPath( + jsonTransformationDTO.getWorkspaceId(), + jsonTransformationDTO.getBaseArtifactId(), + jsonTransformationDTO.getRepoName()); + + String branchName = jsonTransformationDTO.getRefName(); + + // git checkout and pull origin branchName + try { + return fsGitHandler + .checkoutToBranch(repoSuffix, jsonTransformationDTO.getRefName()) + .then(fsGitHandler.pullApplication( + repoSuffix, + baseMetadata.getRemoteUrl(), + branchName, + baseMetadata.getGitAuth().getPrivateKey(), + baseMetadata.getGitAuth().getPublicKey())) + .onErrorResume(error -> { + if (error.getMessage().contains("conflict")) { + return Mono.error( + new AppsmithException(AppsmithError.GIT_PULL_CONFLICTS, error.getMessage())); + } else if (error.getMessage().contains("Nothing to fetch")) { + MergeStatusDTO mergeStatus = new MergeStatusDTO(); + mergeStatus.setStatus("Nothing to fetch from remote. All changes are up to date."); + mergeStatus.setMergeAble(true); + return Mono.just(mergeStatus); + } + return Mono.error( + new AppsmithException(AppsmithError.GIT_ACTION_FAILED, "pull", error.getMessage())); + }); + } catch (IOException e) { + return Mono.error(new AppsmithException(AppsmithError.GIT_FILE_SYSTEM_ERROR, e.getMessage())); + } + } } From de2d5a4461fc357aadf108d9f69eb6674233ba16 Mon Sep 17 00:00:00 2001 From: Valera Melnikov Date: Mon, 30 Dec 2024 17:47:07 +0300 Subject: [PATCH 09/13] fix: split default tab logic (#38414) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Split the logic for the plugin action tabs. Now the files in CE and EE repo for the `ce` folder are the same. Redefine the logic in EE hooks only. EE PR β€” https://github.com/appsmithorg/appsmith-ee/pull/5840 ## Automation /ok-to-test tags="@tag.All" ### :mag: Cypress test results > [!TIP] > 🟒 🟒 🟒 All cypress tests have passed! πŸŽ‰ πŸŽ‰ πŸŽ‰ > Workflow run: > Commit: 8fa499eb02ab83a9dd0737f39e4cc2372dc7f174 > Cypress dashboard. > Tags: `@tag.All` > Spec: >
Mon, 30 Dec 2024 13:26:11 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No --- .../PluginActionResponse.tsx | 30 ++------------ .../hooks/useDefaultTab.tsx | 40 +++++++++++++++++++ .../hooks/useDefaultTab.tsx | 5 +++ 3 files changed, 48 insertions(+), 27 deletions(-) create mode 100644 app/client/src/ce/PluginActionEditor/components/PluginActionResponse/hooks/useDefaultTab.tsx create mode 100644 app/client/src/ee/PluginActionEditor/components/PluginActionResponse/hooks/useDefaultTab.tsx diff --git a/app/client/src/PluginActionEditor/components/PluginActionResponse/PluginActionResponse.tsx b/app/client/src/PluginActionEditor/components/PluginActionResponse/PluginActionResponse.tsx index e450a2b7821b..ef8fdb3f4558 100644 --- a/app/client/src/PluginActionEditor/components/PluginActionResponse/PluginActionResponse.tsx +++ b/app/client/src/PluginActionEditor/components/PluginActionResponse/PluginActionResponse.tsx @@ -9,20 +9,15 @@ import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/constant import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import { usePluginActionResponseTabs } from "./hooks"; import { usePluginActionContext } from "../../PluginActionContext"; -import { doesPluginRequireDatasource } from "ee/entities/Engine/actionHelpers"; -import useShowSchema from "./hooks/useShowSchema"; import { actionResponseDisplayDataFormats } from "pages/Editor/utils"; -import { PluginType } from "entities/Action"; import { hasFailed } from "./utils"; +import { useDefaultTab } from "ee/PluginActionEditor/components/PluginActionResponse/hooks/useDefaultTab"; function PluginActionResponse() { const dispatch = useDispatch(); - const { actionResponse, plugin } = usePluginActionContext(); + const { actionResponse } = usePluginActionContext(); const tabs = usePluginActionResponseTabs(); - const pluginRequireDatasource = doesPluginRequireDatasource(plugin); - - const showSchema = useShowSchema(plugin?.id || "") && pluginRequireDatasource; // TODO combine API and Query Debugger state const { open, responseTabHeight, selectedTab } = useSelector( @@ -75,26 +70,7 @@ function PluginActionResponse() { [executionFailed, dispatch], ); - useEffect( - function openDefaultTabWhenNoTabIsSelected() { - if (showSchema && !selectedTab) { - dispatch( - setPluginActionEditorDebuggerState({ - open: true, - selectedTab: DEBUGGER_TAB_KEYS.DATASOURCE_TAB, - }), - ); - } else if (plugin.type === PluginType.API && !selectedTab) { - dispatch( - setPluginActionEditorDebuggerState({ - open: true, - selectedTab: DEBUGGER_TAB_KEYS.RESPONSE_TAB, - }), - ); - } - }, - [showSchema, selectedTab, dispatch, plugin.type], - ); + useDefaultTab(); const toggleHide = useCallback( () => dispatch(setPluginActionEditorDebuggerState({ open: !open })), diff --git a/app/client/src/ce/PluginActionEditor/components/PluginActionResponse/hooks/useDefaultTab.tsx b/app/client/src/ce/PluginActionEditor/components/PluginActionResponse/hooks/useDefaultTab.tsx new file mode 100644 index 000000000000..399b32064751 --- /dev/null +++ b/app/client/src/ce/PluginActionEditor/components/PluginActionResponse/hooks/useDefaultTab.tsx @@ -0,0 +1,40 @@ +import { useEffect } from "react"; +import { useDispatch, useSelector } from "react-redux"; +import { DEBUGGER_TAB_KEYS } from "components/editorComponents/Debugger/constants"; +import { PluginType } from "entities/Action"; +import { usePluginActionContext } from "PluginActionEditor"; +import useShowSchema from "PluginActionEditor/components/PluginActionResponse/hooks/useShowSchema"; +import { + getPluginActionDebuggerState, + setPluginActionEditorDebuggerState, +} from "PluginActionEditor/store"; +import { doesPluginRequireDatasource } from "ee/entities/Engine/actionHelpers"; + +export function useDefaultTab() { + const dispatch = useDispatch(); + const { plugin } = usePluginActionContext(); + const pluginRequireDatasource = doesPluginRequireDatasource(plugin); + const showSchema = useShowSchema(plugin?.id || "") && pluginRequireDatasource; + const { selectedTab } = useSelector(getPluginActionDebuggerState); + + useEffect( + function openDefaultTabWhenNoTabIsSelected() { + if (showSchema && !selectedTab) { + dispatch( + setPluginActionEditorDebuggerState({ + open: true, + selectedTab: DEBUGGER_TAB_KEYS.DATASOURCE_TAB, + }), + ); + } else if (plugin.type === PluginType.API && !selectedTab) { + dispatch( + setPluginActionEditorDebuggerState({ + open: true, + selectedTab: DEBUGGER_TAB_KEYS.RESPONSE_TAB, + }), + ); + } + }, + [showSchema, selectedTab, dispatch, plugin.type], + ); +} diff --git a/app/client/src/ee/PluginActionEditor/components/PluginActionResponse/hooks/useDefaultTab.tsx b/app/client/src/ee/PluginActionEditor/components/PluginActionResponse/hooks/useDefaultTab.tsx new file mode 100644 index 000000000000..82827533ab5c --- /dev/null +++ b/app/client/src/ee/PluginActionEditor/components/PluginActionResponse/hooks/useDefaultTab.tsx @@ -0,0 +1,5 @@ +import { useDefaultTab as CE_useDefaultTab } from "ce/PluginActionEditor/components/PluginActionResponse/hooks/useDefaultTab"; + +export function useDefaultTab() { + return CE_useDefaultTab(); +} From 0eee667493503605c32c92361b202744eea5d7e6 Mon Sep 17 00:00:00 2001 From: Rudraprasad Das Date: Tue, 31 Dec 2024 17:46:11 +0530 Subject: [PATCH 10/13] chore: revert - git mod - integration app (#38431) --- .../ads/src/Icon/Icon.provider.tsx | 5 - .../request/apiRequestInterceptor.ts | 1 - app/client/src/ce/entities/FeatureFlag.ts | 2 - .../FocusStrategy/AppIDEFocusStrategy.ts | 27 +- .../Applications/CreateNewAppsOption.test.tsx | 4 - .../src/ce/pages/Applications/index.tsx | 12 +- .../pages/Editor/IDE/MainPane/useRoutes.tsx | 4 +- app/client/src/ce/reducers/index.tsx | 7 - .../uiReducers/applicationsReducer.tsx | 16 -- app/client/src/ce/sagas/PageSagas.tsx | 14 +- app/client/src/ce/sagas/index.tsx | 2 - .../src/ce/selectors/entitiesSelector.ts | 79 +++--- app/client/src/components/BottomBar/index.tsx | 24 +- .../appsmith/header/DeployLinkButton.tsx | 61 ++--- .../editorComponents/ApiResponseView.test.tsx | 4 - .../editorComponents/GlobalSearch/HelpBar.tsx | 40 +-- .../GitApplicationContextProvider.tsx | 36 --- .../src/entities/Engine/AppEditorEngine.ts | 86 +++---- app/client/src/entities/Engine/index.ts | 9 +- .../application/applicationArtifact.ts | 11 - .../git/artifact-helpers/application/index.ts | 2 - .../application/statusTransformer.ts} | 143 +---------- .../src/git/ce/components/GitModals/index.tsx | 2 - .../src/git/ce/hooks/useDefaultBranch.ts | 14 +- .../ConflictErrorModalView.tsx | 16 +- .../components/ConflictErrorModal/index.tsx | 4 +- .../ConnectInitialize/AddDeployKey.test.tsx | 231 ++++++++++++++++++ .../ConnectInitialize/AddDeployKey.tsx | 100 ++++---- .../ChooseGitProvider.test.tsx | 13 +- .../ConnectInitialize/ChooseGitProvider.tsx | 32 ++- .../ConnectInitialize/GenerateSSH.test.tsx | 6 +- .../ConnectInitialize/GenerateSSH.tsx | 10 +- .../ConnectInitialize/index.test.tsx | 32 ++- .../ConnectModal/ConnectInitialize/index.tsx | 126 ++++++---- .../ConnectModal/ConnectModalView.tsx | 82 +++++-- .../ConnectSuccess/index.tsx} | 105 ++++---- .../src/git/components/ConnectModal/index.tsx | 93 ++++--- .../components/ConnectSuccessModal/index.tsx | 29 --- .../DeployMenuItems/DeployMenuItemsView.tsx | 32 --- .../git/components/DeployMenuItems/index.tsx | 11 - .../components/GitContextProvider/index.tsx | 23 +- .../GlobalProfile/GlobalProfileView.tsx | 148 ----------- .../git/components/GlobalProfile/index.tsx | 23 -- .../src/git/components/ImportModal/index.tsx | 49 +--- .../OpsModal/TabDeploy/DeployPreview.tsx | 47 ++-- .../OpsModal/TabDeploy/TabDeployView.tsx | 10 +- .../src/git/components/OpsModal/index.tsx | 11 +- .../ProtectedBranchCalloutView.tsx | 85 ------- .../ProtectedBranchCallout/index.tsx | 33 --- .../QuickActions/QuickActionsView.test.tsx | 30 +-- .../QuickActions/QuickActionsView.tsx | 6 +- .../src/git/components/QuickActions/index.tsx | 10 +- .../git/components/SettingsModal/index.tsx | 3 +- .../StatusChanges/StatusChangesView.tsx | 16 +- .../components/StatusChanges/StatusLoader.tsx | 10 +- .../components/StatusChanges/StatusTree.tsx | 29 +-- .../src/git/components/StatusChanges/types.ts | 5 - app/client/src/git/components/index.tsx | 3 + .../src/git/hooks/useArtifactSelector.ts | 29 --- app/client/src/git/hooks/useAutocommit.ts | 50 ++-- app/client/src/git/hooks/useBranches.ts | 124 +++++----- app/client/src/git/hooks/useCommit.ts | 39 ++- app/client/src/git/hooks/useConnect.ts | 93 +++++-- app/client/src/git/hooks/useConnected.ts | 8 - app/client/src/git/hooks/useCurrentBranch.ts | 8 - app/client/src/git/hooks/useDiscard.ts | 18 +- app/client/src/git/hooks/useDisconnect.ts | 38 ++- app/client/src/git/hooks/useGitPermissions.ts | 17 +- app/client/src/git/hooks/useGlobalProfile.ts | 8 +- app/client/src/git/hooks/useGlobalSSHKey.ts | 29 --- app/client/src/git/hooks/useImport.ts | 38 --- app/client/src/git/hooks/useLocalProfile.ts | 32 ++- app/client/src/git/hooks/useMerge.ts | 46 ++-- app/client/src/git/hooks/useMetadata.ts | 20 +- app/client/src/git/hooks/useOps.ts | 36 +-- .../src/git/hooks/useProtectedBranches.ts | 50 ++-- app/client/src/git/hooks/useProtectedMode.ts | 8 - app/client/src/git/hooks/usePull.ts | 24 +- app/client/src/git/hooks/useSSHKey.ts | 63 ----- app/client/src/git/hooks/useSettings.ts | 24 +- app/client/src/git/hooks/useStatus.ts | 34 ++- app/client/src/git/index.ts | 39 --- .../src/git/requests/connectRequest.types.ts | 17 +- .../git/requests/disconnectRequest.types.ts | 5 +- .../git/requests/fetchGlobalSSHKeyRequest.ts | 15 -- .../fetchGlobalSSHKeyRequest.types.ts | 15 -- .../git/requests/fetchStatusRequest.types.ts | 1 - .../src/git/requests/generateSSHKeyRequest.ts | 8 +- .../requests/generateSSHKeyRequest.types.ts | 1 + .../git/requests/gitImportRequest.types.ts | 18 +- .../src/git/sagas/checkoutBranchSaga.ts | 13 +- app/client/src/git/sagas/commitSaga.ts | 16 +- app/client/src/git/sagas/connectSaga.ts | 48 ++-- app/client/src/git/sagas/createBranchSaga.ts | 16 +- app/client/src/git/sagas/deleteBranchSaga.ts | 21 +- app/client/src/git/sagas/disconnectSaga.ts | 24 +- app/client/src/git/sagas/fetchBranchesSaga.ts | 9 +- .../src/git/sagas/fetchGlobalProfileSaga.ts | 6 +- .../src/git/sagas/fetchGlobalSSHKeySaga.ts | 44 ---- .../src/git/sagas/fetchLocalProfileSaga.ts | 9 +- .../src/git/sagas/fetchMergeStatusSaga.ts | 10 +- app/client/src/git/sagas/fetchMetadataSaga.ts | 9 +- .../git/sagas/fetchProtectedBranchesSaga.ts | 12 +- app/client/src/git/sagas/fetchSSHKeySaga.ts | 9 +- app/client/src/git/sagas/fetchStatusSaga.ts | 9 +- .../src/git/sagas/generateSSHKeySaga.ts | 18 +- app/client/src/git/sagas/gitImportSaga.ts | 92 ------- app/client/src/git/sagas/index.ts | 12 +- app/client/src/git/sagas/initGitSaga.ts | 27 +- app/client/src/git/sagas/pullSaga.ts | 11 +- .../src/git/sagas/toggleAutocommitSaga.ts | 11 +- .../src/git/sagas/triggerAutocommitSaga.ts | 50 ++-- .../src/git/sagas/updateGlobalProfileSaga.ts | 8 +- .../src/git/sagas/updateLocalProfileSaga.ts | 15 +- .../git/sagas/updateProtectedBranchesSaga.ts | 13 +- .../store/actions/checkoutBranchActions.ts | 25 +- .../src/git/store/actions/commitActions.ts | 19 +- .../src/git/store/actions/connectActions.ts | 35 ++- .../git/store/actions/createBranchActions.ts | 12 +- .../git/store/actions/deleteBranchActions.ts | 12 +- .../src/git/store/actions/discardActions.ts | 10 +- .../git/store/actions/disconnectActions.ts | 8 +- .../actions/fetchAutocommitProgressActions.ts | 8 +- .../git/store/actions/fetchBranchesActions.ts | 12 +- .../actions/fetchGlobalProfileActions.ts | 8 +- .../store/actions/fetchGlobalSSHKeyActions.ts | 55 ----- .../store/actions/fetchLocalProfileActions.ts | 18 +- .../store/actions/fetchMergeStatusActions.ts | 10 +- .../git/store/actions/fetchMetadataActions.ts | 8 +- .../actions/fetchProtectedBranchesActions.ts | 8 +- .../git/store/actions/fetchSSHKeyActions.ts | 10 +- .../git/store/actions/fetchStatusActions.ts | 12 +- .../store/actions/generateSSHKeyActions.ts | 10 +- .../src/git/store/actions/gitImportActions.ts | 42 ++-- .../src/git/store/actions/initGitActions.ts | 12 +- .../src/git/store/actions/mergeActions.ts | 8 +- .../src/git/store/actions/mountActions.ts | 19 +- .../src/git/store/actions/pullActions.ts | 18 +- .../actions/repoLimitErrorModalActions.ts | 14 +- .../store/actions/toggleAutocommitActions.ts | 26 +- .../store/actions/triggerAutocommitActions.ts | 20 +- app/client/src/git/store/actions/uiActions.ts | 93 +++---- .../actions/updateGlobalProfileActions.ts | 10 +- .../actions/updateLocalProfileActions.ts | 16 +- .../actions/updateProtectedBranchesActions.ts | 8 +- app/client/src/git/store/gitArtifactSlice.ts | 14 +- app/client/src/git/store/gitConfigSlice.ts | 29 +++ app/client/src/git/store/gitGlobalSlice.ts | 49 ---- .../git/store/helpers/createArtifactAction.ts | 35 --- .../helpers/createSingleArtifactAction.ts | 35 +++ .../store/helpers/gitConfigInitialState.ts | 13 + .../helpers/gitSingleArtifactInitialState.ts | 138 +++++++++++ .../src/git/store/helpers/initialState.ts | 157 ------------ app/client/src/git/store/index.ts | 4 +- .../git/store/selectors/gitConfigSelectors.ts | 12 + .../git/store/selectors/gitGlobalSelectors.ts | 21 -- ...ctors.ts => gitSingleArtifactSelectors.ts} | 35 +-- app/client/src/git/store/types.ts | 50 ++-- .../anvil/common/hooks/detachedWidgetHooks.ts | 4 +- .../common/hooks/useWidgetBorderStyles.ts | 4 +- .../anvil/editor/AnvilEditorWidgetOnion.tsx | 4 +- .../anvil/editor/hooks/useAnvilWidgetHover.ts | 4 +- .../sagas/LayoutElementPositionsSaga.ts | 4 +- .../components/zone/useZoneMinWidth.ts | 8 +- .../SectionSpaceDistributor.tsx | 4 +- .../anvil/viewer/AnvilViewerWidgetOnion.tsx | 4 +- .../autolayout/common/FlexComponent.tsx | 8 +- .../common/dropTarget/DropTargetComponent.tsx | 8 +- .../common/resizer/ModalResizableLayer.tsx | 8 +- .../common/resizer/ResizableComponent.tsx | 8 +- .../usePositionObserver.ts | 6 +- .../layoutSystems/common/widgetName/index.tsx | 4 +- .../common/autoHeightOverlay/index.tsx | 4 +- .../CanvasSelectionArena.tsx | 4 +- .../pages/AppViewer/Navigation/Sidebar.tsx | 8 +- .../pages/AppViewer/Navigation/TopInline.tsx | 8 +- .../src/pages/AppViewer/PrimaryCTA.test.tsx | 5 - app/client/src/pages/AppViewer/PrimaryCTA.tsx | 4 +- .../AppSettings/ImportAppSettings.tsx | 4 +- app/client/src/pages/Editor/Canvas.tsx | 4 +- .../Editor/GlobalHotKeys/GlobalHotKeys.tsx | 22 +- .../pages/Editor/IDE/Header/DeployButton.tsx | 131 ---------- .../src/pages/Editor/IDE/Header/index.tsx | 108 +++++++- .../Editor/IDE/Layout/AnimatedLayout.tsx | 25 +- .../pages/Editor/IDE/Layout/StaticLayout.tsx | 25 +- .../hooks/useEditorStateLeftPaneWidth.ts | 4 +- .../IDE/Layout/hooks/useGridLayoutTemplate.ts | 4 +- .../Editor/IDE/ProtectedCallout.test.tsx | 33 ++- .../src/pages/Editor/IDE/hooks.test.tsx | 10 - app/client/src/pages/Editor/IDE/hooks.ts | 5 +- .../LayoutSystemBasedPageViewer.tsx | 4 +- .../NavigationAdjustedPageViewer.tsx | 4 +- .../components/NavigationPreview.tsx | 4 +- .../components/WidgetEditorContentWrapper.tsx | 8 +- .../components/WidgetEditorNavigation.tsx | 6 +- .../Editor/commons/EditorWrapperContainer.tsx | 8 +- .../gitSync/components/DeployPreview.tsx | 1 + .../pages/Editor/gitSync/hooks/modHooks.ts | 44 ---- app/client/src/pages/Editor/index.tsx | 67 ++--- app/client/src/pages/UserProfile/index.tsx | 30 +-- app/client/src/pages/common/ImportModal.tsx | 27 +- .../sagas/ActionExecution/StoreActionSaga.ts | 6 +- app/client/src/sagas/DatasourcesSagas.ts | 1 - app/client/src/sagas/FocusRetentionSaga.ts | 6 +- app/client/src/sagas/GlobalSearchSagas.ts | 8 +- .../src/sagas/autoHeightSagas/helpers.ts | 4 +- .../src/selectors/debuggerSelectors.tsx | 4 +- app/client/src/selectors/editorSelectors.tsx | 6 + app/client/src/selectors/gitModSelectors.ts | 50 ---- .../src/selectors/widgetDragSelectors.ts | 8 +- app/client/src/selectors/widgetSelectors.ts | 4 +- .../utils/hooks/useAllowEditorDragToSelect.ts | 8 +- .../src/utils/hooks/useHoverToFocusWidget.ts | 4 +- .../ChartWidget/component/index.test.tsx | 5 - .../widgets/ChartWidget/component/index.tsx | 4 +- .../widgets/CustomWidget/component/index.tsx | 4 +- .../widgets/IframeWidget/component/index.tsx | 4 +- app/client/src/widgets/withWidgetProps.tsx | 4 +- app/client/test/testUtils.tsx | 7 - 219 files changed, 2200 insertions(+), 3319 deletions(-) delete mode 100644 app/client/src/components/gitContexts/GitApplicationContextProvider.tsx delete mode 100644 app/client/src/git/artifact-helpers/application/applicationArtifact.ts delete mode 100644 app/client/src/git/artifact-helpers/application/index.ts rename app/client/src/git/{artifact-helpers/application/applicationStatusTransformer.ts => artifactHelpers/application/statusTransformer.ts} (62%) create mode 100644 app/client/src/git/components/ConnectModal/ConnectInitialize/AddDeployKey.test.tsx rename app/client/src/git/components/{ConnectSuccessModal/ConnectSuccessModalView.tsx => ConnectModal/ConnectSuccess/index.tsx} (64%) delete mode 100644 app/client/src/git/components/ConnectSuccessModal/index.tsx delete mode 100644 app/client/src/git/components/DeployMenuItems/DeployMenuItemsView.tsx delete mode 100644 app/client/src/git/components/DeployMenuItems/index.tsx delete mode 100644 app/client/src/git/components/GlobalProfile/GlobalProfileView.tsx delete mode 100644 app/client/src/git/components/GlobalProfile/index.tsx delete mode 100644 app/client/src/git/components/ProtectedBranchCallout/ProtectedBranchCalloutView.tsx delete mode 100644 app/client/src/git/components/ProtectedBranchCallout/index.tsx delete mode 100644 app/client/src/git/components/StatusChanges/types.ts create mode 100644 app/client/src/git/components/index.tsx delete mode 100644 app/client/src/git/hooks/useArtifactSelector.ts delete mode 100644 app/client/src/git/hooks/useConnected.ts delete mode 100644 app/client/src/git/hooks/useCurrentBranch.ts delete mode 100644 app/client/src/git/hooks/useGlobalSSHKey.ts delete mode 100644 app/client/src/git/hooks/useImport.ts delete mode 100644 app/client/src/git/hooks/useProtectedMode.ts delete mode 100644 app/client/src/git/hooks/useSSHKey.ts delete mode 100644 app/client/src/git/index.ts delete mode 100644 app/client/src/git/requests/fetchGlobalSSHKeyRequest.ts delete mode 100644 app/client/src/git/requests/fetchGlobalSSHKeyRequest.types.ts delete mode 100644 app/client/src/git/sagas/fetchGlobalSSHKeySaga.ts delete mode 100644 app/client/src/git/sagas/gitImportSaga.ts delete mode 100644 app/client/src/git/store/actions/fetchGlobalSSHKeyActions.ts create mode 100644 app/client/src/git/store/gitConfigSlice.ts delete mode 100644 app/client/src/git/store/gitGlobalSlice.ts delete mode 100644 app/client/src/git/store/helpers/createArtifactAction.ts create mode 100644 app/client/src/git/store/helpers/createSingleArtifactAction.ts create mode 100644 app/client/src/git/store/helpers/gitConfigInitialState.ts create mode 100644 app/client/src/git/store/helpers/gitSingleArtifactInitialState.ts delete mode 100644 app/client/src/git/store/helpers/initialState.ts create mode 100644 app/client/src/git/store/selectors/gitConfigSelectors.ts delete mode 100644 app/client/src/git/store/selectors/gitGlobalSelectors.ts rename app/client/src/git/store/selectors/{gitArtifactSelectors.ts => gitSingleArtifactSelectors.ts} (92%) delete mode 100644 app/client/src/pages/Editor/IDE/Header/DeployButton.tsx delete mode 100644 app/client/src/pages/Editor/gitSync/hooks/modHooks.ts delete mode 100644 app/client/src/selectors/gitModSelectors.ts diff --git a/app/client/packages/design-system/ads/src/Icon/Icon.provider.tsx b/app/client/packages/design-system/ads/src/Icon/Icon.provider.tsx index 611ccff4f2a4..d12bc1f519d5 100644 --- a/app/client/packages/design-system/ads/src/Icon/Icon.provider.tsx +++ b/app/client/packages/design-system/ads/src/Icon/Icon.provider.tsx @@ -1103,10 +1103,6 @@ const ContentTypeRaw = importSvg( async () => import("../__assets__/icons/ads/content-type-raw.svg"), ); -const CloudIconV2 = importSvg( - async () => import("../__assets__/icons/ads/cloudy-line.svg"), -); - const NotionIcon = importSvg( async () => import("../__assets__/icons/ads/notion.svg"), ); @@ -1229,7 +1225,6 @@ const ICON_LOOKUP = { "close-modal": CloseLineIcon, "close-x": CloseLineIcon, "cloud-off-line": CloudOfflineIcon, - "cloud-v2": CloudIconV2, "collapse-control": CollapseIcon, "column-freeze": ColumnFreeze, "column-unfreeze": SubtractIcon, diff --git a/app/client/src/api/interceptors/request/apiRequestInterceptor.ts b/app/client/src/api/interceptors/request/apiRequestInterceptor.ts index 4a9d2ed633cc..5371cbbcf23c 100644 --- a/app/client/src/api/interceptors/request/apiRequestInterceptor.ts +++ b/app/client/src/api/interceptors/request/apiRequestInterceptor.ts @@ -30,7 +30,6 @@ const blockAirgappedRoutes = (config: InternalAxiosRequestConfig) => { const addGitBranchHeader = (config: InternalAxiosRequestConfig) => { const state = store.getState(); - // ! git mod - not sure how to replace this, we could directly read state if required const branch = getCurrentGitBranch(state) || getQueryParamsObject().branch; return _addGitBranchHeader(config, { branch }); diff --git a/app/client/src/ce/entities/FeatureFlag.ts b/app/client/src/ce/entities/FeatureFlag.ts index 4e3020fd98e2..d3048a86f9f1 100644 --- a/app/client/src/ce/entities/FeatureFlag.ts +++ b/app/client/src/ce/entities/FeatureFlag.ts @@ -48,7 +48,6 @@ export const FEATURE_FLAG = { "release_table_html_column_type_enabled", release_gs_all_sheets_options_enabled: "release_gs_all_sheets_options_enabled", - release_git_modularisation_enabled: "release_git_modularisation_enabled", ab_premium_datasources_view_enabled: "ab_premium_datasources_view_enabled", kill_session_recordings_enabled: "kill_session_recordings_enabled", config_mask_session_recordings_enabled: @@ -96,7 +95,6 @@ export const DEFAULT_FEATURE_FLAG_VALUE: FeatureFlags = { release_evaluation_scope_cache: false, release_table_html_column_type_enabled: false, release_gs_all_sheets_options_enabled: false, - release_git_modularisation_enabled: false, ab_premium_datasources_view_enabled: false, kill_session_recordings_enabled: false, config_user_session_recordings_enabled: true, diff --git a/app/client/src/ce/navigation/FocusStrategy/AppIDEFocusStrategy.ts b/app/client/src/ce/navigation/FocusStrategy/AppIDEFocusStrategy.ts index fe5440f22f27..5729a7e8c59d 100644 --- a/app/client/src/ce/navigation/FocusStrategy/AppIDEFocusStrategy.ts +++ b/app/client/src/ce/navigation/FocusStrategy/AppIDEFocusStrategy.ts @@ -2,6 +2,7 @@ import { all, select, take } from "redux-saga/effects"; import type { FocusPath, FocusStrategy } from "sagas/FocusRetentionSaga"; import type { AppsmithLocationState } from "utils/history"; import { NavigationMethod } from "utils/history"; +import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import type { FocusEntityInfo } from "navigation/FocusEntity"; import { FocusEntity, @@ -17,7 +18,6 @@ import { widgetListURL, } from "ee/RouteBuilder"; import AppIDEFocusElements from "../FocusElements/AppIDE"; -import { selectGitApplicationCurrentBranch } from "selectors/gitModSelectors"; function shouldSetState( prevPath: string, @@ -86,17 +86,8 @@ const isPageChange = (prevPath: string, currentPath: string) => { ); }; -export const createEditorFocusInfoKey = ( - basePageId: string, - branch: string | null = null, -) => { - const r = branch - ? `EDITOR_STATE.${basePageId}#${branch}` - : `EDITOR_STATE.${basePageId}`; - - return r; -}; - +export const createEditorFocusInfoKey = (basePageId: string, branch?: string) => + `EDITOR_STATE.${basePageId}#${branch}`; export const createEditorFocusInfo = (basePageId: string, branch?: string) => ({ key: createEditorFocusInfoKey(basePageId, branch), entityInfo: { @@ -118,9 +109,7 @@ export const AppIDEFocusStrategy: FocusStrategy = { return []; } - const branch: string | undefined = yield select( - selectGitApplicationCurrentBranch, - ); + const branch: string | undefined = yield select(getCurrentGitBranch); const entities: Array<{ entityInfo: FocusEntityInfo; key: string }> = []; const prevEntityInfo = identifyEntityFromPath(previousPath); const currentEntityInfo = identifyEntityFromPath(currentPath); @@ -147,9 +136,7 @@ export const AppIDEFocusStrategy: FocusStrategy = { return entities; }, *getEntitiesForStore(path: string, currentPath: string) { - const branch: string | undefined = yield select( - selectGitApplicationCurrentBranch, - ); + const branch: string | undefined = yield select(getCurrentGitBranch); const entities: Array = []; const currentFocusEntityInfo = identifyEntityFromPath(currentPath); const prevFocusEntityInfo = identifyEntityFromPath(path); @@ -192,9 +179,7 @@ export const AppIDEFocusStrategy: FocusStrategy = { appState: EditorState.EDITOR, params: prevFocusEntityInfo.params, }, - key: branch - ? `EDITOR_STATE.${prevFocusEntityInfo.params.basePageId}#${branch}` - : `EDITOR_STATE.${prevFocusEntityInfo.params.basePageId}`, + key: `EDITOR_STATE.${prevFocusEntityInfo.params.basePageId}#${branch}`, }); } diff --git a/app/client/src/ce/pages/Applications/CreateNewAppsOption.test.tsx b/app/client/src/ce/pages/Applications/CreateNewAppsOption.test.tsx index 06940dc36fcc..180268afb6a9 100644 --- a/app/client/src/ce/pages/Applications/CreateNewAppsOption.test.tsx +++ b/app/client/src/ce/pages/Applications/CreateNewAppsOption.test.tsx @@ -9,10 +9,6 @@ import CreateNewAppsOption from "./CreateNewAppsOption"; import { BrowserRouter as Router } from "react-router-dom"; import { unitTestBaseMockStore } from "layoutSystems/common/dropTarget/unitTestUtils"; -jest.mock("selectors/gitModSelectors", () => ({ - selectCombinedPreviewMode: jest.fn(() => false), -})); - const defaultStoreState = { ...unitTestBaseMockStore, tenant: { diff --git a/app/client/src/ce/pages/Applications/index.tsx b/app/client/src/ce/pages/Applications/index.tsx index 19b45abd74e1..edd2b60af280 100644 --- a/app/client/src/ce/pages/Applications/index.tsx +++ b/app/client/src/ce/pages/Applications/index.tsx @@ -122,6 +122,7 @@ import { MOBILE_MAX_WIDTH } from "constants/AppConstants"; import { Indices } from "constants/Layers"; import ImportModal from "pages/common/ImportModal"; import SharedUserList from "pages/common/SharedUserList"; +import GitSyncModal from "pages/Editor/gitSync/GitSyncModal"; import ReconnectDatasourceModal from "pages/Editor/gitSync/ReconnectDatasourceModal"; import RepoLimitExceededErrorModal from "pages/Editor/gitSync/RepoLimitExceededErrorModal"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; @@ -132,15 +133,6 @@ import { getAssetUrl } from "ee/utils/airgapHelpers"; import { ASSETS_CDN_URL } from "constants/ThirdPartyConstants"; import { LayoutSystemTypes } from "layoutSystems/types"; import { getIsAnvilLayoutEnabled } from "layoutSystems/anvil/integrations/selectors"; -import OldGitSyncModal from "pages/Editor/gitSync/GitSyncModal"; -import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks"; -import { GitImportModal as NewGitImportModal } from "git"; - -function GitImportModal() { - const isGitModEnabled = useGitModEnabled(); - - return isGitModEnabled ? : ; -} export const { cloudHosting } = getAppsmithConfigs(); @@ -963,7 +955,7 @@ export function ApplicationsSection(props: any) { isMobile={isMobile} > {workspacesListComponent} - + ); diff --git a/app/client/src/ce/pages/Editor/IDE/MainPane/useRoutes.tsx b/app/client/src/ce/pages/Editor/IDE/MainPane/useRoutes.tsx index 8f16afc63327..cac3ae6f84a8 100644 --- a/app/client/src/ce/pages/Editor/IDE/MainPane/useRoutes.tsx +++ b/app/client/src/ce/pages/Editor/IDE/MainPane/useRoutes.tsx @@ -34,12 +34,12 @@ import DataSourceEditor from "pages/Editor/DataSourceEditor"; import DatasourceBlankState from "pages/Editor/DataSourceEditor/DatasourceBlankState"; import type { RouteProps } from "react-router"; import { useSelector } from "react-redux"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { lazy, Suspense } from "react"; import React from "react"; import { retryPromise } from "utils/AppsmithUtils"; import Skeleton from "widgets/Skeleton"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; const FirstTimeUserOnboardingChecklist = lazy(async () => retryPromise( @@ -67,7 +67,7 @@ export interface RouteReturnType extends RouteProps { */ function useRoutes(path: string): RouteReturnType[] { - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); return [ { diff --git a/app/client/src/ce/reducers/index.tsx b/app/client/src/ce/reducers/index.tsx index 73842c65b5df..f6bb8801940e 100644 --- a/app/client/src/ce/reducers/index.tsx +++ b/app/client/src/ce/reducers/index.tsx @@ -77,8 +77,6 @@ import type { ActiveField } from "reducers/uiReducers/activeFieldEditorReducer"; import type { SelectedWorkspaceReduxState } from "ee/reducers/uiReducers/selectedWorkspaceReducer"; import type { ConsolidatedPageLoadState } from "reducers/uiReducers/consolidatedPageLoadReducer"; import type { BuildingBlocksReduxState } from "reducers/uiReducers/buildingBlockReducer"; -import type { GitArtifactRootReduxState, GitGlobalReduxState } from "git"; -import { gitReducer } from "git/store"; export const reducerObject = { entities: entityReducer, @@ -88,7 +86,6 @@ export const reducerObject = { settings: SettingsReducer, tenant: tenantReducer, linting: lintErrorReducer, - git: gitReducer, }; export interface AppState { @@ -179,8 +176,4 @@ export interface AppState { // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any tenant: TenantReduxState; - git: { - global: GitGlobalReduxState; - artifacts: GitArtifactRootReduxState; - }; } diff --git a/app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx b/app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx index 97830da22ff3..dd2f5b5c4060 100644 --- a/app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx +++ b/app/client/src/ce/reducers/uiReducers/applicationsReducer.tsx @@ -25,8 +25,6 @@ import { import produce from "immer"; import { isEmpty } from "lodash"; import type { ApplicationPayload } from "entities/Application"; -import { gitConnectSuccess, type GitConnectSuccessPayload } from "git"; -import type { PayloadAction } from "@reduxjs/toolkit"; export const initialState: ApplicationsReduxState = { isSavingAppName: false, @@ -746,20 +744,6 @@ export const handlers = { isSavingNavigationSetting: false, }; }, - // git - [gitConnectSuccess.type]: ( - state: ApplicationsReduxState, - action: PayloadAction, - ) => { - return { - ...state, - currentApplication: { - ...state.currentApplication, - gitApplicationMetadata: - action.payload.responseData.gitApplicationMetadata, - }, - }; - }, }; const applicationsReducer = createReducer(initialState, handlers); diff --git a/app/client/src/ce/sagas/PageSagas.tsx b/app/client/src/ce/sagas/PageSagas.tsx index aad81e9f8720..d1c8e1e86837 100644 --- a/app/client/src/ce/sagas/PageSagas.tsx +++ b/app/client/src/ce/sagas/PageSagas.tsx @@ -75,6 +75,7 @@ import { import { IncorrectBindingError, validateResponse } from "sagas/ErrorSagas"; import type { ApiResponse } from "api/ApiResponses"; import { + combinedPreviewModeSelector, getCurrentApplicationId, getCurrentLayoutId, getCurrentPageId, @@ -127,6 +128,7 @@ import { getPageList } from "ee/selectors/entitiesSelector"; import { setPreviewModeAction } from "actions/editorActions"; import { SelectionRequestType } from "sagas/WidgetSelectUtils"; import { toast } from "@appsmith/ads"; +import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import type { MainCanvasReduxState } from "reducers/uiReducers/mainCanvasReducer"; import { UserCancelledActionExecutionError } from "sagas/ActionExecution/errorUtils"; import { getInstanceId } from "ee/selectors/tenantSelectors"; @@ -148,10 +150,6 @@ import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; import { convertToBasePageIdSelector } from "selectors/pageListSelectors"; import type { Page } from "entities/Page"; import { ConsolidatedPageLoadApi } from "api"; -import { - selectCombinedPreviewMode, - selectGitApplicationCurrentBranch, -} from "selectors/gitModSelectors"; export const checkIfMigrationIsNeeded = ( fetchPageResponse?: FetchPageResponse, @@ -174,9 +172,7 @@ export function* refreshTheApp() { const currentPageId: string = yield select(getCurrentPageId); const defaultBasePageId: string = yield select(getDefaultBasePageId); const pagesList: Page[] = yield select(getPageList); - const gitBranch: string | undefined = yield select( - selectGitApplicationCurrentBranch, - ); + const gitBranch: string = yield select(getCurrentGitBranch); const isCurrentPageIdInList = pagesList.filter((page) => page.pageId === currentPageId).length > 0; @@ -641,7 +637,7 @@ export function* saveLayoutSaga(action: ReduxAction<{ isRetry?: boolean }>) { try { const currentPageId: string = yield select(getCurrentPageId); const currentPage: Page = yield select(getPageById(currentPageId)); - const isPreviewMode: boolean = yield select(selectCombinedPreviewMode); + const isPreviewMode: boolean = yield select(combinedPreviewModeSelector); const appMode: APP_MODE | undefined = yield select(getAppMode); @@ -1405,7 +1401,7 @@ export function* setCanvasCardsStateSaga(action: ReduxAction) { } export function* setPreviewModeInitSaga(action: ReduxAction) { - const isPreviewMode: boolean = yield select(selectCombinedPreviewMode); + const isPreviewMode: boolean = yield select(combinedPreviewModeSelector); if (action.payload) { // we animate out elements and then move to the canvas diff --git a/app/client/src/ce/sagas/index.tsx b/app/client/src/ce/sagas/index.tsx index af60e7dc4b93..844f9406af82 100644 --- a/app/client/src/ce/sagas/index.tsx +++ b/app/client/src/ce/sagas/index.tsx @@ -52,7 +52,6 @@ import sendSideBySideWidgetHoverAnalyticsEventSaga from "sagas/AnalyticsSaga"; /* Sagas that are registered by a module that is designed to be independent of the core platform */ import ternSagas from "sagas/TernSaga"; -import gitSagas from "git/sagas"; export const sagas = [ initSagas, @@ -107,5 +106,4 @@ export const sagas = [ ternSagas, ideSagas, sendSideBySideWidgetHoverAnalyticsEventSaga, - gitSagas, ]; diff --git a/app/client/src/ce/selectors/entitiesSelector.ts b/app/client/src/ce/selectors/entitiesSelector.ts index 57daa5964caf..a020e93ad13a 100644 --- a/app/client/src/ce/selectors/entitiesSelector.ts +++ b/app/client/src/ce/selectors/entitiesSelector.ts @@ -51,7 +51,7 @@ import { getEntityNameAndPropertyPath } from "ee/workers/Evaluation/evaluationUt import { getFormValues } from "redux-form"; import { TEMP_DATASOURCE_ID } from "constants/Datasource"; import type { Module } from "ee/constants/ModuleConstants"; -// import { getAnvilSpaceDistributionStatus } from "layoutSystems/anvil/integrations/selectors"; +import { getAnvilSpaceDistributionStatus } from "layoutSystems/anvil/integrations/selectors"; import { getCurrentWorkflowActions, getCurrentWorkflowJSActions, @@ -159,48 +159,47 @@ export const getDatasourceStructureById = ( return state.entities.datasources.structure[id]; }; -// ! git mod - the following function is not getting used /** * Selector to indicate if the widget name should be shown/drawn on canvas */ -// export const getShouldShowWidgetName = createSelector( -// (state: AppState) => state.ui.widgetDragResize.isResizing, -// (state: AppState) => state.ui.widgetDragResize.isDragging, -// (state: AppState) => state.ui.editor.isPreviewMode, -// (state: AppState) => state.ui.widgetDragResize.isAutoCanvasResizing, -// getAnvilSpaceDistributionStatus, -// // cannot import other selectors, breaks the app -// (state) => { -// const gitMetaData = -// state.ui.applications.currentApplication?.gitApplicationMetadata; -// const isGitConnected = !!(gitMetaData && gitMetaData?.remoteUrl); -// const currentBranch = gitMetaData?.branchName; -// const { protectedBranches = [] } = state.ui.gitSync; - -// if (!isGitConnected || !currentBranch) { -// return false; -// } else { -// return protectedBranches.includes(currentBranch); -// } -// }, -// ( -// isResizing, -// isDragging, -// isPreviewMode, -// isAutoCanvasResizing, -// isDistributingSpace, -// isProtectedMode, -// ) => { -// return ( -// !isResizing && -// !isDragging && -// !isPreviewMode && -// !isAutoCanvasResizing && -// !isDistributingSpace && -// !isProtectedMode -// ); -// }, -// ); +export const getShouldShowWidgetName = createSelector( + (state: AppState) => state.ui.widgetDragResize.isResizing, + (state: AppState) => state.ui.widgetDragResize.isDragging, + (state: AppState) => state.ui.editor.isPreviewMode, + (state: AppState) => state.ui.widgetDragResize.isAutoCanvasResizing, + getAnvilSpaceDistributionStatus, + // cannot import other selectors, breaks the app + (state) => { + const gitMetaData = + state.ui.applications.currentApplication?.gitApplicationMetadata; + const isGitConnected = !!(gitMetaData && gitMetaData?.remoteUrl); + const currentBranch = gitMetaData?.branchName; + const { protectedBranches = [] } = state.ui.gitSync; + + if (!isGitConnected || !currentBranch) { + return false; + } else { + return protectedBranches.includes(currentBranch); + } + }, + ( + isResizing, + isDragging, + isPreviewMode, + isAutoCanvasResizing, + isDistributingSpace, + isProtectedMode, + ) => { + return ( + !isResizing && + !isDragging && + !isPreviewMode && + !isAutoCanvasResizing && + !isDistributingSpace && + !isProtectedMode + ); + }, +); export const getDatasourceTableColumns = (datasourceId: string, tableName: string) => (state: AppState) => { diff --git a/app/client/src/components/BottomBar/index.tsx b/app/client/src/components/BottomBar/index.tsx index 1b7ad839d868..565844eacfb4 100644 --- a/app/client/src/components/BottomBar/index.tsx +++ b/app/client/src/components/BottomBar/index.tsx @@ -1,4 +1,5 @@ -import React, { useCallback } from "react"; +import React from "react"; +import QuickGitActions from "pages/Editor/gitSync/QuickGitActions"; import { DebuggerTrigger } from "components/editorComponents/Debugger"; import HelpButton from "pages/Editor/HelpButton"; import ManualUpgrades from "./ManualUpgrades"; @@ -15,30 +16,19 @@ import { softRefreshActions } from "actions/pluginActionActions"; import { START_SWITCH_ENVIRONMENT } from "ee/constants/messages"; import { getIsAnvilEnabledInCurrentApplication } from "layoutSystems/anvil/integrations/selectors"; import PackageUpgradeStatus from "ee/components/BottomBar/PackageUpgradeStatus"; -import OldGitQuickActions from "pages/Editor/gitSync/QuickGitActions"; -import { GitQuickActions } from "git"; -import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks"; - -function GitActions() { - const isGitModEnabled = useGitModEnabled(); - - return isGitModEnabled ? : ; -} export default function BottomBar() { const appId = useSelector(getCurrentApplicationId) || ""; + const isPreviewMode = useSelector(previewModeSelector); + const dispatch = useDispatch(); // We check if the current application is an Anvil application. // If it is an Anvil application, we remove the Git features from the bottomBar // as they donot yet work correctly with Anvil. const isAnvilEnabled = useSelector(getIsAnvilEnabledInCurrentApplication); - const isPreviewMode = useSelector(previewModeSelector); - const isGitEnabled = !isAnvilEnabled && !isPreviewMode; - - const dispatch = useDispatch(); - const onChangeEnv = useCallback(() => { + const onChangeEnv = () => { dispatch(softRefreshActions()); - }, [dispatch]); + }; return ( @@ -51,7 +41,7 @@ export default function BottomBar() { viewMode={isPreviewMode} /> )} - {isGitEnabled && } + {!isPreviewMode && !isAnvilEnabled && }
{!isPreviewMode && ( diff --git a/app/client/src/components/designSystems/appsmith/header/DeployLinkButton.tsx b/app/client/src/components/designSystems/appsmith/header/DeployLinkButton.tsx index 91eea09ab4ab..3257d962223b 100644 --- a/app/client/src/components/designSystems/appsmith/header/DeployLinkButton.tsx +++ b/app/client/src/components/designSystems/appsmith/header/DeployLinkButton.tsx @@ -1,7 +1,8 @@ import type { ReactNode } from "react"; -import React, { useCallback } from "react"; +import React from "react"; import { Menu, MenuItem, MenuContent, MenuTrigger } from "@appsmith/ads"; import { useSelector, useDispatch } from "react-redux"; +import { getIsGitConnected } from "selectors/gitSyncSelectors"; import { setIsGitSyncModalOpen } from "actions/gitSyncActions"; import { GitSyncModalTab } from "entities/GitSync"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; @@ -13,41 +14,6 @@ import { Button } from "@appsmith/ads"; import { KBEditorMenuItem } from "ee/pages/Editor/KnowledgeBase/KBEditorMenuItem"; import { useHasConnectToGitPermission } from "pages/Editor/gitSync/hooks/gitPermissionHooks"; import { getIsAnvilEnabledInCurrentApplication } from "layoutSystems/anvil/integrations/selectors"; -import { - useGitConnected, - useGitModEnabled, -} from "pages/Editor/gitSync/hooks/modHooks"; -import { GitDeployMenuItems as GitDeployMenuItemsNew } from "git"; - -function GitDeployMenuItems() { - const isGitModEnabled = useGitModEnabled(); - - const dispatch = useDispatch(); - const goToGitConnectionPopup = useCallback(() => { - AnalyticsUtil.logEvent("GS_CONNECT_GIT_CLICK", { - source: "Deploy button", - }); - - dispatch( - setIsGitSyncModalOpen({ - isOpen: true, - tab: GitSyncModalTab.GIT_CONNECTION, - }), - ); - }, [dispatch]); - - return isGitModEnabled ? ( - - ) : ( - - {CONNECT_TO_GIT_OPTION()} - - ); -} interface Props { trigger: ReactNode; @@ -55,13 +21,26 @@ interface Props { } export const DeployLinkButton = (props: Props) => { - const isGitConnected = useGitConnected(); + const dispatch = useDispatch(); + const isGitConnected = useSelector(getIsGitConnected); const isConnectToGitPermitted = useHasConnectToGitPermission(); // We check if the current application is an Anvil application. // If it is an Anvil application, we remove the Git features from the deploy button // as they donot yet work correctly with Anvil. const isAnvilEnabled = useSelector(getIsAnvilEnabledInCurrentApplication); + const goToGitConnectionPopup = () => { + AnalyticsUtil.logEvent("GS_CONNECT_GIT_CLICK", { + source: "Deploy button", + }); + dispatch( + setIsGitSyncModalOpen({ + isOpen: true, + tab: GitSyncModalTab.GIT_CONNECTION, + }), + ); + }; + return ( @@ -75,7 +54,13 @@ export const DeployLinkButton = (props: Props) => { {!isGitConnected && isConnectToGitPermitted && !isAnvilEnabled && ( - + + {CONNECT_TO_GIT_OPTION()} + )} ({ default: () =>
, })); -jest.mock("selectors/gitModSelectors", () => ({ - selectCombinedPreviewMode: jest.fn(() => false), -})); - const mockStore = configureStore([]); const storeState = { diff --git a/app/client/src/components/editorComponents/GlobalSearch/HelpBar.tsx b/app/client/src/components/editorComponents/GlobalSearch/HelpBar.tsx index 0a8fb41ffabe..c52eb62c9ef2 100644 --- a/app/client/src/components/editorComponents/GlobalSearch/HelpBar.tsx +++ b/app/client/src/components/editorComponents/GlobalSearch/HelpBar.tsx @@ -1,13 +1,14 @@ -import React, { useCallback } from "react"; +import React from "react"; import styled from "styled-components"; -import { useDispatch } from "react-redux"; +import { connect } from "react-redux"; import { getTypographyByKey, Text, TextType } from "@appsmith/ads-old"; import { Icon } from "@appsmith/ads"; import { setGlobalSearchCategory } from "actions/globalSearchActions"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import { modText } from "utils/helpers"; import { filterCategories, SEARCH_CATEGORY_ID } from "./utils"; -import { useGitProtectedMode } from "pages/Editor/gitSync/hooks/modHooks"; +import { protectedModeSelector } from "selectors/gitSyncSelectors"; +import type { AppState } from "ee/reducers"; const StyledHelpBar = styled.button` padding: 0 var(--ads-v2-spaces-3); @@ -41,18 +42,12 @@ const StyledHelpBar = styled.button` } `; -function HelpBar() { - const isProtectedMode = useGitProtectedMode(); - - const dispatch = useDispatch(); - - const toggleShowModal = useCallback(() => { - AnalyticsUtil.logEvent("OPEN_OMNIBAR", { source: "NAVBAR_CLICK" }); - dispatch( - setGlobalSearchCategory(filterCategories[SEARCH_CATEGORY_ID.INIT]), - ); - }, [dispatch]); +interface Props { + toggleShowModal: () => void; + isProtectedMode: boolean; +} +function HelpBar({ isProtectedMode, toggleShowModal }: Props) { return ( ({ + isProtectedMode: protectedModeSelector(state), +}); + +// TODO: Fix this the next time the file is edited +// eslint-disable-next-line @typescript-eslint/no-explicit-any +const mapDispatchToProps = (dispatch: any) => ({ + toggleShowModal: () => { + AnalyticsUtil.logEvent("OPEN_OMNIBAR", { source: "NAVBAR_CLICK" }); + dispatch( + setGlobalSearchCategory(filterCategories[SEARCH_CATEGORY_ID.INIT]), + ); + }, +}); + +export default connect(mapStateToProps, mapDispatchToProps)(HelpBar); diff --git a/app/client/src/components/gitContexts/GitApplicationContextProvider.tsx b/app/client/src/components/gitContexts/GitApplicationContextProvider.tsx deleted file mode 100644 index 728636e2f6dd..000000000000 --- a/app/client/src/components/gitContexts/GitApplicationContextProvider.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import React from "react"; -import { useSelector } from "react-redux"; -import { GitArtifactType, GitContextProvider } from "git"; -import { getCurrentApplication } from "ee/selectors/applicationSelectors"; -import { hasCreateNewAppPermission } from "ee/utils/permissionHelpers"; -import { setWorkspaceIdForImport } from "ee/actions/applicationActions"; -import { getCurrentAppWorkspace } from "ee/selectors/selectedWorkspaceSelectors"; -import { applicationStatusTransformer } from "git/artifact-helpers/application"; - -interface GitApplicationContextProviderProps { - children: React.ReactNode; -} - -export default function GitApplicationContextProvider({ - children, -}: GitApplicationContextProviderProps) { - const artifactType = GitArtifactType.Application; - const application = useSelector(getCurrentApplication); - const workspace = useSelector(getCurrentAppWorkspace); - const isCreateNewApplicationPermitted = hasCreateNewAppPermission( - workspace.userPermissions, - ); - - return ( - - {children} - - ); -} diff --git a/app/client/src/entities/Engine/AppEditorEngine.ts b/app/client/src/entities/Engine/AppEditorEngine.ts index a0bfb5372c20..f5b0f04b228b 100644 --- a/app/client/src/entities/Engine/AppEditorEngine.ts +++ b/app/client/src/entities/Engine/AppEditorEngine.ts @@ -1,4 +1,14 @@ import { fetchMockDatasources } from "actions/datasourceActions"; +import { + fetchGitProtectedBranchesInit, + fetchGitStatusInit, + remoteUrlInputValue, + resetPullMergeStatus, + fetchBranchesInit, + triggerAutocommitInitAction, + getGitMetadataInitAction, +} from "actions/gitSyncActions"; +import { restoreRecentEntitiesRequest } from "actions/globalSearchActions"; import { resetEditorSuccess } from "actions/initActions"; import { fetchAllPageEntityCompletion, @@ -14,6 +24,7 @@ import { ReduxActionErrorTypes, ReduxActionTypes, } from "ee/constants/ReduxActionConstants"; +import { addBranchParam } from "constants/routes"; import type { APP_MODE } from "entities/App"; import { call, fork, put, select, spawn } from "redux-saga/effects"; import type { EditConsolidatedApi } from "sagas/InitSagas"; @@ -22,9 +33,12 @@ import { reportSWStatus, waitForWidgetConfigBuild, } from "sagas/InitSagas"; -import { isGitPersistBranchEnabledSelector } from "selectors/gitSyncSelectors"; +import { + getCurrentGitBranch, + isGitPersistBranchEnabledSelector, +} from "selectors/gitSyncSelectors"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; -// import history from "utils/history"; +import history from "utils/history"; import type { AppEnginePayload } from "."; import AppEngine, { ActionsNotFoundError, @@ -57,24 +71,6 @@ import { endSpan, startNestedSpan } from "instrumentation/generateTraces"; import { getCurrentUser } from "selectors/usersSelectors"; import type { User } from "constants/userConstants"; import log from "loglevel"; -import { gitArtifactActions } from "git/store/gitArtifactSlice"; -import { restoreRecentEntitiesRequest } from "actions/globalSearchActions"; -import { - fetchBranchesInit, - fetchGitProtectedBranchesInit, - fetchGitStatusInit, - getGitMetadataInitAction, - remoteUrlInputValue, - resetPullMergeStatus, - triggerAutocommitInitAction, -} from "actions/gitSyncActions"; -import history from "utils/history"; -import { addBranchParam } from "constants/routes"; -import { - selectGitApplicationCurrentBranch, - selectGitModEnabled, -} from "selectors/gitModSelectors"; -import { applicationArtifact } from "git/artifact-helpers/application"; export default class AppEditorEngine extends AppEngine { constructor(mode: APP_MODE) { @@ -285,9 +281,6 @@ export default class AppEditorEngine extends AppEngine { const currentApplication: ApplicationPayload = yield select( getCurrentApplication, ); - const currentBranch: string | undefined = yield select( - selectGitApplicationCurrentBranch, - ); const isGitPersistBranchEnabled: boolean = yield select( isGitPersistBranchEnabledSelector, @@ -295,6 +288,7 @@ export default class AppEditorEngine extends AppEngine { if (isGitPersistBranchEnabled) { const currentUser: User = yield select(getCurrentUser); + const currentBranch: string = yield select(getCurrentGitBranch); if (currentUser?.email && currentApplication?.baseId && currentBranch) { yield setLatestGitBranchInLocal( @@ -323,15 +317,6 @@ export default class AppEditorEngine extends AppEngine { }); } - if (currentApplication?.id) { - yield put( - restoreRecentEntitiesRequest({ - applicationId: currentApplication.id, - branch: currentBranch, - }), - ); - } - if (isFirstTimeUserOnboardingComplete) { yield put({ type: ReduxActionTypes.SET_FIRST_TIME_USER_ONBOARDING_APPLICATION_IDS, @@ -374,32 +359,22 @@ export default class AppEditorEngine extends AppEngine { public *loadGit(applicationId: string, rootSpan: Span) { const loadGitSpan = startNestedSpan("AppEditorEngine.loadGit", rootSpan); - const isGitModEnabled: boolean = yield select(selectGitModEnabled); - if (isGitModEnabled) { - const currentApplication: ApplicationPayload = yield select( - getCurrentApplication, - ); + const branchInStore: string = yield select(getCurrentGitBranch); - yield put( - gitArtifactActions.initGitForEditor({ - artifactDef: applicationArtifact(currentApplication.baseId), - artifact: currentApplication, - }), - ); - } else { - const currentBranch: string = yield select( - selectGitApplicationCurrentBranch, - ); - - // init of temporary remote url from old application - yield put(remoteUrlInputValue({ tempRemoteUrl: "" })); - // add branch query to path and fetch status + yield put( + restoreRecentEntitiesRequest({ + applicationId, + branch: branchInStore, + }), + ); + // init of temporary remote url from old application + yield put(remoteUrlInputValue({ tempRemoteUrl: "" })); + // add branch query to path and fetch status - if (currentBranch) { - history.replace(addBranchParam(currentBranch)); - yield fork(this.loadGitInBackground); - } + if (branchInStore) { + history.replace(addBranchParam(branchInStore)); + yield fork(this.loadGitInBackground); } endSpan(loadGitSpan); @@ -408,6 +383,7 @@ export default class AppEditorEngine extends AppEngine { private *loadGitInBackground() { yield put(fetchBranchesInit()); yield put(fetchGitProtectedBranchesInit()); + yield put(fetchGitProtectedBranchesInit()); yield put(getGitMetadataInitAction()); yield put(triggerAutocommitInitAction()); yield put(fetchGitStatusInit({ compareRemote: true })); diff --git a/app/client/src/entities/Engine/index.ts b/app/client/src/entities/Engine/index.ts index b4eb39475753..aadfd66a4316 100644 --- a/app/client/src/entities/Engine/index.ts +++ b/app/client/src/entities/Engine/index.ts @@ -17,10 +17,10 @@ import history from "utils/history"; import type URLRedirect from "entities/URLRedirect/index"; import URLGeneratorFactory from "entities/URLRedirect/factory"; import { updateBranchLocally } from "actions/gitSyncActions"; +import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import { restoreIDEEditorViewMode } from "actions/ideActions"; import type { Span } from "instrumentation/types"; import { endSpan, startNestedSpan } from "instrumentation/generateTraces"; -import { selectGitApplicationCurrentBranch } from "selectors/gitModSelectors"; export interface AppEnginePayload { applicationId?: string; @@ -114,13 +114,12 @@ export default abstract class AppEngine { } const application: ApplicationPayload = yield select(getCurrentApplication); - const currentBranch: string | undefined = yield select( - selectGitApplicationCurrentBranch, - ); + const currentGitBranch: ReturnType = + yield select(getCurrentGitBranch); yield put( updateAppStore( - getPersistentAppStore(application.id, branch || currentBranch), + getPersistentAppStore(application.id, branch || currentGitBranch), ), ); const defaultPageId: string = yield select(getDefaultPageId); diff --git a/app/client/src/git/artifact-helpers/application/applicationArtifact.ts b/app/client/src/git/artifact-helpers/application/applicationArtifact.ts deleted file mode 100644 index 7337db575ac6..000000000000 --- a/app/client/src/git/artifact-helpers/application/applicationArtifact.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { GitArtifactType } from "git/constants/enums"; -import type { GitArtifactDef } from "git/store/types"; - -export default function applicationArtifact( - baseApplicationId: string, -): GitArtifactDef { - return { - artifactType: GitArtifactType.Application, - baseArtifactId: baseApplicationId, - }; -} diff --git a/app/client/src/git/artifact-helpers/application/index.ts b/app/client/src/git/artifact-helpers/application/index.ts deleted file mode 100644 index 579a99c7d975..000000000000 --- a/app/client/src/git/artifact-helpers/application/index.ts +++ /dev/null @@ -1,2 +0,0 @@ -export { default as applicationArtifact } from "./applicationArtifact"; -export { default as applicationStatusTransformer } from "./applicationStatusTransformer"; diff --git a/app/client/src/git/artifact-helpers/application/applicationStatusTransformer.ts b/app/client/src/git/artifactHelpers/application/statusTransformer.ts similarity index 62% rename from app/client/src/git/artifact-helpers/application/applicationStatusTransformer.ts rename to app/client/src/git/artifactHelpers/application/statusTransformer.ts index b803cddfea66..9ac95d9c424e 100644 --- a/app/client/src/git/artifact-helpers/application/applicationStatusTransformer.ts +++ b/app/client/src/git/artifactHelpers/application/statusTransformer.ts @@ -1,11 +1,6 @@ import type { FetchStatusResponseData } from "git/requests/fetchStatusRequest.types"; import { objectKeys } from "@appsmith/utils"; -import { - createMessage, - NOT_PUSHED_YET, - TRY_TO_PULL, -} from "ee/constants/messages"; -import type { StatusTreeStruct } from "git/components/StatusChanges/types"; +import type { StatusTreeStruct } from "git/components/StatusChanges/StatusTree"; const ICON_LOOKUP = { query: "query", @@ -13,29 +8,19 @@ const ICON_LOOKUP = { page: "page-line", datasource: "database-2-line", jsLib: "package", - settings: "settings-v3", - theme: "sip-line", - remote: "git-commit", - package: "package", - module: "package", - moduleInstance: "package", }; interface TreeNodeDef { subject: string; verb: string; type: keyof typeof ICON_LOOKUP; - extra?: string; } function createTreeNode(nodeDef: TreeNodeDef) { - let message = `${nodeDef.subject} ${nodeDef.verb}`; - - if (nodeDef.extra) { - message += ` ${nodeDef.extra}`; - } - - return { icon: ICON_LOOKUP[nodeDef.type], message }; + return { + icon: ICON_LOOKUP[nodeDef.type], + message: `${nodeDef.subject} ${nodeDef.verb}`, + }; } function determineVerbForDefs(defs: TreeNodeDef[]) { @@ -60,11 +45,7 @@ function createTreeNodeGroup(nodeDefs: TreeNodeDef[], subject: string) { return { icon: ICON_LOOKUP[nodeDefs[0].type], message: `${nodeDefs.length} ${subject} ${determineVerbForDefs(nodeDefs)}`, - children: nodeDefs - .sort((a, b) => - a.subject.localeCompare(b.subject, undefined, { sensitivity: "base" }), - ) - .map(createTreeNode), + children: nodeDefs.map(createTreeNode), }; } @@ -144,10 +125,6 @@ function statusPageTransformer(status: FetchStatusResponseData) { tree.push({ ...createTreeNode(pageDef), children }); }); - tree.sort((a, b) => - a.message.localeCompare(b.message, undefined, { sensitivity: "base" }), - ); - objectKeys(pageDefLookup).forEach((page) => { if (!pageEntityDefLookup[page]) { tree.push(createTreeNode(pageDefLookup[page])); @@ -209,121 +186,13 @@ function statusJsLibTransformer(status: FetchStatusResponseData) { return tree; } -function statusRemoteCountTransformer(status: FetchStatusResponseData) { - const { aheadCount, behindCount } = status; - const tree = [] as StatusTreeStruct[]; - - if (behindCount > 0) { - tree.push( - createTreeNode({ - subject: `${behindCount} commit${behindCount > 1 ? "s" : ""}`, - verb: "behind", - type: "remote", - extra: createMessage(TRY_TO_PULL), - }), - ); - } - - if (aheadCount > 0) { - tree.push( - createTreeNode({ - subject: `${aheadCount} commit${aheadCount > 1 ? "s" : ""}`, - verb: "ahead", - type: "remote", - extra: createMessage(NOT_PUSHED_YET), - }), - ); - } - - return tree; -} - -function statusSettingsTransformer(status: FetchStatusResponseData) { - const { modified } = status; - const tree = [] as StatusTreeStruct[]; - - if (modified.includes("application.json")) { - tree.push( - createTreeNode({ - subject: "Application settings", - verb: "modified", - type: "settings", - }), - ); - } - - return tree; -} - -function statusThemeTransformer(status: FetchStatusResponseData) { - const { modified } = status; - const tree = [] as StatusTreeStruct[]; - - if (modified.includes("theme.json")) { - tree.push( - createTreeNode({ - subject: "Theme", - verb: "modified", - type: "theme", - }), - ); - } - - return tree; -} - -function statusPackagesTransformer(status: FetchStatusResponseData) { - const { - modifiedModuleInstances = 0, - modifiedModules = 0, - modifiedPackages = 0, - } = status; - const tree = [] as StatusTreeStruct[]; - - if (modifiedPackages > 0) { - tree.push( - createTreeNode({ - subject: `${modifiedPackages} package${modifiedPackages > 1 ? "s" : ""}`, - verb: "modified", - type: "package", - }), - ); - } - - if (modifiedModules > 0) { - tree.push( - createTreeNode({ - subject: `${modifiedModules} module${modifiedModules > 1 ? "s" : ""}`, - verb: "modified", - type: "module", - }), - ); - } - - if (modifiedModuleInstances > 0) { - tree.push( - createTreeNode({ - subject: `${modifiedModuleInstances} module instance${modifiedModuleInstances > 1 ? "s" : ""}`, - verb: "modified", - type: "moduleInstance", - }), - ); - } - - return tree; -} - export default function applicationStatusTransformer( status: FetchStatusResponseData, ) { const tree = [ - ...statusRemoteCountTransformer(status), ...statusPageTransformer(status), ...statusDatasourceTransformer(status), ...statusJsLibTransformer(status), - ...statusSettingsTransformer(status), - ...statusThemeTransformer(status), - ...statusPackagesTransformer(status), ] as StatusTreeStruct[]; return tree; diff --git a/app/client/src/git/ce/components/GitModals/index.tsx b/app/client/src/git/ce/components/GitModals/index.tsx index 8bd094fa1ffe..a5fcb8c7be36 100644 --- a/app/client/src/git/ce/components/GitModals/index.tsx +++ b/app/client/src/git/ce/components/GitModals/index.tsx @@ -1,6 +1,5 @@ import ConflictErrorModal from "git/components/ConflictErrorModal"; import ConnectModal from "git/components/ConnectModal"; -import ConnectSuccessModal from "git/components/ConnectSuccessModal"; import DisableAutocommitModal from "git/components/DisableAutocommitModal"; import DisconnectModal from "git/components/DisconnectModal"; import OpsModal from "git/components/OpsModal"; @@ -11,7 +10,6 @@ function GitModals() { return ( <> - diff --git a/app/client/src/git/ce/hooks/useDefaultBranch.ts b/app/client/src/git/ce/hooks/useDefaultBranch.ts index 53a0f4a1fb01..6bc27c1c08c0 100644 --- a/app/client/src/git/ce/hooks/useDefaultBranch.ts +++ b/app/client/src/git/ce/hooks/useDefaultBranch.ts @@ -1,11 +1,17 @@ -import useArtifactSelector from "git/hooks/useArtifactSelector"; -import { selectDefaultBranch } from "git/store/selectors/gitArtifactSelectors"; +import { useGitContext } from "git/components/GitContextProvider"; +import { selectDefaultBranch } from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; +import { useSelector } from "react-redux"; function useDefaultBranch() { - const defaultBranch = useArtifactSelector(selectDefaultBranch); + const { artifactDef } = useGitContext(); + + const defaultBranch = useSelector((state: GitRootState) => + selectDefaultBranch(state, artifactDef), + ); return { - defaultBranch: defaultBranch ?? null, + defaultBranch, }; } diff --git a/app/client/src/git/components/ConflictErrorModal/ConflictErrorModalView.tsx b/app/client/src/git/components/ConflictErrorModal/ConflictErrorModalView.tsx index 5090e39c7643..d59ff023af40 100644 --- a/app/client/src/git/components/ConflictErrorModal/ConflictErrorModalView.tsx +++ b/app/client/src/git/components/ConflictErrorModal/ConflictErrorModalView.tsx @@ -6,7 +6,7 @@ import { CONFLICTS_FOUND_WHILE_PULLING_CHANGES, } from "ee/constants/messages"; -import { Button, Flex } from "@appsmith/ads"; +import { Button } from "@appsmith/ads"; import noop from "lodash/noop"; import ConflictError from "../ConflictError"; @@ -62,12 +62,18 @@ function ConflictErrorModalView({ >
- - +
+
{createMessage(CONFLICTS_FOUND_WHILE_PULLING_CHANGES)} - +
diff --git a/app/client/src/git/components/ConflictErrorModal/index.tsx b/app/client/src/git/components/ConflictErrorModal/index.tsx index a67a429aff35..db9568836032 100644 --- a/app/client/src/git/components/ConflictErrorModal/index.tsx +++ b/app/client/src/git/components/ConflictErrorModal/index.tsx @@ -3,11 +3,11 @@ import ConflictErrorModalView from "./ConflictErrorModalView"; import useOps from "git/hooks/useOps"; export default function ConflictErrorModal() { - const { isConflictErrorModalOpen, toggleConflictErrorModal } = useOps(); + const { conflictErrorModalOpen, toggleConflictErrorModal } = useOps(); return ( ); diff --git a/app/client/src/git/components/ConnectModal/ConnectInitialize/AddDeployKey.test.tsx b/app/client/src/git/components/ConnectModal/ConnectInitialize/AddDeployKey.test.tsx new file mode 100644 index 000000000000..176dc5247887 --- /dev/null +++ b/app/client/src/git/components/ConnectModal/ConnectInitialize/AddDeployKey.test.tsx @@ -0,0 +1,231 @@ +import React from "react"; +import { render, screen, fireEvent, waitFor } from "@testing-library/react"; +import type { AddDeployKeyProps } from "./AddDeployKey"; +import AddDeployKey from "./AddDeployKey"; +import AnalyticsUtil from "ee/utils/AnalyticsUtil"; +import "@testing-library/jest-dom"; + +jest.mock("ee/utils/AnalyticsUtil", () => ({ + logEvent: jest.fn(), +})); + +jest.mock("copy-to-clipboard", () => ({ + __esModule: true, + default: () => true, +})); + +const DEFAULT_DOCS_URL = + "https://docs.appsmith.com/advanced-concepts/version-control-with-git/connecting-to-git-repository"; + +const defaultProps: AddDeployKeyProps = { + connectError: null, + isLoading: false, + onChange: jest.fn(), + value: { + gitProvider: "github", + isAddedDeployKey: false, + remoteUrl: "git@github.com:owner/repo.git", + }, + fetchSSHKey: jest.fn(), + generateSSHKey: jest.fn(), + isFetchSSHKeyLoading: false, + isGenerateSSHKeyLoading: false, + sshPublicKey: "ecdsa-sha2-nistp256 AAAAE2VjZHNhAAAIBaj...", +}; + +describe("AddDeployKey Component", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it("renders without crashing and shows default UI", () => { + render(); + expect( + screen.getByText("Add deploy key & give write access"), + ).toBeInTheDocument(); + expect(screen.getByRole("combobox")).toBeInTheDocument(); + // Should show ECDSA by default since sshKeyPair includes "ecdsa" + expect( + screen.getByText(defaultProps.sshPublicKey as string), + ).toBeInTheDocument(); + expect( + screen.getByText("I've added the deploy key and gave it write access"), + ).toBeInTheDocument(); + }); + + it("calls fetchSSHKey if modal is open and not importing", () => { + render(); + expect(defaultProps.fetchSSHKey).toHaveBeenCalledTimes(1); + }); + + it("does not call fetchSSHKey if importing", () => { + render(); + expect(defaultProps.fetchSSHKey).not.toHaveBeenCalled(); + }); + + it("shows dummy key loader if loading keys", () => { + render( + , + ); + // The actual key text should not be displayed + expect(screen.queryByText("ecdsa-sha2-nistp256")).not.toBeInTheDocument(); + }); + + it("changes SSH key type when user selects a different type and triggers generateSSHKey if needed", async () => { + const generateSSHKey = jest.fn(); + + render( + , + ); + + fireEvent.mouseDown(screen.getByRole("combobox")); + const rsaOption = screen.getByText("RSA 4096"); + + fireEvent.click(rsaOption); + + await waitFor(() => { + expect(generateSSHKey).toHaveBeenCalledWith("RSA", false); + }); + }); + + it("displays a generic error when errorData is provided and error code is not AE-GIT-4032 or AE-GIT-4033", () => { + // eslint-disable-next-line react-perf/jsx-no-new-object-as-prop + const connectError = { + code: "GENERIC-ERROR", + errorType: "Some Error", + message: "Something went wrong", + }; + + render(); + expect(screen.getByText("Some Error")).toBeInTheDocument(); + expect(screen.getByText("Something went wrong")).toBeInTheDocument(); + }); + + it("displays a misconfiguration error if error code is AE-GIT-4032", () => { + // eslint-disable-next-line react-perf/jsx-no-new-object-as-prop + const connectError = { + code: "AE-GIT-4032", + errorType: "SSH Key Error", + message: "SSH Key misconfiguration", + }; + + render(); + expect(screen.getByText("SSH key misconfiguration")).toBeInTheDocument(); + expect( + screen.getByText( + "It seems that your SSH key hasn't been added to your repository. To proceed, please revisit the steps below and configure your SSH key correctly.", + ), + ).toBeInTheDocument(); + }); + + it("invokes onChange callback when checkbox is toggled", () => { + const onChange = jest.fn(); + + render(); + const checkbox = screen.getByTestId("t--added-deploy-key-checkbox"); + + fireEvent.click(checkbox); + expect(onChange).toHaveBeenCalledWith({ isAddedDeployKey: true }); + }); + + it("calls AnalyticsUtil on copy button click", () => { + render(); + const copyButton = screen.getByTestId("t--copy-generic"); + + fireEvent.click(copyButton); + expect(AnalyticsUtil.logEvent).toHaveBeenCalledWith( + "GS_COPY_SSH_KEY_BUTTON_CLICK", + ); + }); + + it("hides copy button when connectLoading is true", () => { + render(); + expect(screen.queryByTestId("t--copy-generic")).not.toBeInTheDocument(); + }); + + it("shows repository settings link if gitProvider is known and not 'others'", () => { + render(); + const link = screen.getByRole("link", { name: "repository settings." }); + + expect(link).toHaveAttribute( + "href", + "https://github.com/owner/repo/settings/keys", + ); + }); + + it("does not show repository link if gitProvider = 'others'", () => { + render( + , + ); + expect( + screen.queryByRole("link", { name: "repository settings." }), + ).not.toBeInTheDocument(); + }); + + it("shows collapsible section if gitProvider is not 'others'", () => { + render( + , + ); + expect( + screen.getByText("How to paste SSH Key in repo and give write access?"), + ).toBeInTheDocument(); + expect(screen.getByAltText("Add deploy key in gitlab")).toBeInTheDocument(); + }); + + it("does not display collapsible if gitProvider = 'others'", () => { + render( + , + ); + expect( + screen.queryByText("How to paste SSH Key in repo and give write access?"), + ).not.toBeInTheDocument(); + }); + + it("uses default documentation link if none provided", () => { + render(); + const docsLink = screen.getByRole("link", { name: "Read Docs" }); + + expect(docsLink).toHaveAttribute("href", DEFAULT_DOCS_URL); + }); + + it("generates SSH key if none is present and conditions are met", async () => { + const fetchSSHKey = jest.fn(); + const generateSSHKey = jest.fn(); + + render( + , + ); + + expect(fetchSSHKey).toHaveBeenCalledTimes(1); + + await waitFor(() => { + expect(generateSSHKey).toHaveBeenCalledWith("ECDSA", false); + }); + }); +}); diff --git a/app/client/src/git/components/ConnectModal/ConnectInitialize/AddDeployKey.tsx b/app/client/src/git/components/ConnectModal/ConnectInitialize/AddDeployKey.tsx index 09dcb7df1122..75a4a7a50e86 100644 --- a/app/client/src/git/components/ConnectModal/ConnectInitialize/AddDeployKey.tsx +++ b/app/client/src/git/components/ConnectModal/ConnectInitialize/AddDeployKey.tsx @@ -135,83 +135,93 @@ const DEPLOY_DOCS_URL = "https://docs.appsmith.com/advanced-concepts/version-control-with-git/connecting-to-git-repository"; export interface AddDeployKeyProps { - error: GitApiError | null; - isSubmitLoading: boolean; - isSSHKeyLoading: boolean; + connectError: GitApiError | null; + fetchSSHKey: () => void; + generateSSHKey: (keyType: string, isImport?: boolean) => void; + isFetchSSHKeyLoading: boolean; + isGenerateSSHKeyLoading: boolean; + isImport?: boolean; + isLoading: boolean; onChange: (args: Partial) => void; - onFetchSSHKey?: () => void; - onGenerateSSHKey: (keyType: string) => void; sshPublicKey: string | null; value: Partial | null; } function AddDeployKey({ - error = null, - isSSHKeyLoading = false, - isSubmitLoading = false, + connectError = null, + fetchSSHKey = noop, + generateSSHKey = noop, + isFetchSSHKeyLoading = false, + isGenerateSSHKeyLoading = false, + isImport = false, + isLoading = false, onChange = noop, - onFetchSSHKey = noop, - onGenerateSSHKey = noop, sshPublicKey = null, value = null, }: AddDeployKeyProps) { const [fetched, setFetched] = useState(false); - const [keyType, setKeyType] = useState(); + const [sshKeyType, setSshKeyType] = useState(); useEffect( function fetchKeyPairOnInitEffect() { - if (!fetched) { - onFetchSSHKey(); - setFetched(true); - // doesn't support callback anymore - // fetchSSHKey({ - // onSuccessCallback: () => { - // setFetched(true); - // }, - // onErrorCallback: () => { - // setFetched(true); - // }, - // }); + if (!isImport) { + if (!fetched) { + fetchSSHKey(); + setFetched(true); + // doesn't support callback anymore + // fetchSSHKey({ + // onSuccessCallback: () => { + // setFetched(true); + // }, + // onErrorCallback: () => { + // setFetched(true); + // }, + // }); + } + } else { + if (!fetched) { + setFetched(true); + } } }, - [fetched, onFetchSSHKey], + [isImport, fetched, fetchSSHKey], ); useEffect( function setSSHKeyTypeonInitEffect() { - if (fetched && !isSSHKeyLoading) { + if (fetched && !isFetchSSHKeyLoading) { if (sshPublicKey && sshPublicKey.includes("rsa")) { - setKeyType("RSA"); + setSshKeyType("RSA"); } else if ( !sshPublicKey && value?.remoteUrl && value.remoteUrl.toString().toLocaleLowerCase().includes("azure") ) { - setKeyType("RSA"); + setSshKeyType("RSA"); } else { - setKeyType("ECDSA"); + setSshKeyType("ECDSA"); } } }, - [fetched, sshPublicKey, value?.remoteUrl, isSSHKeyLoading], + [fetched, sshPublicKey, isFetchSSHKeyLoading, value?.remoteUrl], ); useEffect( function generateSSHOnInitEffect() { if ( - (keyType && !sshPublicKey) || - (keyType && !sshPublicKey?.includes(keyType.toLowerCase())) + (sshKeyType && !sshPublicKey) || + (sshKeyType && !sshPublicKey?.includes(sshKeyType.toLowerCase())) ) { - onGenerateSSHKey(keyType); + generateSSHKey(sshKeyType, isImport); // doesn't support callback anymore - // generateSSHKey(keyType, { + // generateSSHKey(sshKeyType, { // onSuccessCallback: () => { // toast.show("SSH Key generated successfully", { kind: "success" }); // }, // }); } }, - [keyType, sshPublicKey, onGenerateSSHKey], + [sshKeyType, sshPublicKey, generateSSHKey, isImport], ); const repositorySettingsUrl = getRepositorySettingsUrl( @@ -219,7 +229,7 @@ function AddDeployKey({ value?.remoteUrl, ); - // const loading = isFetchSSHKeyLoading || isGenerateSSHKeyLoading; + const loading = isFetchSSHKeyLoading || isGenerateSSHKeyLoading; const onCopy = useCallback(() => { AnalyticsUtil.logEvent("GS_COPY_SSH_KEY_BUTTON_CLICK"); @@ -234,19 +244,19 @@ function AddDeployKey({ return ( <> - {error && - error.code !== "AE-GIT-4033" && - error.code !== "AE-GIT-4032" && ( + {connectError && + connectError.code !== "AE-GIT-4033" && + connectError.code !== "AE-GIT-4032" && ( - {error.errorType} + {connectError.errorType} - {error.message} + {connectError.message} )} {/* hardcoding message because server doesn't support feature flag. Will change this later */} - {error && error.code === "AE-GIT-4032" && ( + {connectError && connectError.code === "AE-GIT-4032" && ( {createMessage(ERROR_SSH_KEY_MISCONF_TITLE)} @@ -291,20 +301,20 @@ function AddDeployKey({ Now, give write access to it. - + - {!isSSHKeyLoading ? ( + {!loading ? ( - {keyType} + {sshKeyType} {sshPublicKey} - {!isSubmitLoading && ( + {!isLoading && ( { @@ -168,19 +169,19 @@ describe("ChooseGitProvider Component", () => { }); it("clicking on 'Import via git' link calls onImportFromCalloutLinkClick", () => { - const onOpenImport = jest.fn(); + const mockSetImportWorkspaceId = jest.fn(); render( , ); fireEvent.click(screen.getByText("Import via git")); - expect(onOpenImport).toHaveBeenCalledTimes(1); + expect(mockSetImportWorkspaceId).toHaveBeenCalledTimes(1); }); it("when isImport = true, shows a checkbox for existing repo", () => { @@ -213,11 +214,11 @@ describe("ChooseGitProvider Component", () => { }); it("respects canCreateNewArtifact and device conditions for links", () => { - // If onOpenImport is null, "Import via git" should not appear even if conditions are met + // If canCreateNewArtifact is false, "Import via git" should not appear even if conditions are met render( , ); diff --git a/app/client/src/git/components/ConnectModal/ConnectInitialize/ChooseGitProvider.tsx b/app/client/src/git/components/ConnectModal/ConnectInitialize/ChooseGitProvider.tsx index b8aceed5baf4..d24c31de20de 100644 --- a/app/client/src/git/components/ConnectModal/ConnectInitialize/ChooseGitProvider.tsx +++ b/app/client/src/git/components/ConnectModal/ConnectInitialize/ChooseGitProvider.tsx @@ -34,7 +34,9 @@ import { } from "ee/constants/messages"; import log from "loglevel"; import type { ConnectFormDataState } from "./types"; +import history from "utils/history"; import { useIsMobileDevice } from "utils/hooks/useDeviceDetect"; +import AnalyticsUtil from "ee/utils/AnalyticsUtil"; const WellInnerContainer = styled.div` padding-left: 16px; @@ -51,17 +53,21 @@ export type GitProvider = (typeof GIT_PROVIDERS)[number]; interface ChooseGitProviderProps { artifactType: string; + isCreateArtifactPermitted: boolean; isImport?: boolean; onChange: (args: Partial) => void; - onOpenImport: (() => void) | null; + setImportWorkspaceId: () => void; + toggleConnectModal: (open: boolean) => void; value: Partial; } function ChooseGitProvider({ artifactType, + isCreateArtifactPermitted, isImport = false, onChange = noop, - onOpenImport = null, + setImportWorkspaceId = noop, + toggleConnectModal = noop, value = {}, }: ChooseGitProviderProps) { const isMobile = useIsMobileDevice(); @@ -91,19 +97,19 @@ function ChooseGitProvider({ [onChange], ); - // const handleClickOnImport = useCallback(() => { - // toggleConnectModal(false); - // history.push("/applications"); - // setImportWorkspaceId(); - // toggleConnectModal(true); - // AnalyticsUtil.logEvent("GS_IMPORT_VIA_GIT_DURING_GC"); - // }, [setImportWorkspaceId, toggleConnectModal]); + const handleClickOnImport = useCallback(() => { + toggleConnectModal(false); + history.push("/applications"); + setImportWorkspaceId(); + toggleConnectModal(true); + AnalyticsUtil.logEvent("GS_IMPORT_VIA_GIT_DURING_GC"); + }, [setImportWorkspaceId, toggleConnectModal]); const importCalloutLinks = useMemo(() => { - return !isMobile && onOpenImport && typeof onOpenImport === "function" - ? [{ children: "Import via git", onClick: onOpenImport }] + return !isMobile && isCreateArtifactPermitted + ? [{ children: "Import via git", onClick: handleClickOnImport }] : []; - }, [onOpenImport, isMobile]); + }, [handleClickOnImport, isCreateArtifactPermitted, isMobile]); return ( <> @@ -202,7 +208,7 @@ function ChooseGitProvider({ )} - {!isImport && onOpenImport && value?.gitEmptyRepoExists === "no" ? ( + {!isImport && value?.gitEmptyRepoExists === "no" ? ( {createMessage(IMPORT_ARTIFACT_IF_NOT_EMPTY, artifactType)} diff --git a/app/client/src/git/components/ConnectModal/ConnectInitialize/GenerateSSH.test.tsx b/app/client/src/git/components/ConnectModal/ConnectInitialize/GenerateSSH.test.tsx index fc53b8531a4f..d082ee44546d 100644 --- a/app/client/src/git/components/ConnectModal/ConnectInitialize/GenerateSSH.test.tsx +++ b/app/client/src/git/components/ConnectModal/ConnectInitialize/GenerateSSH.test.tsx @@ -16,7 +16,7 @@ const defaultProps = { gitProvider: "github" as GitProvider, remoteUrl: "", }, - error: null, + connectError: null, }; describe("GenerateSSH Component", () => { @@ -38,7 +38,7 @@ describe("GenerateSSH Component", () => { code: "AE-GIT-4033", }; - render(); + render(); expect( screen.getByText("The repo you added isn't empty"), ).toBeInTheDocument(); @@ -55,7 +55,7 @@ describe("GenerateSSH Component", () => { code: "SOME_OTHER_ERROR", }; - render(); + render(); expect( screen.queryByText("The repo you added isn't empty"), ).not.toBeInTheDocument(); diff --git a/app/client/src/git/components/ConnectModal/ConnectInitialize/GenerateSSH.tsx b/app/client/src/git/components/ConnectModal/ConnectInitialize/GenerateSSH.tsx index 6a8b7536f903..5318b0bd8554 100644 --- a/app/client/src/git/components/ConnectModal/ConnectInitialize/GenerateSSH.tsx +++ b/app/client/src/git/components/ConnectModal/ConnectInitialize/GenerateSSH.tsx @@ -41,13 +41,17 @@ interface GenerateSSHState { interface GenerateSSHProps { onChange: (args: Partial) => void; value: Partial; - error: GitApiError | null; + connectError: GitApiError | null; } const CONNECTING_TO_GIT_DOCS_URL = "https://docs.appsmith.com/advanced-concepts/version-control-with-git/connecting-to-git-repository"; -function GenerateSSH({ error, onChange = noop, value = {} }: GenerateSSHProps) { +function GenerateSSH({ + connectError, + onChange = noop, + value = {}, +}: GenerateSSHProps) { const [isTouched, setIsTouched] = useState(false); const isInvalid = isTouched && @@ -65,7 +69,7 @@ function GenerateSSH({ error, onChange = noop, value = {} }: GenerateSSHProps) { return ( <> {/* hardcoding messages because server doesn't support feature flag. Will change this later */} - {error && error?.code === "AE-GIT-4033" && ( + {connectError && connectError?.code === "AE-GIT-4033" && ( {createMessage(ERROR_REPO_NOT_EMPTY_TITLE)} diff --git a/app/client/src/git/components/ConnectModal/ConnectInitialize/index.test.tsx b/app/client/src/git/components/ConnectModal/ConnectInitialize/index.test.tsx index 21f46cf03525..6ac8b83b0761 100644 --- a/app/client/src/git/components/ConnectModal/ConnectInitialize/index.test.tsx +++ b/app/client/src/git/components/ConnectModal/ConnectInitialize/index.test.tsx @@ -21,15 +21,19 @@ jest.mock("@appsmith/ads", () => ({ const defaultProps = { artifactType: "Application", - error: null, - onFetchSSHKey: jest.fn(), - onGenerateSSHKey: jest.fn(), - isSubmitLoading: false, - isSSHKeyLoading: false, + connect: jest.fn(), + connectError: null, + fetchSSHKey: jest.fn(), + generateSSHKey: jest.fn(), + gitImport: jest.fn(), + isConnectLoading: false, + isFetchSSHKeyLoading: false, + isGenerateSSHKeyLoading: false, + isGitImportLoading: false, isImport: false, - onSubmit: jest.fn(), - onOpenImport: null, sshPublicKey: "ssh-rsa AAAAB3...", + isCreateArtifactPermitted: true, + setImportWorkspaceId: jest.fn(), toggleConnectModal: jest.fn(), }; @@ -122,7 +126,7 @@ describe("ConnectModal Component", () => { completeAddDeployKeyStep(); await waitFor(() => { - expect(defaultProps.onSubmit).toHaveBeenCalledWith( + expect(defaultProps.connect).toHaveBeenCalledWith( expect.objectContaining({ remoteUrl: "git@example.com:user/repo.git", gitProfile: { @@ -135,14 +139,14 @@ describe("ConnectModal Component", () => { }); }); - it("calls onSubmit on completing AddDeployKey step in import mode", async () => { + it("calls gitImport on completing AddDeployKey step in import mode", async () => { render(); completeChooseProviderStep(true); completeGenerateSSHKeyStep(); completeAddDeployKeyStep(); await waitFor(() => { - expect(defaultProps.onSubmit).toHaveBeenCalledWith( + expect(defaultProps.gitImport).toHaveBeenCalledWith( expect.objectContaining({ remoteUrl: "git@example.com:user/repo.git", gitProfile: { @@ -163,11 +167,13 @@ describe("ConnectModal Component", () => { message: "", }; - rerender(); + rerender( + , + ); }); const { rerender } = render( - , + , ); completeChooseProviderStep(); @@ -210,7 +216,7 @@ describe("ConnectModal Component", () => { }); it("renders loading state and removes buttons when connecting", () => { - render(); + render(); expect( screen.getByText("Please wait while we connect to Git..."), ).toBeInTheDocument(); diff --git a/app/client/src/git/components/ConnectModal/ConnectInitialize/index.tsx b/app/client/src/git/components/ConnectModal/ConnectInitialize/index.tsx index 72ba9d797c1d..05046d250d09 100644 --- a/app/client/src/git/components/ConnectModal/ConnectInitialize/index.tsx +++ b/app/client/src/git/components/ConnectModal/ConnectInitialize/index.tsx @@ -71,31 +71,41 @@ interface StyledModalFooterProps { loading?: boolean; } -export interface ConnectInitializeProps { +interface ConnectModalViewProps { artifactType: string; - error: GitApiError | null; + connect: (params: ConnectRequestParams) => void; + connectError: GitApiError | null; + fetchSSHKey: () => void; + generateSSHKey: (keyType: string) => void; + gitImport: (params: GitImportRequestParams) => void; + isConnectLoading: boolean; + isCreateArtifactPermitted: boolean; + isFetchSSHKeyLoading: boolean; + isGenerateSSHKeyLoading: boolean; + isGitImportLoading: boolean; isImport: boolean; - isSSHKeyLoading: boolean; - isSubmitLoading: boolean; - onFetchSSHKey: () => void; - onGenerateSSHKey: (keyType: string) => void; - onOpenImport: (() => void) | null; - onSubmit: (params: ConnectRequestParams | GitImportRequestParams) => void; + setImportWorkspaceId: () => void; sshPublicKey: string | null; + toggleConnectModal: (open: boolean) => void; } function ConnectInitialize({ artifactType, - error = null, + connect = noop, + connectError = null, + fetchSSHKey = noop, + generateSSHKey = noop, + gitImport = noop, + isConnectLoading = false, + isCreateArtifactPermitted = false, + isFetchSSHKeyLoading = false, + isGenerateSSHKeyLoading = false, + isGitImportLoading = false, isImport = false, - isSSHKeyLoading = false, - isSubmitLoading = false, - onFetchSSHKey = noop, - onGenerateSSHKey = noop, - onOpenImport = null, - onSubmit = noop, + setImportWorkspaceId = noop, sshPublicKey = null, -}: ConnectInitializeProps) { + toggleConnectModal = noop, +}: ConnectModalViewProps) { const nextStepText = { [GIT_CONNECT_STEPS.CHOOSE_PROVIDER]: createMessage(CONFIGURE_GIT), [GIT_CONNECT_STEPS.GENERATE_SSH_KEY]: createMessage(GENERATE_SSH_KEY_STEP), @@ -117,8 +127,8 @@ function ConnectInitialize({ GIT_CONNECT_STEPS.CHOOSE_PROVIDER, ); - // const isSubmitLoading = - // (!isImport && isConnectLoading) || (isImport && isGitImportLoading); + const isLoading = + (!isImport && isConnectLoading) || (isImport && isGitImportLoading); const currentIndex = steps.findIndex((s) => s.key === activeStep); @@ -171,40 +181,43 @@ function ConnectInitialize({ }; if (formData.remoteUrl) { - onSubmit({ - remoteUrl: formData.remoteUrl, - gitProfile, - }); - // if (!isImport) { - // AnalyticsUtil.logEvent( - // "GS_CONNECT_BUTTON_ON_GIT_SYNC_MODAL_CLICK", - // { repoUrl: formData?.remoteUrl, connectFlow: "v2" }, - // ); - // connect({ - // remoteUrl: formData.remoteUrl, - // gitProfile, - // }); - // } else { - // gitImport({ - // remoteUrl: formData.remoteUrl, - // gitProfile, - // }); - // } + if (!isImport) { + AnalyticsUtil.logEvent( + "GS_CONNECT_BUTTON_ON_GIT_SYNC_MODAL_CLICK", + { repoUrl: formData?.remoteUrl, connectFlow: "v2" }, + ); + connect({ + remoteUrl: formData.remoteUrl, + gitProfile, + }); + } else { + gitImport({ + remoteUrl: formData.remoteUrl, + gitProfile, + }); + } } break; } } } - }, [activeStep, currentIndex, formData.remoteUrl, onSubmit]); + }, [ + activeStep, + connect, + currentIndex, + formData.remoteUrl, + gitImport, + isImport, + ]); useEffect( function changeStepOnErrorEffect() { - if (error?.code === GitErrorCodes.REPO_NOT_EMPTY) { + if (connectError?.code === GitErrorCodes.REPO_NOT_EMPTY) { setActiveStep(GIT_CONNECT_STEPS.GENERATE_SSH_KEY); } }, - [error?.code], + [connectError?.code], ); return ( @@ -223,38 +236,45 @@ function ConnectInitialize({ {activeStep === GIT_CONNECT_STEPS.CHOOSE_PROVIDER && ( )} {activeStep === GIT_CONNECT_STEPS.GENERATE_SSH_KEY && ( - + )} {activeStep === GIT_CONNECT_STEPS.ADD_DEPLOY_KEY && ( )} - - {isSubmitLoading && ( + + {isLoading && ( )} - {!isSubmitLoading && ( + {!isLoading && ( - - - - + <> + + + + + + + + + ); } -export default ConnectSuccessModalView; +export default ConnectSuccess; diff --git a/app/client/src/git/components/ConnectModal/index.tsx b/app/client/src/git/components/ConnectModal/index.tsx index 651626e933a7..a8f268132d95 100644 --- a/app/client/src/git/components/ConnectModal/index.tsx +++ b/app/client/src/git/components/ConnectModal/index.tsx @@ -1,78 +1,67 @@ -import React, { useCallback } from "react"; +import React from "react"; import ConnectModalView from "./ConnectModalView"; import { useGitContext } from "../GitContextProvider"; import useConnect from "git/hooks/useConnect"; -import { GitArtifactType } from "git/constants/enums"; -import type { ConnectRequestParams } from "git/requests/connectRequest.types"; -import AnalyticsUtil from "ee/utils/AnalyticsUtil"; -import useSSHKey from "git/hooks/useSSHKey"; -import useImport from "git/hooks/useImport"; -import history from "utils/history"; +import useMetadata from "git/hooks/useMetadata"; +import useSettings from "git/hooks/useSettings"; -function ConnectModal() { +interface ConnectModalProps { + isImport?: boolean; +} + +function ConnectModal({ isImport = false }: ConnectModalProps) { const { artifactDef, isCreateArtifactPermitted, setImportWorkspaceId } = useGitContext(); const { connect, connectError, - isConnectLoading, - isConnectModalOpen, - toggleConnectModal, - } = useConnect(); - const { toggleImportModal } = useImport(); - const { fetchSSHKey, generateSSHKey, + gitImport, + isConnectLoading, + isConnectModalOpen, isFetchSSHKeyLoading, isGenerateSSHKeyLoading, + isGitImportLoading, resetFetchSSHKey, resetGenerateSSHKey, sshKey, - } = useSSHKey(); + toggleConnectModal, + } = useConnect(); + const { isGitConnected, metadata } = useMetadata(); + const { toggleSettingsModal } = useSettings(); - const artifactType = artifactDef?.artifactType ?? GitArtifactType.Application; + const { artifactType } = artifactDef; const sshPublicKey = sshKey?.publicKey ?? null; - const isSSHKeyLoading = isFetchSSHKeyLoading || isGenerateSSHKeyLoading; - - const onSubmit = useCallback( - (params: ConnectRequestParams) => { - AnalyticsUtil.logEvent("GS_CONNECT_BUTTON_ON_GIT_SYNC_MODAL_CLICK", { - repoUrl: params?.remoteUrl, - connectFlow: "v2", - }); - connect(params); - }, - [connect], - ); - - const onOpenImport = useCallback(() => { - toggleConnectModal(false); - history.push("/applications"); - setImportWorkspaceId(); - toggleImportModal(true); - AnalyticsUtil.logEvent("GS_IMPORT_VIA_GIT_DURING_GC"); - }, [setImportWorkspaceId, toggleConnectModal, toggleImportModal]); - - const resetSSHKey = useCallback(() => { - resetFetchSSHKey(); - resetGenerateSSHKey(); - }, [resetFetchSSHKey, resetGenerateSSHKey]); + const remoteUrl = metadata?.remoteUrl ?? null; + const repoName = metadata?.repoName ?? null; + const defaultBranch = metadata?.defaultBranchName ?? null; return ( ); } diff --git a/app/client/src/git/components/ConnectSuccessModal/index.tsx b/app/client/src/git/components/ConnectSuccessModal/index.tsx deleted file mode 100644 index c492e5aa4bb3..000000000000 --- a/app/client/src/git/components/ConnectSuccessModal/index.tsx +++ /dev/null @@ -1,29 +0,0 @@ -import React from "react"; -import ConnectSuccessModalView from "./ConnectSuccessModalView"; -import useMetadata from "git/hooks/useMetadata"; -import useConnect from "git/hooks/useConnect"; -import useSettings from "git/hooks/useSettings"; - -function ConnectSuccessModal() { - const { isConnectSuccessModalOpen, toggleConnectSuccessModal } = useConnect(); - const { toggleSettingsModal } = useSettings(); - - const { metadata } = useMetadata(); - - const remoteUrl = metadata?.remoteUrl ?? null; - const repoName = metadata?.repoName ?? null; - const defaultBranch = metadata?.defaultBranchName ?? null; - - return ( - - ); -} - -export default ConnectSuccessModal; diff --git a/app/client/src/git/components/DeployMenuItems/DeployMenuItemsView.tsx b/app/client/src/git/components/DeployMenuItems/DeployMenuItemsView.tsx deleted file mode 100644 index 09ce5be3178a..000000000000 --- a/app/client/src/git/components/DeployMenuItems/DeployMenuItemsView.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React, { useCallback } from "react"; -import { MenuItem } from "@appsmith/ads"; -import { CONNECT_TO_GIT_OPTION, createMessage } from "ee/constants/messages"; -import AnalyticsUtil from "ee/utils/AnalyticsUtil"; -import noop from "lodash/noop"; - -interface DeployMenuItemsViewProps { - toggleConnectModal: (open: boolean) => void; -} - -function DeployMenuItemsView({ - toggleConnectModal = noop, -}: DeployMenuItemsViewProps) { - const handleClickOnConnect = useCallback(() => { - AnalyticsUtil.logEvent("GS_CONNECT_GIT_CLICK", { - source: "Deploy button", - }); - toggleConnectModal(true); - }, [toggleConnectModal]); - - return ( - - {createMessage(CONNECT_TO_GIT_OPTION)} - - ); -} - -export default DeployMenuItemsView; diff --git a/app/client/src/git/components/DeployMenuItems/index.tsx b/app/client/src/git/components/DeployMenuItems/index.tsx deleted file mode 100644 index de6c61f9af9b..000000000000 --- a/app/client/src/git/components/DeployMenuItems/index.tsx +++ /dev/null @@ -1,11 +0,0 @@ -import useConnect from "git/hooks/useConnect"; -import React from "react"; -import DeployMenuItemsView from "./DeployMenuItemsView"; - -function DeployMenuItems() { - const { toggleConnectModal } = useConnect(); - - return ; -} - -export default DeployMenuItems; diff --git a/app/client/src/git/components/GitContextProvider/index.tsx b/app/client/src/git/components/GitContextProvider/index.tsx index 89736de113eb..4d4b88b4f6ad 100644 --- a/app/client/src/git/components/GitContextProvider/index.tsx +++ b/app/client/src/git/components/GitContextProvider/index.tsx @@ -2,12 +2,14 @@ import React, { createContext, useCallback, useContext, useMemo } from "react"; import type { GitArtifactType } from "git/constants/enums"; import type { ApplicationPayload } from "entities/Application"; import type { FetchStatusResponseData } from "git/requests/fetchStatusRequest.types"; +import type { StatusTreeStruct } from "../StatusChanges/StatusTree"; import { useDispatch } from "react-redux"; -import type { GitArtifactDef } from "git/store/types"; -import type { StatusTreeStruct } from "../StatusChanges/types"; export interface GitContextValue { - artifactDef: GitArtifactDef | null; + artifactDef: { + artifactType: keyof typeof GitArtifactType; + baseArtifactId: string; + }; artifact: ApplicationPayload | null; statusTransformer: ( status: FetchStatusResponseData, @@ -25,8 +27,8 @@ export const useGitContext = () => { }; interface GitContextProviderProps { - artifactType: keyof typeof GitArtifactType | null; - baseArtifactId: string | null; + artifactType: keyof typeof GitArtifactType; + baseArtifactId: string; artifact: ApplicationPayload | null; isCreateArtifactPermitted: boolean; setWorkspaceIdForImport: (params: { @@ -48,13 +50,10 @@ export default function GitContextProvider({ setWorkspaceIdForImport, statusTransformer, }: GitContextProviderProps) { - const artifactDef = useMemo(() => { - if (artifactType && baseArtifactId) { - return { artifactType, baseArtifactId }; - } - - return null; - }, [artifactType, baseArtifactId]); + const artifactDef = useMemo( + () => ({ artifactType, baseArtifactId }), + [artifactType, baseArtifactId], + ); const dispatch = useDispatch(); diff --git a/app/client/src/git/components/GlobalProfile/GlobalProfileView.tsx b/app/client/src/git/components/GlobalProfile/GlobalProfileView.tsx deleted file mode 100644 index ddb2d7935387..000000000000 --- a/app/client/src/git/components/GlobalProfile/GlobalProfileView.tsx +++ /dev/null @@ -1,148 +0,0 @@ -import React, { useCallback, useEffect, useState } from "react"; -import { - createMessage, - AUTHOR_EMAIL, - AUTHOR_NAME, - SUBMIT, -} from "ee/constants/messages"; -import { Classes } from "@blueprintjs/core"; -import { Button, Input, toast } from "@appsmith/ads"; -import { emailValidator } from "@appsmith/ads-old"; -import styled from "styled-components"; -import type { FetchGlobalProfileResponseData } from "git/requests/fetchGlobalProfileRequest.types"; -import type { UpdateGlobalProfileInitPayload } from "git/store/actions/updateGlobalProfileActions"; -import noop from "lodash/noop"; - -const Wrapper = styled.div` - width: 320px; - & > div { - margin-bottom: 16px; - } -`; - -const FieldWrapper = styled.div` - .user-profile-image-picker { - width: 166px; - margin-top: 4px; - } -`; - -const Loader = styled.div` - height: 38px; - width: 320px; - border-radius: 0; -`; - -interface GlobalProfileViewProps { - globalProfile: FetchGlobalProfileResponseData | null; - isFetchGlobalProfileLoading: boolean; - isUpdateGlobalProfileLoading: boolean; - updateGlobalProfile: (data: UpdateGlobalProfileInitPayload) => void; -} - -export default function GlobalProfileView({ - globalProfile = null, - isFetchGlobalProfileLoading = false, - isUpdateGlobalProfileLoading = false, - updateGlobalProfile = noop, -}: GlobalProfileViewProps) { - const [areFormValuesUpdated, setAreFormValuesUpdated] = useState(false); - - const [authorName, setAuthorNameInState] = useState( - globalProfile?.authorName, - ); - const [authorEmail, setAuthorEmailInState] = useState( - globalProfile?.authorEmail, - ); - - const isSubmitDisabled = !authorName || !authorEmail || !areFormValuesUpdated; - - const isLoading = isFetchGlobalProfileLoading || isUpdateGlobalProfileLoading; - - const setAuthorName = useCallback( - (value: string) => { - setAuthorNameInState(value); - - if (authorName) setAreFormValuesUpdated(true); - }, - [authorName], - ); - - const setAuthorEmail = useCallback( - (value: string) => { - setAuthorEmailInState(value); - - if (authorEmail) setAreFormValuesUpdated(true); - }, - [authorEmail], - ); - - const onClickUpdate = useCallback(() => { - if (authorName && authorEmail && emailValidator(authorEmail).isValid) { - setAreFormValuesUpdated(false); - updateGlobalProfile({ authorName, authorEmail }); - } else { - toast.show("Please enter valid user details"); - } - }, [authorEmail, authorName, updateGlobalProfile]); - - useEffect( - function resetOnInitEffect() { - setAreFormValuesUpdated(false); - setAuthorNameInState(globalProfile?.authorName ?? ""); - setAuthorEmailInState(globalProfile?.authorEmail ?? ""); - }, - [globalProfile], - ); - - return ( - - - {isLoading && } - {!isLoading && ( - - )} - - - {isLoading && } - {!isLoading && ( - - )} - - -
- -
-
-
- ); -} diff --git a/app/client/src/git/components/GlobalProfile/index.tsx b/app/client/src/git/components/GlobalProfile/index.tsx deleted file mode 100644 index 5ecc06e70c87..000000000000 --- a/app/client/src/git/components/GlobalProfile/index.tsx +++ /dev/null @@ -1,23 +0,0 @@ -import useGlobalProfile from "git/hooks/useGlobalProfile"; -import React from "react"; -import GlobalProfileView from "./GlobalProfileView"; - -function GlobalProfile() { - const { - globalProfile, - isFetchGlobalProfileLoading, - isUpdateGlobalProfileLoading, - updateGlobalProfile, - } = useGlobalProfile(); - - return ( - - ); -} - -export default GlobalProfile; diff --git a/app/client/src/git/components/ImportModal/index.tsx b/app/client/src/git/components/ImportModal/index.tsx index 8192fa9e88a7..f55a468d702b 100644 --- a/app/client/src/git/components/ImportModal/index.tsx +++ b/app/client/src/git/components/ImportModal/index.tsx @@ -1,51 +1,8 @@ -import React, { useCallback } from "react"; -import ConnectModalView from "../ConnectModal/ConnectModalView"; -import type { GitImportRequestParams } from "git/requests/gitImportRequest.types"; -import useImport from "git/hooks/useImport"; -import useGlobalSSHKey from "git/hooks/useGlobalSSHKey"; -import noop from "lodash/noop"; +import React from "react"; +import ConnectModal from "../ConnectModal"; function ImportModal() { - const { - gitImport, - gitImportError, - isGitImportLoading, - isImportModalOpen, - toggleImportModal, - } = useImport(); - const { - fetchGlobalSSHKey, - globalSSHKey, - isFetchGlobalSSHKeyLoading, - resetGlobalSSHKey, - } = useGlobalSSHKey(); - - const sshPublicKey = globalSSHKey?.publicKey ?? null; - - const onSubmit = useCallback( - (params: GitImportRequestParams) => { - gitImport(params); - }, - [gitImport], - ); - - return ( - - ); + return ; } export default ImportModal; diff --git a/app/client/src/git/components/OpsModal/TabDeploy/DeployPreview.tsx b/app/client/src/git/components/OpsModal/TabDeploy/DeployPreview.tsx index 311019abdc24..79abbe1439dc 100644 --- a/app/client/src/git/components/OpsModal/TabDeploy/DeployPreview.tsx +++ b/app/client/src/git/components/OpsModal/TabDeploy/DeployPreview.tsx @@ -1,4 +1,4 @@ -import React, { useCallback, useEffect, useState } from "react"; +import React from "react"; import styled from "styled-components"; import { useSelector } from "react-redux"; @@ -15,47 +15,32 @@ import SuccessTick from "pages/common/SuccessTick"; import { howMuchTimeBeforeText } from "utils/helpers"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import { viewerURL } from "ee/RouteBuilder"; -import { Icon, Link, Text } from "@appsmith/ads"; +import { Link, Text } from "@appsmith/ads"; +import { importSvg } from "@appsmith/ads-old"; -const StyledIcon = styled(Icon)` - svg { - width: 30px; - height: 30px; - } -`; +const CloudyIcon = importSvg( + async () => import("assets/icons/ads/cloudy-line.svg"), +); const Container = styled.div` display: flex; flex: 1; flex-direction: row; gap: ${(props) => props.theme.spaces[6]}px; -`; - -interface DeployPreviewProps { - isCommitSuccess: boolean; -} - -export default function DeployPreview({ isCommitSuccess }: DeployPreviewProps) { - const [showSuccess, setShowSuccess] = useState(false); - useEffect( - function startTimerForCommitSuccessEffect() { - if (isCommitSuccess) { - setShowSuccess(true); - const timer = setTimeout(() => { - setShowSuccess(false); - }, 5000); + .cloud-icon { + stroke: var(--ads-v2-color-fg); + } +`; - return () => clearTimeout(timer); - } - }, - [isCommitSuccess], - ); +export default function DeployPreview() { + // ! case: should reset after timer + const showSuccess = false; const basePageId = useSelector(getCurrentBasePageId); const lastDeployedAt = useSelector(getApplicationLastDeployedAt); - const showDeployPreview = useCallback(() => { + const showDeployPreview = () => { AnalyticsUtil.logEvent("GS_LAST_DEPLOYED_PREVIEW_LINK_CLICK", { source: "GIT_DEPLOY_MODAL", }); @@ -64,7 +49,7 @@ export default function DeployPreview({ isCommitSuccess }: DeployPreviewProps) { }); window.open(path, "_blank"); - }, [basePageId]); + }; const lastDeployedAtMsg = lastDeployedAt ? `${createMessage(LATEST_DP_SUBTITLE)} ${howMuchTimeBeforeText( @@ -81,7 +66,7 @@ export default function DeployPreview({ isCommitSuccess }: DeployPreviewProps) { {showSuccess ? ( ) : ( - + )}
diff --git a/app/client/src/git/components/OpsModal/TabDeploy/TabDeployView.tsx b/app/client/src/git/components/OpsModal/TabDeploy/TabDeployView.tsx index a2db0f28805d..d22c93f79b97 100644 --- a/app/client/src/git/components/OpsModal/TabDeploy/TabDeployView.tsx +++ b/app/client/src/git/components/OpsModal/TabDeploy/TabDeployView.tsx @@ -108,7 +108,6 @@ function TabDeployView({ statusBehindCount = 0, statusIsClean = false, }: TabDeployViewProps) { - const [hasSubmitted, setHasSubmitted] = useState(false); const hasChangesToCommit = !statusIsClean; const commitInputRef = useRef(null); const [commitMessage, setCommitMessage] = useState( @@ -158,10 +157,6 @@ function TabDeployView({ ((pullRequired && !isConflicting) || (statusBehindCount > 0 && statusIsClean)); - const isCommitSuccess = useMemo(() => { - return hasSubmitted && !isCommitLoading; - }, [isCommitLoading, hasSubmitted]); - useEffect( function focusCommitInputEffect() { if (!commitInputDisabled && commitInputRef.current) { @@ -205,7 +200,6 @@ function TabDeployView({ }); if (currentBranch) { - setHasSubmitted(true); commit(commitMessage.trim()); } }, [commit, commitMessage, currentBranch]); @@ -359,9 +353,7 @@ function TabDeployView({ /> )} - {!pullRequired && !isConflicting && ( - - )} + {!pullRequired && !isConflicting && }
diff --git a/app/client/src/git/components/OpsModal/index.tsx b/app/client/src/git/components/OpsModal/index.tsx index 66ea3ddf0182..114439c29902 100644 --- a/app/client/src/git/components/OpsModal/index.tsx +++ b/app/client/src/git/components/OpsModal/index.tsx @@ -1,15 +1,14 @@ import React from "react"; import OpsModalView from "./OpsModalView"; +import useProtectedBranches from "git/hooks/useProtectedBranches"; import useMetadata from "git/hooks/useMetadata"; import useStatus from "git/hooks/useStatus"; import useOps from "git/hooks/useOps"; -import useProtectedMode from "git/hooks/useProtectedMode"; -import { GitOpsTab } from "git/constants/enums"; export default function OpsModal() { - const { isOpsModalOpen, opsModalTab, toggleOpsModal } = useOps(); + const { opsModalOpen, opsModalTab, toggleOpsModal } = useOps(); const { fetchStatus } = useStatus(); - const isProtectedMode = useProtectedMode(); + const { isProtectedMode } = useProtectedBranches(); const { metadata } = useMetadata(); @@ -18,9 +17,9 @@ export default function OpsModal() { return ( diff --git a/app/client/src/git/components/ProtectedBranchCallout/ProtectedBranchCalloutView.tsx b/app/client/src/git/components/ProtectedBranchCallout/ProtectedBranchCalloutView.tsx deleted file mode 100644 index 89b37bbfa239..000000000000 --- a/app/client/src/git/components/ProtectedBranchCallout/ProtectedBranchCalloutView.tsx +++ /dev/null @@ -1,85 +0,0 @@ -import React, { useCallback, useMemo } from "react"; -import { Callout } from "@appsmith/ads"; -import styled from "styled-components"; -import { - BRANCH_PROTECTION_CALLOUT_CREATE_BRANCH, - BRANCH_PROTECTION_CALLOUT_MSG, - BRANCH_PROTECTION_CALLOUT_UNPROTECT, - BRANCH_PROTECTION_CALLOUT_UNPROTECT_LOADING, - createMessage, -} from "ee/constants/messages"; -import { noop } from "lodash"; -import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types"; - -export const PROTECTED_CALLOUT_HEIGHT = 70; - -const StyledCallout = styled(Callout)` - height: ${PROTECTED_CALLOUT_HEIGHT}px; - overflow-y: hidden; -`; - -interface ProtectedBranchCalloutViewProps { - currentBranch: string | null; - isUpdateProtectedBranchesLoading: boolean; - protectedBranches: FetchProtectedBranchesResponseData | null; - toggleBranchPopup: (isOpen: boolean) => void; - updateProtectedBranches: (branches: string[]) => void; -} - -function ProtectedBranchCalloutView({ - currentBranch = null, - isUpdateProtectedBranchesLoading = false, - protectedBranches = null, - toggleBranchPopup = noop, - updateProtectedBranches = noop, -}: ProtectedBranchCalloutViewProps) { - const handleClickOnNewBranch = useCallback(() => { - toggleBranchPopup(true); - }, [toggleBranchPopup]); - - const handleClickOnUnprotect = useCallback(() => { - const allBranches = protectedBranches || []; - const remainingBranches = allBranches.filter( - (protectedBranch) => protectedBranch !== currentBranch, - ); - - updateProtectedBranches(remainingBranches); - }, [currentBranch, protectedBranches, updateProtectedBranches]); - - const links = useMemo( - () => [ - { - key: "create-branch", - "data-testid": "t--git-protected-create-branch-cta", - children: createMessage(BRANCH_PROTECTION_CALLOUT_CREATE_BRANCH), - onClick: handleClickOnNewBranch, - }, - { - key: "unprotect", - "data-testid": "t--git-protected-unprotect-branch-cta", - children: isUpdateProtectedBranchesLoading - ? createMessage(BRANCH_PROTECTION_CALLOUT_UNPROTECT_LOADING) - : createMessage(BRANCH_PROTECTION_CALLOUT_UNPROTECT), - onClick: handleClickOnUnprotect, - isDisabled: isUpdateProtectedBranchesLoading, - }, - ], - [ - handleClickOnNewBranch, - handleClickOnUnprotect, - isUpdateProtectedBranchesLoading, - ], - ); - - return ( - - {createMessage(BRANCH_PROTECTION_CALLOUT_MSG)} - - ); -} - -export default ProtectedBranchCalloutView; diff --git a/app/client/src/git/components/ProtectedBranchCallout/index.tsx b/app/client/src/git/components/ProtectedBranchCallout/index.tsx deleted file mode 100644 index aca08dfc1e87..000000000000 --- a/app/client/src/git/components/ProtectedBranchCallout/index.tsx +++ /dev/null @@ -1,33 +0,0 @@ -import React from "react"; -import ProtectedBranchCalloutView from "./ProtectedBranchCalloutView"; -import useProtectedBranches from "git/hooks/useProtectedBranches"; -import useCurrentBranch from "git/hooks/useCurrentBranch"; -import useBranches from "git/hooks/useBranches"; -import useProtectedMode from "git/hooks/useProtectedMode"; - -function ProtectedBranchCallout() { - const isProtectedMode = useProtectedMode(); - const currentBranch = useCurrentBranch(); - const { toggleBranchPopup } = useBranches(); - const { - isUpdateProtectedBranchesLoading, - protectedBranches, - updateProtectedBranches, - } = useProtectedBranches(); - - if (!isProtectedMode) { - return null; - } - - return ( - - ); -} - -export default ProtectedBranchCallout; diff --git a/app/client/src/git/components/QuickActions/QuickActionsView.test.tsx b/app/client/src/git/components/QuickActions/QuickActionsView.test.tsx index f6bc193bfc7e..6e696ddffe55 100644 --- a/app/client/src/git/components/QuickActions/QuickActionsView.test.tsx +++ b/app/client/src/git/components/QuickActions/QuickActionsView.test.tsx @@ -29,7 +29,7 @@ describe("QuickActionsView Component", () => { isConnectPermitted: true, isDiscardLoading: false, isFetchStatusLoading: false, - isConnected: false, + isGitConnected: false, isProtectedMode: false, isPullFailing: false, isPullLoading: false, @@ -48,7 +48,7 @@ describe("QuickActionsView Component", () => { jest.clearAllMocks(); }); - it("should render ConnectButton when isConnected is false", () => { + it("should render ConnectButton when isGitConnected is false", () => { render( @@ -57,10 +57,10 @@ describe("QuickActionsView Component", () => { expect(screen.getByTestId("connect-button")).toBeInTheDocument(); }); - it("should render QuickActionButtons when isConnected is true", () => { + it("should render QuickActionButtons when isGitConnected is true", () => { const props = { ...defaultProps, - isConnected: true, + isGitConnected: true, }; const { container } = render( @@ -86,7 +86,7 @@ describe("QuickActionsView Component", () => { it("should render Statusbar when isAutocommitEnabled and isPollingAutocommit are true", () => { const props = { ...defaultProps, - isConnected: true, + isGitConnected: true, isAutocommitEnabled: true, isAutocommitPolling: true, }; @@ -106,7 +106,7 @@ describe("QuickActionsView Component", () => { it("should call onCommitClick when commit button is clicked", () => { const props = { ...defaultProps, - isConnected: true, + isGitConnected: true, }; const { container } = render( @@ -131,7 +131,7 @@ describe("QuickActionsView Component", () => { it("should call onPullClick when pull button is clicked", () => { const props = { ...defaultProps, - isConnected: true, + isGitConnected: true, isDiscardLoading: false, isPullLoading: false, isFetchStatusLoading: false, @@ -159,7 +159,7 @@ describe("QuickActionsView Component", () => { it("should call onMerge when merge button is clicked", () => { const props = { ...defaultProps, - isConnected: true, + isGitConnected: true, }; const { container } = render( @@ -184,7 +184,7 @@ describe("QuickActionsView Component", () => { it("should call onSettingsClick when settings button is clicked", () => { const props = { ...defaultProps, - isConnected: true, + isGitConnected: true, }; const { container } = render( @@ -209,7 +209,7 @@ describe("QuickActionsView Component", () => { it("should disable commit button when isProtectedMode is true", () => { const props = { ...defaultProps, - isConnected: true, + isGitConnected: true, isProtectedMode: true, }; @@ -228,7 +228,7 @@ describe("QuickActionsView Component", () => { it("should show loading state on pull button when showPullLoadingState is true", () => { const props = { ...defaultProps, - isConnected: true, + isGitConnected: true, isPullLoading: true, }; @@ -250,7 +250,7 @@ describe("QuickActionsView Component", () => { it("should display changesToCommit count on commit button", () => { const props = { ...defaultProps, - isConnected: true, + isGitConnected: true, statusChangeCount: 5, }; @@ -267,7 +267,7 @@ describe("QuickActionsView Component", () => { it("should not display count on commit button when isProtectedMode is true", () => { const props = { ...defaultProps, - isConnected: true, + isGitConnected: true, isProtectedMode: true, statusChangeCount: 5, }; @@ -292,7 +292,7 @@ describe("QuickActionsView Component", () => { const props = { ...defaultProps, - isConnected: true, + isGitConnected: true, }; const { container } = render( @@ -310,7 +310,7 @@ describe("QuickActionsView Component", () => { it("should show behindCount on pull button", () => { const props = { ...defaultProps, - isConnected: true, + isGitConnected: true, statusBehindCount: 3, statusIsClean: true, }; diff --git a/app/client/src/git/components/QuickActions/QuickActionsView.tsx b/app/client/src/git/components/QuickActions/QuickActionsView.tsx index 274dd00f3dba..396984788015 100644 --- a/app/client/src/git/components/QuickActions/QuickActionsView.tsx +++ b/app/client/src/git/components/QuickActions/QuickActionsView.tsx @@ -33,7 +33,7 @@ interface QuickActionsViewProps { isConnectPermitted: boolean; isDiscardLoading: boolean; isFetchStatusLoading: boolean; - isConnected: boolean; + isGitConnected: boolean; isProtectedMode: boolean; isPullFailing: boolean; isPullLoading: boolean; @@ -57,10 +57,10 @@ function QuickActionsView({ isAutocommitEnabled = false, isAutocommitPolling = false, isBranchPopupOpen = false, - isConnected = false, isConnectPermitted = false, isDiscardLoading = false, isFetchStatusLoading = false, + isGitConnected = false, isProtectedMode = false, isPullFailing = false, isPullLoading = false, @@ -131,7 +131,7 @@ function QuickActionsView({ toggleConnectModal(true); }, [toggleConnectModal]); - return isConnected ? ( + return isGitConnected ? ( ); diff --git a/app/client/src/git/components/StatusChanges/StatusChangesView.tsx b/app/client/src/git/components/StatusChanges/StatusChangesView.tsx index f8e6f0c41dfa..c3768c0d866c 100644 --- a/app/client/src/git/components/StatusChanges/StatusChangesView.tsx +++ b/app/client/src/git/components/StatusChanges/StatusChangesView.tsx @@ -1,19 +1,14 @@ import type { FetchStatusResponseData } from "git/requests/fetchStatusRequest.types"; import React, { useMemo } from "react"; +import type { StatusTreeStruct } from "./StatusTree"; import StatusTree from "./StatusTree"; -import { Callout, Text } from "@appsmith/ads"; +import { Text } from "@appsmith/ads"; import { createMessage } from "@appsmith/ads-old"; import { CHANGES_SINCE_LAST_DEPLOYMENT, FETCH_GIT_STATUS, } from "ee/constants/messages"; -import StatusLoader from "./StatusLoader"; -import type { StatusTreeStruct } from "./types"; -import styled from "styled-components"; - -const CalloutContainer = styled.div` - margin-top: 16px; -`; +import StatusLoader from "pages/Editor/gitSync/components/StatusLoader"; const noopStatusTransformer = () => null; @@ -54,11 +49,6 @@ export default function StatusChangesView({ {createMessage(CHANGES_SINCE_LAST_DEPLOYMENT)} - {status.migrationMessage ? ( - - {status.migrationMessage} - - ) : null}
); } diff --git a/app/client/src/git/components/StatusChanges/StatusLoader.tsx b/app/client/src/git/components/StatusChanges/StatusLoader.tsx index 9026b75b38fa..bc0427bd6521 100644 --- a/app/client/src/git/components/StatusChanges/StatusLoader.tsx +++ b/app/client/src/git/components/StatusChanges/StatusLoader.tsx @@ -6,18 +6,16 @@ const LoaderWrapper = styled.div` display: flex; flex-direction: row; align-items: center; - margin-bottom: 8px; -`; - -const LoaderText = styled(Text)` - margin-left: 8px; + margin-top: ${(props) => `${props.theme.spaces[3]}px`}; `; function StatusLoader({ loaderMsg }: { loaderMsg: string }) { return ( - {loaderMsg} + + {loaderMsg} + ); } diff --git a/app/client/src/git/components/StatusChanges/StatusTree.tsx b/app/client/src/git/components/StatusChanges/StatusTree.tsx index 437163d394df..289d2d28b796 100644 --- a/app/client/src/git/components/StatusChanges/StatusTree.tsx +++ b/app/client/src/git/components/StatusChanges/StatusTree.tsx @@ -7,17 +7,12 @@ import { Text, } from "@appsmith/ads"; import clsx from "clsx"; -import styled from "styled-components"; -import type { StatusTreeStruct } from "./types"; -const StyledCollapsible = styled(Collapsible)` - gap: 0; -`; - -const StyledCollapsibleHeader = styled(CollapsibleHeader)` - padding-top: 0; - padding-bottom: 0; -`; +export interface StatusTreeStruct { + icon: string; + message: string; + children?: StatusTreeStruct[]; +} interface StatusTreeNodeProps { icon: string; @@ -48,31 +43,29 @@ interface SingleStatusTreeProps { function SingleStatusTree({ depth = 1, tree }: SingleStatusTreeProps) { if (!tree) return null; - const noEmphasis = depth > 1 && !tree.children; - if (!tree.children) { return ( 2} /> ); } return ( - - + + - + {tree.children.map((child, index) => ( ))} - + ); } diff --git a/app/client/src/git/components/StatusChanges/types.ts b/app/client/src/git/components/StatusChanges/types.ts deleted file mode 100644 index 61a8e074714b..000000000000 --- a/app/client/src/git/components/StatusChanges/types.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface StatusTreeStruct { - icon: string; - message: string; - children?: StatusTreeStruct[]; -} diff --git a/app/client/src/git/components/index.tsx b/app/client/src/git/components/index.tsx new file mode 100644 index 000000000000..c3a1640dbd01 --- /dev/null +++ b/app/client/src/git/components/index.tsx @@ -0,0 +1,3 @@ +export { default as GitModals } from "git/ee/components/GitModals"; +export { default as GitImportModal } from "./ImportModal"; +export { default as GitQuickActions } from "./QuickActions"; diff --git a/app/client/src/git/hooks/useArtifactSelector.ts b/app/client/src/git/hooks/useArtifactSelector.ts deleted file mode 100644 index dba2a0808bf3..000000000000 --- a/app/client/src/git/hooks/useArtifactSelector.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { useGitContext } from "git/components/GitContextProvider"; -import type { GitArtifactDef, GitRootState } from "git/store/types"; -import { useSelector } from "react-redux"; -import type { Tail } from "redux-saga/effects"; - -/** - * This hook is used to select data from the redux store based on the artifactDef. - **/ -export default function useArtifactSelector< - // need any type to properly infer the return type - /* eslint-disable @typescript-eslint/no-explicit-any */ - Fn extends (state: any, artifactDef: GitArtifactDef, ...args: any[]) => any, ->(selector: Fn, ...args: Tail>>): ReturnType | null { - const { artifactDef } = useGitContext(); - - return useSelector((state: GitRootState) => { - if (typeof selector !== "function" || !artifactDef) { - return null; - } - - const { artifactType, baseArtifactId } = artifactDef; - - if (!state.git?.artifacts?.[artifactType]?.[baseArtifactId]) { - return null; - } - - return selector(state, artifactDef, ...args); - }); -} diff --git a/app/client/src/git/hooks/useAutocommit.ts b/app/client/src/git/hooks/useAutocommit.ts index 91ad0e8aaae5..73d7d955caca 100644 --- a/app/client/src/git/hooks/useAutocommit.ts +++ b/app/client/src/git/hooks/useAutocommit.ts @@ -6,50 +6,50 @@ import { selectAutocommitPolling, selectToggleAutocommitState, selectTriggerAutocommitState, -} from "git/store/selectors/gitArtifactSelectors"; +} from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useDispatch, useSelector } from "react-redux"; export default function useAutocommit() { const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const toggleAutocommitState = useArtifactSelector( - selectToggleAutocommitState, + const toggleAutocommitState = useSelector((state: GitRootState) => + selectToggleAutocommitState(state, artifactDef), ); - const triggerAutocommitState = useArtifactSelector( - selectTriggerAutocommitState, + const triggerAutocommitState = useSelector((state: GitRootState) => + selectTriggerAutocommitState(state, artifactDef), ); const toggleAutocommit = useCallback(() => { - if (artifactDef) { - dispatch(gitArtifactActions.toggleAutocommitInit({ artifactDef })); - } + dispatch(gitArtifactActions.toggleAutocommitInit(artifactDef)); }, [artifactDef, dispatch]); - const isAutocommitDisableModalOpen = useArtifactSelector( - selectAutocommitDisableModalOpen, + const isAutocommitDisableModalOpen = useSelector((state: GitRootState) => + selectAutocommitDisableModalOpen(state, artifactDef), ); const toggleAutocommitDisableModal = useCallback( (open: boolean) => { - if (artifactDef) { - dispatch( - gitArtifactActions.toggleAutocommitDisableModal({ - artifactDef, - open, - }), - ); - } + dispatch( + gitArtifactActions.toggleAutocommitDisableModal({ + ...artifactDef, + open, + }), + ); }, [artifactDef, dispatch], ); - const isAutocommitEnabled = useArtifactSelector(selectAutocommitEnabled); + const isAutocommitEnabled = useSelector((state: GitRootState) => + selectAutocommitEnabled(state, artifactDef), + ); - const isAutocommitPolling = useArtifactSelector(selectAutocommitPolling); + const isAutocommitPolling = useSelector((state: GitRootState) => + selectAutocommitPolling(state, artifactDef), + ); return { isToggleAutocommitLoading: toggleAutocommitState?.loading ?? false, @@ -57,9 +57,9 @@ export default function useAutocommit() { toggleAutocommit, isTriggerAutocommitLoading: triggerAutocommitState?.loading ?? false, triggerAutocommitError: triggerAutocommitState?.error ?? null, - isAutocommitDisableModalOpen: isAutocommitDisableModalOpen ?? false, + isAutocommitDisableModalOpen, toggleAutocommitDisableModal, - isAutocommitEnabled: isAutocommitEnabled ?? false, - isAutocommitPolling: isAutocommitPolling ?? false, + isAutocommitEnabled, + isAutocommitPolling, }; } diff --git a/app/client/src/git/hooks/useBranches.ts b/app/client/src/git/hooks/useBranches.ts index fe85a318b8d4..4a0ecead44d7 100644 --- a/app/client/src/git/hooks/useBranches.ts +++ b/app/client/src/git/hooks/useBranches.ts @@ -8,105 +8,103 @@ import { selectCreateBranchState, selectDeleteBranchState, selectCurrentBranch, -} from "git/store/selectors/gitArtifactSelectors"; +} from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useDispatch, useSelector } from "react-redux"; export default function useBranches() { - const { artifact, artifactDef } = useGitContext(); - const artifactId = artifact?.id; + const { artifactDef } = useGitContext(); const dispatch = useDispatch(); // fetch branches - const branchesState = useArtifactSelector(selectFetchBranchesState); - + const branchesState = useSelector((state: GitRootState) => + selectFetchBranchesState(state, artifactDef), + ); const fetchBranches = useCallback(() => { - if (artifactDef && artifactId) { - dispatch( - gitArtifactActions.fetchBranchesInit({ - artifactId, - artifactDef, - pruneBranches: true, - }), - ); - } - }, [artifactDef, artifactId, dispatch]); + dispatch( + gitArtifactActions.fetchBranchesInit({ + ...artifactDef, + pruneBranches: true, + }), + ); + }, [artifactDef, dispatch]); // create branch - const createBranchState = useArtifactSelector(selectCreateBranchState); + const createBranchState = useSelector((state: GitRootState) => + selectCreateBranchState(state, artifactDef), + ); const createBranch = useCallback( (branchName: string) => { - if (artifactDef && artifactId) { - dispatch( - gitArtifactActions.createBranchInit({ - artifactDef, - artifactId, - branchName, - }), - ); - } + dispatch( + gitArtifactActions.createBranchInit({ + ...artifactDef, + branchName, + }), + ); }, - [artifactDef, artifactId, dispatch], + [artifactDef, dispatch], ); // delete branch - const deleteBranchState = useArtifactSelector(selectDeleteBranchState); + const deleteBranchState = useSelector((state: GitRootState) => + selectDeleteBranchState(state, artifactDef), + ); const deleteBranch = useCallback( (branchName: string) => { - if (artifactDef && artifactId) { - dispatch( - gitArtifactActions.deleteBranchInit({ - artifactId, - artifactDef, - branchName, - }), - ); - } + dispatch( + gitArtifactActions.deleteBranchInit({ + ...artifactDef, + branchName, + }), + ); }, - [artifactDef, artifactId, dispatch], + [artifactDef, dispatch], ); // checkout branch - const checkoutBranchState = useArtifactSelector(selectCheckoutBranchState); + const checkoutBranchState = useSelector((state: GitRootState) => + selectCheckoutBranchState(state, artifactDef), + ); const checkoutBranch = useCallback( (branchName: string) => { - if (artifactDef && artifactId) { - dispatch( - gitArtifactActions.checkoutBranchInit({ - artifactDef, - artifactId, - branchName, - }), - ); - } + dispatch( + gitArtifactActions.checkoutBranchInit({ + ...artifactDef, + branchName, + }), + ); }, - [artifactDef, artifactId, dispatch], + [artifactDef, dispatch], ); - const checkoutDestBranch = useArtifactSelector(selectCheckoutDestBranch); + const checkoutDestBranch = useSelector((state: GitRootState) => + selectCheckoutDestBranch(state, artifactDef), + ); // derived - const currentBranch = useArtifactSelector(selectCurrentBranch); + const currentBranch = useSelector((state: GitRootState) => + selectCurrentBranch(state, artifactDef), + ); // git branch list popup - const isBranchPopupOpen = useArtifactSelector(selectBranchPopupOpen); + const isBranchPopupOpen = useSelector((state: GitRootState) => + selectBranchPopupOpen(state, artifactDef), + ); const toggleBranchPopup = useCallback( (open: boolean) => { - if (artifactDef) { - dispatch( - gitArtifactActions.toggleBranchPopup({ - artifactDef, - open, - }), - ); - } + dispatch( + gitArtifactActions.toggleBranchPopup({ + ...artifactDef, + open, + }), + ); }, [artifactDef, dispatch], ); return { - branches: branchesState?.value ?? null, + branches: branchesState?.value, isFetchBranchesLoading: branchesState?.loading ?? false, fetchBranchesError: branchesState?.error ?? null, fetchBranches, @@ -121,7 +119,7 @@ export default function useBranches() { checkoutBranch, checkoutDestBranch, currentBranch: currentBranch ?? null, - isBranchPopupOpen: isBranchPopupOpen ?? false, + isBranchPopupOpen, toggleBranchPopup, }; } diff --git a/app/client/src/git/hooks/useCommit.ts b/app/client/src/git/hooks/useCommit.ts index 6a468046a84b..56f78cc11bcd 100644 --- a/app/client/src/git/hooks/useCommit.ts +++ b/app/client/src/git/hooks/useCommit.ts @@ -1,43 +1,38 @@ import { useGitContext } from "git/components/GitContextProvider"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; -import { selectCommitState } from "git/store/selectors/gitArtifactSelectors"; +import { selectCommitState } from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useDispatch, useSelector } from "react-redux"; export default function useCommit() { - const { artifact, artifactDef } = useGitContext(); - const artifactId = artifact?.id; - + const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const commitState = useArtifactSelector(selectCommitState); + const commitState = useSelector((state: GitRootState) => + selectCommitState(state, artifactDef), + ); const commit = useCallback( (commitMessage: string) => { - if (artifactDef && artifactId) { - dispatch( - gitArtifactActions.commitInit({ - artifactId, - artifactDef, - commitMessage, - doPush: true, - }), - ); - } + dispatch( + gitArtifactActions.commitInit({ + ...artifactDef, + commitMessage, + doPush: true, + }), + ); }, - [artifactDef, artifactId, dispatch], + [artifactDef, dispatch], ); const clearCommitError = useCallback(() => { - if (artifactDef) { - dispatch(gitArtifactActions.clearCommitError({ artifactDef })); - } + dispatch(gitArtifactActions.clearCommitError(artifactDef)); }, [artifactDef, dispatch]); return { isCommitLoading: commitState?.loading ?? false, - commitError: commitState?.error ?? null, + commitError: commitState?.error, commit, clearCommitError, }; diff --git a/app/client/src/git/hooks/useConnect.ts b/app/client/src/git/hooks/useConnect.ts index 884addac0fd7..1064ce7ff26e 100644 --- a/app/client/src/git/hooks/useConnect.ts +++ b/app/client/src/git/hooks/useConnect.ts @@ -4,53 +4,82 @@ import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { selectConnectModalOpen, selectConnectState, - selectConnectSuccessModalOpen, -} from "git/store/selectors/gitArtifactSelectors"; + selectFetchSSHKeysState, + selectGenerateSSHKeyState, + selectGitImportState, +} from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useSelector } from "react-redux"; export default function useConnect() { const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const connectState = useArtifactSelector(selectConnectState); + const connectState = useSelector((state: GitRootState) => + selectConnectState(state, artifactDef), + ); const connect = useCallback( (params: ConnectRequestParams) => { - if (artifactDef) { - dispatch(gitArtifactActions.connectInit({ artifactDef, ...params })); - } + dispatch(gitArtifactActions.connectInit({ ...artifactDef, ...params })); }, [artifactDef, dispatch], ); - const isConnectModalOpen = useArtifactSelector(selectConnectModalOpen); + const gitImportState = useSelector((state: GitRootState) => + selectGitImportState(state, artifactDef), + ); - const toggleConnectModal = useCallback( - (open: boolean) => { - if (artifactDef) { - dispatch(gitArtifactActions.toggleConnectModal({ artifactDef, open })); - } + const gitImport = useCallback( + (params) => { + dispatch(gitArtifactActions.gitImportInit({ ...artifactDef, ...params })); + }, + [artifactDef, dispatch], + ); + + const fetchSSHKeyState = useSelector((state: GitRootState) => + selectFetchSSHKeysState(state, artifactDef), + ); + + const fetchSSHKey = useCallback(() => { + dispatch(gitArtifactActions.fetchSSHKeyInit(artifactDef)); + }, [artifactDef, dispatch]); + + const resetFetchSSHKey = useCallback(() => { + dispatch(gitArtifactActions.resetFetchSSHKey(artifactDef)); + }, [artifactDef, dispatch]); + + const generateSSHKeyState = useSelector((state: GitRootState) => + selectGenerateSSHKeyState(state, artifactDef), + ); + + const generateSSHKey = useCallback( + (keyType: string, isImport: boolean = false) => { + dispatch( + gitArtifactActions.generateSSHKeyInit({ + ...artifactDef, + keyType, + isImport, + }), + ); }, [artifactDef, dispatch], ); - const isConnectSuccessModalOpen = useArtifactSelector( - selectConnectSuccessModalOpen, + const resetGenerateSSHKey = useCallback(() => { + dispatch(gitArtifactActions.resetGenerateSSHKey(artifactDef)); + }, [artifactDef, dispatch]); + + const isConnectModalOpen = useSelector((state: GitRootState) => + selectConnectModalOpen(state, artifactDef), ); - const toggleConnectSuccessModal = useCallback( + const toggleConnectModal = useCallback( (open: boolean) => { - if (artifactDef) { - dispatch( - gitArtifactActions.toggleConnectSuccessModal({ - artifactDef, - open, - }), - ); - } + dispatch(gitArtifactActions.toggleConnectModal({ ...artifactDef, open })); }, [artifactDef, dispatch], ); @@ -59,9 +88,19 @@ export default function useConnect() { isConnectLoading: connectState?.loading ?? false, connectError: connectState?.error ?? null, connect, - isConnectModalOpen: isConnectModalOpen ?? false, + isGitImportLoading: gitImportState?.loading ?? false, + gitImportError: gitImportState?.error ?? null, + gitImport, + sshKey: fetchSSHKeyState?.value ?? null, + isFetchSSHKeyLoading: fetchSSHKeyState?.loading ?? false, + fetchSSHKeyError: fetchSSHKeyState?.error ?? null, + fetchSSHKey, + resetFetchSSHKey, + isGenerateSSHKeyLoading: generateSSHKeyState?.loading ?? false, + generateSSHKeyError: generateSSHKeyState?.error ?? null, + generateSSHKey, + resetGenerateSSHKey, + isConnectModalOpen, toggleConnectModal, - isConnectSuccessModalOpen: isConnectSuccessModalOpen ?? false, - toggleConnectSuccessModal, }; } diff --git a/app/client/src/git/hooks/useConnected.ts b/app/client/src/git/hooks/useConnected.ts deleted file mode 100644 index 39cfa55ca245..000000000000 --- a/app/client/src/git/hooks/useConnected.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { selectConnected } from "git/store/selectors/gitArtifactSelectors"; -import useArtifactSelector from "./useArtifactSelector"; - -export default function useConnected() { - const isConnected = useArtifactSelector(selectConnected); - - return isConnected ?? false; -} diff --git a/app/client/src/git/hooks/useCurrentBranch.ts b/app/client/src/git/hooks/useCurrentBranch.ts deleted file mode 100644 index 797d8d598ba5..000000000000 --- a/app/client/src/git/hooks/useCurrentBranch.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { selectCurrentBranch } from "git/store/selectors/gitArtifactSelectors"; -import useArtifactSelector from "./useArtifactSelector"; - -export default function useCurrentBranch() { - const currentBranch = useArtifactSelector(selectCurrentBranch); - - return currentBranch; -} diff --git a/app/client/src/git/hooks/useDiscard.ts b/app/client/src/git/hooks/useDiscard.ts index 19818cb7f8fa..2f71c11608f9 100644 --- a/app/client/src/git/hooks/useDiscard.ts +++ b/app/client/src/git/hooks/useDiscard.ts @@ -1,26 +1,24 @@ import { useGitContext } from "git/components/GitContextProvider"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; -import { selectDiscardState } from "git/store/selectors/gitArtifactSelectors"; +import { selectDiscardState } from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useDispatch, useSelector } from "react-redux"; export default function useDiscard() { const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const discardState = useArtifactSelector(selectDiscardState); + const discardState = useSelector((state: GitRootState) => + selectDiscardState(state, artifactDef), + ); const discard = useCallback(() => { - if (artifactDef) { - dispatch(gitArtifactActions.discardInit({ artifactDef })); - } + dispatch(gitArtifactActions.discardInit(artifactDef)); }, [artifactDef, dispatch]); const clearDiscardError = useCallback(() => { - if (artifactDef) { - dispatch(gitArtifactActions.clearDiscardError({ artifactDef })); - } + dispatch(gitArtifactActions.clearDiscardError(artifactDef)); }, [artifactDef, dispatch]); return { diff --git a/app/client/src/git/hooks/useDisconnect.ts b/app/client/src/git/hooks/useDisconnect.ts index 42fd878319fd..36dfd2cf8cf9 100644 --- a/app/client/src/git/hooks/useDisconnect.ts +++ b/app/client/src/git/hooks/useDisconnect.ts @@ -4,10 +4,10 @@ import { selectDisconnectArtifactName, selectDisconnectBaseArtifactId, selectDisconnectState, -} from "git/store/selectors/gitArtifactSelectors"; +} from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useDispatch, useSelector } from "react-redux"; export default function useDisconnect() { const { artifact, artifactDef } = useGitContext(); @@ -15,38 +15,30 @@ export default function useDisconnect() { const dispatch = useDispatch(); - const disconnectState = useArtifactSelector(selectDisconnectState); + const disconnectState = useSelector((state: GitRootState) => + selectDisconnectState(state, artifactDef), + ); const disconnect = useCallback(() => { - if (artifactDef) { - dispatch( - gitArtifactActions.disconnectInit({ - artifactDef, - }), - ); - } + dispatch(gitArtifactActions.disconnectInit(artifactDef)); }, [artifactDef, dispatch]); - const disconnectBaseArtifactId = useArtifactSelector( - selectDisconnectBaseArtifactId, + const disconnectBaseArtifactId = useSelector((state: GitRootState) => + selectDisconnectBaseArtifactId(state, artifactDef), ); - const disconnectArtifactName = useArtifactSelector( - selectDisconnectArtifactName, + const disconnectArtifactName = useSelector((state: GitRootState) => + selectDisconnectArtifactName(state, artifactDef), ); const openDisconnectModal = useCallback(() => { - if (artifactDef) { - dispatch( - gitArtifactActions.openDisconnectModal({ artifactDef, artifactName }), - ); - } + dispatch( + gitArtifactActions.openDisconnectModal({ ...artifactDef, artifactName }), + ); }, [artifactDef, artifactName, dispatch]); const closeDisconnectModal = useCallback(() => { - if (artifactDef) { - dispatch(gitArtifactActions.closeDisconnectModal({ artifactDef })); - } + dispatch(gitArtifactActions.closeDisconnectModal(artifactDef)); }, [artifactDef, dispatch]); return { diff --git a/app/client/src/git/hooks/useGitPermissions.ts b/app/client/src/git/hooks/useGitPermissions.ts index 13ca2404a161..3279dcd3e00e 100644 --- a/app/client/src/git/hooks/useGitPermissions.ts +++ b/app/client/src/git/hooks/useGitPermissions.ts @@ -10,46 +10,47 @@ import { useMemo } from "react"; export default function useGitPermissions() { const { artifact, artifactDef } = useGitContext(); + const { artifactType } = artifactDef; const isConnectPermitted = useMemo(() => { if (artifact) { - if (artifactDef?.artifactType === GitArtifactType.Application) { + if (artifactType === GitArtifactType.Application) { return hasConnectToGitPermission(artifact.userPermissions); } } return false; - }, [artifact, artifactDef?.artifactType]); + }, [artifact, artifactType]); const isManageDefaultBranchPermitted = useMemo(() => { if (artifact) { - if (artifactDef?.artifactType === GitArtifactType.Application) { + if (artifactType === GitArtifactType.Application) { return hasManageDefaultBranchPermission(artifact.userPermissions); } } return false; - }, [artifact, artifactDef?.artifactType]); + }, [artifact, artifactType]); const isManageProtectedBranchesPermitted = useMemo(() => { if (artifact) { - if (artifactDef?.artifactType === GitArtifactType.Application) { + if (artifactType === GitArtifactType.Application) { return hasManageProtectedBranchesPermission(artifact.userPermissions); } } return false; - }, [artifact, artifactDef?.artifactType]); + }, [artifact, artifactType]); const isManageAutocommitPermitted = useMemo(() => { if (artifact) { - if (artifactDef?.artifactType === GitArtifactType.Application) { + if (artifactType === GitArtifactType.Application) { return hasManageAutoCommitPermission(artifact.userPermissions); } } return false; - }, [artifact, artifactDef?.artifactType]); + }, [artifact, artifactType]); return { isConnectPermitted, diff --git a/app/client/src/git/hooks/useGlobalProfile.ts b/app/client/src/git/hooks/useGlobalProfile.ts index 3cc3a80aad98..f319f9c1f5db 100644 --- a/app/client/src/git/hooks/useGlobalProfile.ts +++ b/app/client/src/git/hooks/useGlobalProfile.ts @@ -1,9 +1,9 @@ import type { UpdateGlobalProfileRequestParams } from "git/requests/updateGlobalProfileRequest.types"; -import { gitGlobalActions } from "git/store/gitGlobalSlice"; +import { gitConfigActions } from "git/store/gitConfigSlice"; import { selectFetchGlobalProfileState, selectUpdateGlobalProfileState, -} from "git/store/selectors/gitGlobalSelectors"; +} from "git/store/selectors/gitConfigSelectors"; import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; @@ -16,7 +16,7 @@ export default function useGlobalProfile() { ); const fetchGlobalProfile = useCallback(() => { - dispatch(gitGlobalActions.fetchGlobalProfileInit()); + dispatch(gitConfigActions.fetchGlobalProfileInit()); }, [dispatch]); const updateGlobalProfileState = useSelector((state: GitRootState) => @@ -25,7 +25,7 @@ export default function useGlobalProfile() { const updateGlobalProfile = useCallback( (params: UpdateGlobalProfileRequestParams) => { - dispatch(gitGlobalActions.updateGlobalProfileInit(params)); + dispatch(gitConfigActions.updateGlobalProfileInit(params)); }, [dispatch], ); diff --git a/app/client/src/git/hooks/useGlobalSSHKey.ts b/app/client/src/git/hooks/useGlobalSSHKey.ts deleted file mode 100644 index ac7216045a6a..000000000000 --- a/app/client/src/git/hooks/useGlobalSSHKey.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; -import { selectFetchGlobalSSHKeyState } from "git/store/selectors/gitGlobalSelectors"; -import { gitGlobalActions } from "git/store/gitGlobalSlice"; - -export default function useGlobalSSHKey() { - const dispatch = useDispatch(); - - const globalSSHKeyState = useSelector(selectFetchGlobalSSHKeyState); - - const fetchGlobalSSHKey = useCallback( - (keyType: string) => { - dispatch(gitGlobalActions.fetchGlobalSSHKeyInit({ keyType })); - }, - [dispatch], - ); - - const resetGlobalSSHKey = useCallback(() => { - dispatch(gitGlobalActions.resetGlobalSSHKey()); - }, [dispatch]); - - return { - globalSSHKey: globalSSHKeyState?.value ?? null, - globalSSHKeyError: globalSSHKeyState?.error ?? null, - isFetchGlobalSSHKeyLoading: globalSSHKeyState?.loading ?? false, - fetchGlobalSSHKey, - resetGlobalSSHKey, - }; -} diff --git a/app/client/src/git/hooks/useImport.ts b/app/client/src/git/hooks/useImport.ts deleted file mode 100644 index 62069b888d68..000000000000 --- a/app/client/src/git/hooks/useImport.ts +++ /dev/null @@ -1,38 +0,0 @@ -import { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; -import { - selectGitImportState, - selectImportModalOpen, -} from "git/store/selectors/gitGlobalSelectors"; -import { gitGlobalActions } from "git/store/gitGlobalSlice"; -import type { GitImportRequestParams } from "git/requests/gitImportRequest.types"; - -export default function useImport() { - const dispatch = useDispatch(); - - const gitImportState = useSelector(selectGitImportState); - - const gitImport = useCallback( - (params: GitImportRequestParams) => { - dispatch(gitGlobalActions.gitImportInit(params)); - }, - [dispatch], - ); - - const isImportModalOpen = useSelector(selectImportModalOpen); - - const toggleImportModal = useCallback( - (open: boolean) => { - dispatch(gitGlobalActions.toggleImportModal({ open })); - }, - [dispatch], - ); - - return { - isGitImportLoading: gitImportState?.loading ?? false, - gitImportError: gitImportState?.error ?? null, - gitImport, - isImportModalOpen: isImportModalOpen ?? false, - toggleImportModal, - }; -} diff --git a/app/client/src/git/hooks/useLocalProfile.ts b/app/client/src/git/hooks/useLocalProfile.ts index 8d77899a7602..e770ad6356bc 100644 --- a/app/client/src/git/hooks/useLocalProfile.ts +++ b/app/client/src/git/hooks/useLocalProfile.ts @@ -4,40 +4,36 @@ import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { selectFetchLocalProfileState, selectUpdateLocalProfileState, -} from "git/store/selectors/gitArtifactSelectors"; +} from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useDispatch, useSelector } from "react-redux"; export default function useLocalProfile() { const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const fetchLocalProfileState = useArtifactSelector( - selectFetchLocalProfileState, + const fetchLocalProfileState = useSelector((state: GitRootState) => + selectFetchLocalProfileState(state, artifactDef), ); const fetchLocalProfile = useCallback(() => { - if (artifactDef) { - dispatch(gitArtifactActions.fetchLocalProfileInit({ artifactDef })); - } + dispatch(gitArtifactActions.fetchLocalProfileInit(artifactDef)); }, [artifactDef, dispatch]); - const updateLocalProfileState = useArtifactSelector( - selectUpdateLocalProfileState, + const updateLocalProfileState = useSelector((state: GitRootState) => + selectUpdateLocalProfileState(state, artifactDef), ); const updateLocalProfile = useCallback( (params: UpdateLocalProfileRequestParams) => { - if (artifactDef) { - dispatch( - gitArtifactActions.updateLocalProfileInit({ - artifactDef, - ...params, - }), - ); - } + dispatch( + gitArtifactActions.updateLocalProfileInit({ + ...artifactDef, + ...params, + }), + ); }, [artifactDef, dispatch], ); diff --git a/app/client/src/git/hooks/useMerge.ts b/app/client/src/git/hooks/useMerge.ts index 8fa79b16049f..f7394601b191 100644 --- a/app/client/src/git/hooks/useMerge.ts +++ b/app/client/src/git/hooks/useMerge.ts @@ -3,10 +3,10 @@ import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { selectMergeState, selectMergeStatusState, -} from "git/store/selectors/gitArtifactSelectors"; +} from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useDispatch, useSelector } from "react-redux"; export default function useMerge() { const { artifact, artifactDef } = useGitContext(); @@ -14,46 +14,44 @@ export default function useMerge() { const dispatch = useDispatch(); // merge - const mergeState = useArtifactSelector(selectMergeState); + const mergeState = useSelector((state: GitRootState) => + selectMergeState(state, artifactDef), + ); const merge = useCallback(() => { - if (artifactDef) { - dispatch(gitArtifactActions.mergeInit({ artifactDef })); - } + dispatch(gitArtifactActions.mergeInit(artifactDef)); }, [artifactDef, dispatch]); // merge status - const mergeStatusState = useArtifactSelector(selectMergeStatusState); + const mergeStatusState = useSelector((state: GitRootState) => + selectMergeStatusState(state, artifactDef), + ); const fetchMergeStatus = useCallback( (sourceBranch: string, destinationBranch: string) => { - if (artifactDef) { - dispatch( - gitArtifactActions.fetchMergeStatusInit({ - artifactDef, - artifactId: artifactId ?? "", - sourceBranch, - destinationBranch, - }), - ); - } + dispatch( + gitArtifactActions.fetchMergeStatusInit({ + ...artifactDef, + artifactId: artifactId ?? "", + sourceBranch, + destinationBranch, + }), + ); }, [artifactId, artifactDef, dispatch], ); const clearMergeStatus = useCallback(() => { - if (artifactDef) { - dispatch(gitArtifactActions.clearMergeStatus({ artifactDef })); - } + dispatch(gitArtifactActions.clearMergeStatus(artifactDef)); }, [artifactDef, dispatch]); return { isMergeLoading: mergeState?.loading ?? false, - mergeError: mergeState?.error ?? null, + mergeError: mergeState?.error, merge, - mergeStatus: mergeStatusState?.value ?? null, + mergeStatus: mergeStatusState?.value, isFetchMergeStatusLoading: mergeStatusState?.loading ?? false, - fetchMergeStatusError: mergeStatusState?.error ?? null, + fetchMergeStatusError: mergeStatusState?.error, fetchMergeStatus, clearMergeStatus, }; diff --git a/app/client/src/git/hooks/useMetadata.ts b/app/client/src/git/hooks/useMetadata.ts index 2ccd15d7ec89..9bd5356ad763 100644 --- a/app/client/src/git/hooks/useMetadata.ts +++ b/app/client/src/git/hooks/useMetadata.ts @@ -1,12 +1,26 @@ -import { selectMetadataState } from "git/store/selectors/gitArtifactSelectors"; -import useArtifactSelector from "./useArtifactSelector"; +import { useGitContext } from "git/components/GitContextProvider"; +import { + selectGitConnected, + selectMetadataState, +} from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; +import { useSelector } from "react-redux"; export default function useMetadata() { - const metadataState = useArtifactSelector(selectMetadataState); + const { artifactDef } = useGitContext(); + + const metadataState = useSelector((state: GitRootState) => + selectMetadataState(state, artifactDef), + ); + + const isGitConnected = useSelector((state: GitRootState) => + selectGitConnected(state, artifactDef), + ); return { metadata: metadataState?.value ?? null, isFetchMetadataLoading: metadataState?.loading ?? false, fetchMetadataError: metadataState?.error ?? null, + isGitConnected, }; } diff --git a/app/client/src/git/hooks/useOps.ts b/app/client/src/git/hooks/useOps.ts index 9b15bd035d85..32eec997cf25 100644 --- a/app/client/src/git/hooks/useOps.ts +++ b/app/client/src/git/hooks/useOps.ts @@ -5,10 +5,10 @@ import { selectConflictErrorModalOpen, selectOpsModalOpen, selectOpsModalTab, -} from "git/store/selectors/gitArtifactSelectors"; +} from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useDispatch, useSelector } from "react-redux"; export default function useOps() { const { artifactDef } = useGitContext(); @@ -16,40 +16,42 @@ export default function useOps() { const dispatch = useDispatch(); // ops modal - const opsModalOpen = useArtifactSelector(selectOpsModalOpen); + const opsModalOpen = useSelector((state: GitRootState) => + selectOpsModalOpen(state, artifactDef), + ); - const opsModalTab = useArtifactSelector(selectOpsModalTab); + const opsModalTab = useSelector((state: GitRootState) => + selectOpsModalTab(state, artifactDef), + ); const toggleOpsModal = useCallback( (open: boolean, tab: keyof typeof GitOpsTab = GitOpsTab.Deploy) => { - if (artifactDef) { - dispatch(gitArtifactActions.toggleOpsModal({ artifactDef, open, tab })); - } + dispatch( + gitArtifactActions.toggleOpsModal({ ...artifactDef, open, tab }), + ); }, [artifactDef, dispatch], ); // conflict error modal - const conflictErrorModalOpen = useArtifactSelector( - selectConflictErrorModalOpen, + const conflictErrorModalOpen = useSelector((state: GitRootState) => + selectConflictErrorModalOpen(state, artifactDef), ); const toggleConflictErrorModal = useCallback( (open: boolean) => { - if (artifactDef) { - dispatch( - gitArtifactActions.toggleConflictErrorModal({ artifactDef, open }), - ); - } + dispatch( + gitArtifactActions.toggleConflictErrorModal({ ...artifactDef, open }), + ); }, [artifactDef, dispatch], ); return { opsModalTab, - isOpsModalOpen: opsModalOpen ?? false, + opsModalOpen, toggleOpsModal, - isConflictErrorModalOpen: conflictErrorModalOpen ?? false, + conflictErrorModalOpen, toggleConflictErrorModal, }; } diff --git a/app/client/src/git/hooks/useProtectedBranches.ts b/app/client/src/git/hooks/useProtectedBranches.ts index 6ec68ee23b74..fa3b2ef89307 100644 --- a/app/client/src/git/hooks/useProtectedBranches.ts +++ b/app/client/src/git/hooks/useProtectedBranches.ts @@ -2,55 +2,55 @@ import { useGitContext } from "git/components/GitContextProvider"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { selectFetchProtectedBranchesState, + selectProtectedMode, selectUpdateProtectedBranchesState, -} from "git/store/selectors/gitArtifactSelectors"; +} from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useDispatch, useSelector } from "react-redux"; function useProtectedBranches() { const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const fetchProtectedBranchesState = useArtifactSelector( - selectFetchProtectedBranchesState, + const fetchProtectedBranchesState = useSelector((state: GitRootState) => + selectFetchProtectedBranchesState(state, artifactDef), ); const fetchProtectedBranches = useCallback(() => { - if (artifactDef) { - dispatch(gitArtifactActions.fetchProtectedBranchesInit({ artifactDef })); - } + dispatch(gitArtifactActions.fetchProtectedBranchesInit(artifactDef)); }, [dispatch, artifactDef]); - const updateProtectedBranchesState = useArtifactSelector( - selectUpdateProtectedBranchesState, + const updateProtectedBranchesState = useSelector((state: GitRootState) => + selectUpdateProtectedBranchesState(state, artifactDef), ); const updateProtectedBranches = useCallback( (branches: string[]) => { - if (artifactDef) { - dispatch( - gitArtifactActions.updateProtectedBranchesInit({ - artifactDef, - branchNames: branches, - }), - ); - } + dispatch( + gitArtifactActions.updateProtectedBranchesInit({ + ...artifactDef, + branchNames: branches, + }), + ); }, [dispatch, artifactDef], ); + const isProtectedMode = useSelector((state: GitRootState) => + selectProtectedMode(state, artifactDef), + ); + return { - protectedBranches: fetchProtectedBranchesState?.value ?? null, - isFetchProtectedBranchesLoading: - fetchProtectedBranchesState?.loading ?? false, - fetchProtectedBranchesError: fetchProtectedBranchesState?.error ?? null, + protectedBranches: fetchProtectedBranchesState.value, + isFetchProtectedBranchesLoading: fetchProtectedBranchesState.loading, + fetchProtectedBranchesError: fetchProtectedBranchesState.error, fetchProtectedBranches, - isUpdateProtectedBranchesLoading: - updateProtectedBranchesState?.loading ?? false, - updateProtectedBranchesError: updateProtectedBranchesState?.error ?? null, + isUpdateProtectedBranchesLoading: updateProtectedBranchesState.loading, + updateProtectedBranchesError: updateProtectedBranchesState.error, updateProtectedBranches, + isProtectedMode, }; } diff --git a/app/client/src/git/hooks/useProtectedMode.ts b/app/client/src/git/hooks/useProtectedMode.ts deleted file mode 100644 index e8e86e9f04a2..000000000000 --- a/app/client/src/git/hooks/useProtectedMode.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { selectProtectedMode } from "git/store/selectors/gitArtifactSelectors"; -import useArtifactSelector from "./useArtifactSelector"; - -export default function useProtectedMode() { - const isProtectedMode = useArtifactSelector(selectProtectedMode); - - return isProtectedMode ?? false; -} diff --git a/app/client/src/git/hooks/usePull.ts b/app/client/src/git/hooks/usePull.ts index 19900c98f38e..992866f2c277 100644 --- a/app/client/src/git/hooks/usePull.ts +++ b/app/client/src/git/hooks/usePull.ts @@ -1,26 +1,26 @@ import { useGitContext } from "git/components/GitContextProvider"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; -import { selectPullState } from "git/store/selectors/gitArtifactSelectors"; +import { selectPullState } from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useDispatch, useSelector } from "react-redux"; export default function usePull() { const { artifact, artifactDef } = useGitContext(); const artifactId = artifact?.id; const dispatch = useDispatch(); - const pullState = useArtifactSelector(selectPullState); + const pullState = useSelector((state: GitRootState) => + selectPullState(state, artifactDef), + ); const pull = useCallback(() => { - if (artifactDef) { - dispatch( - gitArtifactActions.pullInit({ - artifactDef, - artifactId: artifactId ?? "", - }), - ); - } + dispatch( + gitArtifactActions.pullInit({ + ...artifactDef, + artifactId: artifactId ?? "", + }), + ); }, [artifactDef, artifactId, dispatch]); return { diff --git a/app/client/src/git/hooks/useSSHKey.ts b/app/client/src/git/hooks/useSSHKey.ts deleted file mode 100644 index 93c95ade8d31..000000000000 --- a/app/client/src/git/hooks/useSSHKey.ts +++ /dev/null @@ -1,63 +0,0 @@ -import { useGitContext } from "git/components/GitContextProvider"; -import { gitArtifactActions } from "git/store/gitArtifactSlice"; -import { - selectFetchSSHKeysState, - selectGenerateSSHKeyState, -} from "git/store/selectors/gitArtifactSelectors"; -import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; - -export default function useSSHKey() { - const { artifactDef } = useGitContext(); - - const dispatch = useDispatch(); - - const fetchSSHKeyState = useArtifactSelector(selectFetchSSHKeysState); - - const fetchSSHKey = useCallback(() => { - if (artifactDef) { - dispatch(gitArtifactActions.fetchSSHKeyInit({ artifactDef })); - } - }, [artifactDef, dispatch]); - - const resetFetchSSHKey = useCallback(() => { - if (artifactDef) { - dispatch(gitArtifactActions.resetFetchSSHKey({ artifactDef })); - } - }, [artifactDef, dispatch]); - - const generateSSHKeyState = useArtifactSelector(selectGenerateSSHKeyState); - - const generateSSHKey = useCallback( - (keyType: string) => { - if (artifactDef) { - dispatch( - gitArtifactActions.generateSSHKeyInit({ - artifactDef, - keyType, - }), - ); - } - }, - [artifactDef, dispatch], - ); - - const resetGenerateSSHKey = useCallback(() => { - if (artifactDef) { - dispatch(gitArtifactActions.resetGenerateSSHKey({ artifactDef })); - } - }, [artifactDef, dispatch]); - - return { - sshKey: fetchSSHKeyState?.value ?? null, - isFetchSSHKeyLoading: fetchSSHKeyState?.loading ?? false, - fetchSSHKeyError: fetchSSHKeyState?.error ?? null, - fetchSSHKey, - resetFetchSSHKey, - isGenerateSSHKeyLoading: generateSSHKeyState?.loading ?? false, - generateSSHKeyError: generateSSHKeyState?.error ?? null, - generateSSHKey, - resetGenerateSSHKey, - }; -} diff --git a/app/client/src/git/hooks/useSettings.ts b/app/client/src/git/hooks/useSettings.ts index 0a8b48aa368c..d94f9c0e530b 100644 --- a/app/client/src/git/hooks/useSettings.ts +++ b/app/client/src/git/hooks/useSettings.ts @@ -4,37 +4,39 @@ import { gitArtifactActions } from "git/store/gitArtifactSlice"; import { selectSettingsModalOpen, selectSettingsModalTab, -} from "git/store/selectors/gitArtifactSelectors"; +} from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useDispatch, useSelector } from "react-redux"; export default function useSettings() { const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const settingsModalOpen = useArtifactSelector(selectSettingsModalOpen); + const settingsModalOpen = useSelector((state: GitRootState) => + selectSettingsModalOpen(state, artifactDef), + ); - const settingsModalTab = useArtifactSelector(selectSettingsModalTab); + const settingsModalTab = useSelector((state: GitRootState) => + selectSettingsModalTab(state, artifactDef), + ); const toggleSettingsModal = useCallback( ( open: boolean, tab: keyof typeof GitSettingsTab = GitSettingsTab.General, ) => { - if (artifactDef) { - dispatch( - gitArtifactActions.toggleSettingsModal({ artifactDef, open, tab }), - ); - } + dispatch( + gitArtifactActions.toggleSettingsModal({ ...artifactDef, open, tab }), + ); }, [artifactDef, dispatch], ); return { isSettingsModalOpen: settingsModalOpen ?? false, - settingsModalTab: settingsModalTab, + settingsModalTab: settingsModalTab ?? GitSettingsTab.General, toggleSettingsModal, }; } diff --git a/app/client/src/git/hooks/useStatus.ts b/app/client/src/git/hooks/useStatus.ts index 37a5584911aa..97b09b57498a 100644 --- a/app/client/src/git/hooks/useStatus.ts +++ b/app/client/src/git/hooks/useStatus.ts @@ -1,33 +1,31 @@ import { useGitContext } from "git/components/GitContextProvider"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; -import { selectStatusState } from "git/store/selectors/gitArtifactSelectors"; +import { selectStatusState } from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitRootState } from "git/store/types"; import { useCallback } from "react"; -import { useDispatch } from "react-redux"; -import useArtifactSelector from "./useArtifactSelector"; +import { useDispatch, useSelector } from "react-redux"; export default function useStatus() { - const { artifact, artifactDef } = useGitContext(); - const artifactId = artifact?.id; + const { artifactDef } = useGitContext(); const dispatch = useDispatch(); - const statusState = useArtifactSelector(selectStatusState); + const statusState = useSelector((state: GitRootState) => + selectStatusState(state, artifactDef), + ); const fetchStatus = useCallback(() => { - if (artifactDef && artifactId) { - dispatch( - gitArtifactActions.fetchStatusInit({ - artifactId, - artifactDef, - compareRemote: true, - }), - ); - } - }, [artifactDef, artifactId, dispatch]); + dispatch( + gitArtifactActions.fetchStatusInit({ + ...artifactDef, + compareRemote: true, + }), + ); + }, [artifactDef, dispatch]); return { - status: statusState?.value ?? null, + status: statusState?.value, isFetchStatusLoading: statusState?.loading ?? false, - fetchStatusError: statusState?.error ?? null, + fetchStatusError: statusState?.error, fetchStatus, }; } diff --git a/app/client/src/git/index.ts b/app/client/src/git/index.ts deleted file mode 100644 index 892ca77d7f43..000000000000 --- a/app/client/src/git/index.ts +++ /dev/null @@ -1,39 +0,0 @@ -// enums -export { GitArtifactType, GitOpsTab } from "./constants/enums"; - -// components -export { default as GitContextProvider } from "./components/GitContextProvider"; -export { default as GitModals } from "./ee/components/GitModals"; -export { default as GitImportModal } from "./components/ImportModal"; -export { default as GitQuickActions } from "./components/QuickActions"; -export { default as GitProtectedBranchCallout } from "./components/ProtectedBranchCallout"; -export { default as GitGlobalProfile } from "./components/GlobalProfile"; -export { default as GitDeployMenuItems } from "./components/DeployMenuItems"; - -// hooks -export { default as useGitCurrentBranch } from "./hooks/useCurrentBranch"; -export { default as useGitProtectedMode } from "./hooks/useProtectedMode"; -export { default as useGitConnected } from "./hooks/useConnected"; -export { default as useGitOps } from "./hooks/useOps"; - -// actions -import { gitGlobalActions } from "./store/gitGlobalSlice"; -export const fetchGitGlobalProfile = gitGlobalActions.fetchGlobalProfileInit; -export const toggleGitImportModal = gitGlobalActions.toggleImportModal; - -import { gitArtifactActions } from "./store/gitArtifactSlice"; -export const gitConnectSuccess = gitArtifactActions.connectSuccess; - -// selectors -export { - selectCurrentBranch as selectGitCurrentBranch, - selectProtectedMode as selectGitProtectedMode, -} from "./store/selectors/gitArtifactSelectors"; - -// types -export type { - GitArtifactDef, - GitArtifactRootReduxState, - GitGlobalReduxState, -} from "./store/types"; -export type { ConnectSuccessPayload as GitConnectSuccessPayload } from "./store/actions/connectActions"; diff --git a/app/client/src/git/requests/connectRequest.types.ts b/app/client/src/git/requests/connectRequest.types.ts index d47cc4114b21..7e31cf32bf82 100644 --- a/app/client/src/git/requests/connectRequest.types.ts +++ b/app/client/src/git/requests/connectRequest.types.ts @@ -1,5 +1,4 @@ import type { ApiResponse } from "api/types"; -import type { ApplicationPayload } from "entities/Application"; export interface ConnectRequestParams { remoteUrl: string; @@ -10,6 +9,20 @@ export interface ConnectRequestParams { }; } -export interface ConnectResponseData extends ApplicationPayload {} +export interface ConnectResponseData { + id: string; + baseId: string; + gitApplicationMetadata: { + branchName: string; + browserSupportedRemoteUrl: string; + defaultApplicationId: string; + defaultArtifactId: string; + defaultBranchName: string; + isRepoPrivate: boolean; + lastCommitedAt: string; + remoteUrl: string; + repoName: string; + }; +} export type ConnectResponse = ApiResponse; diff --git a/app/client/src/git/requests/disconnectRequest.types.ts b/app/client/src/git/requests/disconnectRequest.types.ts index b1cd5827d951..2cbf5969ccca 100644 --- a/app/client/src/git/requests/disconnectRequest.types.ts +++ b/app/client/src/git/requests/disconnectRequest.types.ts @@ -1,6 +1,7 @@ import type { ApiResponse } from "api/types"; -import type { ApplicationPayload } from "entities/Application"; -export interface DisconnectResponseData extends ApplicationPayload {} +export interface DisconnectResponseData { + [key: string]: string; +} export type DisconnectResponse = ApiResponse; diff --git a/app/client/src/git/requests/fetchGlobalSSHKeyRequest.ts b/app/client/src/git/requests/fetchGlobalSSHKeyRequest.ts deleted file mode 100644 index 00d900637f42..000000000000 --- a/app/client/src/git/requests/fetchGlobalSSHKeyRequest.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { AxiosPromise } from "axios"; -import { GIT_BASE_URL } from "./constants"; -import Api from "api/Api"; -import type { - FetchGlobalSSHKeyRequestParams, - FetchGlobalSSHKeyResponse, -} from "./fetchGlobalSSHKeyRequest.types"; - -export default async function fetchGlobalSSHKeyRequest( - params: FetchGlobalSSHKeyRequestParams, -): AxiosPromise { - const url = `${GIT_BASE_URL}/import/keys?keyType=${params.keyType}`; - - return Api.get(url); -} diff --git a/app/client/src/git/requests/fetchGlobalSSHKeyRequest.types.ts b/app/client/src/git/requests/fetchGlobalSSHKeyRequest.types.ts deleted file mode 100644 index 7b092ceccff2..000000000000 --- a/app/client/src/git/requests/fetchGlobalSSHKeyRequest.types.ts +++ /dev/null @@ -1,15 +0,0 @@ -import type { ApiResponse } from "api/types"; - -export interface FetchGlobalSSHKeyRequestParams { - keyType: string; -} - -export interface FetchGlobalSSHKeyResponseData { - publicKey: string; - docUrl: string; - isRegeneratedKey: boolean; - regeneratedKey: boolean; -} - -export type FetchGlobalSSHKeyResponse = - ApiResponse; diff --git a/app/client/src/git/requests/fetchStatusRequest.types.ts b/app/client/src/git/requests/fetchStatusRequest.types.ts index feb064d3618d..c4400688b794 100644 --- a/app/client/src/git/requests/fetchStatusRequest.types.ts +++ b/app/client/src/git/requests/fetchStatusRequest.types.ts @@ -24,7 +24,6 @@ export interface FetchStatusResponseData { modifiedDatasources: number; modifiedJSLibs: number; modifiedJSObjects: number; - modifiedPackages: number; modifiedModuleInstances: number; modifiedModules: number; modifiedPages: number; diff --git a/app/client/src/git/requests/generateSSHKeyRequest.ts b/app/client/src/git/requests/generateSSHKeyRequest.ts index b0bea4f20ff8..896426347f30 100644 --- a/app/client/src/git/requests/generateSSHKeyRequest.ts +++ b/app/client/src/git/requests/generateSSHKeyRequest.ts @@ -3,14 +3,16 @@ import type { GenerateSSHKeyRequestParams, GenerateSSHKeyResponse, } from "./generateSSHKeyRequest.types"; -import { APPLICATION_BASE_URL } from "./constants"; +import { APPLICATION_BASE_URL, GIT_BASE_URL } from "./constants"; import Api from "api/Api"; export default async function generateSSHKeyRequest( baseApplicationId: string, params: GenerateSSHKeyRequestParams, ): AxiosPromise { - const url = `${APPLICATION_BASE_URL}/ssh-keypair/${baseApplicationId}?keyType=${params.keyType}`; + const url = params.isImport + ? `${GIT_BASE_URL}/import/keys?keyType=${params.keyType}` + : `${APPLICATION_BASE_URL}/ssh-keypair/${baseApplicationId}?keyType=${params.keyType}`; - return Api.post(url); + return params.isImport ? Api.get(url) : Api.post(url); } diff --git a/app/client/src/git/requests/generateSSHKeyRequest.types.ts b/app/client/src/git/requests/generateSSHKeyRequest.types.ts index fbc4a4c0e959..45374e42d5b1 100644 --- a/app/client/src/git/requests/generateSSHKeyRequest.types.ts +++ b/app/client/src/git/requests/generateSSHKeyRequest.types.ts @@ -2,6 +2,7 @@ import type { ApiResponse } from "api/types"; export interface GenerateSSHKeyRequestParams { keyType: string; + isImport: boolean; } export interface GenerateSSHKeyResponseData { diff --git a/app/client/src/git/requests/gitImportRequest.types.ts b/app/client/src/git/requests/gitImportRequest.types.ts index 4eb29b11a88b..9f76b379c9cc 100644 --- a/app/client/src/git/requests/gitImportRequest.types.ts +++ b/app/client/src/git/requests/gitImportRequest.types.ts @@ -1,6 +1,4 @@ import type { ApiResponse } from "api/types"; -import type { ApplicationResponsePayload } from "ee/api/ApplicationApi"; -import type { Datasource } from "entities/Datasource"; export interface GitImportRequestParams { remoteUrl: string; @@ -12,9 +10,19 @@ export interface GitImportRequestParams { } export interface GitImportResponseData { - application: ApplicationResponsePayload; - isPartialImport: boolean; - unconfiguredDatasourceList?: Datasource[]; + id: string; + baseId: string; + gitApplicationMetadata: { + branchName: string; + browserSupportedRemoteUrl: string; + defaultApplicationId: string; + defaultArtifactId: string; + defaultBranchName: string; + isRepoPrivate: boolean; + lastCommitedAt: string; + remoteUrl: string; + repoName: string; + }; } export type GitImportResponse = ApiResponse; diff --git a/app/client/src/git/sagas/checkoutBranchSaga.ts b/app/client/src/git/sagas/checkoutBranchSaga.ts index 7fc454f36bc0..34e48434626c 100644 --- a/app/client/src/git/sagas/checkoutBranchSaga.ts +++ b/app/client/src/git/sagas/checkoutBranchSaga.ts @@ -25,7 +25,8 @@ import { captureException } from "@sentry/react"; export default function* checkoutBranchSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef, artifactId, branchName } = action.payload; + const { artifactType, baseArtifactId, branchName } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: CheckoutBranchResponse | undefined; try { @@ -33,12 +34,12 @@ export default function* checkoutBranchSaga( branchName, }; - response = yield call(checkoutBranchRequest, artifactId, params); + response = yield call(checkoutBranchRequest, baseArtifactId, params); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { - if (artifactDef.artifactType === GitArtifactType.Application) { - yield put(gitArtifactActions.checkoutBranchSuccess({ artifactDef })); + if (artifactType === GitArtifactType.Application) { + yield put(gitArtifactActions.checkoutBranchSuccess(basePayload)); const trimmedBranch = branchName.replace(/^origin\//, ""); const destinationHref = addBranchParam(trimmedBranch); @@ -48,7 +49,7 @@ export default function* checkoutBranchSaga( yield put( gitArtifactActions.toggleBranchPopup({ - artifactDef, + ...basePayload, open: false, }), ); @@ -117,7 +118,7 @@ export default function* checkoutBranchSaga( yield put( gitArtifactActions.checkoutBranchError({ - artifactDef, + ...basePayload, error, }), ); diff --git a/app/client/src/git/sagas/commitSaga.ts b/app/client/src/git/sagas/commitSaga.ts index 7ebcb70b9a71..159021acc145 100644 --- a/app/client/src/git/sagas/commitSaga.ts +++ b/app/client/src/git/sagas/commitSaga.ts @@ -17,7 +17,8 @@ import { validateResponse } from "sagas/ErrorSagas"; export default function* commitSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef, artifactId } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: CommitResponse | undefined; @@ -27,21 +28,20 @@ export default function* commitSaga( doPush: action.payload.doPush, }; - response = yield call(commitRequest, artifactId, params); + response = yield call(commitRequest, baseArtifactId, params); const isValidResponse: boolean = yield validateResponse(response, false); if (isValidResponse) { - yield put(gitArtifactActions.commitSuccess({ artifactDef })); + yield put(gitArtifactActions.commitSuccess(basePayload)); yield put( gitArtifactActions.fetchStatusInit({ - artifactDef, - artifactId, + ...basePayload, compareRemote: true, }), ); - if (artifactDef.artifactType === GitArtifactType.Application) { + if (artifactType === GitArtifactType.Application) { // ! case for updating lastDeployedAt in application manually? } } @@ -52,13 +52,13 @@ export default function* commitSaga( if (error.code === GitErrorCodes.REPO_LIMIT_REACHED) { yield put( gitArtifactActions.toggleRepoLimitErrorModal({ - artifactDef, + ...basePayload, open: true, }), ); } - yield put(gitArtifactActions.commitError({ artifactDef, error })); + yield put(gitArtifactActions.commitError({ ...basePayload, error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/connectSaga.ts b/app/client/src/git/sagas/connectSaga.ts index b6de0cdea53e..b13c2f6c2c2a 100644 --- a/app/client/src/git/sagas/connectSaga.ts +++ b/app/client/src/git/sagas/connectSaga.ts @@ -8,7 +8,7 @@ import { GitArtifactType, GitErrorCodes } from "../constants/enums"; import type { GitArtifactPayloadAction } from "../store/types"; import type { ConnectInitPayload } from "../store/actions/connectActions"; -import { call, put, select } from "redux-saga/effects"; +import { call, put } from "redux-saga/effects"; // Internal dependencies import { validateResponse } from "sagas/ErrorSagas"; @@ -17,12 +17,12 @@ import history from "utils/history"; import { addBranchParam } from "constants/routes"; import log from "loglevel"; import { captureException } from "@sentry/react"; -import { getCurrentPageId } from "selectors/editorSelectors"; export default function* connectSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: ConnectResponse | undefined; @@ -32,50 +32,34 @@ export default function* connectSaga( gitProfile: action.payload.gitProfile, }; - response = yield call(connectRequest, artifactDef.baseArtifactId, params); + response = yield call(connectRequest, baseArtifactId, params); const isValidResponse: boolean = yield validateResponse(response, false); if (response && isValidResponse) { - yield put( - gitArtifactActions.connectSuccess({ - artifactDef, - responseData: response.data, - }), - ); + yield put(gitArtifactActions.connectSuccess(basePayload)); // needs to happen only when artifactType is application - if (artifactDef.artifactType === GitArtifactType.Application) { - const pageId: string = yield select(getCurrentPageId); - - yield put(fetchPageAction(pageId)); - - const branch = response.data?.gitApplicationMetadata?.branchName; - - if (branch) { - const newUrl = addBranchParam(branch); + if (artifactType === GitArtifactType.Application) { + const { branchedPageId } = action.payload; - history.replace(newUrl); + if (branchedPageId) { + yield put(fetchPageAction(branchedPageId)); } + const branch = response.data.gitApplicationMetadata.branchName; + const newUrl = addBranchParam(branch); + + history.replace(newUrl); // ! case for updating lastDeployedAt in application manually? } yield put( gitArtifactActions.initGitForEditor({ - artifactDef, + ...basePayload, artifact: response.data, }), ); - yield put( - gitArtifactActions.toggleConnectModal({ artifactDef, open: false }), - ); - yield put( - gitArtifactActions.toggleConnectSuccessModal({ - artifactDef, - open: true, - }), - ); } } catch (e) { if (response && response.responseMeta.error) { @@ -84,13 +68,13 @@ export default function* connectSaga( if (GitErrorCodes.REPO_LIMIT_REACHED === error.code) { yield put( gitArtifactActions.toggleRepoLimitErrorModal({ - artifactDef, + ...basePayload, open: true, }), ); } - yield put(gitArtifactActions.connectError({ artifactDef, error })); + yield put(gitArtifactActions.connectError({ ...basePayload, error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/createBranchSaga.ts b/app/client/src/git/sagas/createBranchSaga.ts index d8aa65418977..7796f43d74bd 100644 --- a/app/client/src/git/sagas/createBranchSaga.ts +++ b/app/client/src/git/sagas/createBranchSaga.ts @@ -16,8 +16,8 @@ import log from "loglevel"; export default function* createBranchSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef, artifactId } = action.payload; - const basePayload = { artifactDef }; + const { artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: CreateBranchResponse | undefined; try { @@ -25,29 +25,27 @@ export default function* createBranchSaga( branchName: action.payload.branchName, }; - response = yield call(createBranchRequest, artifactId, params); + response = yield call(createBranchRequest, baseArtifactId, params); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { yield put(gitArtifactActions.createBranchSuccess(basePayload)); yield put( gitArtifactActions.toggleBranchPopup({ - artifactDef, + ...basePayload, open: false, }), ); yield put( gitArtifactActions.fetchBranchesInit({ - artifactDef, - artifactId, + ...basePayload, pruneBranches: true, }), ); yield put( gitArtifactActions.checkoutBranchInit({ - artifactDef, - artifactId, + ...basePayload, branchName: action.payload.branchName, }), ); @@ -58,7 +56,7 @@ export default function* createBranchSaga( yield put( gitArtifactActions.createBranchError({ - artifactDef, + ...basePayload, error, }), ); diff --git a/app/client/src/git/sagas/deleteBranchSaga.ts b/app/client/src/git/sagas/deleteBranchSaga.ts index ecf560889f1c..4f6bdde2f7fc 100644 --- a/app/client/src/git/sagas/deleteBranchSaga.ts +++ b/app/client/src/git/sagas/deleteBranchSaga.ts @@ -16,7 +16,8 @@ import { captureException } from "@sentry/react"; export default function* deleteBranchSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef, artifactId } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: DeleteBranchResponse | undefined; try { @@ -24,19 +25,14 @@ export default function* deleteBranchSaga( branchName: action.payload.branchName, }; - response = yield call( - deleteBranchRequest, - artifactDef.baseArtifactId, - params, - ); + response = yield call(deleteBranchRequest, baseArtifactId, params); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { - yield put(gitArtifactActions.deleteBranchSuccess({ artifactDef })); + yield put(gitArtifactActions.deleteBranchSuccess(basePayload)); yield put( gitArtifactActions.fetchBranchesInit({ - artifactDef, - artifactId, + ...basePayload, pruneBranches: true, }), ); @@ -45,7 +41,12 @@ export default function* deleteBranchSaga( if (response && response.responseMeta.error) { const { error } = response.responseMeta; - yield put(gitArtifactActions.deleteBranchError({ artifactDef, error })); + yield put( + gitArtifactActions.deleteBranchError({ + ...basePayload, + error, + }), + ); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/disconnectSaga.ts b/app/client/src/git/sagas/disconnectSaga.ts index ef6315c25cd5..3dc25f1ff079 100644 --- a/app/client/src/git/sagas/disconnectSaga.ts +++ b/app/client/src/git/sagas/disconnectSaga.ts @@ -12,30 +12,26 @@ import { validateResponse } from "sagas/ErrorSagas"; import history from "utils/history"; export default function* disconnectSaga(action: GitArtifactPayloadAction) { - const { artifactDef } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const artifactDef = { artifactType, baseArtifactId }; let response: DisconnectResponse | undefined; try { - response = yield call(disconnectRequest, artifactDef.baseArtifactId); + response = yield call(disconnectRequest, baseArtifactId); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { - yield put(gitArtifactActions.disconnectSuccess({ artifactDef })); + yield put(gitArtifactActions.disconnectSuccess(artifactDef)); const url = new URL(window.location.href); url.searchParams.delete(GIT_BRANCH_QUERY_KEY); - history.replace(url.toString().slice(url.origin.length)); - yield put(gitArtifactActions.unmount({ artifactDef })); - yield put( - gitArtifactActions.initGitForEditor({ - artifactDef, - artifact: response.data, - }), - ); - yield put(gitArtifactActions.closeDisconnectModal({ artifactDef })); + history.push(url.toString().slice(url.origin.length)); + yield put(gitArtifactActions.closeDisconnectModal(artifactDef)); + // !case: why? + // yield put(importAppViaGitStatusReset()); yield put( gitArtifactActions.toggleOpsModal({ - artifactDef, + ...artifactDef, open: false, tab: GitOpsTab.Deploy, }), @@ -56,7 +52,7 @@ export default function* disconnectSaga(action: GitArtifactPayloadAction) { if (response && response.responseMeta.error) { const { error } = response.responseMeta; - yield put(gitArtifactActions.disconnectError({ artifactDef, error })); + yield put(gitArtifactActions.disconnectError({ ...artifactDef, error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/fetchBranchesSaga.ts b/app/client/src/git/sagas/fetchBranchesSaga.ts index 5141db03e34f..465310e01a4f 100644 --- a/app/client/src/git/sagas/fetchBranchesSaga.ts +++ b/app/client/src/git/sagas/fetchBranchesSaga.ts @@ -14,7 +14,8 @@ import { captureException } from "@sentry/react"; export default function* fetchBranchesSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef, artifactId } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: FetchBranchesResponse | undefined; try { @@ -22,13 +23,13 @@ export default function* fetchBranchesSaga( pruneBranches: action.payload.pruneBranches, }; - response = yield call(fetchBranchesRequest, artifactId, params); + response = yield call(fetchBranchesRequest, baseArtifactId, params); const isValidResponse: boolean = yield validateResponse(response, false); if (response && isValidResponse) { yield put( gitArtifactActions.fetchBranchesSuccess({ - artifactDef, + ...basePayload, responseData: response.data, }), ); @@ -39,7 +40,7 @@ export default function* fetchBranchesSaga( yield put( gitArtifactActions.fetchBranchesError({ - artifactDef, + ...basePayload, error, }), ); diff --git a/app/client/src/git/sagas/fetchGlobalProfileSaga.ts b/app/client/src/git/sagas/fetchGlobalProfileSaga.ts index 86713acf8787..71e7ca1a9c29 100644 --- a/app/client/src/git/sagas/fetchGlobalProfileSaga.ts +++ b/app/client/src/git/sagas/fetchGlobalProfileSaga.ts @@ -1,12 +1,12 @@ import { call, put } from "redux-saga/effects"; import fetchGlobalProfileRequest from "../requests/fetchGlobalProfileRequest"; import type { FetchGlobalProfileResponse } from "../requests/fetchGlobalProfileRequest.types"; +import { gitConfigActions } from "../store/gitConfigSlice"; // internal dependencies import { validateResponse } from "sagas/ErrorSagas"; import log from "loglevel"; import { captureException } from "@sentry/react"; -import { gitGlobalActions } from "git/store/gitGlobalSlice"; export default function* fetchGlobalProfileSaga() { let response: FetchGlobalProfileResponse | undefined; @@ -18,7 +18,7 @@ export default function* fetchGlobalProfileSaga() { if (response && isValidResponse) { yield put( - gitGlobalActions.fetchGlobalProfileSuccess({ + gitConfigActions.fetchGlobalProfileSuccess({ responseData: response.data, }), ); @@ -28,7 +28,7 @@ export default function* fetchGlobalProfileSaga() { const { error } = response.responseMeta; yield put( - gitGlobalActions.fetchGlobalProfileError({ + gitConfigActions.fetchGlobalProfileError({ error, }), ); diff --git a/app/client/src/git/sagas/fetchGlobalSSHKeySaga.ts b/app/client/src/git/sagas/fetchGlobalSSHKeySaga.ts deleted file mode 100644 index e72711961844..000000000000 --- a/app/client/src/git/sagas/fetchGlobalSSHKeySaga.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { captureException } from "@sentry/react"; -import fetchGlobalSSHKeyRequest from "git/requests/fetchGlobalSSHKeyRequest"; -import type { - GenerateSSHKeyRequestParams, - GenerateSSHKeyResponse, -} from "git/requests/generateSSHKeyRequest.types"; -import type { FetchGlobalSSHKeyInitPayload } from "git/store/actions/fetchGlobalSSHKeyActions"; -import { gitGlobalActions } from "git/store/gitGlobalSlice"; -import type { GitArtifactPayloadAction } from "git/store/types"; -import log from "loglevel"; -import { call, put } from "redux-saga/effects"; -import { validateResponse } from "sagas/ErrorSagas"; - -export function* fetchGlobalSSHKeySaga( - action: GitArtifactPayloadAction, -) { - let response: GenerateSSHKeyResponse | undefined; - - try { - const params: GenerateSSHKeyRequestParams = { - keyType: action.payload.keyType, - }; - - response = yield call(fetchGlobalSSHKeyRequest, params); - const isValidResponse: boolean = yield validateResponse(response); - - if (response && isValidResponse) { - yield put( - gitGlobalActions.fetchGlobalSSHKeySuccess({ - responseData: response.data, - }), - ); - } - } catch (e) { - if (response && response.responseMeta.error) { - const { error } = response.responseMeta; - - yield put(gitGlobalActions.fetchGlobalSSHKeyError({ error })); - } else { - log.error(e); - captureException(e); - } - } -} diff --git a/app/client/src/git/sagas/fetchLocalProfileSaga.ts b/app/client/src/git/sagas/fetchLocalProfileSaga.ts index 28f24ef2198d..c568129beab9 100644 --- a/app/client/src/git/sagas/fetchLocalProfileSaga.ts +++ b/app/client/src/git/sagas/fetchLocalProfileSaga.ts @@ -10,17 +10,18 @@ import { captureException } from "@sentry/react"; export default function* fetchLocalProfileSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: FetchLocalProfileResponse | undefined; try { - response = yield call(fetchLocalProfileRequest, artifactDef.baseArtifactId); + response = yield call(fetchLocalProfileRequest, baseArtifactId); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { yield put( gitArtifactActions.fetchLocalProfileSuccess({ - artifactDef, + ...basePayload, responseData: response.data, }), ); @@ -30,7 +31,7 @@ export default function* fetchLocalProfileSaga( const { error } = response.responseMeta; yield put( - gitArtifactActions.fetchLocalProfileError({ artifactDef, error }), + gitArtifactActions.fetchLocalProfileError({ ...basePayload, error }), ); } else { log.error(e); diff --git a/app/client/src/git/sagas/fetchMergeStatusSaga.ts b/app/client/src/git/sagas/fetchMergeStatusSaga.ts index 024954b017c5..684233de206d 100644 --- a/app/client/src/git/sagas/fetchMergeStatusSaga.ts +++ b/app/client/src/git/sagas/fetchMergeStatusSaga.ts @@ -14,7 +14,8 @@ import { validateResponse } from "sagas/ErrorSagas"; export default function* fetchMergeStatusSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef, artifactId } = action.payload; + const { artifactId, artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: FetchMergeStatusResponse | undefined; try { @@ -29,7 +30,7 @@ export default function* fetchMergeStatusSaga( if (response && isValidResponse) { yield put( gitArtifactActions.fetchMergeStatusSuccess({ - artifactDef, + ...basePayload, responseData: response.data, }), ); @@ -39,7 +40,10 @@ export default function* fetchMergeStatusSaga( const { error } = response.responseMeta; yield put( - gitArtifactActions.fetchMergeStatusError({ artifactDef, error }), + gitArtifactActions.fetchMergeStatusError({ + ...basePayload, + error, + }), ); } else { log.error(e); diff --git a/app/client/src/git/sagas/fetchMetadataSaga.ts b/app/client/src/git/sagas/fetchMetadataSaga.ts index 9f8285847ee7..3e2029b6c6b8 100644 --- a/app/client/src/git/sagas/fetchMetadataSaga.ts +++ b/app/client/src/git/sagas/fetchMetadataSaga.ts @@ -8,17 +8,18 @@ import { call, put } from "redux-saga/effects"; import { validateResponse } from "sagas/ErrorSagas"; export default function* fetchMetadataSaga(action: GitArtifactPayloadAction) { - const { artifactDef } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: FetchMetadataResponse | undefined; try { - response = yield call(fetchMetadataRequest, artifactDef.baseArtifactId); + response = yield call(fetchMetadataRequest, baseArtifactId); const isValidResponse: boolean = yield validateResponse(response, false); if (response && isValidResponse) { yield put( gitArtifactActions.fetchMetadataSuccess({ - artifactDef, + ...basePayload, responseData: response.data, }), ); @@ -29,7 +30,7 @@ export default function* fetchMetadataSaga(action: GitArtifactPayloadAction) { yield put( gitArtifactActions.fetchMetadataError({ - artifactDef, + ...basePayload, error, }), ); diff --git a/app/client/src/git/sagas/fetchProtectedBranchesSaga.ts b/app/client/src/git/sagas/fetchProtectedBranchesSaga.ts index 62f36f8ce93c..9c81123ea26f 100644 --- a/app/client/src/git/sagas/fetchProtectedBranchesSaga.ts +++ b/app/client/src/git/sagas/fetchProtectedBranchesSaga.ts @@ -10,21 +10,19 @@ import { validateResponse } from "sagas/ErrorSagas"; export default function* fetchProtectedBranchesSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: FetchProtectedBranchesResponse | undefined; try { - response = yield call( - fetchProtectedBranchesRequest, - artifactDef.baseArtifactId, - ); + response = yield call(fetchProtectedBranchesRequest, baseArtifactId); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { yield put( gitArtifactActions.fetchProtectedBranchesSuccess({ - artifactDef, + ...basePayload, responseData: response.data, }), ); @@ -35,7 +33,7 @@ export default function* fetchProtectedBranchesSaga( yield put( gitArtifactActions.fetchProtectedBranchesError({ - artifactDef, + ...basePayload, error, }), ); diff --git a/app/client/src/git/sagas/fetchSSHKeySaga.ts b/app/client/src/git/sagas/fetchSSHKeySaga.ts index 16736e92f5d1..02f797edae66 100644 --- a/app/client/src/git/sagas/fetchSSHKeySaga.ts +++ b/app/client/src/git/sagas/fetchSSHKeySaga.ts @@ -8,17 +8,18 @@ import { call, put } from "redux-saga/effects"; import { validateResponse } from "sagas/ErrorSagas"; export function* fetchSSHKeySaga(action: GitArtifactPayloadAction) { - const { artifactDef } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const artifactDef = { artifactType, baseArtifactId }; let response: FetchSSHKeyResponse | undefined; try { - response = yield call(fetchSSHKeyRequest, artifactDef.baseArtifactId); + response = yield call(fetchSSHKeyRequest, baseArtifactId); const isValidResponse: boolean = yield validateResponse(response, false); if (response && isValidResponse) { yield put( gitArtifactActions.fetchSSHKeySuccess({ - artifactDef, + ...artifactDef, responseData: response.data, }), ); @@ -27,7 +28,7 @@ export function* fetchSSHKeySaga(action: GitArtifactPayloadAction) { if (response && response.responseMeta.error) { const { error } = response.responseMeta; - yield put(gitArtifactActions.fetchSSHKeyError({ artifactDef, error })); + yield put(gitArtifactActions.fetchSSHKeyError({ ...artifactDef, error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/fetchStatusSaga.ts b/app/client/src/git/sagas/fetchStatusSaga.ts index 733f18cce776..4c714a22c0da 100644 --- a/app/client/src/git/sagas/fetchStatusSaga.ts +++ b/app/client/src/git/sagas/fetchStatusSaga.ts @@ -11,17 +11,18 @@ import { validateResponse } from "sagas/ErrorSagas"; export default function* fetchStatusSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef, artifactId } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: FetchStatusResponse | undefined; try { - response = yield call(fetchStatusRequest, artifactId); + response = yield call(fetchStatusRequest, baseArtifactId); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { yield put( gitArtifactActions.fetchStatusSuccess({ - artifactDef, + ...basePayload, responseData: response.data, }), ); @@ -32,7 +33,7 @@ export default function* fetchStatusSaga( yield put( gitArtifactActions.fetchStatusError({ - artifactDef, + ...basePayload, error, }), ); diff --git a/app/client/src/git/sagas/generateSSHKeySaga.ts b/app/client/src/git/sagas/generateSSHKeySaga.ts index afbccf24b2e6..09773f9dc0d4 100644 --- a/app/client/src/git/sagas/generateSSHKeySaga.ts +++ b/app/client/src/git/sagas/generateSSHKeySaga.ts @@ -15,25 +15,23 @@ import { validateResponse } from "sagas/ErrorSagas"; export function* generateSSHKeySaga( action: GitArtifactPayloadAction, ) { - const { artifactDef } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const artifactDef = { artifactType, baseArtifactId }; let response: GenerateSSHKeyResponse | undefined; try { const params: GenerateSSHKeyRequestParams = { keyType: action.payload.keyType, + isImport: action.payload.isImport, }; - response = yield call( - generateSSHKeyRequest, - artifactDef.baseArtifactId, - params, - ); + response = yield call(generateSSHKeyRequest, baseArtifactId, params); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { yield put( gitArtifactActions.generateSSHKeySuccess({ - artifactDef, + ...artifactDef, responseData: response.data, }), ); @@ -45,13 +43,15 @@ export function* generateSSHKeySaga( if (GitErrorCodes.REPO_LIMIT_REACHED === error.code) { yield put( gitArtifactActions.toggleRepoLimitErrorModal({ - artifactDef, + ...artifactDef, open: true, }), ); } - yield put(gitArtifactActions.generateSSHKeyError({ artifactDef, error })); + yield put( + gitArtifactActions.generateSSHKeyError({ ...artifactDef, error }), + ); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/gitImportSaga.ts b/app/client/src/git/sagas/gitImportSaga.ts deleted file mode 100644 index ecf3d718ae08..000000000000 --- a/app/client/src/git/sagas/gitImportSaga.ts +++ /dev/null @@ -1,92 +0,0 @@ -import log from "loglevel"; -import { call, put, select } from "redux-saga/effects"; -import { validateResponse } from "sagas/ErrorSagas"; -import history from "utils/history"; -import { toast } from "@appsmith/ads"; -import type { PayloadAction } from "@reduxjs/toolkit"; -import { captureException } from "@sentry/react"; -import gitImportRequest from "git/requests/gitImportRequest"; -import type { GitImportResponse } from "git/requests/gitImportRequest.types"; -import type { GitImportInitPayload } from "git/store/actions/gitImportActions"; -import { gitGlobalActions } from "git/store/gitGlobalSlice"; -import { createMessage, IMPORT_APP_SUCCESSFUL } from "ee/constants/messages"; -import { builderURL } from "ee/RouteBuilder"; -import { getWorkspaceIdForImport } from "ee/selectors/applicationSelectors"; -import { showReconnectDatasourceModal } from "ee/actions/applicationActions"; -import type { Workspace } from "ee/constants/workspaceConstants"; -import { getFetchedWorkspaces } from "ee/selectors/workspaceSelectors"; - -export default function* gitImportSaga( - action: PayloadAction, -) { - const { ...params } = action.payload; - const workspaceId: string = yield select(getWorkspaceIdForImport); - - let response: GitImportResponse | undefined; - - try { - response = yield call(gitImportRequest, workspaceId, params); - const isValidResponse: boolean = yield validateResponse(response); - - if (response && isValidResponse) { - const allWorkspaces: Workspace[] = yield select(getFetchedWorkspaces); - const currentWorkspace = allWorkspaces.filter( - (el: Workspace) => el.id === workspaceId, - ); - - if (currentWorkspace.length > 0) { - const { application, isPartialImport, unconfiguredDatasourceList } = - response.data; - - yield put(gitGlobalActions.gitImportSuccess()); - yield put(gitGlobalActions.toggleImportModal({ open: false })); - - // there is configuration-missing datasources - if (isPartialImport) { - yield put( - showReconnectDatasourceModal({ - application: application, - unConfiguredDatasourceList: unconfiguredDatasourceList ?? [], - workspaceId, - }), - ); - } else { - let basePageId = ""; - - if (application.pages && application.pages.length > 0) { - const defaultPage = application.pages.find( - (eachPage) => !!eachPage.isDefault, - ); - - basePageId = defaultPage ? defaultPage.baseId : ""; - } - - const pageURL = builderURL({ - basePageId, - }); - - history.push(pageURL); - toast.show(createMessage(IMPORT_APP_SUCCESSFUL), { - kind: "success", - }); - } - } - } - } catch (e) { - // const isRepoLimitReachedError: boolean = yield call( - // handleRepoLimitReachedError, - // response, - // ); - - // if (isRepoLimitReachedError) return; - - if (response?.responseMeta?.error) { - yield put( - gitGlobalActions.gitImportError({ error: response.responseMeta.error }), - ); - } else { - log.error(e); - captureException(e); - } - } -} diff --git a/app/client/src/git/sagas/index.ts b/app/client/src/git/sagas/index.ts index 61c0a0747330..13e19bd4c9f8 100644 --- a/app/client/src/git/sagas/index.ts +++ b/app/client/src/git/sagas/index.ts @@ -8,6 +8,7 @@ import { import type { TakeableChannel } from "redux-saga"; import type { PayloadAction } from "@reduxjs/toolkit"; import { objectKeys } from "@appsmith/utils"; +import { gitConfigActions } from "../store/gitConfigSlice"; import { gitArtifactActions } from "../store/gitArtifactSlice"; import connectSaga from "./connectSaga"; import commitSaga from "./commitSaga"; @@ -36,9 +37,6 @@ import { blockingActionSagas as blockingActionSagasExtended, nonBlockingActionSagas as nonBlockingActionSagasExtended, } from "git/ee/sagas"; -import { gitGlobalActions } from "git/store/gitGlobalSlice"; -import { fetchGlobalSSHKeySaga } from "./fetchGlobalSSHKeySaga"; -import gitImportSaga from "./gitImportSaga"; const blockingActionSagas: Record< string, @@ -52,9 +50,6 @@ const blockingActionSagas: Record< [gitArtifactActions.connectInit.type]: connectSaga, [gitArtifactActions.disconnectInit.type]: disconnectSaga, - // import - [gitGlobalActions.gitImportInit.type]: gitImportSaga, - // ops [gitArtifactActions.commitInit.type]: commitSaga, [gitArtifactActions.fetchStatusInit.type]: fetchStatusSaga, @@ -70,8 +65,8 @@ const blockingActionSagas: Record< // user profiles [gitArtifactActions.fetchLocalProfileInit.type]: fetchLocalProfileSaga, [gitArtifactActions.updateLocalProfileInit.type]: updateLocalProfileSaga, - [gitGlobalActions.fetchGlobalProfileInit.type]: fetchGlobalProfileSaga, - [gitGlobalActions.updateGlobalProfileInit.type]: updateGlobalProfileSaga, + [gitConfigActions.fetchGlobalProfileInit.type]: fetchGlobalProfileSaga, + [gitConfigActions.updateGlobalProfileInit.type]: updateGlobalProfileSaga, // protected branches [gitArtifactActions.fetchProtectedBranchesInit.type]: @@ -98,7 +93,6 @@ const nonBlockingActionSagas: Record< // ssh key [gitArtifactActions.fetchSSHKeyInit.type]: fetchSSHKeySaga, [gitArtifactActions.generateSSHKeyInit.type]: generateSSHKeySaga, - [gitGlobalActions.fetchGlobalSSHKeyInit.type]: fetchGlobalSSHKeySaga, // EE ...nonBlockingActionSagasExtended, diff --git a/app/client/src/git/sagas/initGitSaga.ts b/app/client/src/git/sagas/initGitSaga.ts index b880b1854c41..aa50efce17b1 100644 --- a/app/client/src/git/sagas/initGitSaga.ts +++ b/app/client/src/git/sagas/initGitSaga.ts @@ -7,25 +7,24 @@ import { put, take } from "redux-saga/effects"; export default function* initGitForEditorSaga( action: GitArtifactPayloadAction, ) { - const { artifact, artifactDef } = action.payload; - const artifactId = artifact?.id; + const { artifact, artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; - yield put(gitArtifactActions.mount({ artifactDef })); + yield put(gitArtifactActions.mount(basePayload)); - if (artifactId && artifactDef.artifactType === GitArtifactType.Application) { - if (!!artifact?.gitApplicationMetadata?.remoteUrl) { - yield put(gitArtifactActions.fetchMetadataInit({ artifactDef })); + if (artifactType === GitArtifactType.Application) { + if (!!artifact.gitApplicationMetadata?.remoteUrl) { + yield put(gitArtifactActions.fetchMetadataInit(basePayload)); yield take(gitArtifactActions.fetchMetadataSuccess.type); yield put( - gitArtifactActions.triggerAutocommitInit({ artifactDef, artifactId }), - ); - yield put( - gitArtifactActions.fetchBranchesInit({ artifactDef, artifactId }), - ); - yield put(gitArtifactActions.fetchProtectedBranchesInit({ artifactDef })); - yield put( - gitArtifactActions.fetchStatusInit({ artifactDef, artifactId }), + gitArtifactActions.triggerAutocommitInit({ + ...basePayload, + artifactId: artifact.id, + }), ); + yield put(gitArtifactActions.fetchBranchesInit(basePayload)); + yield put(gitArtifactActions.fetchProtectedBranchesInit(basePayload)); + yield put(gitArtifactActions.fetchStatusInit(basePayload)); } } } diff --git a/app/client/src/git/sagas/pullSaga.ts b/app/client/src/git/sagas/pullSaga.ts index 07347326e3e0..eafb4a5c098b 100644 --- a/app/client/src/git/sagas/pullSaga.ts +++ b/app/client/src/git/sagas/pullSaga.ts @@ -4,7 +4,7 @@ import type { PullResponse } from "git/requests/pullRequest.types"; import type { PullInitPayload } from "git/store/actions/pullActions"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; import type { GitArtifactPayloadAction } from "git/store/types"; -import { selectCurrentBranch } from "git/store/selectors/gitArtifactSelectors"; +import { selectCurrentBranch } from "git/store/selectors/gitSingleArtifactSelectors"; // internal dependencies import { validateResponse } from "sagas/ErrorSagas"; @@ -17,7 +17,8 @@ import { captureException } from "@sentry/react"; export default function* pullSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef, artifactId } = action.payload; + const { artifactId, artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: PullResponse | undefined; try { @@ -25,12 +26,12 @@ export default function* pullSaga( const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { - yield put(gitArtifactActions.pullSuccess({ artifactDef })); + yield put(gitArtifactActions.pullSuccess(basePayload)); const currentBasePageId: string = yield select(getCurrentBasePageId); const currentBranch: string = yield select( selectCurrentBranch, - artifactDef, + basePayload, ); yield put( @@ -50,7 +51,7 @@ export default function* pullSaga( // yield put(setIsGitErrorPopupVisible({ isVisible: true })); // } - yield put(gitArtifactActions.pullError({ artifactDef, error })); + yield put(gitArtifactActions.pullError({ ...basePayload, error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/toggleAutocommitSaga.ts b/app/client/src/git/sagas/toggleAutocommitSaga.ts index 4f97d0289543..cf8b0e923c67 100644 --- a/app/client/src/git/sagas/toggleAutocommitSaga.ts +++ b/app/client/src/git/sagas/toggleAutocommitSaga.ts @@ -10,23 +10,24 @@ import { validateResponse } from "sagas/ErrorSagas"; export default function* toggleAutocommitSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const artifactDef = { artifactType, baseArtifactId }; let response: ToggleAutocommitResponse | undefined; try { - response = yield call(toggleAutocommitRequest, artifactDef.baseArtifactId); + response = yield call(toggleAutocommitRequest, baseArtifactId); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { - yield put(gitArtifactActions.toggleAutocommitSuccess({ artifactDef })); - yield put(gitArtifactActions.fetchMetadataInit({ artifactDef })); + yield put(gitArtifactActions.toggleAutocommitSuccess(artifactDef)); + yield put(gitArtifactActions.fetchMetadataInit(artifactDef)); } } catch (e) { if (response && response.responseMeta.error) { const { error } = response.responseMeta; yield put( - gitArtifactActions.toggleAutocommitError({ artifactDef, error }), + gitArtifactActions.toggleAutocommitError({ ...artifactDef, error }), ); } else { log.error(e); diff --git a/app/client/src/git/sagas/triggerAutocommitSaga.ts b/app/client/src/git/sagas/triggerAutocommitSaga.ts index 6725fb0d59f9..d0b316f594ec 100644 --- a/app/client/src/git/sagas/triggerAutocommitSaga.ts +++ b/app/client/src/git/sagas/triggerAutocommitSaga.ts @@ -1,5 +1,8 @@ import { triggerAutocommitSuccessAction } from "actions/gitSyncActions"; -import { AutocommitStatusState } from "git/constants/enums"; +import { + AutocommitStatusState, + type GitArtifactType, +} from "git/constants/enums"; import fetchAutocommitProgressRequest from "git/requests/fetchAutocommitProgressRequest"; import type { FetchAutocommitProgressResponse, @@ -12,8 +15,8 @@ import type { } from "git/requests/triggerAutocommitRequest.types"; import type { TriggerAutocommitInitPayload } from "git/store/actions/triggerAutocommitActions"; import { gitArtifactActions } from "git/store/gitArtifactSlice"; -import { selectAutocommitEnabled } from "git/store/selectors/gitArtifactSelectors"; -import type { GitArtifactDef, GitArtifactPayloadAction } from "git/store/types"; +import { selectAutocommitEnabled } from "git/store/selectors/gitSingleArtifactSelectors"; +import type { GitArtifactPayloadAction } from "git/store/types"; import { call, cancel, @@ -36,7 +39,8 @@ const AUTOCOMMIT_WHITELISTED_STATES = [ ]; interface PollAutocommitProgressParams { - artifactDef: GitArtifactDef; + artifactType: keyof typeof GitArtifactType; + baseArtifactId: string; artifactId: string; } @@ -53,7 +57,8 @@ function isAutocommitHappening( } function* pollAutocommitProgressSaga(params: PollAutocommitProgressParams) { - const { artifactDef, artifactId } = params; + const { artifactId, artifactType, baseArtifactId } = params; + const basePayload = { artifactType, baseArtifactId }; let triggerResponse: TriggerAutocommitResponse | undefined; try { @@ -61,14 +66,14 @@ function* pollAutocommitProgressSaga(params: PollAutocommitProgressParams) { const isValidResponse: boolean = yield validateResponse(triggerResponse); if (triggerResponse && isValidResponse) { - yield put(gitArtifactActions.triggerAutocommitSuccess({ artifactDef })); + yield put(gitArtifactActions.triggerAutocommitSuccess(basePayload)); } } catch (e) { if (triggerResponse && triggerResponse.responseMeta.error) { const { error } = triggerResponse.responseMeta; yield put( - gitArtifactActions.triggerAutocommitError({ artifactDef, error }), + gitArtifactActions.triggerAutocommitError({ ...basePayload, error }), ); } else { log.error(e); @@ -80,47 +85,39 @@ function* pollAutocommitProgressSaga(params: PollAutocommitProgressParams) { try { if (isAutocommitHappening(triggerResponse?.data)) { - yield put( - gitArtifactActions.pollAutocommitProgressStart({ artifactDef }), - ); + yield put(gitArtifactActions.pollAutocommitProgressStart(basePayload)); while (true) { - yield put( - gitArtifactActions.fetchAutocommitProgressInit({ artifactDef }), - ); + yield put(gitArtifactActions.fetchAutocommitProgressInit(basePayload)); progressResponse = yield call( fetchAutocommitProgressRequest, - artifactDef.baseArtifactId, + baseArtifactId, ); const isValidResponse: boolean = yield validateResponse(progressResponse); if (isValidResponse && !isAutocommitHappening(progressResponse?.data)) { - yield put( - gitArtifactActions.pollAutocommitProgressStop({ artifactDef }), - ); + yield put(gitArtifactActions.pollAutocommitProgressStop(basePayload)); } if (!isValidResponse) { - yield put( - gitArtifactActions.pollAutocommitProgressStop({ artifactDef }), - ); + yield put(gitArtifactActions.pollAutocommitProgressStop(basePayload)); } yield delay(AUTOCOMMIT_POLL_DELAY); } } else { - yield put(gitArtifactActions.pollAutocommitProgressStop({ artifactDef })); + yield put(gitArtifactActions.pollAutocommitProgressStop(basePayload)); } } catch (e) { - yield put(gitArtifactActions.pollAutocommitProgressStop({ artifactDef })); + yield put(gitArtifactActions.pollAutocommitProgressStop(basePayload)); if (progressResponse && progressResponse.responseMeta.error) { const { error } = progressResponse.responseMeta; yield put( gitArtifactActions.fetchAutocommitProgressError({ - artifactDef, + ...basePayload, error, }), ); @@ -134,14 +131,15 @@ function* pollAutocommitProgressSaga(params: PollAutocommitProgressParams) { export default function* triggerAutocommitSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef, artifactId } = action.payload; + const { artifactId, artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; const isAutocommitEnabled: boolean = yield select( selectAutocommitEnabled, - artifactDef, + basePayload, ); if (isAutocommitEnabled) { - const params = { artifactDef, artifactId }; + const params = { artifactType, baseArtifactId, artifactId }; const pollTask: Task = yield fork(pollAutocommitProgressSaga, params); yield take(gitArtifactActions.pollAutocommitProgressStop.type); diff --git a/app/client/src/git/sagas/updateGlobalProfileSaga.ts b/app/client/src/git/sagas/updateGlobalProfileSaga.ts index d7466b1ed007..2ce98fe47fb4 100644 --- a/app/client/src/git/sagas/updateGlobalProfileSaga.ts +++ b/app/client/src/git/sagas/updateGlobalProfileSaga.ts @@ -6,12 +6,12 @@ import type { UpdateGlobalProfileRequestParams, UpdateGlobalProfileResponse, } from "../requests/updateGlobalProfileRequest.types"; +import { gitConfigActions } from "../store/gitConfigSlice"; // internal dependencies import { validateResponse } from "sagas/ErrorSagas"; import log from "loglevel"; import { captureException } from "@sentry/react"; -import { gitGlobalActions } from "git/store/gitGlobalSlice"; export default function* updateGlobalProfileSaga( action: PayloadAction, @@ -29,14 +29,14 @@ export default function* updateGlobalProfileSaga( const isValidResponse: boolean = yield validateResponse(response, true); if (response && isValidResponse) { - yield put(gitGlobalActions.updateGlobalProfileSuccess()); - yield put(gitGlobalActions.fetchGlobalProfileInit()); + yield put(gitConfigActions.updateGlobalProfileSuccess()); + yield put(gitConfigActions.fetchGlobalProfileInit()); } } catch (e) { if (response && response.responseMeta.error) { const { error } = response.responseMeta; - yield put(gitGlobalActions.updateGlobalProfileError({ error })); + yield put(gitConfigActions.updateGlobalProfileError({ error })); } else { log.error(e); captureException(e); diff --git a/app/client/src/git/sagas/updateLocalProfileSaga.ts b/app/client/src/git/sagas/updateLocalProfileSaga.ts index 3b7253a391fe..74579562b058 100644 --- a/app/client/src/git/sagas/updateLocalProfileSaga.ts +++ b/app/client/src/git/sagas/updateLocalProfileSaga.ts @@ -14,7 +14,8 @@ import { captureException } from "@sentry/react"; export default function* updateLocalProfileSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const basePayload = { artifactType, baseArtifactId }; let response: UpdateLocalProfileResponse | undefined; try { @@ -24,24 +25,20 @@ export default function* updateLocalProfileSaga( useGlobalProfile: action.payload.useGlobalProfile, }; - response = yield call( - updateLocalProfileRequest, - artifactDef.baseArtifactId, - params, - ); + response = yield call(updateLocalProfileRequest, baseArtifactId, params); const isValidResponse: boolean = yield validateResponse(response); if (isValidResponse) { - yield put(gitArtifactActions.updateLocalProfileSuccess({ artifactDef })); - yield put(gitArtifactActions.fetchLocalProfileInit({ artifactDef })); + yield put(gitArtifactActions.updateLocalProfileSuccess(basePayload)); + yield put(gitArtifactActions.fetchLocalProfileInit(basePayload)); } } catch (e) { if (response && response.responseMeta.error) { const { error } = response.responseMeta; yield put( - gitArtifactActions.updateLocalProfileError({ artifactDef, error }), + gitArtifactActions.updateLocalProfileError({ ...basePayload, error }), ); } else { log.error(e); diff --git a/app/client/src/git/sagas/updateProtectedBranchesSaga.ts b/app/client/src/git/sagas/updateProtectedBranchesSaga.ts index f24b20ee9290..3f7bd121270e 100644 --- a/app/client/src/git/sagas/updateProtectedBranchesSaga.ts +++ b/app/client/src/git/sagas/updateProtectedBranchesSaga.ts @@ -14,7 +14,8 @@ import { validateResponse } from "sagas/ErrorSagas"; export default function* updateProtectedBranchesSaga( action: GitArtifactPayloadAction, ) { - const { artifactDef } = action.payload; + const { artifactType, baseArtifactId } = action.payload; + const artifactDef = { artifactType, baseArtifactId }; let response: UpdateProtectedBranchesResponse | undefined; try { @@ -24,16 +25,14 @@ export default function* updateProtectedBranchesSaga( response = yield call( updateProtectedBranchesRequest, - artifactDef.baseArtifactId, + baseArtifactId, params, ); const isValidResponse: boolean = yield validateResponse(response); if (response && isValidResponse) { - yield put( - gitArtifactActions.updateProtectedBranchesSuccess({ artifactDef }), - ); - yield put(gitArtifactActions.fetchProtectedBranchesInit({ artifactDef })); + yield put(gitArtifactActions.updateProtectedBranchesSuccess(artifactDef)); + yield put(gitArtifactActions.fetchProtectedBranchesInit(artifactDef)); } } catch (e) { if (response && response.responseMeta.error) { @@ -41,7 +40,7 @@ export default function* updateProtectedBranchesSaga( yield put( gitArtifactActions.updateProtectedBranchesError({ - artifactDef, + ...artifactDef, error, }), ); diff --git a/app/client/src/git/store/actions/checkoutBranchActions.ts b/app/client/src/git/store/actions/checkoutBranchActions.ts index e9451a614d7f..c771d1887e34 100644 --- a/app/client/src/git/store/actions/checkoutBranchActions.ts +++ b/app/client/src/git/store/actions/checkoutBranchActions.ts @@ -1,13 +1,12 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; import type { CheckoutBranchRequestParams } from "git/requests/checkoutBranchRequest.types"; -export interface CheckoutBranchInitPayload extends CheckoutBranchRequestParams { - artifactId: string; -} +export interface CheckoutBranchInitPayload + extends CheckoutBranchRequestParams {} export const checkoutBranchInitAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { state.apiResponses.checkoutBranch.loading = true; state.apiResponses.checkoutBranch.error = null; state.ui.checkoutDestBranch = action.payload.branchName; @@ -15,16 +14,18 @@ export const checkoutBranchInitAction = return state; }); -export const checkoutBranchSuccessAction = createArtifactAction((state) => { - state.apiResponses.checkoutBranch.loading = false; - state.apiResponses.checkoutBranch.error = null; - state.ui.checkoutDestBranch = null; +export const checkoutBranchSuccessAction = createSingleArtifactAction( + (state) => { + state.apiResponses.checkoutBranch.loading = false; + state.apiResponses.checkoutBranch.error = null; + state.ui.checkoutDestBranch = null; - return state; -}); + return state; + }, +); export const checkoutBranchErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.checkoutBranch.loading = false; diff --git a/app/client/src/git/store/actions/commitActions.ts b/app/client/src/git/store/actions/commitActions.ts index 876463e803a9..9ebb8d37db60 100644 --- a/app/client/src/git/store/actions/commitActions.ts +++ b/app/client/src/git/store/actions/commitActions.ts @@ -1,12 +1,10 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; import type { CommitRequestParams } from "git/requests/commitRequest.types"; -export interface CommitInitPayload extends CommitRequestParams { - artifactId: string; -} +export interface CommitInitPayload extends CommitRequestParams {} -export const commitInitAction = createArtifactAction( +export const commitInitAction = createSingleArtifactAction( (state) => { state.apiResponses.commit.loading = true; state.apiResponses.commit.error = null; @@ -15,24 +13,23 @@ export const commitInitAction = createArtifactAction( }, ); -export const commitSuccessAction = createArtifactAction((state) => { +export const commitSuccessAction = createSingleArtifactAction((state) => { state.apiResponses.commit.loading = false; return state; }); -export const commitErrorAction = createArtifactAction( - (state, action) => { +export const commitErrorAction = + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.commit.loading = false; state.apiResponses.commit.error = error; return state; - }, -); + }); -export const clearCommitErrorAction = createArtifactAction((state) => { +export const clearCommitErrorAction = createSingleArtifactAction((state) => { state.apiResponses.commit.error = null; return state; diff --git a/app/client/src/git/store/actions/connectActions.ts b/app/client/src/git/store/actions/connectActions.ts index 9e5e2bcf10b1..7fed98500000 100644 --- a/app/client/src/git/store/actions/connectActions.ts +++ b/app/client/src/git/store/actions/connectActions.ts @@ -1,13 +1,12 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; -import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; -import type { - ConnectRequestParams, - ConnectResponseData, -} from "git/requests/connectRequest.types"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import type { GitAsyncErrorPayload } from "../types"; +import type { ConnectRequestParams } from "git/requests/connectRequest.types"; -export interface ConnectInitPayload extends ConnectRequestParams {} +export interface ConnectInitPayload extends ConnectRequestParams { + branchedPageId?: string; +} -export const connectInitAction = createArtifactAction( +export const connectInitAction = createSingleArtifactAction( (state) => { state.apiResponses.connect.loading = true; state.apiResponses.connect.error = null; @@ -16,24 +15,18 @@ export const connectInitAction = createArtifactAction( }, ); -export interface ConnectSuccessPayload - extends GitAsyncSuccessPayload {} +export const connectSuccessAction = createSingleArtifactAction((state) => { + state.apiResponses.connect.loading = false; -export const connectSuccessAction = createArtifactAction( - (state) => { - state.apiResponses.connect.loading = false; - - return state; - }, -); + return state; +}); -export const connectErrorAction = createArtifactAction( - (state, action) => { +export const connectErrorAction = + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.connect.loading = false; state.apiResponses.connect.error = error; return state; - }, -); + }); diff --git a/app/client/src/git/store/actions/createBranchActions.ts b/app/client/src/git/store/actions/createBranchActions.ts index 010a7550888f..be0e08445de2 100644 --- a/app/client/src/git/store/actions/createBranchActions.ts +++ b/app/client/src/git/store/actions/createBranchActions.ts @@ -1,27 +1,25 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; import type { CreateBranchRequestParams } from "git/requests/createBranchRequest.types"; -export interface CreateBranchInitPayload extends CreateBranchRequestParams { - artifactId: string; -} +export interface CreateBranchInitPayload extends CreateBranchRequestParams {} export const createBranchInitAction = - createArtifactAction((state) => { + createSingleArtifactAction((state) => { state.apiResponses.createBranch.loading = true; state.apiResponses.createBranch.error = null; return state; }); -export const createBranchSuccessAction = createArtifactAction((state) => { +export const createBranchSuccessAction = createSingleArtifactAction((state) => { state.apiResponses.createBranch.loading = false; return state; }); export const createBranchErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.createBranch.loading = false; diff --git a/app/client/src/git/store/actions/deleteBranchActions.ts b/app/client/src/git/store/actions/deleteBranchActions.ts index 0656886f39d4..09296625f0d6 100644 --- a/app/client/src/git/store/actions/deleteBranchActions.ts +++ b/app/client/src/git/store/actions/deleteBranchActions.ts @@ -1,27 +1,25 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; import type { DeleteBranchRequestParams } from "../../requests/deleteBranchRequest.types"; -export interface DeleteBranchInitPayload extends DeleteBranchRequestParams { - artifactId: string; -} +export interface DeleteBranchInitPayload extends DeleteBranchRequestParams {} export const deleteBranchInitAction = - createArtifactAction((state) => { + createSingleArtifactAction((state) => { state.apiResponses.deleteBranch.loading = true; state.apiResponses.deleteBranch.error = null; return state; }); -export const deleteBranchSuccessAction = createArtifactAction((state) => { +export const deleteBranchSuccessAction = createSingleArtifactAction((state) => { state.apiResponses.deleteBranch.loading = false; return state; }); export const deleteBranchErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.deleteBranch.loading = false; diff --git a/app/client/src/git/store/actions/discardActions.ts b/app/client/src/git/store/actions/discardActions.ts index 0f514cd0e585..35d37c0a6d0e 100644 --- a/app/client/src/git/store/actions/discardActions.ts +++ b/app/client/src/git/store/actions/discardActions.ts @@ -1,20 +1,20 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitArtifactErrorPayloadAction } from "../types"; -export const discardInitAction = createArtifactAction((state) => { +export const discardInitAction = createSingleArtifactAction((state) => { state.apiResponses.discard.loading = true; state.apiResponses.discard.error = null; return state; }); -export const discardSuccessAction = createArtifactAction((state) => { +export const discardSuccessAction = createSingleArtifactAction((state) => { state.apiResponses.discard.loading = false; return state; }); -export const discardErrorAction = createArtifactAction( +export const discardErrorAction = createSingleArtifactAction( (state, action: GitArtifactErrorPayloadAction) => { const { error } = action.payload; @@ -25,7 +25,7 @@ export const discardErrorAction = createArtifactAction( }, ); -export const clearDiscardErrorAction = createArtifactAction((state) => { +export const clearDiscardErrorAction = createSingleArtifactAction((state) => { state.apiResponses.discard.error = null; return state; diff --git a/app/client/src/git/store/actions/disconnectActions.ts b/app/client/src/git/store/actions/disconnectActions.ts index 082aa91b7970..dba26c0de629 100644 --- a/app/client/src/git/store/actions/disconnectActions.ts +++ b/app/client/src/git/store/actions/disconnectActions.ts @@ -1,20 +1,20 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitArtifactErrorPayloadAction } from "../types"; -export const disconnectInitAction = createArtifactAction((state) => { +export const disconnectInitAction = createSingleArtifactAction((state) => { state.apiResponses.disconnect.loading = true; state.apiResponses.disconnect.error = null; return state; }); -export const disconnectSuccessAction = createArtifactAction((state) => { +export const disconnectSuccessAction = createSingleArtifactAction((state) => { state.apiResponses.disconnect.loading = false; return state; }); -export const disconnectErrorAction = createArtifactAction( +export const disconnectErrorAction = createSingleArtifactAction( (state, action: GitArtifactErrorPayloadAction) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/fetchAutocommitProgressActions.ts b/app/client/src/git/store/actions/fetchAutocommitProgressActions.ts index bbde6e4dd649..a7d92793e4aa 100644 --- a/app/client/src/git/store/actions/fetchAutocommitProgressActions.ts +++ b/app/client/src/git/store/actions/fetchAutocommitProgressActions.ts @@ -1,7 +1,7 @@ import type { GitAsyncErrorPayload } from "../types"; -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; -export const fetchAutocommitProgressInitAction = createArtifactAction( +export const fetchAutocommitProgressInitAction = createSingleArtifactAction( (state) => { state.apiResponses.autocommitProgress.loading = true; state.apiResponses.autocommitProgress.error = null; @@ -10,7 +10,7 @@ export const fetchAutocommitProgressInitAction = createArtifactAction( }, ); -export const fetchAutocommitProgressSuccessAction = createArtifactAction( +export const fetchAutocommitProgressSuccessAction = createSingleArtifactAction( (state) => { state.apiResponses.autocommitProgress.loading = false; @@ -19,7 +19,7 @@ export const fetchAutocommitProgressSuccessAction = createArtifactAction( ); export const fetchAutocommitProgressErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.autocommitProgress.loading = false; diff --git a/app/client/src/git/store/actions/fetchBranchesActions.ts b/app/client/src/git/store/actions/fetchBranchesActions.ts index 6758ad918eb0..e83ce0325e59 100644 --- a/app/client/src/git/store/actions/fetchBranchesActions.ts +++ b/app/client/src/git/store/actions/fetchBranchesActions.ts @@ -3,21 +3,19 @@ import type { FetchBranchesResponseData, } from "../../requests/fetchBranchesRequest.types"; import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; -export interface FetchBranchesInitPayload extends FetchBranchesRequestParams { - artifactId: string; -} +export interface FetchBranchesInitPayload extends FetchBranchesRequestParams {} export const fetchBranchesInitAction = - createArtifactAction((state) => { + createSingleArtifactAction((state) => { state.apiResponses.branches.loading = true; state.apiResponses.branches.error = null; return state; }); -export const fetchBranchesSuccessAction = createArtifactAction< +export const fetchBranchesSuccessAction = createSingleArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.branches.loading = false; @@ -27,7 +25,7 @@ export const fetchBranchesSuccessAction = createArtifactAction< }); export const fetchBranchesErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.branches.loading = false; diff --git a/app/client/src/git/store/actions/fetchGlobalProfileActions.ts b/app/client/src/git/store/actions/fetchGlobalProfileActions.ts index bc2d0b6b92a3..7cfb2390b021 100644 --- a/app/client/src/git/store/actions/fetchGlobalProfileActions.ts +++ b/app/client/src/git/store/actions/fetchGlobalProfileActions.ts @@ -2,11 +2,11 @@ import type { FetchGlobalProfileResponseData } from "git/requests/fetchGlobalPro import type { GitAsyncSuccessPayload, GitAsyncErrorPayload, - GitGlobalReduxState, + GitConfigReduxState, } from "../types"; import type { PayloadAction } from "@reduxjs/toolkit"; -export const fetchGlobalProfileInitAction = (state: GitGlobalReduxState) => { +export const fetchGlobalProfileInitAction = (state: GitConfigReduxState) => { state.globalProfile.loading = true; state.globalProfile.error = null; @@ -14,7 +14,7 @@ export const fetchGlobalProfileInitAction = (state: GitGlobalReduxState) => { }; export const fetchGlobalProfileSuccessAction = ( - state: GitGlobalReduxState, + state: GitConfigReduxState, action: PayloadAction>, ) => { state.globalProfile.loading = false; @@ -24,7 +24,7 @@ export const fetchGlobalProfileSuccessAction = ( }; export const fetchGlobalProfileErrorAction = ( - state: GitGlobalReduxState, + state: GitConfigReduxState, action: PayloadAction, ) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/fetchGlobalSSHKeyActions.ts b/app/client/src/git/store/actions/fetchGlobalSSHKeyActions.ts deleted file mode 100644 index de9add1c5ee0..000000000000 --- a/app/client/src/git/store/actions/fetchGlobalSSHKeyActions.ts +++ /dev/null @@ -1,55 +0,0 @@ -import type { - FetchGlobalSSHKeyRequestParams, - FetchGlobalSSHKeyResponseData, -} from "git/requests/fetchGlobalSSHKeyRequest.types"; -import type { - GitAsyncSuccessPayload, - GitAsyncErrorPayload, - GitGlobalReduxState, -} from "../types"; -import type { PayloadAction } from "@reduxjs/toolkit"; - -export interface FetchGlobalSSHKeyInitPayload - extends FetchGlobalSSHKeyRequestParams {} - -export const fetchGlobalSSHKeyInitAction = ( - state: GitGlobalReduxState, - // need action to better define action type - // eslint-disable-next-line @typescript-eslint/no-unused-vars - action: PayloadAction, -) => { - state.globalSSHKey.loading = true; - state.globalSSHKey.error = null; - - return state; -}; - -export const fetchGlobalSSHKeySuccessAction = ( - state: GitGlobalReduxState, - action: PayloadAction>, -) => { - state.globalSSHKey.loading = false; - state.globalSSHKey.value = action.payload.responseData; - - return state; -}; - -export const fetchGlobalSSHKeyErrorAction = ( - state: GitGlobalReduxState, - action: PayloadAction, -) => { - const { error } = action.payload; - - state.globalSSHKey.loading = false; - state.globalSSHKey.error = error; - - return state; -}; - -export const resetGlobalSSHKeyAction = (state: GitGlobalReduxState) => { - state.globalSSHKey.loading = false; - state.globalSSHKey.value = null; - state.globalSSHKey.error = null; - - return state; -}; diff --git a/app/client/src/git/store/actions/fetchLocalProfileActions.ts b/app/client/src/git/store/actions/fetchLocalProfileActions.ts index 33a62514f44c..3559a2814c35 100644 --- a/app/client/src/git/store/actions/fetchLocalProfileActions.ts +++ b/app/client/src/git/store/actions/fetchLocalProfileActions.ts @@ -3,16 +3,18 @@ import type { GitArtifactErrorPayloadAction, GitAsyncSuccessPayload, } from "../types"; -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; -export const fetchLocalProfileInitAction = createArtifactAction((state) => { - state.apiResponses.localProfile.loading = true; - state.apiResponses.localProfile.error = null; +export const fetchLocalProfileInitAction = createSingleArtifactAction( + (state) => { + state.apiResponses.localProfile.loading = true; + state.apiResponses.localProfile.error = null; - return state; -}); + return state; + }, +); -export const fetchLocalProfileSuccessAction = createArtifactAction< +export const fetchLocalProfileSuccessAction = createSingleArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.localProfile.loading = false; @@ -21,7 +23,7 @@ export const fetchLocalProfileSuccessAction = createArtifactAction< return state; }); -export const fetchLocalProfileErrorAction = createArtifactAction( +export const fetchLocalProfileErrorAction = createSingleArtifactAction( (state, action: GitArtifactErrorPayloadAction) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/fetchMergeStatusActions.ts b/app/client/src/git/store/actions/fetchMergeStatusActions.ts index 26b72829fadd..65ed313114cb 100644 --- a/app/client/src/git/store/actions/fetchMergeStatusActions.ts +++ b/app/client/src/git/store/actions/fetchMergeStatusActions.ts @@ -1,5 +1,5 @@ import type { GitAsyncSuccessPayload, GitAsyncErrorPayload } from "../types"; -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { FetchMergeStatusRequestParams, FetchMergeStatusResponseData, @@ -11,14 +11,14 @@ export interface FetchMergeStatusInitPayload } export const fetchMergeStatusInitAction = - createArtifactAction((state) => { + createSingleArtifactAction((state) => { state.apiResponses.mergeStatus.loading = true; state.apiResponses.mergeStatus.error = null; return state; }); -export const fetchMergeStatusSuccessAction = createArtifactAction< +export const fetchMergeStatusSuccessAction = createSingleArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.mergeStatus.loading = false; @@ -28,7 +28,7 @@ export const fetchMergeStatusSuccessAction = createArtifactAction< }); export const fetchMergeStatusErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.mergeStatus.loading = false; @@ -37,7 +37,7 @@ export const fetchMergeStatusErrorAction = return state; }); -export const clearMergeStatusAction = createArtifactAction((state) => { +export const clearMergeStatusAction = createSingleArtifactAction((state) => { state.apiResponses.mergeStatus.loading = false; state.apiResponses.mergeStatus.error = null; state.apiResponses.mergeStatus.value = null; diff --git a/app/client/src/git/store/actions/fetchMetadataActions.ts b/app/client/src/git/store/actions/fetchMetadataActions.ts index 6e7a9f2f1e3d..176413dfbaaa 100644 --- a/app/client/src/git/store/actions/fetchMetadataActions.ts +++ b/app/client/src/git/store/actions/fetchMetadataActions.ts @@ -1,15 +1,15 @@ import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { FetchMetadataResponseData } from "git/requests/fetchMetadataRequest.types"; -export const fetchMetadataInitAction = createArtifactAction((state) => { +export const fetchMetadataInitAction = createSingleArtifactAction((state) => { state.apiResponses.metadata.loading = true; state.apiResponses.metadata.error = null; return state; }); -export const fetchMetadataSuccessAction = createArtifactAction< +export const fetchMetadataSuccessAction = createSingleArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.metadata.loading = false; @@ -19,7 +19,7 @@ export const fetchMetadataSuccessAction = createArtifactAction< }); export const fetchMetadataErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.metadata.loading = false; diff --git a/app/client/src/git/store/actions/fetchProtectedBranchesActions.ts b/app/client/src/git/store/actions/fetchProtectedBranchesActions.ts index 1ad38bf4096c..dc66ff2290c0 100644 --- a/app/client/src/git/store/actions/fetchProtectedBranchesActions.ts +++ b/app/client/src/git/store/actions/fetchProtectedBranchesActions.ts @@ -1,8 +1,8 @@ import type { GitAsyncSuccessPayload, GitAsyncErrorPayload } from "../types"; -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { FetchProtectedBranchesResponseData } from "git/requests/fetchProtectedBranchesRequest.types"; -export const fetchProtectedBranchesInitAction = createArtifactAction( +export const fetchProtectedBranchesInitAction = createSingleArtifactAction( (state) => { state.apiResponses.protectedBranches.loading = true; state.apiResponses.protectedBranches.error = null; @@ -11,7 +11,7 @@ export const fetchProtectedBranchesInitAction = createArtifactAction( }, ); -export const fetchProtectedBranchesSuccessAction = createArtifactAction< +export const fetchProtectedBranchesSuccessAction = createSingleArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.protectedBranches.loading = false; @@ -21,7 +21,7 @@ export const fetchProtectedBranchesSuccessAction = createArtifactAction< }); export const fetchProtectedBranchesErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.protectedBranches.loading = false; diff --git a/app/client/src/git/store/actions/fetchSSHKeyActions.ts b/app/client/src/git/store/actions/fetchSSHKeyActions.ts index 386dd4643411..828cf6ebcb75 100644 --- a/app/client/src/git/store/actions/fetchSSHKeyActions.ts +++ b/app/client/src/git/store/actions/fetchSSHKeyActions.ts @@ -1,15 +1,15 @@ import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { FetchSSHKeyResponseData } from "git/requests/fetchSSHKeyRequest.types"; -export const fetchSSHKeyInitAction = createArtifactAction((state) => { +export const fetchSSHKeyInitAction = createSingleArtifactAction((state) => { state.apiResponses.sshKey.loading = true; state.apiResponses.sshKey.error = null; return state; }); -export const fetchSSHKeySuccessAction = createArtifactAction< +export const fetchSSHKeySuccessAction = createSingleArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.sshKey.loading = false; @@ -20,7 +20,7 @@ export const fetchSSHKeySuccessAction = createArtifactAction< }); export const fetchSSHKeyErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.sshKey.loading = false; @@ -29,7 +29,7 @@ export const fetchSSHKeyErrorAction = return state; }); -export const resetFetchSSHKeyAction = createArtifactAction((state) => { +export const resetFetchSSHKeyAction = createSingleArtifactAction((state) => { state.apiResponses.sshKey.loading = false; state.apiResponses.sshKey.error = null; state.apiResponses.sshKey.value = null; diff --git a/app/client/src/git/store/actions/fetchStatusActions.ts b/app/client/src/git/store/actions/fetchStatusActions.ts index 47097593260b..1121e368d012 100644 --- a/app/client/src/git/store/actions/fetchStatusActions.ts +++ b/app/client/src/git/store/actions/fetchStatusActions.ts @@ -3,21 +3,19 @@ import type { FetchStatusResponseData, } from "git/requests/fetchStatusRequest.types"; import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; -export interface FetchStatusInitPayload extends FetchStatusRequestParams { - artifactId: string; -} +export interface FetchStatusInitPayload extends FetchStatusRequestParams {} export const fetchStatusInitAction = - createArtifactAction((state) => { + createSingleArtifactAction((state) => { state.apiResponses.status.loading = true; state.apiResponses.status.error = null; return state; }); -export const fetchStatusSuccessAction = createArtifactAction< +export const fetchStatusSuccessAction = createSingleArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.status.loading = false; @@ -27,7 +25,7 @@ export const fetchStatusSuccessAction = createArtifactAction< }); export const fetchStatusErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.status.loading = false; diff --git a/app/client/src/git/store/actions/generateSSHKeyActions.ts b/app/client/src/git/store/actions/generateSSHKeyActions.ts index 569d7d9995c2..fa70c3a1ba28 100644 --- a/app/client/src/git/store/actions/generateSSHKeyActions.ts +++ b/app/client/src/git/store/actions/generateSSHKeyActions.ts @@ -2,21 +2,21 @@ import type { GenerateSSHKeyRequestParams, GenerateSSHKeyResponseData, } from "git/requests/generateSSHKeyRequest.types"; -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitAsyncErrorPayload, GitAsyncSuccessPayload } from "../types"; export interface GenerateSSHKeyInitPayload extends GenerateSSHKeyRequestParams {} export const generateSSHKeyInitAction = - createArtifactAction((state) => { + createSingleArtifactAction((state) => { state.apiResponses.generateSSHKey.loading = true; state.apiResponses.generateSSHKey.error = null; return state; }); -export const generateSSHKeySuccessAction = createArtifactAction< +export const generateSSHKeySuccessAction = createSingleArtifactAction< GitAsyncSuccessPayload >((state, action) => { state.apiResponses.generateSSHKey.loading = false; @@ -27,7 +27,7 @@ export const generateSSHKeySuccessAction = createArtifactAction< }); export const generateSSHKeyErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.generateSSHKey.loading = false; @@ -36,7 +36,7 @@ export const generateSSHKeyErrorAction = return state; }); -export const resetGenerateSSHKeyAction = createArtifactAction((state) => { +export const resetGenerateSSHKeyAction = createSingleArtifactAction((state) => { state.apiResponses.generateSSHKey.loading = false; state.apiResponses.generateSSHKey.error = null; diff --git a/app/client/src/git/store/actions/gitImportActions.ts b/app/client/src/git/store/actions/gitImportActions.ts index 30e9c7417b2d..49411b55dd55 100644 --- a/app/client/src/git/store/actions/gitImportActions.ts +++ b/app/client/src/git/store/actions/gitImportActions.ts @@ -1,35 +1,25 @@ -import type { PayloadAction } from "@reduxjs/toolkit"; -import type { GitAsyncErrorPayload, GitGlobalReduxState } from "../types"; -import type { GitImportRequestParams } from "git/requests/gitImportRequest.types"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; +import type { GitAsyncErrorPayload } from "../types"; -export interface GitImportInitPayload extends GitImportRequestParams {} - -export const gitImportInitAction = ( - state: GitGlobalReduxState, - // need type for better import - // eslint-disable-next-line @typescript-eslint/no-unused-vars - action: PayloadAction, -) => { - state.gitImport.loading = true; - state.gitImport.error = null; +export const gitImportInitAction = createSingleArtifactAction((state) => { + state.apiResponses.gitImport.loading = true; + state.apiResponses.gitImport.error = null; return state; -}; +}); -export const gitImportSuccessAction = (state: GitGlobalReduxState) => { - state.gitImport.loading = false; +export const gitImportSuccessAction = createSingleArtifactAction((state) => { + state.apiResponses.gitImport.loading = false; return state; -}; +}); -export const gitImportErrorAction = ( - state: GitGlobalReduxState, - action: PayloadAction, -) => { - const { error } = action.payload; +export const gitImportErrorAction = + createSingleArtifactAction((state, action) => { + const { error } = action.payload; - state.gitImport.loading = false; - state.gitImport.error = error; + state.apiResponses.gitImport.loading = false; + state.apiResponses.gitImport.error = error; - return state; -}; + return state; + }); diff --git a/app/client/src/git/store/actions/initGitActions.ts b/app/client/src/git/store/actions/initGitActions.ts index ebe588555a24..d93cf955eeec 100644 --- a/app/client/src/git/store/actions/initGitActions.ts +++ b/app/client/src/git/store/actions/initGitActions.ts @@ -1,11 +1,15 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; -import type { ApplicationPayload } from "entities/Application"; +import type { FetchMetadataResponseData } from "git/requests/fetchMetadataRequest.types"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; export interface InitGitForEditorPayload { - artifact: ApplicationPayload | null; + artifact: { + id: string; + baseId: string; + gitApplicationMetadata?: Partial; + }; } export const initGitForEditorAction = - createArtifactAction((state) => { + createSingleArtifactAction((state) => { return state; }); diff --git a/app/client/src/git/store/actions/mergeActions.ts b/app/client/src/git/store/actions/mergeActions.ts index 0d4e67eea8fe..5bb17a351ce6 100644 --- a/app/client/src/git/store/actions/mergeActions.ts +++ b/app/client/src/git/store/actions/mergeActions.ts @@ -1,20 +1,20 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitArtifactErrorPayloadAction } from "../types"; -export const mergeInitAction = createArtifactAction((state) => { +export const mergeInitAction = createSingleArtifactAction((state) => { state.apiResponses.merge.loading = true; state.apiResponses.merge.error = null; return state; }); -export const mergeSuccessAction = createArtifactAction((state) => { +export const mergeSuccessAction = createSingleArtifactAction((state) => { state.apiResponses.merge.loading = false; return state; }); -export const mergeErrorAction = createArtifactAction( +export const mergeErrorAction = createSingleArtifactAction( (state, action: GitArtifactErrorPayloadAction) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/mountActions.ts b/app/client/src/git/store/actions/mountActions.ts index 8d35126d9502..07a08ee2b566 100644 --- a/app/client/src/git/store/actions/mountActions.ts +++ b/app/client/src/git/store/actions/mountActions.ts @@ -1,31 +1,26 @@ import type { PayloadAction } from "@reduxjs/toolkit"; -import type { - GitArtifactBasePayload, - GitArtifactRootReduxState, -} from "../types"; -import { gitArtifactInitialState } from "../helpers/initialState"; +import type { GitArtifactBasePayload, GitArtifactReduxState } from "../types"; +import { gitSingleArtifactInitialState } from "../helpers/gitSingleArtifactInitialState"; // ! This might be removed later export const mountAction = ( - state: GitArtifactRootReduxState, + state: GitArtifactReduxState, action: PayloadAction, ) => { - const { artifactDef } = action.payload; - const { artifactType, baseArtifactId } = artifactDef; + const { artifactType, baseArtifactId } = action.payload; state[artifactType] ??= {}; - state[artifactType][baseArtifactId] ??= gitArtifactInitialState; + state[artifactType][baseArtifactId] ??= gitSingleArtifactInitialState; return state; }; export const unmountAction = ( - state: GitArtifactRootReduxState, + state: GitArtifactReduxState, action: PayloadAction, ) => { - const { artifactDef } = action.payload; - const { artifactType, baseArtifactId } = artifactDef; + const { artifactType, baseArtifactId } = action.payload; delete state?.[artifactType]?.[baseArtifactId]; diff --git a/app/client/src/git/store/actions/pullActions.ts b/app/client/src/git/store/actions/pullActions.ts index 48d3398e18c6..00a0d00f2033 100644 --- a/app/client/src/git/store/actions/pullActions.ts +++ b/app/client/src/git/store/actions/pullActions.ts @@ -1,24 +1,26 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; export interface PullInitPayload { artifactId: string; } -export const pullInitAction = createArtifactAction((state) => { - state.apiResponses.pull.loading = true; - state.apiResponses.pull.error = null; +export const pullInitAction = createSingleArtifactAction( + (state) => { + state.apiResponses.pull.loading = true; + state.apiResponses.pull.error = null; - return state; -}); + return state; + }, +); -export const pullSuccessAction = createArtifactAction((state) => { +export const pullSuccessAction = createSingleArtifactAction((state) => { state.apiResponses.pull.loading = false; return state; }); -export const pullErrorAction = createArtifactAction( +export const pullErrorAction = createSingleArtifactAction( (state, action) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/repoLimitErrorModalActions.ts b/app/client/src/git/store/actions/repoLimitErrorModalActions.ts index a2c96bac7721..b1867c1d5926 100644 --- a/app/client/src/git/store/actions/repoLimitErrorModalActions.ts +++ b/app/client/src/git/store/actions/repoLimitErrorModalActions.ts @@ -1,14 +1,16 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; interface ToggleRepoLimitModalActionPayload { open: boolean; } export const toggleRepoLimitErrorModalAction = - createArtifactAction((state, action) => { - const { open } = action.payload; + createSingleArtifactAction( + (state, action) => { + const { open } = action.payload; - state.ui.repoLimitErrorModalOpen = open; + state.ui.repoLimitErrorModalOpen = open; - return state; - }); + return state; + }, + ); diff --git a/app/client/src/git/store/actions/toggleAutocommitActions.ts b/app/client/src/git/store/actions/toggleAutocommitActions.ts index d9c700cbb457..96721698196f 100644 --- a/app/client/src/git/store/actions/toggleAutocommitActions.ts +++ b/app/client/src/git/store/actions/toggleAutocommitActions.ts @@ -1,20 +1,24 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitArtifactErrorPayloadAction } from "../types"; -export const toggleAutocommitInitAction = createArtifactAction((state) => { - state.apiResponses.toggleAutocommit.loading = true; - state.apiResponses.toggleAutocommit.error = null; +export const toggleAutocommitInitAction = createSingleArtifactAction( + (state) => { + state.apiResponses.toggleAutocommit.loading = true; + state.apiResponses.toggleAutocommit.error = null; - return state; -}); + return state; + }, +); -export const toggleAutocommitSuccessAction = createArtifactAction((state) => { - state.apiResponses.toggleAutocommit.loading = false; +export const toggleAutocommitSuccessAction = createSingleArtifactAction( + (state) => { + state.apiResponses.toggleAutocommit.loading = false; - return state; -}); + return state; + }, +); -export const toggleAutocommitErrorAction = createArtifactAction( +export const toggleAutocommitErrorAction = createSingleArtifactAction( (state, action: GitArtifactErrorPayloadAction) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/triggerAutocommitActions.ts b/app/client/src/git/store/actions/triggerAutocommitActions.ts index da8075bc347f..28e88ecd2f16 100644 --- a/app/client/src/git/store/actions/triggerAutocommitActions.ts +++ b/app/client/src/git/store/actions/triggerAutocommitActions.ts @@ -1,4 +1,4 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; export interface TriggerAutocommitInitPayload { @@ -6,21 +6,23 @@ export interface TriggerAutocommitInitPayload { } export const triggerAutocommitInitAction = - createArtifactAction((state) => { + createSingleArtifactAction((state) => { state.apiResponses.triggerAutocommit.loading = true; state.apiResponses.triggerAutocommit.error = null; return state; }); -export const triggerAutocommitSuccessAction = createArtifactAction((state) => { - state.apiResponses.triggerAutocommit.loading = false; +export const triggerAutocommitSuccessAction = createSingleArtifactAction( + (state) => { + state.apiResponses.triggerAutocommit.loading = false; - return state; -}); + return state; + }, +); export const triggerAutocommitErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.triggerAutocommit.loading = false; @@ -29,7 +31,7 @@ export const triggerAutocommitErrorAction = return state; }); -export const pollAutocommitProgressStartAction = createArtifactAction( +export const pollAutocommitProgressStartAction = createSingleArtifactAction( (state) => { state.ui.autocommitPolling = true; @@ -37,7 +39,7 @@ export const pollAutocommitProgressStartAction = createArtifactAction( }, ); -export const pollAutocommitProgressStopAction = createArtifactAction( +export const pollAutocommitProgressStopAction = createSingleArtifactAction( (state) => { state.ui.autocommitPolling = false; diff --git a/app/client/src/git/store/actions/uiActions.ts b/app/client/src/git/store/actions/uiActions.ts index 162382c3b876..577d1dfa3d10 100644 --- a/app/client/src/git/store/actions/uiActions.ts +++ b/app/client/src/git/store/actions/uiActions.ts @@ -1,7 +1,5 @@ import type { GitOpsTab, GitSettingsTab } from "git/constants/enums"; -import { createArtifactAction } from "../helpers/createArtifactAction"; -import type { GitGlobalReduxState } from "../types"; -import type { PayloadAction } from "@reduxjs/toolkit"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; // connect modal export interface ToggleConnectModalPayload { @@ -9,7 +7,7 @@ export interface ToggleConnectModalPayload { } export const toggleConnectModalAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { open } = action.payload; state.ui.connectModalOpen = open; @@ -17,54 +15,27 @@ export const toggleConnectModalAction = return state; }); -export interface ToggleConnectSuccessModalPayload { - open: boolean; -} - -export const toggleConnectSuccessModalAction = - createArtifactAction((state, action) => { - const { open } = action.payload; - - state.ui.connectSuccessModalOpen = open; - - return state; - }); - -export interface ToggleImportModalPayload { - open: boolean; -} - -export const toggleImportModalAction = ( - state: GitGlobalReduxState, - action: PayloadAction, -) => { - const { open } = action.payload; - - state.isImportModalOpen = open; - - return state; -}; - // disconnect modal export interface OpenDisconnectModalPayload { artifactName: string; } export const openDisconnectModalAction = - createArtifactAction((state, action) => { - state.ui.disconnectBaseArtifactId = - action.payload.artifactDef.baseArtifactId; + createSingleArtifactAction((state, action) => { + state.ui.disconnectBaseArtifactId = action.payload.baseArtifactId; state.ui.disconnectArtifactName = action.payload.artifactName; return state; }); -export const closeDisconnectModalAction = createArtifactAction((state) => { - state.ui.disconnectBaseArtifactId = null; - state.ui.disconnectArtifactName = null; +export const closeDisconnectModalAction = createSingleArtifactAction( + (state) => { + state.ui.disconnectBaseArtifactId = null; + state.ui.disconnectArtifactName = null; - return state; -}); + return state; + }, +); // ops modal @@ -73,16 +44,15 @@ export interface ToggleOpsModalPayload { tab: keyof typeof GitOpsTab; } -export const toggleOpsModalAction = createArtifactAction( - (state, action) => { +export const toggleOpsModalAction = + createSingleArtifactAction((state, action) => { const { open, tab } = action.payload; state.ui.opsModalOpen = open; state.ui.opsModalTab = tab; return state; - }, -); + }); // settings modal export interface ToggleSettingsModalPayload { @@ -91,7 +61,7 @@ export interface ToggleSettingsModalPayload { } export const toggleSettingsModalAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { open, tab } = action.payload; state.ui.settingsModalOpen = open; @@ -106,28 +76,29 @@ interface ToggleAutocommitDisableModalPayload { } export const toggleAutocommitDisableModalAction = - createArtifactAction((state, action) => { - const { open } = action.payload; + createSingleArtifactAction( + (state, action) => { + const { open } = action.payload; - state.ui.autocommitDisableModalOpen = open; + state.ui.autocommitDisableModalOpen = open; - return state; - }); + return state; + }, + ); // branch popup interface BranchPopupPayload { open: boolean; } -export const toggleBranchPopupAction = createArtifactAction( - (state, action) => { +export const toggleBranchPopupAction = + createSingleArtifactAction((state, action) => { const { open } = action.payload; state.ui.branchPopupOpen = open; return state; - }, -); + }); // error modals interface ToggleRepoLimitModalPayload { @@ -135,7 +106,7 @@ interface ToggleRepoLimitModalPayload { } export const toggleRepoLimitErrorModalAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { open } = action.payload; state.ui.repoLimitErrorModalOpen = open; @@ -148,10 +119,12 @@ interface ToggleConflictErrorModalPayload { } export const toggleConflictErrorModalAction = - createArtifactAction((state, action) => { - const { open } = action.payload; + createSingleArtifactAction( + (state, action) => { + const { open } = action.payload; - state.ui.conflictErrorModalOpen = open; + state.ui.conflictErrorModalOpen = open; - return state; - }); + return state; + }, + ); diff --git a/app/client/src/git/store/actions/updateGlobalProfileActions.ts b/app/client/src/git/store/actions/updateGlobalProfileActions.ts index 3549672deb56..b4d25b0b57d7 100644 --- a/app/client/src/git/store/actions/updateGlobalProfileActions.ts +++ b/app/client/src/git/store/actions/updateGlobalProfileActions.ts @@ -1,14 +1,14 @@ import type { UpdateGlobalProfileRequestParams } from "git/requests/updateGlobalProfileRequest.types"; -import type { GitAsyncErrorPayload, GitGlobalReduxState } from "../types"; +import type { GitAsyncErrorPayload, GitConfigReduxState } from "../types"; import type { PayloadAction } from "@reduxjs/toolkit"; export interface UpdateGlobalProfileInitPayload extends UpdateGlobalProfileRequestParams {} type UpdateGlobalProfileInitAction = ( - state: GitGlobalReduxState, + state: GitConfigReduxState, action: PayloadAction, -) => GitGlobalReduxState; +) => GitConfigReduxState; export const updateGlobalProfileInitAction: UpdateGlobalProfileInitAction = ( state, @@ -20,7 +20,7 @@ export const updateGlobalProfileInitAction: UpdateGlobalProfileInitAction = ( }; export const updateGlobalProfileSuccessAction = ( - state: GitGlobalReduxState, + state: GitConfigReduxState, ) => { state.updateGlobalProfile.loading = false; @@ -28,7 +28,7 @@ export const updateGlobalProfileSuccessAction = ( }; export const updateGlobalProfileErrorAction = ( - state: GitGlobalReduxState, + state: GitConfigReduxState, action: PayloadAction, ) => { const { error } = action.payload; diff --git a/app/client/src/git/store/actions/updateLocalProfileActions.ts b/app/client/src/git/store/actions/updateLocalProfileActions.ts index 84ac561a5026..717bb388cb9b 100644 --- a/app/client/src/git/store/actions/updateLocalProfileActions.ts +++ b/app/client/src/git/store/actions/updateLocalProfileActions.ts @@ -1,4 +1,4 @@ -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitAsyncErrorPayload } from "../types"; import type { UpdateLocalProfileRequestParams } from "git/requests/updateLocalProfileRequest.types"; @@ -6,21 +6,23 @@ export interface UpdateLocalProfileInitPayload extends UpdateLocalProfileRequestParams {} export const updateLocalProfileInitAction = - createArtifactAction((state) => { + createSingleArtifactAction((state) => { state.apiResponses.updateLocalProfile.loading = true; state.apiResponses.updateLocalProfile.error = null; return state; }); -export const updateLocalProfileSuccessAction = createArtifactAction((state) => { - state.apiResponses.updateLocalProfile.loading = false; +export const updateLocalProfileSuccessAction = createSingleArtifactAction( + (state) => { + state.apiResponses.updateLocalProfile.loading = false; - return state; -}); + return state; + }, +); export const updateLocalProfileErrorAction = - createArtifactAction((state, action) => { + createSingleArtifactAction((state, action) => { const { error } = action.payload; state.apiResponses.updateLocalProfile.loading = false; diff --git a/app/client/src/git/store/actions/updateProtectedBranchesActions.ts b/app/client/src/git/store/actions/updateProtectedBranchesActions.ts index a19926b673f9..6e45bf0dcca5 100644 --- a/app/client/src/git/store/actions/updateProtectedBranchesActions.ts +++ b/app/client/src/git/store/actions/updateProtectedBranchesActions.ts @@ -1,19 +1,19 @@ import type { UpdateProtectedBranchesRequestParams } from "git/requests/updateProtectedBranchesRequest.types"; -import { createArtifactAction } from "../helpers/createArtifactAction"; +import { createSingleArtifactAction } from "../helpers/createSingleArtifactAction"; import type { GitArtifactErrorPayloadAction } from "../types"; export interface UpdateProtectedBranchesInitPayload extends UpdateProtectedBranchesRequestParams {} export const updateProtectedBranchesInitAction = - createArtifactAction((state) => { + createSingleArtifactAction((state) => { state.apiResponses.updateProtectedBranches.loading = true; state.apiResponses.updateProtectedBranches.error = null; return state; }); -export const updateProtectedBranchesSuccessAction = createArtifactAction( +export const updateProtectedBranchesSuccessAction = createSingleArtifactAction( (state) => { state.apiResponses.updateProtectedBranches.loading = false; @@ -21,7 +21,7 @@ export const updateProtectedBranchesSuccessAction = createArtifactAction( }, ); -export const updateProtectedBranchesErrorAction = createArtifactAction( +export const updateProtectedBranchesErrorAction = createSingleArtifactAction( (state, action: GitArtifactErrorPayloadAction) => { const { error } = action.payload; diff --git a/app/client/src/git/store/gitArtifactSlice.ts b/app/client/src/git/store/gitArtifactSlice.ts index 15bbb4de65d2..924785f80c76 100644 --- a/app/client/src/git/store/gitArtifactSlice.ts +++ b/app/client/src/git/store/gitArtifactSlice.ts @@ -1,5 +1,5 @@ import { createSlice } from "@reduxjs/toolkit"; -import type { GitArtifactRootReduxState } from "./types"; +import type { GitArtifactReduxState } from "./types"; import { mountAction, unmountAction } from "./actions/mountActions"; import { connectErrorAction, @@ -62,7 +62,6 @@ import { openDisconnectModalAction, closeDisconnectModalAction, toggleAutocommitDisableModalAction, - toggleConnectSuccessModalAction, } from "./actions/uiActions"; import { checkoutBranchErrorAction, @@ -120,6 +119,11 @@ import { disconnectInitAction, disconnectSuccessAction, } from "./actions/disconnectActions"; +import { + gitImportErrorAction, + gitImportInitAction, + gitImportSuccessAction, +} from "./actions/gitImportActions"; import { fetchSSHKeyErrorAction, fetchSSHKeyInitAction, @@ -133,7 +137,7 @@ import { resetGenerateSSHKeyAction, } from "./actions/generateSSHKeyActions"; -const initialState: GitArtifactRootReduxState = {}; +const initialState: GitArtifactReduxState = {}; export const gitArtifactSlice = createSlice({ name: "git/artifact", @@ -152,6 +156,9 @@ export const gitArtifactSlice = createSlice({ connectInit: connectInitAction, connectSuccess: connectSuccessAction, connectError: connectErrorAction, + gitImportInit: gitImportInitAction, + gitImportSuccess: gitImportSuccessAction, + gitImportError: gitImportErrorAction, fetchSSHKeyInit: fetchSSHKeyInitAction, fetchSSHKeySuccess: fetchSSHKeySuccessAction, fetchSSHKeyError: fetchSSHKeyErrorAction, @@ -164,7 +171,6 @@ export const gitArtifactSlice = createSlice({ disconnectSuccess: disconnectSuccessAction, disconnectError: disconnectErrorAction, toggleConnectModal: toggleConnectModalAction, - toggleConnectSuccessModal: toggleConnectSuccessModalAction, openDisconnectModal: openDisconnectModalAction, closeDisconnectModal: closeDisconnectModalAction, toggleRepoLimitErrorModal: toggleRepoLimitErrorModalAction, diff --git a/app/client/src/git/store/gitConfigSlice.ts b/app/client/src/git/store/gitConfigSlice.ts new file mode 100644 index 000000000000..a07a45d9730b --- /dev/null +++ b/app/client/src/git/store/gitConfigSlice.ts @@ -0,0 +1,29 @@ +import { createSlice } from "@reduxjs/toolkit"; +import { + fetchGlobalProfileErrorAction, + fetchGlobalProfileInitAction, + fetchGlobalProfileSuccessAction, +} from "./actions/fetchGlobalProfileActions"; +import { + updateGlobalProfileErrorAction, + updateGlobalProfileInitAction, + updateGlobalProfileSuccessAction, +} from "./actions/updateGlobalProfileActions"; +import { gitConfigInitialState } from "./helpers/gitConfigInitialState"; + +export const gitConfigSlice = createSlice({ + name: "git/config", + initialState: gitConfigInitialState, + reducers: { + fetchGlobalProfileInit: fetchGlobalProfileInitAction, + fetchGlobalProfileSuccess: fetchGlobalProfileSuccessAction, + fetchGlobalProfileError: fetchGlobalProfileErrorAction, + updateGlobalProfileInit: updateGlobalProfileInitAction, + updateGlobalProfileSuccess: updateGlobalProfileSuccessAction, + updateGlobalProfileError: updateGlobalProfileErrorAction, + }, +}); + +export const gitConfigActions = gitConfigSlice.actions; + +export const gitConfigReducer = gitConfigSlice.reducer; diff --git a/app/client/src/git/store/gitGlobalSlice.ts b/app/client/src/git/store/gitGlobalSlice.ts deleted file mode 100644 index 4a26f5d6132f..000000000000 --- a/app/client/src/git/store/gitGlobalSlice.ts +++ /dev/null @@ -1,49 +0,0 @@ -import { createSlice } from "@reduxjs/toolkit"; -import { - fetchGlobalProfileErrorAction, - fetchGlobalProfileInitAction, - fetchGlobalProfileSuccessAction, -} from "./actions/fetchGlobalProfileActions"; -import { - updateGlobalProfileErrorAction, - updateGlobalProfileInitAction, - updateGlobalProfileSuccessAction, -} from "./actions/updateGlobalProfileActions"; -import { gitGlobalInitialState } from "./helpers/initialState"; -import { toggleImportModalAction } from "./actions/uiActions"; -import { - gitImportErrorAction, - gitImportInitAction, - gitImportSuccessAction, -} from "./actions/gitImportActions"; -import { - fetchGlobalSSHKeyErrorAction, - fetchGlobalSSHKeyInitAction, - fetchGlobalSSHKeySuccessAction, - resetGlobalSSHKeyAction, -} from "./actions/fetchGlobalSSHKeyActions"; - -export const gitGlobalSlice = createSlice({ - name: "git/config", - initialState: gitGlobalInitialState, - reducers: { - fetchGlobalProfileInit: fetchGlobalProfileInitAction, - fetchGlobalProfileSuccess: fetchGlobalProfileSuccessAction, - fetchGlobalProfileError: fetchGlobalProfileErrorAction, - updateGlobalProfileInit: updateGlobalProfileInitAction, - updateGlobalProfileSuccess: updateGlobalProfileSuccessAction, - updateGlobalProfileError: updateGlobalProfileErrorAction, - fetchGlobalSSHKeyInit: fetchGlobalSSHKeyInitAction, - fetchGlobalSSHKeySuccess: fetchGlobalSSHKeySuccessAction, - fetchGlobalSSHKeyError: fetchGlobalSSHKeyErrorAction, - resetGlobalSSHKey: resetGlobalSSHKeyAction, - gitImportInit: gitImportInitAction, - gitImportSuccess: gitImportSuccessAction, - gitImportError: gitImportErrorAction, - toggleImportModal: toggleImportModalAction, - }, -}); - -export const gitGlobalActions = gitGlobalSlice.actions; - -export const gitGlobalReducer = gitGlobalSlice.reducer; diff --git a/app/client/src/git/store/helpers/createArtifactAction.ts b/app/client/src/git/store/helpers/createArtifactAction.ts deleted file mode 100644 index c138af710d53..000000000000 --- a/app/client/src/git/store/helpers/createArtifactAction.ts +++ /dev/null @@ -1,35 +0,0 @@ -import type { - GitArtifactBasePayload, - GitArtifactPayloadAction, - GitArtifactReduxState, - GitArtifactRootReduxState, -} from "../types"; -import { gitArtifactInitialState } from "./initialState"; - -type ArtifactStateCb = ( - artifactState: GitArtifactReduxState, - action: GitArtifactPayloadAction, -) => GitArtifactReduxState; - -export const createArtifactAction = ( - artifactStateCb: ArtifactStateCb, -) => { - return ( - state: GitArtifactRootReduxState, - action: GitArtifactPayloadAction, - ) => { - const { artifactType, baseArtifactId } = action.payload.artifactDef; - - state[artifactType] ??= {}; - state[artifactType][baseArtifactId] ??= gitArtifactInitialState; - - const artifactState = state[artifactType][baseArtifactId]; - - state[artifactType][baseArtifactId] = artifactStateCb( - artifactState, - action, - ); - - return state; - }; -}; diff --git a/app/client/src/git/store/helpers/createSingleArtifactAction.ts b/app/client/src/git/store/helpers/createSingleArtifactAction.ts new file mode 100644 index 000000000000..2e0642959be8 --- /dev/null +++ b/app/client/src/git/store/helpers/createSingleArtifactAction.ts @@ -0,0 +1,35 @@ +import type { + GitArtifactBasePayload, + GitArtifactPayloadAction, + GitArtifactReduxState, + GitSingleArtifactReduxState, +} from "../types"; +import { gitSingleArtifactInitialState } from "./gitSingleArtifactInitialState"; + +type SingleArtifactStateCb = ( + singleArtifactState: GitSingleArtifactReduxState, + action: GitArtifactPayloadAction, +) => GitSingleArtifactReduxState; + +export const createSingleArtifactAction = ( + singleArtifactStateCb: SingleArtifactStateCb, +) => { + return ( + state: GitArtifactReduxState, + action: GitArtifactPayloadAction, + ) => { + const { artifactType, baseArtifactId } = action.payload; + + state[artifactType] ??= {}; + state[artifactType][baseArtifactId] ??= gitSingleArtifactInitialState; + + const singleArtifactState = state[artifactType][baseArtifactId]; + + state[artifactType][baseArtifactId] = singleArtifactStateCb( + singleArtifactState, + action, + ); + + return state; + }; +}; diff --git a/app/client/src/git/store/helpers/gitConfigInitialState.ts b/app/client/src/git/store/helpers/gitConfigInitialState.ts new file mode 100644 index 000000000000..7017399dfb16 --- /dev/null +++ b/app/client/src/git/store/helpers/gitConfigInitialState.ts @@ -0,0 +1,13 @@ +import type { GitConfigReduxState } from "../types"; + +export const gitConfigInitialState: GitConfigReduxState = { + globalProfile: { + value: null, + loading: false, + error: null, + }, + updateGlobalProfile: { + loading: false, + error: null, + }, +}; diff --git a/app/client/src/git/store/helpers/gitSingleArtifactInitialState.ts b/app/client/src/git/store/helpers/gitSingleArtifactInitialState.ts new file mode 100644 index 000000000000..b17c93a126cb --- /dev/null +++ b/app/client/src/git/store/helpers/gitSingleArtifactInitialState.ts @@ -0,0 +1,138 @@ +import { + gitArtifactAPIResponsesInitialState as gitArtifactAPIResponsesInitialStateExtended, + gitArtifactUIInitialState as gitArtifactUIInitialStateExtended, +} from "git/ee/store/helpers/initialState"; +import { GitOpsTab, GitSettingsTab } from "../../constants/enums"; +import type { + GitSingleArtifactAPIResponsesReduxState, + GitSingleArtifactUIReduxState, + GitSingleArtifactReduxState, +} from "../types"; + +const gitSingleArtifactInitialUIState: GitSingleArtifactUIReduxState = { + connectModalOpen: false, + disconnectBaseArtifactId: null, + disconnectArtifactName: null, + branchPopupOpen: false, + checkoutDestBranch: null, + opsModalOpen: false, + opsModalTab: GitOpsTab.Deploy, + settingsModalOpen: false, + settingsModalTab: GitSettingsTab.General, + autocommitDisableModalOpen: false, + autocommitPolling: false, + conflictErrorModalOpen: false, + repoLimitErrorModalOpen: false, + // EE + ...gitArtifactUIInitialStateExtended, +}; + +const gitSingleArtifactInitialAPIResponses: GitSingleArtifactAPIResponsesReduxState = + { + metadata: { + value: null, + loading: false, + error: null, + }, + connect: { + loading: false, + error: null, + }, + gitImport: { + loading: false, + error: null, + }, + status: { + value: null, + loading: false, + error: null, + }, + commit: { + loading: false, + error: null, + }, + pull: { + loading: false, + error: null, + }, + discard: { + loading: false, + error: null, + }, + mergeStatus: { + value: null, + loading: false, + error: null, + }, + merge: { + loading: false, + error: null, + }, + branches: { + value: null, + loading: false, + error: null, + }, + checkoutBranch: { + loading: false, + error: null, + }, + createBranch: { + loading: false, + error: null, + }, + deleteBranch: { + loading: false, + error: null, + }, + localProfile: { + value: null, + loading: false, + error: null, + }, + updateLocalProfile: { + loading: false, + error: null, + }, + disconnect: { + loading: false, + error: null, + }, + protectedBranches: { + value: null, + loading: false, + error: null, + }, + updateProtectedBranches: { + loading: false, + error: null, + }, + autocommitProgress: { + loading: false, + error: null, + }, + toggleAutocommit: { + loading: false, + error: null, + }, + triggerAutocommit: { + loading: false, + error: null, + }, + generateSSHKey: { + loading: false, + error: null, + }, + sshKey: { + value: null, + loading: false, + error: null, + }, + // EE + ...gitArtifactAPIResponsesInitialStateExtended, + }; + +export const gitSingleArtifactInitialState: GitSingleArtifactReduxState = { + ui: gitSingleArtifactInitialUIState, + apiResponses: gitSingleArtifactInitialAPIResponses, +}; diff --git a/app/client/src/git/store/helpers/initialState.ts b/app/client/src/git/store/helpers/initialState.ts deleted file mode 100644 index 382833be2782..000000000000 --- a/app/client/src/git/store/helpers/initialState.ts +++ /dev/null @@ -1,157 +0,0 @@ -import { - gitArtifactAPIResponsesInitialState as gitArtifactAPIResponsesInitialStateExtended, - gitArtifactUIInitialState as gitArtifactUIInitialStateExtended, -} from "git/ee/store/helpers/initialState"; -import { GitOpsTab, GitSettingsTab } from "../../constants/enums"; -import type { - GitArtifactAPIResponsesReduxState, - GitArtifactUIReduxState, - GitArtifactReduxState, - GitGlobalReduxState, -} from "../types"; - -const gitArtifactInitialUIState: GitArtifactUIReduxState = { - connectModalOpen: false, - connectSuccessModalOpen: false, - disconnectBaseArtifactId: null, - disconnectArtifactName: null, - branchPopupOpen: false, - checkoutDestBranch: null, - opsModalOpen: false, - opsModalTab: GitOpsTab.Deploy, - settingsModalOpen: false, - settingsModalTab: GitSettingsTab.General, - autocommitDisableModalOpen: false, - autocommitPolling: false, - conflictErrorModalOpen: false, - repoLimitErrorModalOpen: false, - // EE - ...gitArtifactUIInitialStateExtended, -}; - -const gitArtifactInitialAPIResponses: GitArtifactAPIResponsesReduxState = { - metadata: { - value: null, - loading: false, - error: null, - }, - connect: { - loading: false, - error: null, - }, - status: { - value: null, - loading: false, - error: null, - }, - commit: { - loading: false, - error: null, - }, - pull: { - loading: false, - error: null, - }, - discard: { - loading: false, - error: null, - }, - mergeStatus: { - value: null, - loading: false, - error: null, - }, - merge: { - loading: false, - error: null, - }, - branches: { - value: null, - loading: false, - error: null, - }, - checkoutBranch: { - loading: false, - error: null, - }, - createBranch: { - loading: false, - error: null, - }, - deleteBranch: { - loading: false, - error: null, - }, - localProfile: { - value: null, - loading: false, - error: null, - }, - updateLocalProfile: { - loading: false, - error: null, - }, - disconnect: { - loading: false, - error: null, - }, - protectedBranches: { - value: null, - loading: false, - error: null, - }, - updateProtectedBranches: { - loading: false, - error: null, - }, - autocommitProgress: { - loading: false, - error: null, - }, - toggleAutocommit: { - loading: false, - error: null, - }, - triggerAutocommit: { - loading: false, - error: null, - }, - generateSSHKey: { - loading: false, - error: null, - }, - sshKey: { - value: null, - loading: false, - error: null, - }, - // EE - ...gitArtifactAPIResponsesInitialStateExtended, -}; - -export const gitArtifactInitialState: GitArtifactReduxState = { - ui: gitArtifactInitialUIState, - apiResponses: gitArtifactInitialAPIResponses, -}; - -export const gitGlobalInitialState: GitGlobalReduxState = { - globalProfile: { - value: null, - loading: false, - error: null, - }, - updateGlobalProfile: { - loading: false, - error: null, - }, - globalSSHKey: { - value: null, - loading: false, - error: null, - }, - gitImport: { - loading: false, - error: null, - }, - isImportModalOpen: false, -}; diff --git a/app/client/src/git/store/index.ts b/app/client/src/git/store/index.ts index 6d210139ada4..f5337e564f97 100644 --- a/app/client/src/git/store/index.ts +++ b/app/client/src/git/store/index.ts @@ -1,8 +1,8 @@ import { combineReducers } from "@reduxjs/toolkit"; import { gitArtifactReducer } from "./gitArtifactSlice"; -import { gitGlobalReducer } from "./gitGlobalSlice"; +import { gitConfigReducer } from "./gitConfigSlice"; export const gitReducer = combineReducers({ artifacts: gitArtifactReducer, - global: gitGlobalReducer, + config: gitConfigReducer, }); diff --git a/app/client/src/git/store/selectors/gitConfigSelectors.ts b/app/client/src/git/store/selectors/gitConfigSelectors.ts new file mode 100644 index 000000000000..be31a23cda5e --- /dev/null +++ b/app/client/src/git/store/selectors/gitConfigSelectors.ts @@ -0,0 +1,12 @@ +import type { GitRootState } from "../types"; + +export const selectGitConfig = (state: GitRootState) => { + return state.git.config; +}; + +// global profile +export const selectFetchGlobalProfileState = (state: GitRootState) => + selectGitConfig(state).globalProfile; + +export const selectUpdateGlobalProfileState = (state: GitRootState) => + selectGitConfig(state).updateGlobalProfile; diff --git a/app/client/src/git/store/selectors/gitGlobalSelectors.ts b/app/client/src/git/store/selectors/gitGlobalSelectors.ts deleted file mode 100644 index 1d1fdb555d0c..000000000000 --- a/app/client/src/git/store/selectors/gitGlobalSelectors.ts +++ /dev/null @@ -1,21 +0,0 @@ -import type { GitRootState } from "../types"; - -export const selectGitGlobal = (state: GitRootState) => { - return state.git.global; -}; - -// global profile -export const selectFetchGlobalProfileState = (state: GitRootState) => - selectGitGlobal(state).globalProfile; - -export const selectUpdateGlobalProfileState = (state: GitRootState) => - selectGitGlobal(state).updateGlobalProfile; - -export const selectImportModalOpen = (state: GitRootState) => - selectGitGlobal(state).isImportModalOpen; - -export const selectGitImportState = (state: GitRootState) => - selectGitGlobal(state).gitImport; - -export const selectFetchGlobalSSHKeyState = (state: GitRootState) => - selectGitGlobal(state).globalSSHKey; diff --git a/app/client/src/git/store/selectors/gitArtifactSelectors.ts b/app/client/src/git/store/selectors/gitSingleArtifactSelectors.ts similarity index 92% rename from app/client/src/git/store/selectors/gitArtifactSelectors.ts rename to app/client/src/git/store/selectors/gitSingleArtifactSelectors.ts index 5bf8267df889..845a2cfe41fe 100644 --- a/app/client/src/git/store/selectors/gitArtifactSelectors.ts +++ b/app/client/src/git/store/selectors/gitSingleArtifactSelectors.ts @@ -1,4 +1,10 @@ -import type { GitArtifactDef, GitRootState } from "../types"; +import type { GitArtifactType } from "git/constants/enums"; +import type { GitRootState } from "../types"; + +export interface GitArtifactDef { + artifactType: keyof typeof GitArtifactType; + baseArtifactId: string; +} export const selectGitArtifact = ( state: GitRootState, @@ -15,7 +21,7 @@ export const selectMetadataState = ( artifactDef: GitArtifactDef, ) => selectGitArtifact(state, artifactDef)?.apiResponses.metadata; -export const selectConnected = ( +export const selectGitConnected = ( state: GitRootState, artifactDef: GitArtifactDef, ) => !!selectMetadataState(state, artifactDef)?.value; @@ -26,6 +32,11 @@ export const selectConnectState = ( artifactDef: GitArtifactDef, ) => selectGitArtifact(state, artifactDef)?.apiResponses.connect; +export const selectGitImportState = ( + state: GitRootState, + artifactDef: GitArtifactDef, +) => selectGitArtifact(state, artifactDef)?.apiResponses.gitImport; + export const selectFetchSSHKeysState = ( state: GitRootState, artifactDef: GitArtifactDef, @@ -41,11 +52,6 @@ export const selectConnectModalOpen = ( artifactDef: GitArtifactDef, ) => selectGitArtifact(state, artifactDef)?.ui.connectModalOpen; -export const selectConnectSuccessModalOpen = ( - state: GitRootState, - artifactDef: GitArtifactDef, -) => selectGitArtifact(state, artifactDef)?.ui.connectSuccessModalOpen; - export const selectDisconnectState = ( state: GitRootState, artifactDef: GitArtifactDef, @@ -111,14 +117,11 @@ export const selectConflictErrorModalOpen = ( export const selectCurrentBranch = ( state: GitRootState, - // need this to preserve interface - // eslint-disable-next-line @typescript-eslint/no-unused-vars artifactDef: GitArtifactDef, ) => { - return ( - state?.ui?.applications?.currentApplication?.gitApplicationMetadata - ?.branchName ?? null - ); + const gitMetadataState = selectMetadataState(state, artifactDef).value; + + return gitMetadataState?.branchName; }; export const selectFetchBranchesState = ( @@ -217,8 +220,10 @@ export const selectProtectedMode = ( artifactDef: GitArtifactDef, ) => { const currentBranch = selectCurrentBranch(state, artifactDef); - const protectedBranches = - selectFetchProtectedBranchesState(state, artifactDef)?.value ?? []; + const protectedBranches = selectFetchProtectedBranchesState( + state, + artifactDef, + ).value; return protectedBranches?.includes(currentBranch ?? "") ?? false; }; diff --git a/app/client/src/git/store/types.ts b/app/client/src/git/store/types.ts index 90a2e72998a5..ccb67a2e7a8b 100644 --- a/app/client/src/git/store/types.ts +++ b/app/client/src/git/store/types.ts @@ -17,7 +17,6 @@ import type { GitArtifactAPIResponsesReduxState as GitArtifactAPIResponsesReduxStateExtended, GitArtifactUIReduxState as GitArtifactUIReduxStateExtended, } from "git/ee/store/types"; -import type { FetchGlobalSSHKeyResponseData } from "git/requests/fetchGlobalSSHKeyRequest.types"; export interface GitApiError extends ApiResponseError { errorType?: string; @@ -34,10 +33,11 @@ export interface GitAsyncStateWithoutValue { loading: boolean; error: GitApiError | null; } -export interface GitArtifactAPIResponsesReduxState +export interface GitSingleArtifactAPIResponsesReduxState extends GitArtifactAPIResponsesReduxStateExtended { metadata: GitAsyncState; connect: GitAsyncStateWithoutValue; + gitImport: GitAsyncStateWithoutValue; status: GitAsyncState; commit: GitAsyncStateWithoutValue; pull: GitAsyncStateWithoutValue; @@ -60,10 +60,9 @@ export interface GitArtifactAPIResponsesReduxState generateSSHKey: GitAsyncStateWithoutValue; } -export interface GitArtifactUIReduxState +export interface GitSingleArtifactUIReduxState extends GitArtifactUIReduxStateExtended { connectModalOpen: boolean; - connectSuccessModalOpen: boolean; disconnectBaseArtifactId: string | null; disconnectArtifactName: string | null; branchPopupOpen: boolean; @@ -77,51 +76,30 @@ export interface GitArtifactUIReduxState conflictErrorModalOpen: boolean; repoLimitErrorModalOpen: boolean; } - -export interface GitArtifactDef { - artifactType: keyof typeof GitArtifactType; - baseArtifactId: string; +export interface GitSingleArtifactReduxState { + ui: GitSingleArtifactUIReduxState; + apiResponses: GitSingleArtifactAPIResponsesReduxState; } + export interface GitArtifactReduxState { - ui: GitArtifactUIReduxState; - apiResponses: GitArtifactAPIResponsesReduxState; + [key: string]: Record; } -export interface GitGlobalReduxState { +export interface GitConfigReduxState { globalProfile: GitAsyncState; updateGlobalProfile: GitAsyncStateWithoutValue; - gitImport: GitAsyncStateWithoutValue; - globalSSHKey: GitAsyncState; - // ui - isImportModalOpen: boolean; -} - -export type GitArtifactRootReduxState = Record< - string, - Record ->; - -export interface GitReduxState { - artifacts: GitArtifactRootReduxState; - global: GitGlobalReduxState; } export interface GitRootState { - // will have to remove this later, once metadata is fixed - ui: { - applications: { - currentApplication?: { - gitApplicationMetadata?: { - branchName: string; - }; - }; - }; + git: { + artifacts: GitArtifactReduxState; + config: GitConfigReduxState; }; - git: GitReduxState; } export interface GitArtifactBasePayload { - artifactDef: GitArtifactDef; + artifactType: keyof typeof GitArtifactType; + baseArtifactId: string; } export interface GitAsyncErrorPayload { diff --git a/app/client/src/layoutSystems/anvil/common/hooks/detachedWidgetHooks.ts b/app/client/src/layoutSystems/anvil/common/hooks/detachedWidgetHooks.ts index 6bf86d26a55d..c3ad4a82bd8d 100644 --- a/app/client/src/layoutSystems/anvil/common/hooks/detachedWidgetHooks.ts +++ b/app/client/src/layoutSystems/anvil/common/hooks/detachedWidgetHooks.ts @@ -1,6 +1,7 @@ import { useWidgetBorderStyles } from "./useWidgetBorderStyles"; import { useDispatch, useSelector } from "react-redux"; import { useWidgetSelection } from "utils/hooks/useWidgetSelection"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { SELECT_ANVIL_WIDGET_CUSTOM_EVENT } from "layoutSystems/anvil/utils/constants"; import log from "loglevel"; import { useEffect, useMemo } from "react"; @@ -8,7 +9,6 @@ import { getAnvilWidgetDOMId } from "layoutSystems/common/utils/LayoutElementPos import { getCurrentlyOpenAnvilDetachedWidgets } from "layoutSystems/anvil/integrations/modalSelectors"; import { getCanvasWidgetsStructure } from "ee/selectors/entitiesSelector"; import type { CanvasWidgetStructure } from "WidgetProvider/constants"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; /** * This hook is used to select and focus on a detached widget * As detached widgets are outside of the layout flow, we need to access the correct element in the DOM @@ -17,7 +17,7 @@ import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; */ export function useHandleDetachedWidgetSelect(widgetId: string) { const dispatch = useDispatch(); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const className = getAnvilWidgetDOMId(widgetId); const element = document.querySelector(`.${className}`); diff --git a/app/client/src/layoutSystems/anvil/common/hooks/useWidgetBorderStyles.ts b/app/client/src/layoutSystems/anvil/common/hooks/useWidgetBorderStyles.ts index 1213f9134b3a..fea0cc19424c 100644 --- a/app/client/src/layoutSystems/anvil/common/hooks/useWidgetBorderStyles.ts +++ b/app/client/src/layoutSystems/anvil/common/hooks/useWidgetBorderStyles.ts @@ -7,8 +7,8 @@ import { getWidgetsDistributingSpace, } from "layoutSystems/anvil/integrations/selectors"; import { useSelector } from "react-redux"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { isWidgetFocused, isWidgetSelected } from "selectors/widgetSelectors"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export function useWidgetBorderStyles(widgetId: string, widgetType: string) { /** Selectors */ @@ -32,7 +32,7 @@ export function useWidgetBorderStyles(widgetId: string, widgetType: string) { const widgetsEffectedBySpaceDistribution = useSelector( getWidgetsDistributingSpace, ); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); /** EO selectors */ diff --git a/app/client/src/layoutSystems/anvil/editor/AnvilEditorWidgetOnion.tsx b/app/client/src/layoutSystems/anvil/editor/AnvilEditorWidgetOnion.tsx index 839c055f0f40..f5a6505a2be2 100644 --- a/app/client/src/layoutSystems/anvil/editor/AnvilEditorWidgetOnion.tsx +++ b/app/client/src/layoutSystems/anvil/editor/AnvilEditorWidgetOnion.tsx @@ -4,7 +4,7 @@ import type { BaseWidgetProps } from "widgets/BaseWidgetHOC/withBaseWidgetHOC"; import { AnvilWidgetComponent } from "../common/widgetComponent/AnvilWidgetComponent"; import { getWidgetSizeConfiguration } from "../utils/widgetUtils"; import { useSelector } from "react-redux"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { AnvilEditorFlexComponent } from "./AnvilEditorFlexComponent"; import { AnvilFlexComponent } from "../common/AnvilFlexComponent"; import { SKELETON_WIDGET_TYPE } from "constants/WidgetConstants"; @@ -25,7 +25,7 @@ import { SKELETON_WIDGET_TYPE } from "constants/WidgetConstants"; * @returns Enhanced Widget */ export const AnvilEditorWidgetOnion = (props: BaseWidgetProps) => { - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const { widgetSize, WidgetWrapper } = useMemo(() => { return { widgetSize: getWidgetSizeConfiguration(props.type, props, isPreviewMode), diff --git a/app/client/src/layoutSystems/anvil/editor/hooks/useAnvilWidgetHover.ts b/app/client/src/layoutSystems/anvil/editor/hooks/useAnvilWidgetHover.ts index e51d921bf1bd..abdb88561f68 100644 --- a/app/client/src/layoutSystems/anvil/editor/hooks/useAnvilWidgetHover.ts +++ b/app/client/src/layoutSystems/anvil/editor/hooks/useAnvilWidgetHover.ts @@ -2,7 +2,7 @@ import type { AppState } from "ee/reducers"; import { getAnvilSpaceDistributionStatus } from "layoutSystems/anvil/integrations/selectors"; import { useCallback, useEffect } from "react"; import { useSelector } from "react-redux"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { isWidgetFocused } from "selectors/widgetSelectors"; import { useWidgetSelection } from "utils/hooks/useWidgetSelection"; @@ -12,7 +12,7 @@ export const useAnvilWidgetHover = ( ) => { // Retrieve state from the Redux store const isFocused = useSelector(isWidgetFocused(widgetId)); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isDistributingSpace = useSelector(getAnvilSpaceDistributionStatus); const isDragging = useSelector( (state: AppState) => state.ui.widgetDragResize.isDragging, diff --git a/app/client/src/layoutSystems/anvil/integrations/sagas/LayoutElementPositionsSaga.ts b/app/client/src/layoutSystems/anvil/integrations/sagas/LayoutElementPositionsSaga.ts index 2cddcc974bc8..a882919710b1 100644 --- a/app/client/src/layoutSystems/anvil/integrations/sagas/LayoutElementPositionsSaga.ts +++ b/app/client/src/layoutSystems/anvil/integrations/sagas/LayoutElementPositionsSaga.ts @@ -8,7 +8,7 @@ import log from "loglevel"; import type { AppState } from "ee/reducers"; import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; import { APP_MODE } from "entities/App"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { getAppMode } from "ee/selectors/entitiesSelector"; import type { RefObject } from "react"; import { getAnvilSpaceDistributionStatus } from "../selectors"; @@ -87,7 +87,7 @@ function* readAndUpdateLayoutElementPositions() { // The positions are used only in the editor, so we should not be running this saga // in the viewer or the preview mode. - const isPreviewMode: boolean = yield select(selectCombinedPreviewMode); + const isPreviewMode: boolean = yield select(combinedPreviewModeSelector); const appMode: APP_MODE = yield select(getAppMode); if (isPreviewMode || appMode === APP_MODE.PUBLISHED) { diff --git a/app/client/src/layoutSystems/anvil/layoutComponents/components/zone/useZoneMinWidth.ts b/app/client/src/layoutSystems/anvil/layoutComponents/components/zone/useZoneMinWidth.ts index c8ba600c5fb6..fe49ee655230 100644 --- a/app/client/src/layoutSystems/anvil/layoutComponents/components/zone/useZoneMinWidth.ts +++ b/app/client/src/layoutSystems/anvil/layoutComponents/components/zone/useZoneMinWidth.ts @@ -3,20 +3,22 @@ import { ChildrenMapContext } from "layoutSystems/anvil/context/childrenMapConte import type { WidgetProps } from "widgets/BaseWidget"; import { RenderModes } from "constants/WidgetConstants"; import { useSelector } from "react-redux"; -import { getRenderMode } from "selectors/editorSelectors"; +import { + combinedPreviewModeSelector, + getRenderMode, +} from "selectors/editorSelectors"; import type { SizeConfig } from "WidgetProvider/constants"; import { getWidgetSizeConfiguration } from "layoutSystems/anvil/utils/widgetUtils"; import type { CanvasWidgetsReduxState } from "reducers/entityReducers/canvasWidgetsReducer"; import { getWidgets } from "sagas/selectors"; import isObject from "lodash/isObject"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export function useZoneMinWidth() { const childrenMap: Record = useContext(ChildrenMapContext); const widgets: CanvasWidgetsReduxState = useSelector(getWidgets); const renderMode: RenderModes = useSelector(getRenderMode); - const isPreviewMode: boolean = useSelector(selectCombinedPreviewMode); + const isPreviewMode: boolean = useSelector(combinedPreviewModeSelector); if (renderMode === RenderModes.CANVAS && !isPreviewMode) return "auto"; diff --git a/app/client/src/layoutSystems/anvil/sectionSpaceDistributor/SectionSpaceDistributor.tsx b/app/client/src/layoutSystems/anvil/sectionSpaceDistributor/SectionSpaceDistributor.tsx index 25e94d38d9e8..fd719bfd1f6f 100644 --- a/app/client/src/layoutSystems/anvil/sectionSpaceDistributor/SectionSpaceDistributor.tsx +++ b/app/client/src/layoutSystems/anvil/sectionSpaceDistributor/SectionSpaceDistributor.tsx @@ -2,7 +2,7 @@ import { getLayoutElementPositions } from "layoutSystems/common/selectors"; import type { LayoutElementPosition } from "layoutSystems/common/types"; import React, { useMemo } from "react"; import { useSelector } from "react-redux"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import type { WidgetLayoutProps } from "../utils/anvilTypes"; import { getWidgetByID } from "sagas/selectors"; import { getDefaultSpaceDistributed } from "./utils/spaceRedistributionSagaUtils"; @@ -113,7 +113,7 @@ export const SectionSpaceDistributor = ( props: SectionSpaceDistributorProps, ) => { const { zones } = props; - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isWidgetSelectionBlocked = useSelector(getWidgetSelectionBlock); const isDragging = useSelector( (state) => state.ui.widgetDragResize.isDragging, diff --git a/app/client/src/layoutSystems/anvil/viewer/AnvilViewerWidgetOnion.tsx b/app/client/src/layoutSystems/anvil/viewer/AnvilViewerWidgetOnion.tsx index 763785755918..99ca7dddf492 100644 --- a/app/client/src/layoutSystems/anvil/viewer/AnvilViewerWidgetOnion.tsx +++ b/app/client/src/layoutSystems/anvil/viewer/AnvilViewerWidgetOnion.tsx @@ -5,7 +5,7 @@ import { AnvilWidgetComponent } from "../common/widgetComponent/AnvilWidgetCompo import type { SizeConfig } from "WidgetProvider/constants"; import { getWidgetSizeConfiguration } from "../utils/widgetUtils"; import { useSelector } from "react-redux"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; /** * AnvilViewerWidgetOnion @@ -20,7 +20,7 @@ import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; * @returns Enhanced Widget */ export const AnvilViewerWidgetOnion = (props: BaseWidgetProps) => { - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const widgetSize: SizeConfig = useMemo( () => getWidgetSizeConfiguration(props.type, props, isPreviewMode), [isPreviewMode, props.type], diff --git a/app/client/src/layoutSystems/autolayout/common/FlexComponent.tsx b/app/client/src/layoutSystems/autolayout/common/FlexComponent.tsx index 334ca9fd95ec..20edbf4ce0d8 100644 --- a/app/client/src/layoutSystems/autolayout/common/FlexComponent.tsx +++ b/app/client/src/layoutSystems/autolayout/common/FlexComponent.tsx @@ -4,7 +4,10 @@ import styled from "styled-components"; import { WIDGET_PADDING } from "constants/WidgetConstants"; import { useSelector } from "react-redux"; -import { snipingModeSelector } from "selectors/editorSelectors"; +import { + combinedPreviewModeSelector, + snipingModeSelector, +} from "selectors/editorSelectors"; import { getIsResizing } from "selectors/widgetSelectors"; import { useClickToSelectWidget } from "utils/hooks/useClickToSelectWidget"; import { usePositionedContainerZIndex } from "utils/hooks/usePositionedContainerZIndex"; @@ -13,7 +16,6 @@ import { RESIZE_BORDER_BUFFER } from "layoutSystems/common/resizer/common"; import { checkIsDropTarget } from "WidgetProvider/factory/helpers"; import type { FlexComponentProps } from "../../autolayout/utils/types"; import { useHoverToFocusWidget } from "utils/hooks/useHoverToFocusWidget"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; const FlexWidget = styled.div` position: relative; @@ -56,7 +58,7 @@ export function FlexComponent(props: FlexComponentProps) { )} t--widget-${props.widgetName.toLowerCase()}`, [props.parentId, props.widgetId, props.widgetType, props.widgetName], ); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isResizing = useSelector(getIsResizing); const widgetDimensionsViewCss = { diff --git a/app/client/src/layoutSystems/common/dropTarget/DropTargetComponent.tsx b/app/client/src/layoutSystems/common/dropTarget/DropTargetComponent.tsx index fcb93c9205a6..d1df63825448 100644 --- a/app/client/src/layoutSystems/common/dropTarget/DropTargetComponent.tsx +++ b/app/client/src/layoutSystems/common/dropTarget/DropTargetComponent.tsx @@ -21,7 +21,10 @@ import { } from "actions/autoHeightActions"; import { useDispatch } from "react-redux"; import { getDragDetails } from "sagas/selectors"; -import { getOccupiedSpacesSelectorForContainer } from "selectors/editorSelectors"; +import { + combinedPreviewModeSelector, + getOccupiedSpacesSelectorForContainer, +} from "selectors/editorSelectors"; import { getCanvasSnapRows } from "utils/WidgetPropsUtils"; import { useAutoHeightUIState } from "utils/hooks/autoHeightUIHooks"; import { useShowPropertyPane } from "utils/hooks/dragResizeHooks"; @@ -39,7 +42,6 @@ import { import DragLayerComponent from "./DragLayerComponent"; import Onboarding from "./OnBoarding"; import { isDraggingBuildingBlockToCanvas } from "selectors/buildingBlocksSelectors"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export type DropTargetComponentProps = PropsWithChildren<{ snapColumnSpace: number; @@ -194,7 +196,7 @@ function useUpdateRows( export function DropTargetComponent(props: DropTargetComponentProps) { // Get if this is in preview mode. - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/layoutSystems/common/resizer/ModalResizableLayer.tsx b/app/client/src/layoutSystems/common/resizer/ModalResizableLayer.tsx index 1a516b9623fe..559556bbbf42 100644 --- a/app/client/src/layoutSystems/common/resizer/ModalResizableLayer.tsx +++ b/app/client/src/layoutSystems/common/resizer/ModalResizableLayer.tsx @@ -19,9 +19,11 @@ import { } from "./ResizeStyledComponents"; import type { UIElementSize } from "./ResizableUtils"; import { useModalWidth } from "widgets/ModalWidget/component/useModalWidth"; -import { snipingModeSelector } from "selectors/editorSelectors"; +import { + combinedPreviewModeSelector, + snipingModeSelector, +} from "selectors/editorSelectors"; import { getWidgetSelectionBlock } from "../../../selectors/ui"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; const minSize = 100; /** @@ -99,7 +101,7 @@ export const ModalResizableLayer = ({ widgetType: "MODAL_WIDGET", }); }; - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isSnipingMode = useSelector(snipingModeSelector); const isWidgetSelectionBlocked = useSelector(getWidgetSelectionBlock); const enableResizing = diff --git a/app/client/src/layoutSystems/common/resizer/ResizableComponent.tsx b/app/client/src/layoutSystems/common/resizer/ResizableComponent.tsx index fb5aca05d16f..f0336f382b87 100644 --- a/app/client/src/layoutSystems/common/resizer/ResizableComponent.tsx +++ b/app/client/src/layoutSystems/common/resizer/ResizableComponent.tsx @@ -17,7 +17,10 @@ import { FixedLayoutResizable } from "layoutSystems/fixedlayout/common/resizer/F import { SelectionRequestType } from "sagas/WidgetSelectUtils"; import { getIsAutoLayout } from "selectors/canvasSelectors"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; -import { snipingModeSelector } from "selectors/editorSelectors"; +import { + combinedPreviewModeSelector, + snipingModeSelector, +} from "selectors/editorSelectors"; import { getParentToOpenSelector, isWidgetFocused, @@ -66,7 +69,6 @@ import { getAltBlockWidgetSelection, getWidgetSelectionBlock, } from "selectors/ui"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export type ResizableComponentProps = WidgetProps & { paddingOffset: number; @@ -81,7 +83,7 @@ export const ResizableComponent = memo(function ResizableComponent( const isAutoLayout = useSelector(getIsAutoLayout); const Resizable = isAutoLayout ? AutoLayoutResizable : FixedLayoutResizable; const isSnipingMode = useSelector(snipingModeSelector); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isWidgetSelectionBlock = useSelector(getWidgetSelectionBlock); const isAltWidgetSelectionBlock = useSelector(getAltBlockWidgetSelection); const isAppSettingsPaneWithNavigationTabOpen: boolean = useSelector( diff --git a/app/client/src/layoutSystems/common/utils/LayoutElementPositionsObserver/usePositionObserver.ts b/app/client/src/layoutSystems/common/utils/LayoutElementPositionsObserver/usePositionObserver.ts index 9c981c66f397..1d5a9c38f354 100644 --- a/app/client/src/layoutSystems/common/utils/LayoutElementPositionsObserver/usePositionObserver.ts +++ b/app/client/src/layoutSystems/common/utils/LayoutElementPositionsObserver/usePositionObserver.ts @@ -3,7 +3,7 @@ import { useEffect } from "react"; import { positionObserver } from "."; import { APP_MODE } from "entities/App"; import { useSelector } from "react-redux"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { getAppMode } from "ee/selectors/entitiesSelector"; import { getAnvilLayoutDOMId, getAnvilWidgetDOMId } from "./utils"; import { LayoutComponentTypes } from "layoutSystems/anvil/utils/anvilTypes"; @@ -13,7 +13,7 @@ export function useObserveDetachedWidget(widgetId: string) { // We don't need the observer in preview mode or the published app // This is because the positions need to be observed only to enable // editor features - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const appMode = useSelector(getAppMode); if (isPreviewMode || appMode === APP_MODE.PUBLISHED) { @@ -54,7 +54,7 @@ export function usePositionObserver( }, ref: RefObject, ) { - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const appMode = useSelector(getAppMode); useEffect(() => { diff --git a/app/client/src/layoutSystems/common/widgetName/index.tsx b/app/client/src/layoutSystems/common/widgetName/index.tsx index 8d5770b995a0..bb8c265946e5 100644 --- a/app/client/src/layoutSystems/common/widgetName/index.tsx +++ b/app/client/src/layoutSystems/common/widgetName/index.tsx @@ -8,6 +8,7 @@ import { SelectionRequestType } from "sagas/WidgetSelectUtils"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; import { hideErrors } from "selectors/debuggerSelectors"; import { + combinedPreviewModeSelector, getIsAutoLayout, snipingModeSelector, } from "selectors/editorSelectors"; @@ -30,7 +31,6 @@ import { RESIZE_BORDER_BUFFER } from "layoutSystems/common/resizer/common"; import { Layers } from "constants/Layers"; import memoize from "micro-memoize"; import { NavigationMethod } from "utils/history"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; const WidgetTypes = WidgetFactory.widgetTypes; @@ -78,7 +78,7 @@ interface WidgetNameComponentProps { export function WidgetNameComponent(props: WidgetNameComponentProps) { const dispatch = useDispatch(); const isSnipingMode = useSelector(snipingModeSelector); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/layoutSystems/fixedlayout/common/autoHeightOverlay/index.tsx b/app/client/src/layoutSystems/fixedlayout/common/autoHeightOverlay/index.tsx index 48015d2efff1..89519283f7cb 100644 --- a/app/client/src/layoutSystems/fixedlayout/common/autoHeightOverlay/index.tsx +++ b/app/client/src/layoutSystems/fixedlayout/common/autoHeightOverlay/index.tsx @@ -3,7 +3,7 @@ import type { CSSProperties } from "react"; import React, { memo } from "react"; import { useSelector } from "react-redux"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import type { WidgetProps } from "widgets/BaseWidget"; import AutoHeightOverlayWithStateContext from "./AutoHeightOverlayWithStateContext"; @@ -31,7 +31,7 @@ const AutoHeightOverlayContainer: React.FC = selectedWidgets, } = useSelector((state: AppState) => state.ui.widgetDragResize); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/CanvasSelectionArena.tsx b/app/client/src/layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/CanvasSelectionArena.tsx index c299eaef18db..c0cf29167981 100644 --- a/app/client/src/layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/CanvasSelectionArena.tsx +++ b/app/client/src/layoutSystems/fixedlayout/editor/FixedLayoutCanvasArenas/CanvasSelectionArena.tsx @@ -21,6 +21,7 @@ import { getIsDraggingForSelection, } from "selectors/canvasSelectors"; import { + combinedPreviewModeSelector, getCurrentApplicationLayout, getCurrentPageId, } from "selectors/editorSelectors"; @@ -30,7 +31,6 @@ import type { XYCord } from "layoutSystems/common/canvasArenas/ArenaTypes"; import { useCanvasDragToScroll } from "layoutSystems/common/canvasArenas/useCanvasDragToScroll"; import { StickyCanvasArena } from "layoutSystems/common/canvasArenas/StickyCanvasArena"; import { getWidgetSelectionBlock } from "../../../../selectors/ui"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export interface SelectedArenaDimensions { top: number; @@ -71,7 +71,7 @@ export function CanvasSelectionArena({ (parentWidget && parentWidget.detachFromLayout) ); const appMode = useSelector(getAppMode); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isWidgetSelectionBlocked = useSelector(getWidgetSelectionBlock); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, diff --git a/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx b/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx index 5ad23ff2e567..3b6b80aa7328 100644 --- a/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx +++ b/app/client/src/pages/AppViewer/Navigation/Sidebar.tsx @@ -12,7 +12,10 @@ import ShareButton from "./components/ShareButton"; import PrimaryCTA from "../PrimaryCTA"; import { useHref } from "pages/Editor/utils"; import { builderURL } from "ee/RouteBuilder"; -import { getCurrentBasePageId } from "selectors/editorSelectors"; +import { + combinedPreviewModeSelector, + getCurrentBasePageId, +} from "selectors/editorSelectors"; import type { User } from "constants/userConstants"; import SidebarProfileComponent from "./components/SidebarProfileComponent"; import CollapseButton from "./components/CollapseButton"; @@ -33,7 +36,6 @@ import MenuItemContainer from "./components/MenuItemContainer"; import BackToAppsButton from "./components/BackToAppsButton"; import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; import { BOTTOM_BAR_HEIGHT } from "components/BottomBar/constants"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; interface SidebarProps { currentApplicationDetails?: ApplicationPayload; @@ -79,7 +81,7 @@ export function Sidebar(props: SidebarProps) { const isPinned = useSelector(getAppSidebarPinned); const [isOpen, setIsOpen] = useState(true); const { x } = useMouse(); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/pages/AppViewer/Navigation/TopInline.tsx b/app/client/src/pages/AppViewer/Navigation/TopInline.tsx index af09e8497fd1..f15dd093ff21 100644 --- a/app/client/src/pages/AppViewer/Navigation/TopInline.tsx +++ b/app/client/src/pages/AppViewer/Navigation/TopInline.tsx @@ -5,12 +5,14 @@ import MenuItem from "./components/MenuItem"; import { Container } from "./TopInline.styled"; import MenuItemContainer from "./components/MenuItemContainer"; import MoreDropdownButton from "./components/MoreDropdownButton"; -import { getCanvasWidth } from "selectors/editorSelectors"; +import { + combinedPreviewModeSelector, + getCanvasWidth, +} from "selectors/editorSelectors"; import { useSelector } from "react-redux"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; import { throttle } from "lodash"; import type { NavigationProps } from "./constants"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export function TopInline(props: NavigationProps) { const { currentApplicationDetails, pages } = props; @@ -21,7 +23,7 @@ export function TopInline(props: NavigationProps) { const maxMenuItemWidth = 220; const [maxMenuItemsThatCanFit, setMaxMenuItemsThatCanFit] = useState(0); const { width: screenWidth } = useWindowSizeHooks(); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/pages/AppViewer/PrimaryCTA.test.tsx b/app/client/src/pages/AppViewer/PrimaryCTA.test.tsx index 63b76d0e0fcc..3b03a559fbfb 100644 --- a/app/client/src/pages/AppViewer/PrimaryCTA.test.tsx +++ b/app/client/src/pages/AppViewer/PrimaryCTA.test.tsx @@ -7,11 +7,6 @@ import { lightTheme } from "selectors/themeSelectors"; import PrimaryCTA from "./PrimaryCTA"; import configureStore from "redux-mock-store"; -jest.mock("pages/Editor/gitSync/hooks/modHooks", () => ({ - ...jest.requireActual("pages/Editor/gitSync/hooks/modHooks"), - useGitProtectedMode: jest.fn(() => false), -})); - jest.mock("react-router", () => ({ ...jest.requireActual("react-router"), useHistory: () => ({ push: jest.fn() }), diff --git a/app/client/src/pages/AppViewer/PrimaryCTA.tsx b/app/client/src/pages/AppViewer/PrimaryCTA.tsx index 97d0363bbf5f..9e2816166454 100644 --- a/app/client/src/pages/AppViewer/PrimaryCTA.tsx +++ b/app/client/src/pages/AppViewer/PrimaryCTA.tsx @@ -25,8 +25,8 @@ import { Icon, Tooltip } from "@appsmith/ads"; import { getApplicationNameTextColor } from "./utils"; import { ButtonVariantTypes } from "components/constants"; import { setPreviewModeInitAction } from "actions/editorActions"; +import { protectedModeSelector } from "selectors/gitSyncSelectors"; import { getCurrentApplication } from "ee/selectors/applicationSelectors"; -import { useGitProtectedMode } from "pages/Editor/gitSync/hooks/modHooks"; /** * --------------------------------------------------------------------------------------------------- @@ -67,7 +67,7 @@ function PrimaryCTA(props: Props) { const canEdit = isPermitted(userPermissions, permissionRequired); const [isForkModalOpen, setIsForkModalOpen] = useState(false); const isPreviewMode = useSelector(previewModeSelector); - const isProtectedMode = useGitProtectedMode(); + const isProtectedMode = useSelector(protectedModeSelector); const dispatch = useDispatch(); const location = useLocation(); const queryParams = new URLSearchParams(location.search); diff --git a/app/client/src/pages/Editor/AppSettingsPane/AppSettings/ImportAppSettings.tsx b/app/client/src/pages/Editor/AppSettingsPane/AppSettings/ImportAppSettings.tsx index b721e7c5c7af..8da3b25343c3 100644 --- a/app/client/src/pages/Editor/AppSettingsPane/AppSettings/ImportAppSettings.tsx +++ b/app/client/src/pages/Editor/AppSettingsPane/AppSettings/ImportAppSettings.tsx @@ -8,8 +8,8 @@ import ImportModal from "pages/common/ImportModal"; import React from "react"; import { useSelector } from "react-redux"; import { getCurrentApplicationId } from "selectors/editorSelectors"; +import { getIsGitConnected } from "selectors/gitSyncSelectors"; import styled from "styled-components"; -import { useGitConnected } from "pages/Editor/gitSync/hooks/modHooks"; const SettingWrapper = styled.div` display: flex; @@ -21,7 +21,7 @@ const SettingWrapper = styled.div` export function ImportAppSettings() { const appId = useSelector(getCurrentApplicationId); const workspace = useSelector(getCurrentAppWorkspace); - const isGitConnected = useGitConnected(); + const isGitConnected = useSelector(getIsGitConnected); const [isModalOpen, setIsModalOpen] = React.useState(false); function handleClose() { diff --git a/app/client/src/pages/Editor/Canvas.tsx b/app/client/src/pages/Editor/Canvas.tsx index c34f2fc358c8..742e6d8a74b1 100644 --- a/app/client/src/pages/Editor/Canvas.tsx +++ b/app/client/src/pages/Editor/Canvas.tsx @@ -5,7 +5,7 @@ import * as Sentry from "@sentry/react"; import { useDispatch, useSelector } from "react-redux"; import type { CanvasWidgetStructure } from "WidgetProvider/constants"; import useWidgetFocus from "utils/hooks/useWidgetFocus"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { getSelectedAppTheme } from "selectors/appThemingSelectors"; import { getViewportClassName } from "layoutSystems/autolayout/utils/AutoLayoutUtils"; import { @@ -44,7 +44,7 @@ const Wrapper = styled.section<{ `; const Canvas = (props: CanvasProps) => { const { canvasWidth } = props; - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/pages/Editor/GlobalHotKeys/GlobalHotKeys.tsx b/app/client/src/pages/Editor/GlobalHotKeys/GlobalHotKeys.tsx index 1e01349df831..651f57e792c0 100644 --- a/app/client/src/pages/Editor/GlobalHotKeys/GlobalHotKeys.tsx +++ b/app/client/src/pages/Editor/GlobalHotKeys/GlobalHotKeys.tsx @@ -45,8 +45,8 @@ import { toast } from "@appsmith/ads"; import { showDebuggerFlag } from "selectors/debuggerSelectors"; import { getIsFirstTimeUserOnboardingEnabled } from "selectors/onboardingSelectors"; import WalkthroughContext from "components/featureWalkthrough/walkthroughContext"; +import { protectedModeSelector } from "selectors/gitSyncSelectors"; import { setPreviewModeInitAction } from "actions/editorActions"; -import { selectGitApplicationProtectedMode } from "selectors/gitModSelectors"; interface Props { copySelectedWidget: () => void; @@ -372,17 +372,15 @@ class GlobalHotKeys extends React.Component { } } -const mapStateToProps = (state: AppState) => { - return { - selectedWidget: getLastSelectedWidget(state), - selectedWidgets: getSelectedWidgets(state), - isDebuggerOpen: showDebuggerFlag(state), - appMode: getAppMode(state), - isPreviewMode: previewModeSelector(state), - isProtectedMode: selectGitApplicationProtectedMode(state), - isSignpostingEnabled: getIsFirstTimeUserOnboardingEnabled(state), - }; -}; +const mapStateToProps = (state: AppState) => ({ + selectedWidget: getLastSelectedWidget(state), + selectedWidgets: getSelectedWidgets(state), + isDebuggerOpen: showDebuggerFlag(state), + appMode: getAppMode(state), + isPreviewMode: previewModeSelector(state), + isProtectedMode: protectedModeSelector(state), + isSignpostingEnabled: getIsFirstTimeUserOnboardingEnabled(state), +}); // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any diff --git a/app/client/src/pages/Editor/IDE/Header/DeployButton.tsx b/app/client/src/pages/Editor/IDE/Header/DeployButton.tsx deleted file mode 100644 index 843da728dddf..000000000000 --- a/app/client/src/pages/Editor/IDE/Header/DeployButton.tsx +++ /dev/null @@ -1,131 +0,0 @@ -import { Button, Tooltip } from "@appsmith/ads"; -import { objectKeys } from "@appsmith/utils"; -import { showConnectGitModal } from "actions/gitSyncActions"; -import { publishApplication } from "ee/actions/applicationActions"; -import { getCurrentApplication } from "ee/selectors/applicationSelectors"; -import type { NavigationSetting } from "constants/AppConstants"; -import { - createMessage, - DEPLOY_BUTTON_TOOLTIP, - DEPLOY_MENU_OPTION, - PACKAGE_UPGRADING_ACTION_STATUS, -} from "ee/constants/messages"; -import { getIsPackageUpgrading } from "ee/selectors/packageSelectors"; -import AnalyticsUtil from "ee/utils/AnalyticsUtil"; -import { useGitOps, useGitProtectedMode } from "git"; -import { - useGitConnected, - useGitModEnabled, -} from "pages/Editor/gitSync/hooks/modHooks"; -import React, { useCallback } from "react"; -import { useDispatch, useSelector } from "react-redux"; -import { - getCurrentApplicationId, - getIsPublishingApplication, -} from "selectors/editorSelectors"; -import styled from "styled-components"; - -// This wrapper maintains pointer events for tooltips when the child button is disabled. -// Without this, disabled buttons won't trigger tooltips because they have pointer-events: none -const StyledTooltipTarget = styled.span` - display: inline-block; -`; - -function DeployButton() { - const applicationId = useSelector(getCurrentApplicationId); - const currentApplication = useSelector(getCurrentApplication); - const isPackageUpgrading = useSelector(getIsPackageUpgrading); - const isProtectedMode = useGitProtectedMode(); - const isDeployDisabled = isPackageUpgrading || isProtectedMode; - const isPublishing = useSelector(getIsPublishingApplication); - const isGitConnected = useGitConnected(); - const isGitModEnabled = useGitModEnabled(); - const { toggleOpsModal } = useGitOps(); - - const deployTooltipText = isPackageUpgrading - ? createMessage(PACKAGE_UPGRADING_ACTION_STATUS, "deploy this app") - : createMessage(DEPLOY_BUTTON_TOOLTIP); - - const dispatch = useDispatch(); - - const handlePublish = useCallback(() => { - if (applicationId) { - dispatch(publishApplication(applicationId)); - - const appName = currentApplication ? currentApplication.name : ""; - const pageCount = currentApplication?.pages?.length; - const navigationSettingsWithPrefix: Record< - string, - NavigationSetting[keyof NavigationSetting] - > = {}; - - if (currentApplication?.applicationDetail?.navigationSetting) { - const settingKeys = objectKeys( - currentApplication.applicationDetail.navigationSetting, - ) as Array; - - settingKeys.map((key: keyof NavigationSetting) => { - if (currentApplication?.applicationDetail?.navigationSetting?.[key]) { - const value: NavigationSetting[keyof NavigationSetting] = - currentApplication.applicationDetail.navigationSetting[key]; - - navigationSettingsWithPrefix[`navigationSetting_${key}`] = value; - } - }); - } - - AnalyticsUtil.logEvent("PUBLISH_APP", { - appId: applicationId, - appName, - pageCount, - ...navigationSettingsWithPrefix, - isPublic: !!currentApplication?.isPublic, - templateTitle: currentApplication?.forkedFromTemplateTitle, - }); - } - }, [applicationId, currentApplication, dispatch]); - - const handleClickDeploy = useCallback(() => { - if (isGitConnected) { - if (isGitModEnabled) { - toggleOpsModal(true); - } else { - dispatch(showConnectGitModal()); - } - - AnalyticsUtil.logEvent("GS_DEPLOY_GIT_CLICK", { - source: "Deploy button", - }); - } else { - handlePublish(); - } - }, [ - dispatch, - handlePublish, - isGitConnected, - isGitModEnabled, - toggleOpsModal, - ]); - - return ( - - - - - - ); -} - -export default DeployButton; diff --git a/app/client/src/pages/Editor/IDE/Header/index.tsx b/app/client/src/pages/Editor/IDE/Header/index.tsx index c26b641ba40d..f8e75cda9db7 100644 --- a/app/client/src/pages/Editor/IDE/Header/index.tsx +++ b/app/client/src/pages/Editor/IDE/Header/index.tsx @@ -1,6 +1,7 @@ -import React, { useState } from "react"; +import React, { useCallback, useState } from "react"; import { Flex, + Tooltip, Divider, Modal, ModalContent, @@ -10,6 +11,7 @@ import { TabsList, Tab, TabPanel, + Button, Link, IDEHeader, IDEHeaderTitle, @@ -22,15 +24,19 @@ import { APPLICATION_INVITE, COMMUNITY_TEMPLATES, createMessage, + DEPLOY_BUTTON_TOOLTIP, + DEPLOY_MENU_OPTION, IN_APP_EMBED_SETTING, INVITE_TAB, HEADER_TITLES, + PACKAGE_UPGRADING_ACTION_STATUS, } from "ee/constants/messages"; import EditorName from "pages/Editor/EditorName"; import { getCurrentApplicationId, getCurrentPageId, getIsPageSaving, + getIsPublishingApplication, getPageById, getPageSavingError, } from "selectors/editorSelectors"; @@ -40,7 +46,10 @@ import { getIsErroredSavingAppName, getIsSavingAppName, } from "ee/selectors/applicationSelectors"; -import { updateApplication } from "ee/actions/applicationActions"; +import { + publishApplication, + updateApplication, +} from "ee/actions/applicationActions"; import { getCurrentAppWorkspace } from "ee/selectors/selectedWorkspaceSelectors"; import { Omnibar } from "pages/Editor/commons/Omnibar"; import ToggleModeButton from "pages/Editor/ToggleModeButton"; @@ -53,6 +62,13 @@ import DeployLinkButtonDialog from "components/designSystems/appsmith/header/Dep import { useFeatureFlag } from "utils/hooks/useFeatureFlag"; import { FEATURE_FLAG } from "ee/entities/FeatureFlag"; import { getAppsmithConfigs } from "ee/configs"; +import { + getIsGitConnected, + protectedModeSelector, +} from "selectors/gitSyncSelectors"; +import { showConnectGitModal } from "actions/gitSyncActions"; +import AnalyticsUtil from "ee/utils/AnalyticsUtil"; +import type { NavigationSetting } from "constants/AppConstants"; import { useHref } from "pages/Editor/utils"; import { viewerURL } from "ee/RouteBuilder"; import HelpBar from "components/editorComponents/GlobalSearch/HelpBar"; @@ -64,8 +80,7 @@ import { APPLICATIONS_URL } from "constants/routes"; import { useNavigationMenuData } from "../../EditorName/useNavigationMenuData"; import useLibraryHeaderTitle from "ee/pages/Editor/IDE/Header/useLibraryHeaderTitle"; import { AppsmithLink } from "pages/Editor/AppsmithLink"; -import DeployButton from "./DeployButton"; -import GitApplicationContextProvider from "components/gitContexts/GitApplicationContextProvider"; +import { getIsPackageUpgrading } from "ee/selectors/packageSelectors"; const StyledDivider = styled(Divider)` height: 50%; @@ -73,6 +88,12 @@ const StyledDivider = styled(Divider)` margin-right: 8px; `; +// This wrapper maintains pointer events for tooltips when the child button is disabled. +// Without this, disabled buttons won't trigger tooltips because they have pointer-events: none +const StyledTooltipTarget = styled.span` + display: inline-block; +`; + const { cloudHosting } = getAppsmithConfigs(); interface HeaderTitleProps { @@ -116,11 +137,19 @@ const Header = () => { const currentApplication = useSelector(getCurrentApplication); const isErroredSavingName = useSelector(getIsErroredSavingAppName); const applicationList = useSelector(getApplicationList); + const isProtectedMode = useSelector(protectedModeSelector); + const isPackageUpgrading = useSelector(getIsPackageUpgrading); + const isPublishing = useSelector(getIsPublishingApplication); + const isGitConnected = useSelector(getIsGitConnected); const pageId = useSelector(getCurrentPageId) as string; const currentPage = useSelector(getPageById(pageId)); const appState = useCurrentAppState(); const isSaving = useSelector(getIsPageSaving); const pageSaveError = useSelector(getPageSavingError); + const isDeployDisabled = isPackageUpgrading || isProtectedMode; + const deployTooltipText = isPackageUpgrading + ? createMessage(PACKAGE_UPGRADING_ACTION_STATUS, "deploy this app") + : createMessage(DEPLOY_BUTTON_TOOLTIP); // states const [isPopoverOpen, setIsPopoverOpen] = useState(false); const [showModal, setShowModal] = useState(false); @@ -150,8 +179,56 @@ const Header = () => { dispatch(updateApplication(id, data)); }; + const handlePublish = useCallback(() => { + if (applicationId) { + dispatch(publishApplication(applicationId)); + + const appName = currentApplication ? currentApplication.name : ""; + const pageCount = currentApplication?.pages?.length; + const navigationSettingsWithPrefix: Record< + string, + NavigationSetting[keyof NavigationSetting] + > = {}; + + if (currentApplication?.applicationDetail?.navigationSetting) { + const settingKeys = Object.keys( + currentApplication.applicationDetail.navigationSetting, + ) as Array; + + settingKeys.map((key: keyof NavigationSetting) => { + if (currentApplication?.applicationDetail?.navigationSetting?.[key]) { + const value: NavigationSetting[keyof NavigationSetting] = + currentApplication.applicationDetail.navigationSetting[key]; + + navigationSettingsWithPrefix[`navigationSetting_${key}`] = value; + } + }); + } + + AnalyticsUtil.logEvent("PUBLISH_APP", { + appId: applicationId, + appName, + pageCount, + ...navigationSettingsWithPrefix, + isPublic: !!currentApplication?.isPublic, + templateTitle: currentApplication?.forkedFromTemplateTitle, + }); + } + }, [applicationId, currentApplication, dispatch]); + + const handleClickDeploy = useCallback(() => { + if (isGitConnected) { + dispatch(showConnectGitModal()); + AnalyticsUtil.logEvent("GS_DEPLOY_GIT_CLICK", { + source: "Deploy button", + }); + } else { + handlePublish(); + } + }, [dispatch, handlePublish, isGitConnected]); + return ( - + <> }> @@ -261,13 +338,30 @@ const Header = () => { showModal={showPublishCommunityTemplateModal} />
- + + + + + +
-
+ ); }; diff --git a/app/client/src/pages/Editor/IDE/Layout/AnimatedLayout.tsx b/app/client/src/pages/Editor/IDE/Layout/AnimatedLayout.tsx index d58e70910a3f..952b3542c3f8 100644 --- a/app/client/src/pages/Editor/IDE/Layout/AnimatedLayout.tsx +++ b/app/client/src/pages/Editor/IDE/Layout/AnimatedLayout.tsx @@ -2,6 +2,7 @@ import React from "react"; import { useGridLayoutTemplate } from "./hooks/useGridLayoutTemplate"; import EditorWrapperContainer from "pages/Editor/commons/EditorWrapperContainer"; import { AnimatedGridLayout, LayoutArea } from "components/AnimatedGridLayout"; +import { useSelector } from "react-redux"; import BottomBar from "components/BottomBar"; import Sidebar from "../Sidebar"; import LeftPane from "../LeftPane"; @@ -9,28 +10,10 @@ import MainPane from "../MainPane"; import RightPane from "../RightPane"; import { Areas } from "./constants"; import ProtectedCallout from "../ProtectedCallout"; -import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks"; -import { - GitProtectedBranchCallout as GitProtectedBranchCalloutNew, - useGitProtectedMode, -} from "git"; - -function GitProtectedBranchCallout() { - const isGitModEnabled = useGitModEnabled(); - const isProtectedMode = useGitProtectedMode(); - - if (isGitModEnabled) { - return ; - } - - if (isProtectedMode) { - return ; - } - - return null; -} +import { protectedModeSelector } from "selectors/gitSyncSelectors"; function AnimatedLayout() { + const isProtectedMode = useSelector(protectedModeSelector); const { areas, columns, rows } = useGridLayoutTemplate(); if (columns.length === 0) { @@ -39,7 +22,7 @@ function AnimatedLayout() { return ( <> - + {isProtectedMode && } ; - } - - if (isProtectedMode) { - return ; - } - - return null; -} const GridContainer = styled.div` display: grid; @@ -44,13 +26,14 @@ const LayoutContainer = styled.div<{ name: string }>` `; export const StaticLayout = React.memo(() => { + const isProtectedMode = useSelector(protectedModeSelector); const { areas, columns } = useGridLayoutTemplate(); const isSidebarVisible = columns[0] !== "0px"; return ( <> - + {isProtectedMode && } { const [windowWidth] = useWindowDimensions(); @@ -20,7 +20,7 @@ export const useEditorStateLeftPaneWidth = (): number => { const { segment } = useCurrentEditorState(); const propertyPaneWidth = useSelector(getPropertyPaneWidth); const isPreviewMode = useSelector(previewModeSelector); - const isProtectedMode = useGitProtectedMode(); + const isProtectedMode = useSelector(protectedModeSelector); useEffect( function updateWidth() { diff --git a/app/client/src/pages/Editor/IDE/Layout/hooks/useGridLayoutTemplate.ts b/app/client/src/pages/Editor/IDE/Layout/hooks/useGridLayoutTemplate.ts index bf97ce71790b..b2dc0558af59 100644 --- a/app/client/src/pages/Editor/IDE/Layout/hooks/useGridLayoutTemplate.ts +++ b/app/client/src/pages/Editor/IDE/Layout/hooks/useGridLayoutTemplate.ts @@ -7,6 +7,7 @@ import { useCurrentAppState } from "../../hooks/useCurrentAppState"; import { getPropertyPaneWidth } from "selectors/propertyPaneSelectors"; import { previewModeSelector } from "selectors/editorSelectors"; import { getIDEViewMode } from "selectors/ideSelectors"; +import { protectedModeSelector } from "selectors/gitSyncSelectors"; import { EditorEntityTab, EditorState, @@ -19,7 +20,6 @@ import { } from "constants/AppConstants"; import { useEditorStateLeftPaneWidth } from "./useEditorStateLeftPaneWidth"; import { type Area, Areas, SIDEBAR_WIDTH } from "../constants"; -import { useGitProtectedMode } from "pages/Editor/gitSync/hooks/modHooks"; interface ReturnValue { areas: Area[][]; @@ -43,7 +43,7 @@ function useGridLayoutTemplate(): ReturnValue { const appState = useCurrentAppState(); const isPreviewMode = useSelector(previewModeSelector); const editorMode = useSelector(getIDEViewMode); - const isProtectedMode = useGitProtectedMode(); + const isProtectedMode = useSelector(protectedModeSelector); React.useEffect( function updateIDEColumns() { diff --git a/app/client/src/pages/Editor/IDE/ProtectedCallout.test.tsx b/app/client/src/pages/Editor/IDE/ProtectedCallout.test.tsx index d735d5663d88..2a60c70f3f86 100644 --- a/app/client/src/pages/Editor/IDE/ProtectedCallout.test.tsx +++ b/app/client/src/pages/Editor/IDE/ProtectedCallout.test.tsx @@ -3,11 +3,11 @@ import { render } from "@testing-library/react"; import { merge } from "lodash"; import { Provider } from "react-redux"; import configureStore from "redux-mock-store"; +import IDE from "."; import { BrowserRouter } from "react-router-dom"; import "@testing-library/jest-dom"; import { ReduxActionTypes } from "ee/constants/ReduxActionConstants"; import store from "store"; -import ProtectedCallout from "./ProtectedCallout"; // TODO: Fix this the next time the file is edited // eslint-disable-next-line @typescript-eslint/no-explicit-any @@ -64,7 +64,7 @@ describe("Protected callout test cases", () => { const { getByTestId } = render( - + , ); @@ -72,6 +72,33 @@ describe("Protected callout test cases", () => { expect(getByTestId("t--git-protected-branch-callout")).toBeInTheDocument(); }); + it("should not render the protected view if branch is not protected", () => { + const store = getMockStore({ + ui: { + applications: { + currentApplication: { + gitApplicationMetadata: { + branchName: "branch-1", + }, + }, + }, + gitSync: { + protectedBranches: ["main"], + }, + }, + }); + const { queryByTestId } = render( + + + + + , + ); + + expect( + queryByTestId("t--git-protected-branch-callout"), + ).not.toBeInTheDocument(); + }); it("should unprotect only the current branch if clicked on unprotect cta", () => { const store = getMockStore({ ui: { @@ -90,7 +117,7 @@ describe("Protected callout test cases", () => { const { queryByTestId } = render( - + , ); diff --git a/app/client/src/pages/Editor/IDE/hooks.test.tsx b/app/client/src/pages/Editor/IDE/hooks.test.tsx index 9e5e40d6e98f..0a12538bf260 100644 --- a/app/client/src/pages/Editor/IDE/hooks.test.tsx +++ b/app/client/src/pages/Editor/IDE/hooks.test.tsx @@ -6,12 +6,6 @@ import { useGetPageFocusUrl } from "./hooks"; // eslint-disable-next-line @typescript-eslint/no-restricted-imports import { createEditorFocusInfo } from "../../../ce/navigation/FocusStrategy/AppIDEFocusStrategy"; -const mockUseGitCurrentBranch = jest.fn(() => null); - -jest.mock("../gitSync/hooks/modHooks", () => ({ - useGitCurrentBranch: () => mockUseGitCurrentBranch(), -})); - describe("useGetPageFocusUrl", () => { const pages = PageFactory.buildList(4); @@ -48,7 +42,6 @@ describe("useGetPageFocusUrl", () => { const wrapper = hookWrapper({ initialState: state }); it("works for JS focus history", () => { - mockUseGitCurrentBranch.mockReturnValue(null); const { result } = renderHook(() => useGetPageFocusUrl(pages[0].pageId), { wrapper, }); @@ -90,13 +83,10 @@ describe("useGetPageFocusUrl", () => { it("returns correct state when branches exist", () => { const branch = "featureBranch"; - - mockUseGitCurrentBranch.mockReturnValue(branch); const page1FocusHistoryWithBranch = createEditorFocusInfo( pages[0].pageId, branch, ); - const state = getIDETestState({ pages, focusHistory: { diff --git a/app/client/src/pages/Editor/IDE/hooks.ts b/app/client/src/pages/Editor/IDE/hooks.ts index 6d356af8626b..178a02e94222 100644 --- a/app/client/src/pages/Editor/IDE/hooks.ts +++ b/app/client/src/pages/Editor/IDE/hooks.ts @@ -15,6 +15,7 @@ import { widgetListURL, } from "ee/RouteBuilder"; import { getCurrentFocusInfo } from "selectors/focusHistorySelectors"; +import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import { getIsAltFocusWidget, getWidgetSelectionBlock } from "selectors/ui"; import { altFocusWidget, setWidgetSelectionBlock } from "actions/widgetActions"; import { useJSAdd } from "ee/pages/Editor/IDE/EditorPane/JS/hooks"; @@ -26,7 +27,6 @@ import { closeJSActionTab } from "actions/jsActionActions"; import { closeQueryActionTab } from "actions/pluginActionActions"; import { getCurrentBasePageId } from "selectors/editorSelectors"; import { getCurrentEntityInfo } from "../utils"; -import { useGitCurrentBranch } from "../gitSync/hooks/modHooks"; import { useEditorType } from "ee/hooks"; import { useParentEntityInfo } from "ee/hooks/datasourceEditorHooks"; import { useBoolean } from "usehooks-ts"; @@ -102,8 +102,7 @@ export const useSegmentNavigation = (): { export const useGetPageFocusUrl = (basePageId: string): string => { const [focusPageUrl, setFocusPageUrl] = useState(builderURL({ basePageId })); - const branch = useGitCurrentBranch(); - + const branch = useSelector(getCurrentGitBranch); const editorStateFocusInfo = useSelector((appState) => getCurrentFocusInfo(appState, createEditorFocusInfoKey(basePageId, branch)), ); diff --git a/app/client/src/pages/Editor/WidgetsEditor/components/LayoutSystemBasedPageViewer.tsx b/app/client/src/pages/Editor/WidgetsEditor/components/LayoutSystemBasedPageViewer.tsx index 935e67cd90f0..a430ed2fd02e 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/components/LayoutSystemBasedPageViewer.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/components/LayoutSystemBasedPageViewer.tsx @@ -8,9 +8,9 @@ import { getCurrentPageId, previewModeSelector, } from "selectors/editorSelectors"; +import { protectedModeSelector } from "selectors/gitSyncSelectors"; import { getAppSettingsPaneContext } from "selectors/appSettingsPaneSelectors"; import { useShowSnapShotBanner } from "pages/Editor/CanvasLayoutConversion/hooks/useShowSnapShotBanner"; -import { useGitProtectedMode } from "pages/Editor/gitSync/hooks/modHooks"; /** * LayoutSystemBasedPageViewer @@ -25,7 +25,7 @@ export const LayoutSystemBasedPageViewer = ({ }) => { const currentPageId = useSelector(getCurrentPageId); const isPreviewMode = useSelector(previewModeSelector); - const isProtectedMode = useGitProtectedMode(); + const isProtectedMode = useSelector(protectedModeSelector); const appSettingsPaneContext = useSelector(getAppSettingsPaneContext); const canvasWidth = useSelector(getCanvasWidth); const shouldShowSnapShotBanner = useShowSnapShotBanner( diff --git a/app/client/src/pages/Editor/WidgetsEditor/components/NavigationAdjustedPageViewer.tsx b/app/client/src/pages/Editor/WidgetsEditor/components/NavigationAdjustedPageViewer.tsx index 6eb0f1ff10a6..7ec7cdd62ec4 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/components/NavigationAdjustedPageViewer.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/components/NavigationAdjustedPageViewer.tsx @@ -4,7 +4,7 @@ import { EditorState } from "ee/entities/IDE/constants"; import { useCurrentAppState } from "pages/Editor/IDE/hooks/useCurrentAppState"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; import { useSelector } from "react-redux"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { PageViewWrapper } from "pages/AppViewer/AppPage"; import classNames from "classnames"; import { APP_MODE } from "entities/App"; @@ -27,7 +27,7 @@ import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; export const NavigationAdjustedPageViewer = (props: { children: ReactNode; }) => { - const isPreview = useSelector(selectCombinedPreviewMode); + const isPreview = useSelector(combinedPreviewModeSelector); const currentApplicationDetails = useSelector(getCurrentApplication); const isAppSidebarPinned = useSelector(getAppSidebarPinned); const sidebarWidth = useSelector(getSidebarWidth); diff --git a/app/client/src/pages/Editor/WidgetsEditor/components/NavigationPreview.tsx b/app/client/src/pages/Editor/WidgetsEditor/components/NavigationPreview.tsx index 8f2aa0e23c24..0478d6f63439 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/components/NavigationPreview.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/components/NavigationPreview.tsx @@ -2,7 +2,7 @@ import type { LegacyRef } from "react"; import React, { forwardRef } from "react"; import classNames from "classnames"; import { useSelector } from "react-redux"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { Navigation } from "pages/AppViewer/Navigation"; import { useCurrentAppState } from "pages/Editor/IDE/hooks/useCurrentAppState"; import { EditorState } from "ee/entities/IDE/constants"; @@ -22,7 +22,7 @@ const NavigationPreview = forwardRef( const appState = useCurrentAppState(); const isAppSettingsPaneWithNavigationTabOpen = appState === EditorState.SETTINGS && isNavigationSelectedInSettings; - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); return (
{ const allowDragToSelect = useAllowEditorDragToSelect(); const { isAutoHeightWithLimitsChanging } = useAutoHeightUIState(); const dispatch = useDispatch(); - const isCombinedPreviewMode = useSelector(selectCombinedPreviewMode); + const isCombinedPreviewMode = useSelector(combinedPreviewModeSelector); const handleWrapperClick = useCallback( (e) => { diff --git a/app/client/src/pages/Editor/WidgetsEditor/components/WidgetEditorNavigation.tsx b/app/client/src/pages/Editor/WidgetsEditor/components/WidgetEditorNavigation.tsx index d7b7d2869271..852c210685ee 100644 --- a/app/client/src/pages/Editor/WidgetsEditor/components/WidgetEditorNavigation.tsx +++ b/app/client/src/pages/Editor/WidgetsEditor/components/WidgetEditorNavigation.tsx @@ -7,7 +7,7 @@ import { getIsAppSettingsPaneWithNavigationTabOpen, } from "selectors/appSettingsPaneSelectors"; import { useSelector } from "react-redux"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { getCurrentApplication } from "ee/selectors/applicationSelectors"; /** @@ -20,7 +20,7 @@ import { getCurrentApplication } from "ee/selectors/applicationSelectors"; export const useNavigationPreviewHeight = () => { const [navigationHeight, setNavigationHeight] = useState(0); const navigationPreviewRef = useRef(null); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const appSettingsPaneContext = useSelector(getAppSettingsPaneContext); const currentApplicationDetails = useSelector(getCurrentApplication); @@ -54,7 +54,7 @@ type DivRef = React.Ref; */ export const WidgetEditorNavigation = forwardRef( (props, navigationPreviewRef: DivRef) => { - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isNavigationSelectedInSettings = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/pages/Editor/commons/EditorWrapperContainer.tsx b/app/client/src/pages/Editor/commons/EditorWrapperContainer.tsx index 3b34d1beecd4..990004cbbec5 100644 --- a/app/client/src/pages/Editor/commons/EditorWrapperContainer.tsx +++ b/app/client/src/pages/Editor/commons/EditorWrapperContainer.tsx @@ -2,11 +2,11 @@ import React from "react"; import styled from "styled-components"; import classNames from "classnames"; import { useSelector } from "react-redux"; +import { combinedPreviewModeSelector } from "../../../selectors/editorSelectors"; +import { protectedModeSelector } from "selectors/gitSyncSelectors"; import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; import { BOTTOM_BAR_HEIGHT } from "../../../components/BottomBar/constants"; import { PROTECTED_CALLOUT_HEIGHT } from "../IDE/ProtectedCallout"; -import { useGitProtectedMode } from "../gitSync/hooks/modHooks"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; interface EditorWrapperContainerProps { children: React.ReactNode; @@ -25,8 +25,8 @@ const Wrapper = styled.div<{ `; function EditorWrapperContainer({ children }: EditorWrapperContainerProps) { - const isCombinedPreviewMode = useSelector(selectCombinedPreviewMode); - const isProtectedMode = useGitProtectedMode(); + const isCombinedPreviewMode = useSelector(combinedPreviewModeSelector); + const isProtectedMode = useSelector(protectedModeSelector); return (
{props.showSuccess ? ( diff --git a/app/client/src/pages/Editor/gitSync/hooks/modHooks.ts b/app/client/src/pages/Editor/gitSync/hooks/modHooks.ts deleted file mode 100644 index e4d4b7fb4b7a..000000000000 --- a/app/client/src/pages/Editor/gitSync/hooks/modHooks.ts +++ /dev/null @@ -1,44 +0,0 @@ -// temp file will be removed after git mod is fully rolled out - -import { useSelector } from "react-redux"; -import { - getCurrentGitBranch, - getIsGitConnected, - protectedModeSelector, -} from "selectors/gitSyncSelectors"; -import { - useGitProtectedMode as useGitProtectedModeNew, - useGitCurrentBranch as useGitCurrentBranchNew, - useGitConnected as useGitConnectedNew, -} from "git"; -import { selectGitModEnabled } from "selectors/gitModSelectors"; - -export function useGitModEnabled() { - const isGitModEnabled = useSelector(selectGitModEnabled); - - return isGitModEnabled; -} - -export function useGitCurrentBranch() { - const isGitModEnabled = useGitModEnabled(); - const currentBranchOld = useSelector(getCurrentGitBranch) ?? null; - const currentBranchNew = useGitCurrentBranchNew(); - - return isGitModEnabled ? currentBranchNew : currentBranchOld; -} - -export function useGitProtectedMode() { - const isGitModEnabled = useGitModEnabled(); - const isProtectedModeOld = useSelector(protectedModeSelector); - const isProtectedModeNew = useGitProtectedModeNew(); - - return isGitModEnabled ? isProtectedModeNew : isProtectedModeOld; -} - -export function useGitConnected() { - const isGitModEnabled = useGitModEnabled(); - const isGitConnectedOld = useSelector(getIsGitConnected); - const isGitConnectedNew = useGitConnectedNew(); - - return isGitModEnabled ? isGitConnectedNew : isGitConnectedOld; -} diff --git a/app/client/src/pages/Editor/index.tsx b/app/client/src/pages/Editor/index.tsx index 746b7ca56733..a7bfff34f2cb 100644 --- a/app/client/src/pages/Editor/index.tsx +++ b/app/client/src/pages/Editor/index.tsx @@ -25,9 +25,12 @@ import { getTheme, ThemeMode } from "selectors/themeSelectors"; import { ThemeProvider } from "styled-components"; import type { Theme } from "constants/DefaultTheme"; import GlobalHotKeys from "./GlobalHotKeys"; +import GitSyncModal from "pages/Editor/gitSync/GitSyncModal"; +import DisconnectGitModal from "pages/Editor/gitSync/DisconnectGitModal"; import { setupPageAction, updateCurrentPage } from "actions/pageActions"; import { getCurrentPageId } from "selectors/editorSelectors"; import { getSearchQuery } from "utils/helpers"; +import RepoLimitExceededErrorModal from "./gitSync/RepoLimitExceededErrorModal"; import ImportedApplicationSuccessModal from "./gitSync/ImportSuccessModal"; import { getIsBranchUpdated } from "../utils"; import { APP_MODE } from "entities/App"; @@ -39,40 +42,16 @@ import SignpostingOverlay from "pages/Editor/FirstTimeUserOnboarding/Overlay"; import { editorInitializer } from "../../utils/editor/EditorUtils"; import { widgetInitialisationSuccess } from "../../actions/widgetActions"; import urlBuilder from "ee/entities/URLRedirect/URLAssembly"; +import DisableAutocommitModal from "./gitSync/DisableAutocommitModal"; +import GitSettingsModal from "./gitSync/GitSettingsModal"; +import ReconfigureCDKeyModal from "ee/components/gitComponents/ReconfigureCDKeyModal"; +import DisableCDModal from "ee/components/gitComponents/DisableCDModal"; import { PartialExportModal } from "components/editorComponents/PartialImportExport/PartialExportModal"; import { PartialImportModal } from "components/editorComponents/PartialImportExport/PartialImportModal"; import type { Page } from "entities/Page"; import { AppCURLImportModal } from "ee/pages/Editor/CurlImport"; import { IDE_HEADER_HEIGHT } from "@appsmith/ads"; import GeneratePageModal from "./GeneratePage"; -import { GitModals as NewGitModals } from "git"; -import GitSyncModal from "./gitSync/GitSyncModal"; -import GitSettingsModal from "./gitSync/GitSettingsModal"; -import DisconnectGitModal from "./gitSync/DisconnectGitModal"; -import DisableAutocommitModal from "./gitSync/DisableAutocommitModal"; -import ReconfigureCDKeyModal from "ee/components/gitComponents/ReconfigureCDKeyModal"; -import DisableCDModal from "ee/components/gitComponents/DisableCDModal"; -import RepoLimitExceededErrorModal from "./gitSync/RepoLimitExceededErrorModal"; -import { useGitModEnabled } from "./gitSync/hooks/modHooks"; -import GitApplicationContextProvider from "components/gitContexts/GitApplicationContextProvider"; - -function GitModals() { - const isGitModEnabled = useGitModEnabled(); - - return isGitModEnabled ? ( - - ) : ( - <> - - - - - - - - - ); -} interface EditorProps { currentApplicationId?: string; @@ -216,20 +195,24 @@ class Editor extends Component { {`${this.props.currentApplicationName} | Editor | Appsmith`} - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + +
diff --git a/app/client/src/pages/UserProfile/index.tsx b/app/client/src/pages/UserProfile/index.tsx index f77d74fedb50..a715171bc31d 100644 --- a/app/client/src/pages/UserProfile/index.tsx +++ b/app/client/src/pages/UserProfile/index.tsx @@ -3,23 +3,12 @@ import PageWrapper from "pages/common/PageWrapper"; import styled from "styled-components"; import { Tabs, Tab, TabsList, TabPanel } from "@appsmith/ads"; import General from "./General"; -import OldGitConfig from "./GitConfig"; +import GitConfig from "./GitConfig"; import { useLocation } from "react-router"; import { GIT_PROFILE_ROUTE } from "constants/routes"; import { BackButton } from "components/utils/helperComponents"; import { useDispatch } from "react-redux"; import { fetchGlobalGitConfigInit } from "actions/gitSyncActions"; -import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks"; -import { - fetchGitGlobalProfile, - GitGlobalProfile as GitGlobalProfileNew, -} from "git"; - -function GitGlobalProfile() { - const isGitModEnabled = useGitModEnabled(); - - return isGitModEnabled ? : ; -} const ProfileWrapper = styled.div` width: 978px; @@ -36,7 +25,6 @@ const ProfileWrapper = styled.div` function UserProfile() { const location = useLocation(); const dispatch = useDispatch(); - const isGitModEnabled = useGitModEnabled(); let initialTab = "general"; const tabs = [ @@ -51,7 +39,7 @@ function UserProfile() { tabs.push({ key: "gitConfig", title: "Git user config", - panelComponent: , + panelComponent: , icon: "git-branch", }); @@ -61,16 +49,10 @@ function UserProfile() { const [selectedTab, setSelectedTab] = useState(initialTab); - useEffect( - function fetchGlobalGitConfigOnInitEffect() { - if (isGitModEnabled) { - dispatch(fetchGitGlobalProfile()); - } else { - dispatch(fetchGlobalGitConfigInit()); - } - }, - [dispatch, isGitModEnabled], - ); + useEffect(() => { + // onMount Fetch Global config + dispatch(fetchGlobalGitConfigInit()); + }, []); return ( diff --git a/app/client/src/pages/common/ImportModal.tsx b/app/client/src/pages/common/ImportModal.tsx index 12cefc5dec8c..b19974788529 100644 --- a/app/client/src/pages/common/ImportModal.tsx +++ b/app/client/src/pages/common/ImportModal.tsx @@ -30,8 +30,6 @@ import { import useMessages from "ee/hooks/importModal/useMessages"; import useMethods from "ee/hooks/importModal/useMethods"; import { getIsAnvilLayoutEnabled } from "layoutSystems/anvil/integrations/selectors"; -import { useGitModEnabled } from "pages/Editor/gitSync/hooks/modHooks"; -import { toggleGitImportModal } from "git"; const TextWrapper = styled.div` padding: 0; @@ -205,7 +203,6 @@ function ImportModal(props: ImportModalProps) { toEditor = false, workspaceId, } = props; - const isGitModEnabled = useGitModEnabled(); const { mainDescription, title } = useMessages(); const { appFileToBeUploaded, @@ -226,21 +223,15 @@ function ImportModal(props: ImportModalProps) { setWorkspaceIdForImport({ editorId: editorId || "", workspaceId }), ); - if (isGitModEnabled) { - dispatch( - toggleGitImportModal({ - open: true, - }), - ); - } else { - dispatch( - setIsGitSyncModalOpen({ - isOpen: true, - tab: GitSyncModalTab.GIT_CONNECTION, - }), - ); - } - }, [dispatch, editorId, isGitModEnabled, onClose, workspaceId]); + dispatch( + setIsGitSyncModalOpen({ + isOpen: true, + tab: GitSyncModalTab.GIT_CONNECTION, + }), + ); + + // dispatch(setIsReconnectingDatasourcesModalOpen({ isOpen: true })); + }, []); useEffect(() => { // finished of importing application diff --git a/app/client/src/sagas/ActionExecution/StoreActionSaga.ts b/app/client/src/sagas/ActionExecution/StoreActionSaga.ts index ee6d99630ffd..4bcd909aabf0 100644 --- a/app/client/src/sagas/ActionExecution/StoreActionSaga.ts +++ b/app/client/src/sagas/ActionExecution/StoreActionSaga.ts @@ -4,6 +4,7 @@ import localStorage from "utils/localStorage"; import { updateAppStore } from "actions/pageActions"; import AppsmithConsole from "utils/AppsmithConsole"; import { getAppStoreData } from "ee/selectors/entitiesSelector"; +import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import { getCurrentApplicationId } from "selectors/editorSelectors"; import type { AppStoreState } from "reducers/entityReducers/appReducer"; import { Severity, LOG_CATEGORY } from "entities/AppsmithConsole"; @@ -12,7 +13,6 @@ import type { TRemoveValueDescription, TStoreValueDescription, } from "workers/Evaluation/fns/storeFns"; -import { selectGitApplicationCurrentBranch } from "selectors/gitModSelectors"; type StoreOperation = | TStoreValueDescription @@ -21,9 +21,7 @@ type StoreOperation = export function* handleStoreOperations(triggers: StoreOperation[]) { const applicationId: string = yield select(getCurrentApplicationId); - const branch: string | undefined = yield select( - selectGitApplicationCurrentBranch, - ); + const branch: string | undefined = yield select(getCurrentGitBranch); const appStoreName = getAppStoreName(applicationId, branch); const existingLocalStore = localStorage.getItem(appStoreName) || "{}"; let parsedLocalStore = JSON.parse(existingLocalStore); diff --git a/app/client/src/sagas/DatasourcesSagas.ts b/app/client/src/sagas/DatasourcesSagas.ts index 841be4eae950..189fe5b80bc4 100644 --- a/app/client/src/sagas/DatasourcesSagas.ts +++ b/app/client/src/sagas/DatasourcesSagas.ts @@ -714,7 +714,6 @@ function* redirectAuthorizationCodeSaga( const { contextId, contextType, datasourceId, pluginType } = actionPayload.payload; const isImport: string = yield select(getWorkspaceIdForImport); - // ! git mod - not sure how to handle this, there is no definition for the artifact used here const branchName: string | undefined = yield select(getCurrentGitBranch); if (pluginType === PluginType.API) { diff --git a/app/client/src/sagas/FocusRetentionSaga.ts b/app/client/src/sagas/FocusRetentionSaga.ts index e92be7bae11b..45232d9560dc 100644 --- a/app/client/src/sagas/FocusRetentionSaga.ts +++ b/app/client/src/sagas/FocusRetentionSaga.ts @@ -18,10 +18,10 @@ import type { AppsmithLocationState } from "utils/history"; import type { Action } from "entities/Action"; import { getAction, getPlugin } from "ee/selectors/entitiesSelector"; import type { Plugin } from "api/PluginApi"; +import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import { getIDETypeByUrl } from "ee/entities/IDE/utils"; import { getIDEFocusStrategy } from "ee/navigation/FocusStrategy"; import { IDE_TYPE } from "ee/entities/IDE/constants"; -import { selectGitApplicationCurrentBranch } from "selectors/gitModSelectors"; export interface FocusPath { key: string; @@ -123,9 +123,7 @@ class FocusRetention { } public *handleRemoveFocusHistory(url: string) { - const branch: string | undefined = yield select( - selectGitApplicationCurrentBranch, - ); + const branch: string | undefined = yield select(getCurrentGitBranch); const removeKeys: string[] = []; const focusEntityInfo = identifyEntityFromPath(url); diff --git a/app/client/src/sagas/GlobalSearchSagas.ts b/app/client/src/sagas/GlobalSearchSagas.ts index 93e29c0b29dc..17cf81e719b3 100644 --- a/app/client/src/sagas/GlobalSearchSagas.ts +++ b/app/client/src/sagas/GlobalSearchSagas.ts @@ -21,20 +21,18 @@ import { } from "selectors/editorSelectors"; import type { RecentEntity } from "components/editorComponents/GlobalSearch/utils"; import log from "loglevel"; +import { getCurrentGitBranch } from "selectors/gitSyncSelectors"; import type { FocusEntity, FocusEntityInfo } from "navigation/FocusEntity"; import { convertToPageIdSelector } from "selectors/pageListSelectors"; -import { selectGitApplicationCurrentBranch } from "selectors/gitModSelectors"; const getRecentEntitiesKey = (applicationId: string, branch?: string) => branch ? `${applicationId}-${branch}` : applicationId; export function* updateRecentEntitySaga(entityInfo: FocusEntityInfo) { try { - const applicationId: string = yield select(getCurrentApplicationId); + const branch: string | undefined = yield select(getCurrentGitBranch); - const branch: string | undefined = yield select( - selectGitApplicationCurrentBranch, - ); + const applicationId: string = yield select(getCurrentApplicationId); const recentEntitiesRestored: boolean = yield select( (state: AppState) => state.ui.globalSearch.recentEntitiesRestored, diff --git a/app/client/src/sagas/autoHeightSagas/helpers.ts b/app/client/src/sagas/autoHeightSagas/helpers.ts index 3ac3086a9d53..da276f65d769 100644 --- a/app/client/src/sagas/autoHeightSagas/helpers.ts +++ b/app/client/src/sagas/autoHeightSagas/helpers.ts @@ -11,7 +11,7 @@ import type { } from "reducers/entityReducers/canvasWidgetsReducer"; import { select } from "redux-saga/effects"; import { getWidgetMetaProps, getWidgets } from "sagas/selectors"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { getAppMode } from "ee/selectors/entitiesSelector"; import { isAutoHeightEnabledForWidget } from "widgets/WidgetUtils"; import { getCanvasHeightOffset } from "utils/WidgetSizeUtils"; @@ -20,7 +20,7 @@ import type { DataTree } from "entities/DataTree/dataTreeTypes"; import { getDataTree } from "selectors/dataTreeSelectors"; export function* shouldWidgetsCollapse() { - const isPreviewMode: boolean = yield select(selectCombinedPreviewMode); + const isPreviewMode: boolean = yield select(combinedPreviewModeSelector); const appMode: APP_MODE = yield select(getAppMode); return isPreviewMode || appMode === APP_MODE.PUBLISHED; diff --git a/app/client/src/selectors/debuggerSelectors.tsx b/app/client/src/selectors/debuggerSelectors.tsx index 624fae4f290f..89c2c46df479 100644 --- a/app/client/src/selectors/debuggerSelectors.tsx +++ b/app/client/src/selectors/debuggerSelectors.tsx @@ -11,8 +11,8 @@ import { isWidget, } from "ee/workers/Evaluation/evaluationUtils"; import { getDataTree } from "./dataTreeSelectors"; +import { combinedPreviewModeSelector } from "./editorSelectors"; import type { CanvasDebuggerState } from "reducers/uiReducers/debuggerReducer"; -import { selectCombinedPreviewMode } from "./gitModSelectors"; interface ErrorObejct { [k: string]: Log; @@ -169,7 +169,7 @@ export const getDebuggerOpen = (state: AppState) => state.ui.debugger.isOpen; export const showDebuggerFlag = createSelector( getDebuggerOpen, - selectCombinedPreviewMode, + combinedPreviewModeSelector, (isOpen, isPreview) => isOpen && !isPreview, ); diff --git a/app/client/src/selectors/editorSelectors.tsx b/app/client/src/selectors/editorSelectors.tsx index 39bd1d46c1b6..ee3560dd5034 100644 --- a/app/client/src/selectors/editorSelectors.tsx +++ b/app/client/src/selectors/editorSelectors.tsx @@ -990,3 +990,9 @@ export const getGsheetToken = (state: AppState) => export const getGsheetProjectID = (state: AppState) => state.entities.datasources.gsheetProjectID; + +export const combinedPreviewModeSelector = createSelector( + previewModeSelector, + protectedModeSelector, + (isPreviewMode, isProtectedMode) => isPreviewMode || isProtectedMode, +); diff --git a/app/client/src/selectors/gitModSelectors.ts b/app/client/src/selectors/gitModSelectors.ts deleted file mode 100644 index 35fe32fbbff7..000000000000 --- a/app/client/src/selectors/gitModSelectors.ts +++ /dev/null @@ -1,50 +0,0 @@ -// temp file will be removed after git mod is fully rolled out - -import { selectFeatureFlags } from "ee/selectors/featureFlagsSelectors"; -import { createSelector } from "reselect"; -import { getCurrentGitBranch, protectedModeSelector } from "./gitSyncSelectors"; -import { - selectGitCurrentBranch as selectGitCurrentBranchNew, - selectGitProtectedMode as selectGitProtectedModeNew, -} from "git"; -import { - getCurrentBaseApplicationId, - previewModeSelector, -} from "./editorSelectors"; -import { applicationArtifact } from "git/artifact-helpers/application"; - -export const selectGitModEnabled = createSelector( - selectFeatureFlags, - (featureFlags) => featureFlags.release_git_modularisation_enabled ?? false, -); - -export const selectGitApplicationArtifactDef = createSelector( - getCurrentBaseApplicationId, - (baseApplicationId) => applicationArtifact(baseApplicationId), -); - -export const selectGitApplicationCurrentBranch = createSelector( - selectGitModEnabled, - getCurrentGitBranch, - (state) => - selectGitCurrentBranchNew(state, selectGitApplicationArtifactDef(state)), - (isGitModEnabled, currentBranchOld, currentBranchNew) => { - return isGitModEnabled ? currentBranchNew : currentBranchOld; - }, -); - -export const selectGitApplicationProtectedMode = createSelector( - selectGitModEnabled, - protectedModeSelector, - (state) => - selectGitProtectedModeNew(state, selectGitApplicationArtifactDef(state)), - (isGitModEnabled, protectedModeOld, protectedModeNew) => { - return isGitModEnabled ? protectedModeNew : protectedModeOld; - }, -); - -export const selectCombinedPreviewMode = createSelector( - previewModeSelector, - selectGitApplicationProtectedMode, - (isPreviewMode, isProtectedMode) => isPreviewMode || isProtectedMode, -); diff --git a/app/client/src/selectors/widgetDragSelectors.ts b/app/client/src/selectors/widgetDragSelectors.ts index 21d5848d5175..0a2b35eb7e1f 100644 --- a/app/client/src/selectors/widgetDragSelectors.ts +++ b/app/client/src/selectors/widgetDragSelectors.ts @@ -1,9 +1,11 @@ import type { AppState } from "ee/reducers"; import { createSelector } from "reselect"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "./appSettingsPaneSelectors"; -import { snipingModeSelector } from "./editorSelectors"; +import { + combinedPreviewModeSelector, + snipingModeSelector, +} from "./editorSelectors"; import { getWidgetSelectionBlock } from "./ui"; -import { selectCombinedPreviewMode } from "./gitModSelectors"; export const getIsDragging = (state: AppState) => state.ui.widgetDragResize.isDragging; @@ -21,7 +23,7 @@ export const getShouldAllowDrag = createSelector( getIsResizing, getIsDragging, getIsDraggingDisabledInEditor, - selectCombinedPreviewMode, + combinedPreviewModeSelector, snipingModeSelector, getIsAppSettingsPaneWithNavigationTabOpen, getWidgetSelectionBlock, diff --git a/app/client/src/selectors/widgetSelectors.ts b/app/client/src/selectors/widgetSelectors.ts index 35d648da50bf..4d45777ef4c9 100644 --- a/app/client/src/selectors/widgetSelectors.ts +++ b/app/client/src/selectors/widgetSelectors.ts @@ -21,8 +21,8 @@ import { APP_MODE } from "entities/App"; import { getIsTableFilterPaneVisible } from "selectors/tableFilterSelectors"; import { getIsAutoHeightWithLimitsChanging } from "utils/hooks/autoHeightUIHooks"; import { getIsPropertyPaneVisible } from "./propertyPaneSelectors"; +import { combinedPreviewModeSelector } from "./editorSelectors"; import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; -import { selectCombinedPreviewMode } from "./gitModSelectors"; export const getIsDraggingOrResizing = (state: AppState) => state.ui.widgetDragResize.isResizing || state.ui.widgetDragResize.isDragging; @@ -186,7 +186,7 @@ export const shouldWidgetIgnoreClicksSelector = (widgetId: string) => { (state: AppState) => state.ui.widgetDragResize.isDragging, (state: AppState) => state.ui.canvasSelection.isDraggingForSelection, getAppMode, - selectCombinedPreviewMode, + combinedPreviewModeSelector, getIsAutoHeightWithLimitsChanging, getAltBlockWidgetSelection, ( diff --git a/app/client/src/utils/hooks/useAllowEditorDragToSelect.ts b/app/client/src/utils/hooks/useAllowEditorDragToSelect.ts index a09f5492d648..e074a099ac70 100644 --- a/app/client/src/utils/hooks/useAllowEditorDragToSelect.ts +++ b/app/client/src/utils/hooks/useAllowEditorDragToSelect.ts @@ -1,11 +1,13 @@ import type { AppState } from "ee/reducers"; -import { snipingModeSelector } from "selectors/editorSelectors"; +import { + snipingModeSelector, + combinedPreviewModeSelector, +} from "selectors/editorSelectors"; import { useSelector } from "react-redux"; import { getIsAppSettingsPaneWithNavigationTabOpen } from "selectors/appSettingsPaneSelectors"; import { getLayoutSystemType } from "selectors/layoutSystemSelectors"; import { LayoutSystemTypes } from "layoutSystems/types"; import { getWidgetSelectionBlock } from "../../selectors/ui"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; export const useAllowEditorDragToSelect = () => { // This state tells us whether a `ResizableComponent` is resizing @@ -40,7 +42,7 @@ export const useAllowEditorDragToSelect = () => { // True when any widget is dragging or resizing, including this one const isResizingOrDragging = !!isResizing || !!isDragging || !!isSelecting; const isSnipingMode = useSelector(snipingModeSelector); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const isAppSettingsPaneWithNavigationTabOpen = useSelector( getIsAppSettingsPaneWithNavigationTabOpen, ); diff --git a/app/client/src/utils/hooks/useHoverToFocusWidget.ts b/app/client/src/utils/hooks/useHoverToFocusWidget.ts index a6cf7962de9a..10e5f764f06e 100644 --- a/app/client/src/utils/hooks/useHoverToFocusWidget.ts +++ b/app/client/src/utils/hooks/useHoverToFocusWidget.ts @@ -2,7 +2,7 @@ import { useWidgetSelection } from "./useWidgetSelection"; import { useSelector } from "react-redux"; import { isWidgetFocused } from "selectors/widgetSelectors"; import { getAnvilSpaceDistributionStatus } from "layoutSystems/anvil/integrations/selectors"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import type { AppState } from "ee/reducers"; import type React from "react"; import { useCurrentAppState } from "pages/Editor/IDE/hooks/useCurrentAppState"; @@ -35,7 +35,7 @@ export const useHoverToFocusWidget = ( const isResizingOrDragging = isResizing || isDragging; // This state tells us whether space redistribution is in process const isDistributingSpace = useSelector(getAnvilSpaceDistributionStatus); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); // When mouse is over this draggable const handleMouseOver = (e: React.MouseEvent) => { focusWidget && diff --git a/app/client/src/widgets/ChartWidget/component/index.test.tsx b/app/client/src/widgets/ChartWidget/component/index.test.tsx index ee53792993a8..8c043acb36a3 100644 --- a/app/client/src/widgets/ChartWidget/component/index.test.tsx +++ b/app/client/src/widgets/ChartWidget/component/index.test.tsx @@ -22,11 +22,6 @@ import { APP_MODE } from "entities/App"; // eslint-disable-next-line @typescript-eslint/no-explicit-any let container: any; -jest.mock("selectors/gitModSelectors", () => ({ - ...jest.requireActual("selectors/gitModSelectors"), - selectCombinedPreviewMode: jest.fn(() => false), -})); - describe("Chart Widget", () => { const seriesData1: ChartData = { seriesName: "series1", diff --git a/app/client/src/widgets/ChartWidget/component/index.tsx b/app/client/src/widgets/ChartWidget/component/index.tsx index f2a3280bd7a1..4ed693b142c3 100644 --- a/app/client/src/widgets/ChartWidget/component/index.tsx +++ b/app/client/src/widgets/ChartWidget/component/index.tsx @@ -28,7 +28,7 @@ import { CustomEChartIFrameComponent } from "./CustomEChartIFrameComponent"; import type { AppState } from "ee/reducers"; import { connect } from "react-redux"; import { getWidgetPropsForPropertyPane } from "selectors/propertyPaneSelectors"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { getAppMode } from "ee/selectors/applicationSelectors"; import { APP_MODE } from "entities/App"; // Leaving this require here. Ref: https://stackoverflow.com/questions/41292559/could-not-find-a-declaration-file-for-module-module-name-path-to-module-nam/42505940#42505940 @@ -406,7 +406,7 @@ export const mapStateToProps = ( state: AppState, ownProps: ChartComponentProps, ) => { - const isPreviewMode = selectCombinedPreviewMode(state); + const isPreviewMode = combinedPreviewModeSelector(state); const appMode = getAppMode(state); return { diff --git a/app/client/src/widgets/CustomWidget/component/index.tsx b/app/client/src/widgets/CustomWidget/component/index.tsx index a3cf98d4afbb..eb6740b48cd0 100644 --- a/app/client/src/widgets/CustomWidget/component/index.tsx +++ b/app/client/src/widgets/CustomWidget/component/index.tsx @@ -19,7 +19,7 @@ import type { BoxShadow } from "components/designSystems/appsmith/WidgetStyleCon import type { Color } from "constants/Colors"; import { connect } from "react-redux"; import type { AppState } from "ee/reducers"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; import { getWidgetPropsForPropertyPane } from "selectors/propertyPaneSelectors"; import AnalyticsUtil from "ee/utils/AnalyticsUtil"; import { EVENTS } from "./customWidgetscript"; @@ -311,7 +311,7 @@ export const mapStateToProps = ( state: AppState, ownProps: CustomComponentProps, ) => { - const isPreviewMode = selectCombinedPreviewMode(state); + const isPreviewMode = combinedPreviewModeSelector(state); return { needsOverlay: diff --git a/app/client/src/widgets/IframeWidget/component/index.tsx b/app/client/src/widgets/IframeWidget/component/index.tsx index b16f5bdb2fcb..1958ebd55e36 100644 --- a/app/client/src/widgets/IframeWidget/component/index.tsx +++ b/app/client/src/widgets/IframeWidget/component/index.tsx @@ -9,7 +9,7 @@ import { getAppMode } from "ee/selectors/applicationSelectors"; import { APP_MODE } from "entities/App"; import type { RenderMode } from "constants/WidgetConstants"; import { getAppsmithConfigs } from "ee/configs"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; +import { combinedPreviewModeSelector } from "selectors/editorSelectors"; interface IframeContainerProps { borderColor?: string; @@ -145,7 +145,7 @@ function IframeComponent(props: IframeComponentProps) { }, [srcDoc]); const appMode = useSelector(getAppMode); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const selectedWidget = useSelector(getWidgetPropsForPropertyPane); return ( diff --git a/app/client/src/widgets/withWidgetProps.tsx b/app/client/src/widgets/withWidgetProps.tsx index 5a0f13d6c19d..73dfd519687b 100644 --- a/app/client/src/widgets/withWidgetProps.tsx +++ b/app/client/src/widgets/withWidgetProps.tsx @@ -25,6 +25,7 @@ import { getMetaWidget, getIsAutoLayoutMobileBreakPoint, getCanvasWidth, + combinedPreviewModeSelector, } from "selectors/editorSelectors"; import { createCanvasWidget, @@ -49,7 +50,6 @@ import { isWidgetSelectedForPropertyPane } from "selectors/propertyPaneSelectors import WidgetFactory from "WidgetProvider/factory"; import { getIsAnvilLayout } from "layoutSystems/anvil/integrations/selectors"; import { endSpan, startRootSpan } from "instrumentation/generateTraces"; -import { selectCombinedPreviewMode } from "selectors/gitModSelectors"; const WIDGETS_WITH_CHILD_WIDGETS = ["LIST_WIDGET", "FORM_WIDGET"]; const WIDGETS_REQUIRING_SELECTED_ANCESTRY = ["MODAL_WIDGET", "TABS_WIDGET"]; @@ -69,7 +69,7 @@ function withWidgetProps(WrappedWidget: typeof BaseWidget) { } = props; const span = startRootSpan("withWidgetProps", { widgetType: type }); - const isPreviewMode = useSelector(selectCombinedPreviewMode); + const isPreviewMode = useSelector(combinedPreviewModeSelector); const canvasWidget = useSelector((state: AppState) => getWidget(state, widgetId), diff --git a/app/client/test/testUtils.tsx b/app/client/test/testUtils.tsx index 0d57bddfc09a..9b99d698bb90 100644 --- a/app/client/test/testUtils.tsx +++ b/app/client/test/testUtils.tsx @@ -49,12 +49,9 @@ interface State { } const setupState = (state?: State) => { let reduxStore = store; - window.history.pushState({}, "Appsmith", state?.url || "/"); - if (state && (state.initialState || state.featureFlags)) { reduxStore = testStore(state.initialState || {}); - if (state.featureFlags) { reduxStore.dispatch( fetchFeatureFlagsSuccess({ @@ -64,12 +61,10 @@ const setupState = (state?: State) => { ); } } - if (state && state.sagasToRun) { reduxStore = testStoreWithTestMiddleWare(reduxStore.getState()); testSagaMiddleware.run(() => rootSaga(state.sagasToRun)); } - const defaultTheme = getCurrentThemeDetails(reduxStore.getState()); return { reduxStore, defaultTheme }; @@ -81,7 +76,6 @@ const customRender = ( options?: Omit, ) => { const { defaultTheme, reduxStore } = setupState(state); - return render( @@ -98,7 +92,6 @@ const customRender = ( const hookWrapper = (state: State) => { return ({ children }: { children: ReactElement }) => { const { defaultTheme, reduxStore } = setupState(state); - return ( From 8cd827754f57d6cec8bd21d0a012a40f7e270d7f Mon Sep 17 00:00:00 2001 From: Goutham Pratapa Date: Tue, 31 Dec 2024 18:01:48 +0530 Subject: [PATCH 11/13] chore: deprecate ce helm charts and publish ee helm charts (#37794) ## Summary by CodeRabbit ## Release Notes - **New Features** - Enhanced support for PostgreSQL and OpenID Connect (OIDC) authentication in the Helm chart. - Introduced a new template for managing external secrets and a dedicated service for metrics. - Added Horizontal Pod Autoscaler (HPA) and Pod Disruption Budget (PDB) configurations. - New configuration options for custom Certificate Authority (CA) certificates. - **Improvements** - Updated application version and dependencies for better organization and readability. - Expanded configuration options for Redis, MongoDB, and PostgreSQL, allowing for improved customization. - Enhanced deployment configuration with dynamic scaling capabilities. - **Bug Fixes** - Improved error handling for configuration misalignments to prevent runtime issues. - **Documentation** - Updated README and values.yaml to reflect new configuration parameters and options. > [!WARNING] > Tests have not run on the HEAD 0e76b6af34501ed646ea840af22786b33426c9fe yet >
Tue, 31 Dec 2024 12:31:29 UTC --- deploy/helm/Chart.lock | 9 -- deploy/helm/Chart.yaml | 32 +++-- deploy/helm/README.md | 2 + deploy/helm/templates/configMap.yaml | 21 ++- .../{statefulset.yaml => deployment.yaml} | 98 ++++++++++--- deploy/helm/templates/external-secrets.yaml | 18 +++ deploy/helm/templates/headless-svc.yaml | 31 ++++ deploy/helm/templates/hpa.yml | 41 ++++++ deploy/helm/templates/import.yaml | 28 ++++ deploy/helm/templates/pdb.yml | 16 +++ deploy/helm/templates/persistentVolume.yaml | 22 ++- .../helm/templates/persistentVolumeClaim.yaml | 34 +++++ deploy/helm/templates/scaledobject.yml | 28 ++++ deploy/helm/templates/secret.yaml | 16 +++ deploy/helm/templates/service-metrics.yaml | 31 ++++ deploy/helm/templates/service.yaml | 7 +- deploy/helm/templates/trustedCA.yaml | 13 ++ deploy/helm/values.yaml | 133 +++++++++++++++++- scripts/deploy_preview.sh | 1 + 19 files changed, 532 insertions(+), 49 deletions(-) delete mode 100644 deploy/helm/Chart.lock rename deploy/helm/templates/{statefulset.yaml => deployment.yaml} (53%) create mode 100644 deploy/helm/templates/external-secrets.yaml create mode 100644 deploy/helm/templates/headless-svc.yaml create mode 100644 deploy/helm/templates/hpa.yml create mode 100644 deploy/helm/templates/import.yaml create mode 100644 deploy/helm/templates/pdb.yml create mode 100644 deploy/helm/templates/persistentVolumeClaim.yaml create mode 100644 deploy/helm/templates/scaledobject.yml create mode 100644 deploy/helm/templates/secret.yaml create mode 100644 deploy/helm/templates/service-metrics.yaml create mode 100644 deploy/helm/templates/trustedCA.yaml diff --git a/deploy/helm/Chart.lock b/deploy/helm/Chart.lock deleted file mode 100644 index 95e1eacd743c..000000000000 --- a/deploy/helm/Chart.lock +++ /dev/null @@ -1,9 +0,0 @@ -dependencies: -- name: redis - repository: https://charts.bitnami.com/bitnami - version: 16.11.2 -- name: mongodb - repository: https://charts.bitnami.com/bitnami - version: 12.1.16 -digest: sha256:5c331a59e883c66893d2896c24aa2c4edf53423b12d440d1ec832e2c18637805 -generated: "2023-01-26T10:40:02.874578+05:30" diff --git a/deploy/helm/Chart.yaml b/deploy/helm/Chart.yaml index d4fae9cfa7a9..d8eebe8250b1 100644 --- a/deploy/helm/Chart.yaml +++ b/deploy/helm/Chart.yaml @@ -11,15 +11,25 @@ sources: - https://github.com/appsmithorg/appsmith home: https://www.appsmith.com/ icon: https://assets.appsmith.com/appsmith-icon.png -version: 2.3.0 +version: 3.6.0 dependencies: -- condition: redis.enabled - name: redis - version: 16.11.2 - appVersion: 6.2.7 - repository: https://charts.bitnami.com/bitnami -- condition: mongodb.enabled - name: mongodb - version: 12.1.16 - appVersion: 6.0.10 - repository: https://charts.bitnami.com/bitnami + - condition: redis.enabled + name: redis + version: 16.11.2 + appVersion: 6.2.7 + repository: https://charts.bitnami.com/bitnami + - condition: mongodb.enabled + name: mongodb + version: 12.1.16 + appVersion: 6.0.10 + repository: https://charts.bitnami.com/bitnami + - condition: postgresql.enabled + name: postgresql + version: 11.9.5 + appVersion: 14.12.0 + repository: https://charts.bitnami.com/bitnami + - condition: prometheus.enabled + name: prometheus + version: 25.27.0 + appVersion: 2.54.1 + repository: https://prometheus-community.github.io/helm-charts diff --git a/deploy/helm/README.md b/deploy/helm/README.md index f0ca5697e9bc..f4b3d087be6f 100644 --- a/deploy/helm/README.md +++ b/deploy/helm/README.md @@ -174,6 +174,8 @@ To change Appsmith configurations, you can use configuration UI in application o | `applicationConfig.APPSMITH_OAUTH2_GOOGLE_CLIENT_SECRET`| `""` | | `applicationConfig.APPSMITH_OAUTH2_GITHUB_CLIENT_ID` | `""` | | `applicationConfig.APPSMITH_OAUTH2_GITHUB_CLIENT_SECRET`| `""` | +| `applicationConfig.APPSMITH_OAUTH2_OIDC_CLIENT_ID` | `""` | +| `applicationConfig.APPSMITH_OAUTH2_OIDC_CLIENT_SECRET` | `""` | | `applicationConfig.APPSMITH_CLIENT_LOG_LEVEL` | `""` | | `applicationConfig.APPSMITH_MAIL_ENABLED` | `""` | | `applicationConfig.APPSMITH_MAIL_HOST` | `""` | diff --git a/deploy/helm/templates/configMap.yaml b/deploy/helm/templates/configMap.yaml index 4e3ea9a7934c..2b870dc86656 100644 --- a/deploy/helm/templates/configMap.yaml +++ b/deploy/helm/templates/configMap.yaml @@ -1,8 +1,10 @@ {{- $nameSpace := include "appsmith.namespace" . -}} -{{- $name := include "appsmith.fullname" . -}} {{- $mongoUser := .Values.mongodb.auth.rootUser -}} {{- $mongoPassword := .Values.mongodb.auth.rootPassword -}} {{- $mongoServicename := .Values.mongodb.service.nameOverride -}} +{{- $postgresqlUser := .Values.postgresql.auth.username -}} +{{- $postgresqlPassword := .Values.postgresql.auth.password -}} +{{- $postgresqlDatabase := .Values.postgresql.auth.database -}} {{- $releaseName := .Release.Name -}} apiVersion: v1 kind: ConfigMap @@ -18,11 +20,28 @@ data: {{- end }} {{- range $key, $value := .Values.applicationConfig }} + {{- if and (eq "APPSMITH_KEYCLOAK_DB_DRIVER" $key) ( not $value) }} + {{ $key }}: {{ $.Values.postgresql.enabled | ternary "postgresql" "h2" | quote }} + {{- end }} + + {{- if and (eq "APPSMITH_KEYCLOAK_DB_URL" $key) ( not $value) }} + {{ $key }}: {{ $.Values.postgresql.enabled | ternary (printf "%s-postgresql.%s.svc.cluster.local:5432/%s" $releaseName $nameSpace $postgresqlDatabase) "${jboss.server.data.dir}" | quote }} + {{- end }} + + {{- if and (eq "APPSMITH_KEYCLOAK_DB_USERNAME" $key) ( not $value) }} + {{ $key }}: {{ $.Values.postgresql.enabled | ternary $postgresqlUser "sa" | quote }} + {{- end }} + + {{- if and (eq "APPSMITH_KEYCLOAK_DB_PASSWORD" $key) ( not $value) }} + {{ $key }}: {{ $.Values.postgresql.enabled | ternary $postgresqlPassword "sa" | quote }} + {{- end }} + {{- if and (eq "APPSMITH_REDIS_URL" $key) ( not $value) }} {{- if $.Values.redis.enabled }} {{ $key }}: redis://{{ $releaseName }}-redis-master.{{ $nameSpace }}.svc.cluster.local:6379 {{- end }} {{- end }} + {{- if $value }} {{ $key }}: {{ $value | quote }} {{- end }} diff --git a/deploy/helm/templates/statefulset.yaml b/deploy/helm/templates/deployment.yaml similarity index 53% rename from deploy/helm/templates/statefulset.yaml rename to deploy/helm/templates/deployment.yaml index 9a17907b27cd..08d981366f22 100644 --- a/deploy/helm/templates/statefulset.yaml +++ b/deploy/helm/templates/deployment.yaml @@ -1,15 +1,27 @@ +{{- $updateStrategy := .Values.updateStrategy | default dict }} +{{- $postgresuser := .Values.postgresql.auth.username }} +{{- $postgrespass := .Values.postgresql.auth.password }} +{{- $postgrespass := .Values.postgresql.auth.password }} +{{- $releaseName := include "appsmith.fullname" . -}} apiVersion: apps/v1 -kind: StatefulSet +kind: {{ if not .Values.autoscaling.enabled }}StatefulSet{{- else }}Deployment{{- end }} metadata: name: {{ include "appsmith.fullname" . }} namespace: {{ include "appsmith.namespace" . }} labels: {{- include "appsmith.labels" . | nindent 4 }} spec: + {{- if not .Values.autoscaling.enabled }} replicas: 1 serviceName: {{ include "appsmith.fullname" . }} updateStrategy: - type: {{ .Values.strategyType }} + {{- else }} + strategy: + type: {{ .Values.strategyType | default "RollingUpdate" }} + rollingUpdate: + maxSurge: {{ dig "maxSurge" 1 $updateStrategy }} + maxUnavailable: {{ dig "maxUnavailable" "0" $updateStrategy }} + {{- end }} selector: matchLabels: {{- include "appsmith.selectorLabels" . | nindent 6 }} @@ -25,6 +37,10 @@ spec: {{- toYaml .Values.podLabels | nindent 8 }} {{- end }} spec: + {{- with .Values.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml . | nindent 8 }} + {{- end }} {{- if .Values.schedulerName }} schedulerName: {{ .Values.schedulerName | quote }} {{- end }} @@ -58,16 +74,26 @@ spec: {{- if ((.Values.initContainer.mongodb).image) }} image: {{ .Values.initContainer.mongodb.image }} {{- else }} - image: "docker.io/bitnami/mongodb:5.0.21-debian-11-r5" + image: "docker.io/bitnami/mongodb:6.0.13" + {{- end }} + command: ['sh', '-c', "until mongosh --host appsmith-mongodb.{{.Release.Namespace}}.svc.cluster.local --eval 'db.runCommand({ping:1})' ; do echo waiting for mongo; sleep 2; done"] {{- end }} - command: ['sh', '-c', "until mongo --host appsmith-mongodb.{{.Release.Namespace}}.svc.cluster.local --eval 'db.runCommand({ping:1})' ; do echo waiting for mongo; sleep 2; done"] + {{- if .Values.postgresql.enabled }} + - name: psql-init-container + {{- if ((.Values.initContainer.postgresql).image) }} + image: {{ .Values.initContainer.postgresql.image }} + {{- else}} + image: docker.io/bitnami/postgresql:14.5.0-debian-11-r21 + {{- end}} + command: ['sh', '-c', "until pg_isready -U $postgresuser -d $postgresdb -h {{.Release.Name}}-postgresql.{{.Release.Namespace}}.svc.cluster.local; do echo waiting for postgresql; sleep 2; done"] {{- end }} containers: - name: {{ .Values.containerName }} securityContext: {{- toYaml .Values.securityContext | nindent 12 }} - image: "{{ .Values.image.registry }}/{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}" - imagePullPolicy: {{ .Values.image.pullPolicy }} + {{- $customImage := .Values._image | default dict }} + image: {{ dig "registry" "index.docker.io" $customImage }}/{{ dig "repository" "appsmith/appsmith-ee" $customImage }}:{{ dig "tag" (.Values.image.tag | default "latest") $customImage }} + imagePullPolicy: {{ dig "pullPolicy" "IfNotPresent" $customImage }} ports: - name: http containerPort: {{ .Values.HTTPContainerPort | default 80 }} @@ -75,23 +101,26 @@ spec: - name: https containerPort: 443 protocol: TCP + - name: metrics + containerPort: {{ .Values.metrics.port }} + protocol: TCP {{- $probes := .Values.probes | default dict }} startupProbe: # The `livenessProbe` and `readinessProbe` will be disabled until the `startupProbe` is successful. httpGet: - port: http + port: {{ dig "startupProbe" "port" "80" $probes }} path: {{ dig "startupProbe" "api" "/api/v1/health" $probes }} failureThreshold: {{ dig "startupProbe" "failureThreshold" 3 $probes }} periodSeconds: {{ dig "startupProbe" "periodSeconds" 60 $probes }} livenessProbe: httpGet: - port: http + port: {{ dig "livenessProbe" "port" "80" $probes }} path: {{ dig "livenessProbe" "api" "/api/v1/health" $probes }} failureThreshold: {{ dig "livenessProbe" "failureThreshold" 3 $probes }} periodSeconds: {{ dig "livenessProbe" "periodSeconds" 60 $probes }} readinessProbe: httpGet: - port: http + port: {{ dig "readinessProbe" "port" "80" $probes }} path: {{ dig "readinessProbe" "api" "/api/v1/health" $probes }} failureThreshold: {{ dig "readinessProbe" "failureThreshold" 3 $probes }} periodSeconds: {{ dig "readinessProbe" "periodSeconds" 60 $probes }} @@ -100,6 +129,10 @@ spec: volumeMounts: - name: data mountPath: /appsmith-stacks + {{- if .Values.customCAcert }} + - name: ca-cert + mountPath: "/appsmith-stacks/ca-certs" + {{- end }} env: {{- if .Values.HTTPContainerPort }} - name: PORT @@ -107,6 +140,10 @@ spec: {{- end }} - name: APPSMITH_ENABLE_EMBEDDED_DB value: "0" + - name: JGROUPS_DISCOVERY_PROTOCOL + value: kubernetes.KUBE_PING + - name: APPSMITH_HEADLESS_SVC + value: {{ include "appsmith.fullname" . }}-headless envFrom: - configMapRef: name: {{ include "appsmith.fullname" . }} @@ -114,28 +151,57 @@ spec: - secretRef: name: {{ .Values.secretName }} {{- end }} + {{- if .Values.secrets }} + - secretRef: + name: {{ include "appsmith.fullname" . }} + {{- end }} + {{- if .Values.externalSecrets.enabled }} + - secretRef: + name: "{{ include "appsmith.fullname" . }}-external-secret" + {{- end }} {{- if .Values.image.pullSecrets}} imagePullSecrets: - name: {{ .Values.image.pullSecrets }} {{- end }} volumes: + {{- if .Values.customCAcert }} + - name: ca-cert + configMap: + name: {{ $releaseName }}-trustedca + items: + {{- range $key, $value := .Values.customCAcert }} + - key: {{ $key }} + path: {{ $key }}.crt + {{- end }} + {{- end }} {{- if not .Values.persistence.enabled }} - name: data emptyDir: {} - {{- else }} + {{- else if and (not .Values.autoscaling.enabled) (.Values.persistence.enabled) }} volumeClaimTemplates: - metadata: name: data - {{- if .Values.persistence.annotations }} - annotations: {{- include "tplvalues.render" (dict "value" .Values.persistence.annotations "context" $) | nindent 10 }} + {{- if .Values.persistence.annotations}} + annotations: + {{- include "tplvalues.render" (dict "value" .Values.persistence.annotations "context" $) | nindent 10 }} {{- end }} spec: accessModes: - {{- range .Values.persistence.accessModes }} - - {{ . | quote }} - {{- end }} + - ReadWriteOnce resources: requests: storage: {{ .Values.persistence.size | quote }} - {{ include "storage.class" (dict "persistence" .Values.persistence "global" .Values.global) }} + {{- if .Values.persistence.volumeClaimTemplates.selector }} + selector: + {{- include "tplvalues.render" (dict "value" .Values.persistence.volumeClaimTemplates.selector "context" $) | nindent 10 }} + {{- end }} + {{ include "storage.class" (dict "persistence" .Values.persistence "global" .Values.global) | nindent 8 }} + {{- else }} + - name: data + persistentVolumeClaim: + {{- if .Values.persistence.existingClaim.enabled }} + claimName: {{ .Values.persistence.existingClaim.claimName }} + {{- else }} + claimName: {{ include "appsmith.fullname" . }} + {{- end }} {{- end }} diff --git a/deploy/helm/templates/external-secrets.yaml b/deploy/helm/templates/external-secrets.yaml new file mode 100644 index 000000000000..179c991b4f26 --- /dev/null +++ b/deploy/helm/templates/external-secrets.yaml @@ -0,0 +1,18 @@ +{{- if .Values.externalSecrets.enabled }} +apiVersion: external-secrets.io/v1beta1 +kind: ExternalSecret +metadata: + name: "{{ include "appsmith.fullname" . }}-external-secret" + namespace: {{ include "appsmith.namespace" . }} +spec: + refreshInterval: {{ .Values.externalSecrets.refreshInterval }} + secretStoreRef: + name: secretstore + kind: SecretStore + target: + name: "{{ include "appsmith.fullname" . }}-external-secret" + creationPolicy: Owner + dataFrom: + - extract: + key: {{ .Values.externalSecrets.remoteSecretName }} +{{- end }} diff --git a/deploy/helm/templates/headless-svc.yaml b/deploy/helm/templates/headless-svc.yaml new file mode 100644 index 000000000000..60c85fe4f34b --- /dev/null +++ b/deploy/helm/templates/headless-svc.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: Service +metadata: + name: {{ include "appsmith.fullname" . }}-headless + namespace: {{ include "appsmith.namespace" . }} + labels: + {{- include "appsmith.labels" . | nindent 4 }} + {{- if or .Values.service.annotations .Values.commonAnnotations }} + annotations: + {{- if .Values.service.annotations }} + {{- include "tplvalues.render" ( dict "value" .Values.service.annotations "context" $) | nindent 4 }} + {{- end }} + {{- if .Values.commonAnnotations }} + {{- include "tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} + {{- end }} + {{- end }} +spec: + type: ClusterIP + clusterIP: None + clusterIPs: + - None + internalTrafficPolicy: Cluster + ipFamilies: + - IPv4 + ipFamilyPolicy: SingleStack + ports: + - name: http + port: 8080 + targetPort: 8080 + selector: + {{- include "appsmith.selectorLabels" . | nindent 4 }} diff --git a/deploy/helm/templates/hpa.yml b/deploy/helm/templates/hpa.yml new file mode 100644 index 000000000000..2cffa1e02b48 --- /dev/null +++ b/deploy/helm/templates/hpa.yml @@ -0,0 +1,41 @@ +{{- if and (.Values.autoscaling.enabled) (not .Values.keda.enabled) }} +apiVersion: {{ ternary "autoscaling/v2" "autoscaling/v2beta2" (.Capabilities.APIVersions.Has "autoscaling/v2") }} +kind: HorizontalPodAutoscaler +metadata: + name: {{ include "appsmith.fullname" . }} + namespace: {{ include "appsmith.namespace" . }} + labels: + {{- include "appsmith.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "appsmith.fullname" . }} + minReplicas: {{ .Values.autoscaling.minReplicas }} + maxReplicas: {{ .Values.autoscaling.maxReplicas }} + metrics: + {{- if .Values.autoscaling.targetCPUUtilizationPercentage }} + - type: Resource + resource: + name: cpu + {{- if .Capabilities.APIVersions.Has "autoscaling/v2"}} + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- else }} + targetAverageUtilization: {{ .Values.autoscaling.targetCPUUtilizationPercentage }} + {{- end }} + {{- end }} + {{- if .Values.autoscaling.targetMemoryUtilizationPercentage }} + - type: Resource + resource: + name: memory + {{- if .Capabilities.APIVersions.Has "autoscaling/v2"}} + target: + type: Utilization + averageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- else }} + targetAverageUtilization: {{ .Values.autoscaling.targetMemoryUtilizationPercentage }} + {{- end }} + {{- end }} +{{- end }} diff --git a/deploy/helm/templates/import.yaml b/deploy/helm/templates/import.yaml new file mode 100644 index 000000000000..0b196ce56107 --- /dev/null +++ b/deploy/helm/templates/import.yaml @@ -0,0 +1,28 @@ +{{- /* Fail helm chart if autoscaling is enabled and mongo is disabled */ -}} +{{- if and ( .Values.autoscaling.enabled ) ( not .Values.mongodb.enabled ) }} +{{- if and ( not .Values.applicationConfig.APPSMITH_DB_URL ) ( not .Values.applicationConfig.APPSMITH_MONGODB_URI ) }} +{{- fail "To enable autoscaling on Appsmith, MongoDB needs to be enabled or an external MongoDB needs to be configured. Refer: https://docs.appsmith.com/getting-started/setup/installation-guides/kubernetes#install-appsmith" }} +{{- end }} +{{- end }} + +{{- /* Fail helm chart if keycloak is disabled and postgresql is enabled */ -}} +{{- if and ( .Values.postgresql.enabled ) (eq .Values.applicationConfig.APPSMITH_DISABLE_EMBEDDED_KEYCLOAK "1" )}} +{{- fail "Keycloak is disabled therefore postgresql is not required. Please disable postgres or to enable keycloak on Appsmith, set APPSMITH_DISABLE_EMBEDDED_KEYCLOAK to \"0\" Refer: https://docs.appsmith.com/getting-started/setup/installation-guides/kubernetes#install-appsmith" }} +{{- end }} + +{{- /* Fail helm chart if autoscaling, keycloak is enabled and postgresql is disabled */ -}} +{{- if and ( .Values.autoscaling.enabled ) ( not .Values.postgresql.enabled ) ( not .Values.applicationConfig.APPSMITH_KEYCLOAK_DB_URL ) (eq .Values.applicationConfig.APPSMITH_DISABLE_EMBEDDED_KEYCLOAK "0" )}} +{{- fail "To enable autoscaling on Appsmith, PostgreSQL needs to be enabled or an external PostgreSQL has to be configured. Refer: https://docs.appsmith.com/getting-started/setup/installation-guides/kubernetes#install-appsmith" }} +{{- end }} + +{{- /* Fail helm chart if mongodb is enabled along with APPSMITH_DB_URL in the ApplicationConfig */ -}} +{{- if ( .Values.mongodb.enabled ) }} +{{- if or ( .Values.applicationConfig.APPSMITH_DB_URL ) ( .Values.applicationConfig.APPSMITH_MONGODB_URI ) }} +{{- fail "MongoDB is enabled, but also found APPSMITH_DB_URL or APPSMITH_MONGODB_URI configured to an external instance, MongoDB needs to be disabled if using an external MongoDB instance" }} +{{- end }} +{{- end }} + +{{- /* Fail helm chart if postgresql is enabled along with APPSMITH_DB_URL in the ApplicationConfig */ -}} +{{- if and ( .Values.postgresql.enabled ) ( .Values.applicationConfig.APPSMITH_KEYCLOAK_DB_DRIVER ) ( .Values.applicationConfig.APPSMITH_KEYCLOAK_DB_URL ) }} +{{- fail "PostgreSQL is enabled, but also found APPSMITH_KEYCLOAK_DB_URL configured to an external instance, PostgreSQL needs to be disabled if using an external PostgreSQL instance" }} +{{- end }} diff --git a/deploy/helm/templates/pdb.yml b/deploy/helm/templates/pdb.yml new file mode 100644 index 000000000000..94539b9d763d --- /dev/null +++ b/deploy/helm/templates/pdb.yml @@ -0,0 +1,16 @@ +{{- if .Values.podDisruptionBudgets.enabled }} +{{- if .Capabilities.APIVersions.Has "policy/v1" -}} +apiVersion: policy/v1 +{{- else}} +apiVersion: policy/v1beta1 +{{- end }} +kind: PodDisruptionBudget +metadata: + name: "{{ include "appsmith.fullname" . }}-pdb" + namespace: {{ include "appsmith.namespace" . }} +spec: + minAvailable: {{ .Values.podDisruptionBudgets.minAvailable }} + selector: + matchLabels: + {{- include "appsmith.selectorLabels" . | nindent 6 }} +{{- end }} diff --git a/deploy/helm/templates/persistentVolume.yaml b/deploy/helm/templates/persistentVolume.yaml index 5a07b1859a0f..51200363b2a8 100644 --- a/deploy/helm/templates/persistentVolume.yaml +++ b/deploy/helm/templates/persistentVolume.yaml @@ -1,4 +1,4 @@ -{{- if and .Values.persistence.enabled .Values.persistence.localStorage }} +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim.enabled) ( .Values.autoscaling.enabled) }} apiVersion: v1 kind: PersistentVolume metadata: @@ -12,8 +12,8 @@ spec: {{- range .Values.persistence.accessModes }} - {{ . | quote }} {{- end }} - persistentVolumeReclaimPolicy: Delete - storageClassName: {{ .Values.persistence.storageClass | quote }} + persistentVolumeReclaimPolicy: {{ .Values.persistence.reclaimPolicy }} + {{- if .Values.persistence.localStorage }} local: path: {{ .Values.persistence.storagePath }} # Path to the directory this PV refers to. nodeAffinity: # nodeAffinity is required when using local volumes. @@ -24,4 +24,18 @@ spec: operator: In values: {{- toYaml .Values.persistence.localCluster | nindent 12 }} -{{- end }} \ No newline at end of file + {{- end }} + {{- if .Values.persistence.storageClass }} + {{- if (eq "-" .Values.persistence.storageClass) }} + storageClassName: "" + {{- else }} + storageClassName: "{{ .Values.persistence.storageClass }}" + {{- end }} + {{- end }} + {{- if .Values.persistence.efs.enabled }} + csi: + driver: {{ .Values.persistence.efs.driver }} + nfs: + volumeHandle: {{ .Values.persistence.efs.volumeHandle }} + {{ end }} +{{- end }} diff --git a/deploy/helm/templates/persistentVolumeClaim.yaml b/deploy/helm/templates/persistentVolumeClaim.yaml new file mode 100644 index 000000000000..d4e2a22d40f5 --- /dev/null +++ b/deploy/helm/templates/persistentVolumeClaim.yaml @@ -0,0 +1,34 @@ +{{- if and .Values.persistence.enabled (not .Values.persistence.existingClaim.enabled) ( .Values.autoscaling.enabled) }} +kind: PersistentVolumeClaim +apiVersion: v1 +metadata: + name: {{ include "appsmith.fullname" . }} + namespace: {{ include "appsmith.namespace" . }} +{{- with .Values.persistence.annotations }} + annotations: +{{ toYaml . | indent 4 }} +{{- end }} + labels: + app: {{ include "appsmith.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +spec: + accessModes: + {{- range .Values.persistence.accessModes }} + - {{ . | quote }} + {{- end }} + {{- if .Values.persistence.existingClaim.enabled }} + volumeName: {{ .Values.persistence.existingClaim.name }} + {{- else}} + volumeName: {{ include "appsmith.fullname" . }} + {{- end }} + resources: + requests: + storage: {{ .Values.persistence.size | quote }} +{{- if .Values.persistence.storageClass }} + storageClassName: {{ .Values.persistence.storageClass }} +{{- else }} + storageClassName: "" +{{- end }} +{{- end }} diff --git a/deploy/helm/templates/scaledobject.yml b/deploy/helm/templates/scaledobject.yml new file mode 100644 index 000000000000..58f3394cc687 --- /dev/null +++ b/deploy/helm/templates/scaledobject.yml @@ -0,0 +1,28 @@ +{{- if .Values.keda.enabled -}} +apiVersion: keda.sh/v1alpha1 +kind: ScaledObject +metadata: + name: {{ include "appsmith.fullname" . }} + namespace: {{ include "appsmith.namespace" . }} + labels: + {{- include "appsmith.labels" . | nindent 4 }} +spec: + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: {{ include "appsmith.fullname" . }} + pollingInterval: {{ .Values.keda.pollingInterval }} + cooldownPeriod: {{ .Values.keda.cooldownPeriod }} + minReplicaCount: {{ .Values.keda.minReplicaCount }} + maxReplicaCount: {{ .Values.keda.maxReplicaCount }} + {{- with .Values.keda.fallback }} + fallback: + {{- toYaml . | nindent 4 }} + {{- end }} + triggers: + {{- range $v := .Values.keda.triggers }} + - type: {{ $v.type }} + metadata: + {{- toYaml $v.metadata | nindent 6 }} + {{- end }} +{{- end -}} diff --git a/deploy/helm/templates/secret.yaml b/deploy/helm/templates/secret.yaml new file mode 100644 index 000000000000..d34aa28231d7 --- /dev/null +++ b/deploy/helm/templates/secret.yaml @@ -0,0 +1,16 @@ +{{- if .Values.secrets }} +apiVersion: v1 +kind: Secret +metadata: + name: {{ include "appsmith.fullname" . }} + namespace: {{ include "appsmith.namespace" . }} + labels: + {{- include "appsmith.labels" . | nindent 4 }} +type: Opaque +data: + {{- range $key, $value := .Values.secrets }} + {{- if $value }} + {{ $key }}: {{ $value | quote }} + {{- end }} + {{- end }} +{{- end }} diff --git a/deploy/helm/templates/service-metrics.yaml b/deploy/helm/templates/service-metrics.yaml new file mode 100644 index 000000000000..1440ecab3369 --- /dev/null +++ b/deploy/helm/templates/service-metrics.yaml @@ -0,0 +1,31 @@ +{{- if .Values.metrics.enabled }} +apiVersion: v1 +kind: Service +metadata: + name: {{ include "appsmith.fullname" . }}-metrics + namespace: {{ include "appsmith.namespace" . }} + labels: + {{- include "appsmith.labels" . | nindent 4 }} + annotations: + prometheus.io/port: {{ quote .Values.metrics.port }} + prometheus.io/scrape: "true" +spec: + type: {{ .Values.service.type }} + {{- if and (eq .Values.service.type "ClusterIP") .Values.service.clusterIP }} + clusterIP: {{ .Values.service.clusterIP }} + {{- end }} + {{- if and (eq .Values.service.type "LoadBalancer") .Values.service.loadBalancerIP }} + loadBalancerIP: {{ .Values.service.loadBalancerIP }} + {{- end }} + ports: + - name: {{ .Values.service.portName }} + port: {{ .Values.metrics.port }} + targetPort: metrics + {{- if and (or (eq .Values.service.type "LoadBalancer") (eq .Values.service.type "NodePort")) .Values.service.nodePort }} + nodePort: {{ .Values.service.nodePort }} + {{- else if eq .Values.service.type "ClusterIP" }} + nodePort: null + {{- end }} + selector: + {{- include "appsmith.selectorLabels" . | nindent 4 }} +{{- end }} diff --git a/deploy/helm/templates/service.yaml b/deploy/helm/templates/service.yaml index 92584f917a9c..9bf019cebe76 100644 --- a/deploy/helm/templates/service.yaml +++ b/deploy/helm/templates/service.yaml @@ -5,7 +5,7 @@ metadata: namespace: {{ include "appsmith.namespace" . }} labels: {{- include "appsmith.labels" . | nindent 4 }} - {{- if or .Values.service.annotations .Values.commonAnnotations }} + {{- if or .Values.service.annotations .Values.commonAnnotations .Values.metrics.enabled }} annotations: {{- if .Values.service.annotations }} {{- include "tplvalues.render" ( dict "value" .Values.service.annotations "context" $) | nindent 4 }} @@ -13,6 +13,11 @@ metadata: {{- if .Values.commonAnnotations }} {{- include "tplvalues.render" ( dict "value" .Values.commonAnnotations "context" $ ) | nindent 4 }} {{- end }} + {{- if .Values.metrics.enabled }} + prometheus.io/scrape: "true" + prometheus.io/port: "8080" + prometheus.io/path: "/actuator/prometheus" + {{- end }} {{- end }} spec: type: {{ .Values.service.type }} diff --git a/deploy/helm/templates/trustedCA.yaml b/deploy/helm/templates/trustedCA.yaml new file mode 100644 index 000000000000..d9fff15a210f --- /dev/null +++ b/deploy/helm/templates/trustedCA.yaml @@ -0,0 +1,13 @@ +{{- if .Values.customCAcert }} +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ include "appsmith.fullname" . }}-trustedca + namespace: {{ include "appsmith.namespace" . }} + labels: + {{- include "appsmith.labels" . | nindent 4 }} +data: +{{- range $key, $value := .Values.customCAcert }} + {{ $key }}: {{ $value | quote }} +{{- end }} +{{- end }} diff --git a/deploy/helm/values.yaml b/deploy/helm/values.yaml index f5bca3a7cd8a..a315319679b7 100644 --- a/deploy/helm/values.yaml +++ b/deploy/helm/values.yaml @@ -5,9 +5,15 @@ redis: enabled: false master: nodeSelector: {} + disableCommands: [] + affinity: {} + tolerations: [] replica: replicaCount: 1 nodeSelector: {} + disableCommands: [] + affinity: {} + tolerations: [] image: registry: docker.io repository: redis @@ -24,14 +30,58 @@ mongodb: architecture: "replicaset" replicaSetName: rs0 nodeSelector: {} + affinity: {} + tolerations: [] image: registry: docker.io repository: bitnami/mongodb tag: 6.0.13 arbiter: nodeSelector: {} + affinity: {} + tolerations: [] hidden: nodeSelector: {} + affinity: {} + tolerations: [] + image: + registry: docker.io + repository: bitnami/mongodb + tag: 6.0.13 + +## postgresql parameters +postgresql: + enabled: true + auth: + username: root + password: password + postgresPassword: password + database: keycloak + image: + registry: docker.io + repository: bitnami/postgresql + tag: 14.12.0 + primary: + affinity: {} + nodeSelector: {} + tolerations: [] + readReplicas: + affinity: {} + nodeSelector: {} + tolerations: [] + +## external secrets parameters +externalSecrets: + enabled: false + refreshInterval: 1m + remoteNameSecret: "" # name of the secret in Secret provider + + +## prometheus paramaters +prometheus: + enabled: false + image: + tag: v0.74.0 ## @section Global parameters @@ -74,11 +124,13 @@ initContainer: {} # image: docker.io/bitnami/redis-cluster:7.0.13-debian-11-r10 # mongodb: # image: docker.io/bitnami/mongodb:5.0.21-debian-11-r5 + # postgresql: + # image: docker.io/bitnami/postgresql:14.5.0-debian-11-r21 ## Image ## image: registry: index.docker.io - repository: appsmith/appsmith-ce + repository: appsmith/appsmith-ee pullPolicy: IfNotPresent pullSecrets: "" # Overrides the image tag whose default is the chart appVersion. @@ -201,6 +253,12 @@ ingress: ## className: "nginx" +customCAcert: +# cert1: | +# paste-cert-1-contents-here +# cert2: | +# paste-cert-2-contents-here + resources: # We usually recommend not to specify default resources and to leave this as a conscious # choice for the user. This also increases chances charts run on environments with little @@ -213,14 +271,29 @@ resources: # cpu: 100m # memory: 128Mi limits: {} - requests: {} + requests: + cpu: 500m + memory: 3000Mi + +autoscaling: + enabled: false + minReplicas: 2 + maxReplicas: 2 + targetCPUUtilizationPercentage: 5 nodeSelector: {} +#HTTPContainerPort: 8080 + tolerations: [] affinity: {} +#topologySpreadConstraints: +# - maxSkew: 1 # distribute pods in an absolute even manner +# topologyKey: kubernetes.io/hostname # use the hostname as topology domain +# whenUnsatisfiable: ScheduleAnyway # always schedule pods even if it can’t satisfy even distribution of pods + persistence: ## @param persistence.enabled - Enable data persistence using PVC ## @@ -239,15 +312,39 @@ persistence: storagePath: /tmp/hostpath_pv ## @param persistence.localCluster ## - localCluster: - - minikube + localCluster: {} ## @param persistence.accessModes PV Access Mode ## accessModes: - - ReadWriteOnce + - ReadWriteMany ## @param persistence.size PVC Storage Request ## size: 10Gi + ## Fine tuning for volumeClaimTemplates + ## + reclaimPolicy: Retain + existingClaim: + enabled: + name: + claimName: + efs: + enabled: + driver: + volumeHandle: + volumeClaimTemplates: + ## @param persistence.volumeClaimTemplates.selector A label query over volumes to consider for binding (e.g. when using local volumes) + ## A label query over volumes to consider for binding (e.g. when using local volumes) + ## See https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.20/#labelselector-v1-meta for more details + ## + selector: {} + ## @param persistence.volumeClaimTemplates.requests Custom PVC requests attributes + ## Sometime cloud providers use additional requests attributes to provision custom storage instance + ## See https://cloud.ibm.com/docs/containers?topic=containers-file_storage#file_dynamic_statefulset + ## + requests: {} + ## @param persistence.volumeClaimTemplates.dataSource Add dataSource to the VolumeClaimTemplate + ## + dataSource: {} # tags: # install-ingress-nginx: true storageClass: @@ -279,6 +376,25 @@ storageClass: ## parameters: {} +podDisruptionBudgets: + enabled: true + minAvailable: 1 + +metrics: + enabled: false + port: 2019 + +keda: + enabled: false + pollingInterval: 30 + cooldownPeriod: 60 + minReplicaCount: 1 + maxReplicaCount: 6 + fallback: + failureThreshold: 3 + replicas: 4 + triggers: [] + autoupdate: ## @param autoupdate.enabled - Enable config autoupdate ## @@ -316,5 +432,8 @@ applicationConfig: APPSMITH_ENCRYPTION_SALT: "" APPSMITH_CUSTOM_DOMAIN: "" APPSMITH_DISABLE_IFRAME_WIDGET_SANDBOX: "false" - -#HTTPContainerPort: 8080 + APPSMITH_LICENSE_KEY: "" + APPSMITH_KEYCLOAK_DB_DRIVER: "" + APPSMITH_KEYCLOAK_DB_USERNAME: "" + APPSMITH_KEYCLOAK_DB_PASSWORD: "" + APPSMITH_KEYCLOAK_DB_URL: "" diff --git a/scripts/deploy_preview.sh b/scripts/deploy_preview.sh index f7d7873fdb10..194c1463c28e 100755 --- a/scripts/deploy_preview.sh +++ b/scripts/deploy_preview.sh @@ -99,6 +99,7 @@ helm upgrade -i "$CHARTNAME" "appsmith-ee/$HELMCHART" -n "$NAMESPACE" --create-n --set persistence.efs.driver=efs.csi.aws.com --set persistence.storageClass=efs-dp-appsmith \ --set persistence.efs.volumeHandle="$DP_EFS_ID:/$edition/$edition$PULL_REQUEST_NUMBER" \ --set resources.requests.cpu="1m" \ + --set podDisruptionBudgets.enabled=false \ --set resources.requests.memory="2048Mi" \ --set applicationConfig.APPSMITH_SENTRY_DSN="https://abf15a075d1347969df44c746cca7eaa@o296332.ingest.sentry.io/1546547" \ --set applicationConfig.APPSMITH_SENTRY_ENVIRONMENT="$NAMESPACE" \ From d718437b6a2a89ff9ade5bc4d4ba030745a815e6 Mon Sep 17 00:00:00 2001 From: Nidhi Date: Wed, 1 Jan 2025 15:30:29 +0530 Subject: [PATCH 12/13] chore: Added capability of running ITs using ok-to-test (#38355) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description > [!TIP] > _Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content, marketing, and DevRel team)._ > > _Please also include relevant motivation and context. List any dependencies that are required for this change. Add links to Notion, Figma or any other documents that might be relevant to the PR._ Fixes #`Issue Number` _or_ Fixes `Issue URL` > [!WARNING] > _If no issue exists, please create an issue first, and check with the maintainers if the issue is valid._ ## Automation /ok-to-test tags="@tag.Git" it=true ### :mag: Cypress test results > [!TIP] > 🟒 🟒 🟒 All cypress tests have passed! πŸŽ‰ πŸŽ‰ πŸŽ‰ > Workflow run: > Commit: 28ec34d9b20246ce54b7deab8e9fa8e136bbd7ff > Cypress dashboard. > Tags: `@tag.Git` > Spec: >
Mon, 30 Dec 2024 15:48:17 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No ## Summary by CodeRabbit - **New Features** - Added optional integration tests trigger across multiple GitHub Actions workflows - Enhanced test configuration and reporting mechanisms - **Chores** - Updated workflow input parameters and descriptions - Improved test execution and artifact management - **Documentation** - Added clarifying comments in test scripts about test prerequisites --- .github/workflows/pr-automation.yml | 2 + .github/workflows/pr-cypress.yml | 15 ++- .github/workflows/scripts/test-tag-parser.js | 32 ++++-- .github/workflows/server-build.yml | 9 +- .../workflows/server-integration-tests.yml | 108 ++++++++++++++++++ .../appsmith/server/git/GitBranchesIT.java | 2 + 6 files changed, 153 insertions(+), 15 deletions(-) create mode 100644 .github/workflows/server-integration-tests.yml diff --git a/.github/workflows/pr-automation.yml b/.github/workflows/pr-automation.yml index 622274e97451..41d3f8d5e0f5 100644 --- a/.github/workflows/pr-automation.yml +++ b/.github/workflows/pr-automation.yml @@ -71,6 +71,7 @@ jobs: shell: bash outputs: tags: ${{ steps.parseTags.outputs.tags }} + its: ${{ steps.parseTags.outputs.its }} spec: ${{ steps.parseTags.outputs.spec }} matrix: ${{ steps.checkAll.outputs.matrix }} steps: @@ -129,6 +130,7 @@ jobs: uses: ./.github/workflows/pr-cypress.yml secrets: inherit with: + its: ${{ needs.parse-tags.outputs.its}} tags: ${{ needs.parse-tags.outputs.tags}} spec: ${{ needs.parse-tags.outputs.spec}} matrix: ${{ needs.parse-tags.outputs.matrix}} diff --git a/.github/workflows/pr-cypress.yml b/.github/workflows/pr-cypress.yml index 186ca9a63116..f525f54516bc 100644 --- a/.github/workflows/pr-cypress.yml +++ b/.github/workflows/pr-cypress.yml @@ -3,6 +3,10 @@ name: Cypress test suite on: workflow_call: inputs: + its: + required: false + type: string + default: "false" tags: required: true type: string @@ -45,6 +49,15 @@ jobs: with: pr: ${{ github.event.number }} + server-it: + needs: [ server-build, rts-build ] + if: success() && inputs.its == 'true' + uses: ./.github/workflows/server-integration-tests.yml + secrets: inherit + with: + pr: ${{ github.event.number }} + is-pg-build: ${{ github.event.pull_request.base.ref == 'pg' }} + build-docker-image: needs: [client-build, server-build, rts-build] # Only run if the build step is successful @@ -69,7 +82,7 @@ jobs: matrix: ${{ inputs.matrix }} ci-test-result: - needs: [ci-test] + needs: [ci-test, server-it] # Only run if the ci-test with matrices step is successful if: always() runs-on: ubuntu-latest diff --git a/.github/workflows/scripts/test-tag-parser.js b/.github/workflows/scripts/test-tag-parser.js index 2ba8708f810d..f303f3a40f1c 100644 --- a/.github/workflows/scripts/test-tag-parser.js +++ b/.github/workflows/scripts/test-tag-parser.js @@ -21,6 +21,7 @@ module.exports = function ({core, context, github}) { } core.setOutput("tags", parseResult.tags ?? ""); + core.setOutput("its", parseResult.its ?? ""); core.setOutput("spec", parseResult.spec ?? ""); } @@ -28,18 +29,29 @@ function parseTags(body) { const allTags = require(process.env.GITHUB_WORKSPACE + "/app/client/cypress/tags.js").Tag; // "/ok-to-test" matcher. Takes precedence over the "/test" matcher. - const strictMatch = body.match(/^\/ok-to-test tags="(.+?)"/m)?.[1]; - if (strictMatch) { - if (strictMatch === "@tag.All") { - return { tags: strictMatch }; - } - const parts = strictMatch.split(/\s*,\s*/); - for (const part of parts) { - if (!allTags.includes(part)) { - throw new Error("Unknown tag: " + part); + const okToTestPattern = body.match(/^(\/ok-to-test) tags="(.+?)"( it=true)?/m); + + if (okToTestPattern?.[1]) { + var response = {}; + const tagsMatch = okToTestPattern?.[2]; + if (tagsMatch) { + if (tagsMatch === "@tag.All") { + response = { tags: tagsMatch }; + } else { + const parts = tagsMatch.split(/\s*,\s*/); + for (const part of parts) { + if (!allTags.includes(part)) { + throw new Error("Unknown tag: " + part); + } + } + response = { tags: tagsMatch }; } } - return { tags: strictMatch }; + const itsMatch = okToTestPattern?.[3]; + if (itsMatch) { + response = { ...response, its: 'true' }; + } + return response; } // "/test" code-fence matcher. diff --git a/.github/workflows/server-build.yml b/.github/workflows/server-build.yml index df1c1334ccab..55691d6a049e 100644 --- a/.github/workflows/server-build.yml +++ b/.github/workflows/server-build.yml @@ -5,20 +5,20 @@ on: workflow_call: inputs: pr: - description: "This is the PR number in case the workflow is being called in a pull request" + description: "PR number for the workflow" required: false type: number skip-tests: - description: "This is a boolean value in case the workflow is being called in build deploy-preview" + description: "Skip tests flag" required: false type: string default: "false" branch: - description: "This is the branch to be used for the build." + description: "Branch for the build" required: false type: string is-pg-build: - description: "This is a boolean value in case the workflow is being called for a PG build" + description: "Flag for PG build" required: false type: string default: "false" @@ -210,6 +210,7 @@ jobs: fi args=() + if [[ "${{ steps.run_result.outputs.run_result }}" == "failedtest" ]]; then failed_tests="${{ steps.failed_tests.outputs.tests }}" args+=("-DfailIfNoTests=false" "-Dsurefire.failIfNoSpecifiedTests=false" "-Dtest=${failed_tests}") diff --git a/.github/workflows/server-integration-tests.yml b/.github/workflows/server-integration-tests.yml new file mode 100644 index 000000000000..a4c4836ba238 --- /dev/null +++ b/.github/workflows/server-integration-tests.yml @@ -0,0 +1,108 @@ +name: Server Integrations Tests Workflow + +on: + # This line enables manual triggering of this workflow. + workflow_dispatch: + workflow_call: + inputs: + pr: + description: "This is the PR number in case the workflow is being called in a pull request" + required: false + type: number + is-pg-build: + description: "Flag for PG build" + required: false + type: string + default: "false" + +jobs: + run-tests: + runs-on: ubuntu-latest-8-cores + if: | + github.event.pull_request.head.repo.full_name == github.repository || + github.event_name == 'workflow_dispatch' + defaults: + run: + shell: bash + # Service containers to run with this job. Required for running tests + services: + # Label used to access the service container + redis: + # Docker Hub image for Redis + image: redis + ports: + # Opens tcp port 6379 on the host and service container + - 6379:6379 + + steps: + # Check out merge commit + - name: Fork based /ok-to-test checkout + if: inputs.pr != 0 + uses: actions/checkout@v4 + with: + ref: "refs/pull/${{ inputs.pr }}/merge" + + # Checkout the code in the current branch in case the workflow is called because of a branch push event + - name: Checkout the head commit of the branch + if: inputs.pr == 0 + uses: actions/checkout@v4 + + # Setup Java + - name: Set up JDK 17 + uses: actions/setup-java@v4 + with: + distribution: "temurin" + java-version: "17" + + - name: Conditionally start PostgreSQL + if: | + inputs.is-pg-build == 'true' + run: | + docker run --name appsmith-pg -p 5432:5432 -d -e POSTGRES_PASSWORD=password postgres:alpine postgres -N 1500 + + - name: Download the server build artifact + uses: actions/download-artifact@v4 + with: + name: server-build + path: app/server/dist/ + + - name: Download the rts build artifact + uses: actions/download-artifact@v4 + with: + name: rts-dist + path: app/client/packages/rts/dist + + - name: Un-tar the rts folder + run: | + tar -xvf app/client/packages/rts/dist/rts-dist.tar -C app/client/packages/rts/ + echo "Cleaning up the rts tar files" + rm app/client/packages/rts/dist/rts-dist.tar + + - name: Run rts using the untarred files + run: | + nohup -- node app/client/packages/rts/dist/bundle/server.js & + + - name: Run only integration tests on server + env: + ACTIVE_PROFILE: test + APPSMITH_CLOUD_SERVICES_BASE_URL: "https://release-cs.appsmith.com" + APPSMITH_CLOUD_SERVICES_TEMPLATE_UPLOAD_AUTH: ${{ secrets.APPSMITH_CLOUD_SERVICES_TEMPLATE_UPLOAD_AUTH }} + APPSMITH_REDIS_URL: "redis://127.0.0.1:6379" + APPSMITH_ENCRYPTION_PASSWORD: "password" + APPSMITH_ENCRYPTION_SALT: "salt" + APPSMITH_ENVFILE_PATH: /tmp/dummy.env + APPSMITH_VERBOSE_LOGGING_ENABLED: false + run: | + if [[ "${{ inputs.is-pg-build }}" == "true" ]]; then + export APPSMITH_DB_URL="postgresql://postgres:password@localhost:5432/postgres" + else + export APPSMITH_DB_URL="mongodb://localhost:27017/mobtools" + fi + + args=() + + # Run tests and capture logs + cd app/server + mvn verify -DskipUTs=true "${args[@]}" | tee mvn_integration_test.log + + diff --git a/app/server/appsmith-server/src/test/it/com/appsmith/server/git/GitBranchesIT.java b/app/server/appsmith-server/src/test/it/com/appsmith/server/git/GitBranchesIT.java index 02607420a8f6..a20345d049d4 100644 --- a/app/server/appsmith-server/src/test/it/com/appsmith/server/git/GitBranchesIT.java +++ b/app/server/appsmith-server/src/test/it/com/appsmith/server/git/GitBranchesIT.java @@ -212,6 +212,8 @@ void test(GitContext gitContext, ExtensionContext extensionContext) throws IOExc assertThat(autoCommitResponseDTO).isNotNull(); AutoCommitResponseDTO.AutoCommitResponse autoCommitProgress = autoCommitResponseDTO.getAutoCommitResponse(); + // This check requires RTS to be running on your local since client side changes come in from there + // Please make sure to run RTS before triggering this test assertThat(autoCommitProgress).isEqualTo(AutoCommitResponseDTO.AutoCommitResponse.PUBLISHED); // Wait for auto-commit to complete From 463c1199e17c0bf086f85cbd9ad5ccc7ebc64b30 Mon Sep 17 00:00:00 2001 From: Sagar Khalasi Date: Wed, 1 Jan 2025 15:31:30 +0530 Subject: [PATCH 13/13] fix: fix oracle spec (#38435) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## Description Issue with oracle spec in hosted version of ci. Fixes # https://app.zenhub.com/workspaces/stability-pod-6690c4814e31602e25cab7fd/issues/gh/appsmithorg/appsmith/38434 Success RUN: https://internal.appsmith.com/app/cypress-dashboard/all-runs-65890b3c81d7400d08fa9ede?branch=master ## Automation /ok-to-test tags="@tag.Sanity" ### :mag: Cypress test results > [!TIP] > 🟒 🟒 🟒 All cypress tests have passed! πŸŽ‰ πŸŽ‰ πŸŽ‰ > Workflow run: > Commit: 3283b4d9ea35b290c1a58ab186c4b01fed1e9609 > Cypress dashboard. > Tags: `@tag.Sanity` > Spec: >
Wed, 01 Jan 2025 07:26:18 UTC ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [x] No ## Summary by CodeRabbit - **Tests** - Enhanced Oracle data source test suite with improved query validation - Refined SQL query formatting and test case structure - Simplified application deployment process in test scenarios --- .../ServerSide/Datasources/Oracle_Spec.ts | 196 +++++++++--------- 1 file changed, 102 insertions(+), 94 deletions(-) diff --git a/app/client/cypress/e2e/Regression/ServerSide/Datasources/Oracle_Spec.ts b/app/client/cypress/e2e/Regression/ServerSide/Datasources/Oracle_Spec.ts index 440174aefb6c..5cb3cfb1b071 100644 --- a/app/client/cypress/e2e/Regression/ServerSide/Datasources/Oracle_Spec.ts +++ b/app/client/cypress/e2e/Regression/ServerSide/Datasources/Oracle_Spec.ts @@ -19,6 +19,9 @@ import EditorNavigation, { AppSidebar, } from "../../../../support/Pages/EditorNavigation"; import PageList from "../../../../support/Pages/PageList"; +import { PluginActionForm } from "../../../../support/Pages/PluginActionForm"; + +let pluginActionForm = new PluginActionForm(); describe( "Validate Oracle DS", @@ -145,17 +148,17 @@ describe( propPane.EnterJSContext( "Source Data", `[{ - "name": "Cargo Plane", - "value": "Cargo Plane" - }, - { - "name": "Passenger Plane", - "code": "Passenger Plane" - }, - { - "name": "Helicopter", - "code": "Helicopter" - }]`, + "name": "Cargo Plane", + "value": "Cargo Plane" + }, + { + "name": "Passenger Plane", + "code": "Passenger Plane" + }, + { + "name": "Helicopter", + "code": "Helicopter" + }]`, ); propPane.UpdatePropertyFieldValue( "Default selected value", @@ -183,17 +186,17 @@ describe( true, ); query = `CREATE TABLE ${guid} ( - aircraft_id NUMBER(5) PRIMARY KEY, - aircraft_type VARCHAR2(50) NOT NULL, - registration_number VARCHAR2(20) UNIQUE, - manufacturer VARCHAR2(50), - seating_capacity NUMBER(3), - maximum_speed NUMBER(5, 2), - range NUMBER(7, 2), - purchase_date DATE, - maintenance_last_date DATE, - notes CLOB - );`; + aircraft_id NUMBER(5) PRIMARY KEY, + aircraft_type VARCHAR2(50) NOT NULL, + registration_number VARCHAR2(20) UNIQUE, + manufacturer VARCHAR2(50), + seating_capacity NUMBER(3), + maximum_speed NUMBER(5, 2), + range NUMBER(7, 2), + purchase_date DATE, + maintenance_last_date DATE, + notes CLOB + );`; dataSources.CreateQueryForDS(dataSourceName, query); dataSources.RunQuery(); @@ -244,31 +247,31 @@ describe( dataSources.EnterQuery(query); dataSources.RunQuery(); query = `INSERT INTO ${guid} ( - aircraft_id, - aircraft_type, - registration_number, - manufacturer, - seating_capacity, - maximum_speed, - range, - purchase_date, - maintenance_last_date, - notes, - raw_data, - maintenance_interval) VALUES ( - 4, - 'Passenger Plane', - 'N77777', - 'Airbus', - 100, - 600.67, - 3800.82, - TO_DATE('2017-05-25', 'YYYY-MM-DD'), - TO_DATE('2023-02-18', 'YYYY-MM-DD'), - 'This aircraft is part of the international fleet.', - UTL_RAW.CAST_TO_RAW('raw_value'), - INTERVAL '1' YEAR(3) -- 1 year maintenance interval -);`; + aircraft_id, + aircraft_type, + registration_number, + manufacturer, + seating_capacity, + maximum_speed, + range, + purchase_date, + maintenance_last_date, + notes, + raw_data, + maintenance_interval) VALUES ( + 4, + 'Passenger Plane', + 'N77777', + 'Airbus', + 100, + 600.67, + 3800.82, + TO_DATE('2017-05-25', 'YYYY-MM-DD'), + TO_DATE('2023-02-18', 'YYYY-MM-DD'), + 'This aircraft is part of the international fleet.', + UTL_RAW.CAST_TO_RAW('raw_value'), + INTERVAL '1' YEAR(3) -- 1 year maintenance interval + );`; dataSources.EnterQuery(query); dataSources.RunQuery(); dataSources.EnterQuery(selectQuery); @@ -339,7 +342,11 @@ describe( dataSources.EnterQuery(selectQuery); dataSources.runQueryAndVerifyResponseViews({ count: 2 }); dataSources.AddSuggestedWidget(Widgets.Table); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.TABLE)); + deployMode.DeployApp(); + agHelper.AssertElementAbsence(locators._loading); + agHelper.WaitUntilEleAppear( + locators._widgetInDeployed(draggableWidgets.TABLE), + ); table.WaitUntilTableLoad(0, 0, "v2"); table.ReadTableRowColumnData(0, 10, "v2").then(($cellData) => { expect($cellData).to.be.empty; @@ -359,18 +366,18 @@ describe( it("4. Tc #2362 - Update query validation", () => { EditorNavigation.SelectEntityByName("Query1", EntityType.Query); query = `UPDATE ${guid} -SET - maximum_speed = CASE - WHEN seating_capacity <= 100 THEN 400.89 - WHEN seating_capacity > 100 AND seating_capacity <= 200 THEN 500.96 - ELSE 600.00 - END, - maintenance_interval = CASE - WHEN seating_capacity <= 50 THEN INTERVAL '3' MONTH - WHEN seating_capacity > 50 AND seating_capacity <= 150 THEN TO_YMINTERVAL('0-6') - ELSE TO_YMINTERVAL('1-0') - END -WHERE aircraft_type = 'Passenger Plane'`; + SET + maximum_speed = CASE + WHEN seating_capacity <= 100 THEN 400.89 + WHEN seating_capacity > 100 AND seating_capacity <= 200 THEN 500.96 + ELSE 600.00 + END, + maintenance_interval = CASE + WHEN seating_capacity <= 50 THEN INTERVAL '3' MONTH + WHEN seating_capacity > 50 AND seating_capacity <= 150 THEN TO_YMINTERVAL('0-6') + ELSE TO_YMINTERVAL('1-0') + END + WHERE aircraft_type = 'Passenger Plane'`; dataSources.EnterQuery(query); dataSources.RunQuery(); selectQuery = selectQuery + ` or aircraft_type = 'Passenger Plane'`; @@ -380,7 +387,12 @@ WHERE aircraft_type = 'Passenger Plane'`; Widgets.Table, dataSources._addSuggestedExisting, ); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.TABLE)); + agHelper.RefreshPage(); + deployMode.DeployApp(); + agHelper.AssertElementAbsence(locators._loading); + agHelper.WaitUntilEleAppear( + locators._widgetInDeployed(draggableWidgets.TABLE), + ); table.WaitUntilTableLoad(0, 0, "v2"); table.ReadTableRowColumnData(1, 5, "v2").then(($cellData) => { expect($cellData).to.eq("400.89"); @@ -394,12 +406,12 @@ WHERE aircraft_type = 'Passenger Plane'`; it("5. Tc #2361 - Delete query validation", () => { EditorNavigation.SelectEntityByName("Query1", EntityType.Query); query = `DELETE FROM ${guid} - WHERE - (aircraft_type = 'Cargo Plane' AND seating_capacity <= 100) - OR - (aircraft_type = 'Passenger Plane' AND purchase_date < TO_DATE('2020-01-01', 'YYYY-MM-DD')) - OR - (aircraft_type = 'Helicopter' AND manufacturer = 'Robinson' AND maintenance_interval = INTERVAL '6' MONTH)`; + WHERE + (aircraft_type = 'Cargo Plane' AND seating_capacity <= 100) + OR + (aircraft_type = 'Passenger Plane' AND purchase_date < TO_DATE('2020-01-01', 'YYYY-MM-DD')) + OR + (aircraft_type = 'Helicopter' AND manufacturer = 'Robinson' AND maintenance_interval = INTERVAL '6' MONTH)`; dataSources.EnterQuery(query); dataSources.RunQuery(); selectQuery = `SELECT * FROM ${guid}`; @@ -409,25 +421,21 @@ WHERE aircraft_type = 'Passenger Plane'`; Widgets.Table, dataSources._addSuggestedExisting, ); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.TABLE)); + deployMode.DeployApp(); + agHelper.AssertElementAbsence(locators._loading); + agHelper.WaitUntilEleAppear( + locators._widgetInDeployed(draggableWidgets.TABLE), + ); table.WaitUntilTableLoad(0, 0, "v2"); for (let i = 0; i < 2; i++) { table.ReadTableRowColumnData(i, 1, "v2").then(($cellData) => { expect($cellData).to.eq("Cargo Plane"); }); } - - table.OpenNFilterTable("MAINTENANCE_INTERVAL", "not empty"); - table.ReadTableRowColumnData(0, 0, "v2").then(($cellData) => { + table.ReadTableRowColumnData(1, 0, "v2").then(($cellData) => { expect($cellData).to.eq("5"); }); - agHelper - .GetText(table._showPageItemsCount) - .then(($count) => expect($count).contain("1")); - table.CloseFilter(); - agHelper - .GetText(table._filtersCount) - .then(($count) => expect($count).contain("1")); + deployMode.NavigateBacktoEditor(); }); @@ -459,30 +467,30 @@ WHERE aircraft_type = 'Passenger Plane'`; }); it("7. Tc #2365 - Query settings tab validations", () => { - apiPage.ToggleOnPageLoadRun(false); // ALl above cases validated for onpage load run with confirmation dialog set to false + apiPage.ToggleOnPageLoadRun(false); // All above cases validated for onpage load run with confirmation dialog set to false + pluginActionForm.toolbar.toggleSettings(); apiPage.ToggleConfirmBeforeRunning(true); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.TABLE)); + deployMode.DeployApp(); + agHelper.AssertElementAbsence(locators._loading); + agHelper.WaitUntilEleAppear( + locators._widgetInDeployed(draggableWidgets.TABLE), + ); table.WaitForTableEmpty("v2"); deployMode.NavigateBacktoEditor(); entityExplorer.DragDropWidgetNVerify(draggableWidgets.BUTTON, 300, 500); propPane.EnterJSContext("onClick", `{{Query1.run()}}`); - deployMode.DeployApp(locators._widgetInDeployed(draggableWidgets.TABLE)); + deployMode.DeployApp(); + agHelper.AssertElementAbsence(locators._loading); + agHelper.WaitUntilEleAppear( + locators._widgetInDeployed(draggableWidgets.TABLE), + ); agHelper.ClickButton("Submit"); jsEditor.ConfirmationClick("No"); //Handling both No & Yes from confirmation dialog - - table.WaitUntilTableLoad(0, 0, "v2"); + agHelper.AssertElementAbsence(locators._loading); + agHelper.WaitUntilEleAppear( + locators._widgetInDeployed(draggableWidgets.TABLE), + ); deployMode.NavigateBacktoEditor(); }); - - after( - "Verify Deletion of the Oracle datasource after all created queries are deleted", - () => { - dataSources.DeleteDatasourceFromWithinDS(dataSourceName, 409); //Since all queries exists - entityExplorer.DeleteAllQueriesForDB(dataSourceName); - deployMode.DeployApp(); - deployMode.NavigateBacktoEditor(); - dataSources.DeleteDatasourceFromWithinDS(dataSourceName, 200); - }, - ); }, );